diff --git a/BUILD.gn b/BUILD.gn index 58ff72d9..d05b1f7 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -843,6 +843,24 @@ "//media/gpu:video_encode_accelerator_unittest", ] } + + # The following run-time dependencies are needed to deploy chrome to a + # ChromeOS device. See the link for the full list: + # https://codesearch.chromium.org/chromium/src/third_party/chromite/lib/chrome_util.py?l=341 + # Most of these are copy targets, for which GN doesn't add their outputs + # as runtime-deps. See the link below for more details: + # https://chromium.googlesource.com/chromium/src/+/master/tools/gn/docs/reference.md#actions-and-copies + data_deps = [ + "//chrome:xdg_mime", + "//mojo/edk:mojo_core_arc32", + "//mojo/edk:mojo_core_arc64", + ] + + # TODO(bpastene): Figure out what's generating resources/chromeos/ and + # declare it as a dep instead of adding the dir directly. + data = [ + "$root_out_dir/resources/chromeos/", + ] } }
diff --git a/DEPS b/DEPS index 53db2a1e..5b8e921 100644 --- a/DEPS +++ b/DEPS
@@ -105,11 +105,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': '4359d529121fc1f39f882693d641c0133d138d41', + 'skia_revision': 'ae17e65ef4b46ec007df4aa04dbc389ee757c9ba', # 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': '9edff1c22685d21a282af9951040b0fee3caca73', + 'v8_revision': '160d28151492af5a89004945d43a3a37daeba008', # 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. @@ -117,7 +117,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': 'a914f7ff310df18ce64185bee69bdf9275b4463f', + 'angle_revision': 'cd70aa422ce61a94fa5727822cd821f3a7dc5a5f', # 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. @@ -125,11 +125,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '1fa20678010892b3b531e7449f25079868dfba45', + 'swiftshader_revision': '20eea3cd3b2d64e1b8f9811824cb41cacd09389c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'e005dc33c31a2e701e1af3a0a3e5775cabbf1ddd', + 'pdfium_revision': 'd9fb538bc08c4923fbfd3d50c47a61716d679956', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -165,7 +165,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': 'f153b902bec3811dd5faa9e807240b059e7bbc8c', + 'catapult_revision': 'f3c454475aeea9450e3f90de9e9430a335795496', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -518,7 +518,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '2ac4352aea1751d8e928d3e4db519ba9a73a22a9', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0d22d3fa3ae1e575fd0f5baa4d56e94e71ca9011', 'condition': 'checkout_linux', }, @@ -533,7 +533,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': { - 'url': Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '557c37af39f5195d80aaad53c3a06b5ec804da95', + 'url': Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '0e2a5fd43dc395b3fd526c8f726911871597dd82', 'condition': 'checkout_linux', }, @@ -543,7 +543,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1cabdc464313eee47fdc52a95b3f8e028680000d', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a28b14f122463a6d73c623e77c9dea4e228322dc', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -578,7 +578,7 @@ }, 'src/third_party/ffmpeg': - Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'f7d78b109d177427b9519cc41e73126ee86c0382', + Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'c3b8d611c12f31f9df0c0f7a86f1723b33a414fc', 'src/third_party/flac': Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'af862024c8c8fa0ae07ced05e89013d881b00596', @@ -891,7 +891,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '0ff6498e4181c3e3589e59fa68bcbb5ba85672f3', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c203a76fa4008f3dd0b0fa8105953aed49bc7872', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1010,7 +1010,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5e83981c2c44f24109b96b555d6865d481e0c609', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '056a68da896d9a578b9ea83e56d261648ea0adc6', + Var('webrtc_git') + '/src.git' + '@' + '5b8dd4d75ec351e9326c24b42350015db63c3e7b', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1044,7 +1044,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7c2b573628be45199398f14d247482e2333db198', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@393d20a8e911477cf61a676f321c9ecbd66c811f', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_autofill_client.cc b/android_webview/browser/aw_autofill_client.cc index a5f6676..d8cc41c 100644 --- a/android_webview/browser/aw_autofill_client.cc +++ b/android_webview/browser/aw_autofill_client.cc
@@ -91,6 +91,13 @@ return nullptr; } +security_state::SecurityLevel +AwAutofillClient::GetSecurityLevelForUmaHistograms() { + // The metrics are not recorded for Android webview, so return the count value + // which will not be recorded. + return security_state::SecurityLevel::SECURITY_LEVEL_COUNT; +} + autofill::PersonalDataManager* AwAutofillClient::GetPersonalDataManager() { return nullptr; }
diff --git a/android_webview/browser/aw_autofill_client.h b/android_webview/browser/aw_autofill_client.h index 54cdfda..7567143 100644 --- a/android_webview/browser/aw_autofill_client.h +++ b/android_webview/browser/aw_autofill_client.h
@@ -67,6 +67,7 @@ ukm::UkmRecorder* GetUkmRecorder() override; ukm::SourceId GetUkmSourceId() override; autofill::AddressNormalizer* GetAddressNormalizer() override; + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt( const autofill::CreditCard& card,
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java index 86df132..d0c2ded 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
@@ -4,6 +4,7 @@ package com.android.webview.chromium; +import android.webkit.WebChromeClient; import android.webkit.WebViewClient; import org.chromium.android_webview.AwContents; @@ -27,6 +28,7 @@ final static WebViewClient sNullWebViewClient = new WebViewClient(); // The WebViewClient instance that was passed to WebView.setWebViewClient(). private WebViewClient mWebViewClient = sNullWebViewClient; + private WebChromeClient mWebChromeClient; public SharedWebViewChromium(WebViewChromiumRunQueue runQueue, WebViewChromiumAwInit awInit) { mRunQueue = runQueue; @@ -41,6 +43,14 @@ return mWebViewClient; } + void setWebChromeClient(WebChromeClient client) { + mWebChromeClient = client; + } + + public WebChromeClient getWebChromeClient() { + return mWebChromeClient; + } + public void setAwContentsOnUiThread(AwContents awContents) { assert ThreadUtils.runningOnUiThread();
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java index 7dc61f0..e092a73 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -457,7 +457,7 @@ } // Make sure that we do not trigger any callbacks after destruction - mContentsClientAdapter.setWebChromeClient(null); + setWebChromeClient(null); setWebViewClient(null); mContentsClientAdapter.setPictureListener(null, true); mContentsClientAdapter.setFindListener(null); @@ -1295,12 +1295,13 @@ @Override public void setWebChromeClient(WebChromeClient client) { mWebSettings.getAwSettings().setFullscreenSupported(doesSupportFullscreen(client)); - mContentsClientAdapter.setWebChromeClient(client); + mSharedWebViewChromium.setWebChromeClient(client); + mContentsClientAdapter.setWebChromeClient(mSharedWebViewChromium.getWebChromeClient()); } @Override public WebChromeClient getWebChromeClient() { - return mContentsClientAdapter.getWebChromeClient(); + return mSharedWebViewChromium.getWebChromeClient(); } /**
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index 37a62633..4a25fd9c 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -165,6 +165,11 @@ // WebView does not support AndroidOverlay yet for video overlays. CommandLineHelper::AddDisabledFeature(*cl, media::kUseAndroidOverlay.name); + // WebView doesn't support embedding CompositorFrameSinks which is needed for + // UseSurfaceLayerForVideo feature. https://crbug.com/853832 + CommandLineHelper::AddDisabledFeature(*cl, + media::kUseSurfaceLayerForVideo.name); + // WebView does not support EME persistent license yet, because it's not // clear on how user can remove persistent media licenses from UI. CommandLineHelper::AddDisabledFeature(*cl,
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java index b15bee3..3f291a8 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
@@ -5,6 +5,7 @@ package org.chromium.support_lib_boundary; import android.net.Uri; +import android.webkit.WebChromeClient; import android.webkit.WebViewClient; import java.lang.reflect.InvocationHandler; @@ -17,4 +18,5 @@ /* WebMessagePort */ InvocationHandler[] createWebMessageChannel(); void postMessageToMainFrame(/* WebMessage */ InvocationHandler message, Uri targetOrigin); WebViewClient getWebViewClient(); + WebChromeClient getWebChromeClient(); }
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java index b6f1a43..a214a6fd 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
@@ -121,4 +121,7 @@ // WebViewCompat.getWebViewClient public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT"; + + // WebViewCompat.getWebChromeClient + public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT"; }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java index eae8aa5c..e631978 100644 --- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java +++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java
@@ -5,6 +5,7 @@ package org.chromium.support_lib_glue; import android.net.Uri; +import android.webkit.WebChromeClient; import android.webkit.WebViewClient; import com.android.webview.chromium.SharedWebViewChromium; @@ -64,4 +65,9 @@ public WebViewClient getWebViewClient() { return mSharedWebViewChromium.getWebViewClient(); } + + @Override + public WebChromeClient getWebChromeClient() { + return mSharedWebViewChromium.getWebChromeClient(); + } }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java index 45fcf9cc..ffc88c4 100644 --- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java +++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
@@ -61,7 +61,8 @@ Features.CREATE_WEB_MESSAGE_CHANNEL, Features.POST_WEB_MESSAGE, Features.WEB_MESSAGE_CALLBACK_ON_MESSAGE, - Features.GET_WEB_VIEW_CLIENT + Features.GET_WEB_VIEW_CLIENT, + Features.GET_WEB_CHROME_CLIENT }; // clang-format on
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index ff141c0..1ef7966 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -92,21 +92,23 @@ "ash_export.h", "ash_service.cc", "ash_service.h", - "assistant/assistant_bubble_controller.cc", - "assistant/assistant_bubble_controller.h", "assistant/assistant_controller.cc", "assistant/assistant_controller.h", - "assistant/model/assistant_bubble_model.cc", - "assistant/model/assistant_bubble_model.h", - "assistant/model/assistant_bubble_model_observer.h", + "assistant/assistant_interaction_controller.cc", + "assistant/assistant_interaction_controller.h", + "assistant/assistant_ui_controller.cc", + "assistant/assistant_ui_controller.h", "assistant/model/assistant_interaction_model.cc", "assistant/model/assistant_interaction_model.h", "assistant/model/assistant_interaction_model_observer.h", "assistant/model/assistant_query.cc", "assistant/model/assistant_query.h", "assistant/model/assistant_ui_element.h", - "assistant/ui/assistant_bubble_view.cc", - "assistant/ui/assistant_bubble_view.h", + "assistant/model/assistant_ui_model.cc", + "assistant/model/assistant_ui_model.h", + "assistant/model/assistant_ui_model_observer.h", + "assistant/ui/assistant_container_view.cc", + "assistant/ui/assistant_container_view.h", "assistant/ui/assistant_main_view.cc", "assistant/ui/assistant_main_view.h", "assistant/ui/assistant_mini_view.cc",
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index be5673c..2dcb310 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -15,6 +15,7 @@ #include "ash/accessibility/accessibility_controller.h" #include "ash/app_list/app_list_controller_impl.h" #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/debug.h" #include "ash/display/display_configuration_controller.h" #include "ash/display/display_move_window_util.h" @@ -671,7 +672,10 @@ // TODO(dmblack): Remove. Enabling eligibility check bypass for development // purposes only. We should otherwise respect the eligibility rules below. if (chromeos::switches::IsAssistantEnabled()) { - Shell::Get()->assistant_controller()->ToggleInteraction(); + Shell::Get() + ->assistant_controller() + ->interaction_controller() + ->ToggleInteraction(); return; } @@ -707,10 +711,14 @@ break; } - if (!chromeos::switches::IsAssistantEnabled()) + if (!chromeos::switches::IsAssistantEnabled()) { Shell::Get()->app_list_controller()->ToggleVoiceInteractionSession(); - else - Shell::Get()->assistant_controller()->ToggleInteraction(); + } else { + Shell::Get() + ->assistant_controller() + ->interaction_controller() + ->ToggleInteraction(); + } } void HandleSuspend() { @@ -777,7 +785,7 @@ } bool CanHandleToggleDictation() { - return chromeos::switches::AreExperimentalAccessibilityFeaturesEnabled(); + return Shell::Get()->accessibility_controller()->IsDictationEnabled(); } void HandleToggleDictation() {
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc index d248aa2..378541d 100644 --- a/ash/accessibility/accessibility_controller.cc +++ b/ash/accessibility/accessibility_controller.cc
@@ -403,10 +403,6 @@ void AccessibilityController::SetDictationEnabled(bool enabled) { if (!active_user_prefs_) return; - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableExperimentalAccessibilityFeatures)) { - return; - } active_user_prefs_->SetBoolean(prefs::kAccessibilityDictationEnabled, enabled);
diff --git a/ash/assistant/assistant_bubble_controller.cc b/ash/assistant/assistant_bubble_controller.cc deleted file mode 100644 index e89613e..0000000 --- a/ash/assistant/assistant_bubble_controller.cc +++ /dev/null
@@ -1,145 +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. - -#include "ash/assistant/assistant_bubble_controller.h" - -#include "ash/assistant/assistant_controller.h" -#include "ash/assistant/ui/assistant_bubble_view.h" -#include "base/optional.h" - -namespace ash { - -AssistantBubbleController::AssistantBubbleController( - AssistantController* assistant_controller) - : assistant_controller_(assistant_controller) { - assistant_controller_->AddInteractionModelObserver(this); -} - -AssistantBubbleController::~AssistantBubbleController() { - assistant_controller_->RemoveInteractionModelObserver(this); - - if (bubble_view_) - bubble_view_->GetWidget()->RemoveObserver(this); -} - -void AssistantBubbleController::AddModelObserver( - AssistantBubbleModelObserver* observer) { - assistant_bubble_model_.AddObserver(observer); -} - -void AssistantBubbleController::RemoveModelObserver( - AssistantBubbleModelObserver* observer) { - assistant_bubble_model_.RemoveObserver(observer); -} - -void AssistantBubbleController::OnWidgetActivationChanged(views::Widget* widget, - bool active) { - if (active) - bubble_view_->RequestFocus(); -} - -void AssistantBubbleController::OnWidgetVisibilityChanged(views::Widget* widget, - bool visible) { - UpdateUiMode(); -} - -void AssistantBubbleController::OnWidgetDestroying(views::Widget* widget) { - // We need to be sure that the Assistant interaction is stopped when the - // widget is closed. Special cases, such as closing the widget via the |ESC| - // key might otherwise go unhandled, causing inconsistencies between the - // widget visibility state and the underlying interaction model state. - assistant_controller_->StopInteraction(); - - bubble_view_->GetWidget()->RemoveObserver(this); - bubble_view_ = nullptr; -} - -void AssistantBubbleController::OnInputModalityChanged( - InputModality input_modality) { - UpdateUiMode(); -} - -void AssistantBubbleController::OnInteractionStateChanged( - InteractionState interaction_state) { - switch (interaction_state) { - case InteractionState::kActive: - Show(); - break; - case InteractionState::kInactive: - Dismiss(); - break; - } -} - -void AssistantBubbleController::OnMicStateChanged(MicState mic_state) { - UpdateUiMode(); -} - -bool AssistantBubbleController::OnCaptionButtonPressed(CaptionButtonId id) { - switch (id) { - case CaptionButtonId::kMinimize: - UpdateUiMode(AssistantUiMode::kMiniUi); - return true; - case CaptionButtonId::kClose: - return false; - } - return false; -} - -void AssistantBubbleController::OnSettingsButtonPressed() { - // TODO(dmblack): Navigate to Assistant settings. - UpdateUiMode(AssistantUiMode::kWebUi); -} - -bool AssistantBubbleController::IsVisible() const { - return bubble_view_ && bubble_view_->GetWidget()->IsVisible(); -} - -void AssistantBubbleController::Show() { - if (!bubble_view_) { - bubble_view_ = new AssistantBubbleView(assistant_controller_); - bubble_view_->GetWidget()->AddObserver(this); - } - bubble_view_->GetWidget()->Show(); -} - -void AssistantBubbleController::Dismiss() { - if (bubble_view_) - bubble_view_->GetWidget()->Hide(); -} - -void AssistantBubbleController::UpdateUiMode( - base::Optional<AssistantUiMode> ui_mode) { - // If a UI mode is provided, we will use it in lieu of updating UI mode on the - // basis of interaction/widget visibility state. - if (ui_mode.has_value()) { - assistant_bubble_model_.SetUiMode(ui_mode.value()); - return; - } - - // When Assistant UI is not visible, we should reset to main UI mode. - if (!IsVisible()) { - assistant_bubble_model_.SetUiMode(AssistantUiMode::kMainUi); - return; - } - - // When the mic is open, we should be in main UI mode. - if (assistant_controller_->interaction_model()->mic_state() == - MicState::kOpen) { - assistant_bubble_model_.SetUiMode(AssistantUiMode::kMainUi); - return; - } - - // When stylus input modality is selected, we should be in mini UI mode. - if (assistant_controller_->interaction_model()->input_modality() == - InputModality::kStylus) { - assistant_bubble_model_.SetUiMode(AssistantUiMode::kMiniUi); - return; - } - - // By default, we will fall back to main UI mode. - assistant_bubble_model_.SetUiMode(AssistantUiMode::kMainUi); -} - -} // namespace ash
diff --git a/ash/assistant/assistant_controller.cc b/ash/assistant/assistant_controller.cc index e8ff4a5..cb6f0ae 100644 --- a/ash/assistant/assistant_controller.cc +++ b/ash/assistant/assistant_controller.cc
@@ -4,56 +4,23 @@ #include "ash/assistant/assistant_controller.h" -#include "ash/assistant/assistant_bubble_controller.h" -#include "ash/assistant/model/assistant_interaction_model_observer.h" -#include "ash/assistant/model/assistant_query.h" -#include "ash/assistant/model/assistant_ui_element.h" -#include "ash/new_window_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" +#include "ash/assistant/assistant_ui_controller.h" #include "ash/session/session_controller.h" #include "ash/shell.h" -#include "ash/strings/grit/ash_strings.h" -#include "ash/system/toast/toast_data.h" -#include "ash/system/toast/toast_manager.h" -#include "ash/voice_interaction/voice_interaction_controller.h" #include "base/bind.h" #include "base/memory/scoped_refptr.h" -#include "base/strings/utf_string_conversions.h" #include "base/unguessable_token.h" -#include "ui/base/l10n/l10n_util.h" #include "ui/snapshot/snapshot.h" namespace ash { -namespace { - -// Toast ----------------------------------------------------------------------- - -constexpr int kToastDurationMs = 2500; -constexpr char kUnboundServiceToastId[] = - "assistant_controller_unbound_service"; - -void ShowToast(const std::string& id, int message_id) { - ToastData toast(id, l10n_util::GetStringUTF16(message_id), kToastDurationMs, - base::nullopt); - Shell::Get()->toast_manager()->Show(toast); -} - -} // namespace - -// AssistantController --------------------------------------------------------- - AssistantController::AssistantController() - : assistant_event_subscriber_binding_(this), - assistant_bubble_controller_( - std::make_unique<AssistantBubbleController>(this)) { - AddInteractionModelObserver(this); - Shell::Get()->highlighter_controller()->AddObserver(this); -} + : assistant_interaction_controller_( + std::make_unique<AssistantInteractionController>()), + assistant_ui_controller_(std::make_unique<AssistantUiController>(this)) {} -AssistantController::~AssistantController() { - Shell::Get()->highlighter_controller()->RemoveObserver(this); - RemoveInteractionModelObserver(this); -} +AssistantController::~AssistantController() = default; void AssistantController::BindRequest( mojom::AssistantControllerRequest request) { @@ -64,10 +31,8 @@ chromeos::assistant::mojom::AssistantPtr assistant) { assistant_ = std::move(assistant); - // Subscribe to Assistant events. - chromeos::assistant::mojom::AssistantEventSubscriberPtr ptr; - assistant_event_subscriber_binding_.Bind(mojo::MakeRequest(&ptr)); - assistant_->AddAssistantEventSubscriber(std::move(ptr)); + // Provide reference to interaction controller. + assistant_interaction_controller_->SetAssistant(assistant_.get()); } void AssistantController::SetAssistantImageDownloader( @@ -75,14 +40,17 @@ assistant_image_downloader_ = std::move(assistant_image_downloader); } -void AssistantController::SetWebContentsManager( - mojom::WebContentsManagerPtr web_contents_manager) { - web_contents_manager_ = std::move(web_contents_manager); -} - void AssistantController::SetAssistantSetup( mojom::AssistantSetupPtr assistant_setup) { assistant_setup_ = std::move(assistant_setup); + + // Provide reference to interaction controller. + assistant_interaction_controller_->SetAssistantSetup(assistant_setup_.get()); +} + +void AssistantController::SetWebContentsManager( + mojom::WebContentsManagerPtr web_contents_manager) { + web_contents_manager_ = std::move(web_contents_manager); } void AssistantController::RequestScreenshot( @@ -123,8 +91,8 @@ // Specify that we will handle top level browser requests. ash::mojom::ManagedWebContentsOpenUrlDelegatePtr ptr; - web_contents_open_url_delegate_bindings_.AddBinding(this, - mojo::MakeRequest(&ptr)); + web_contents_open_url_delegate_bindings_.AddBinding( + assistant_interaction_controller_.get(), mojo::MakeRequest(&ptr)); params->open_url_delegate_ptr_info = ptr.PassInterface(); web_contents_manager_->ManageWebContents(id_token, std::move(params), @@ -159,238 +127,19 @@ assistant_image_downloader_->Download(account_id, url, std::move(callback)); } -void AssistantController::AddInteractionModelObserver( - AssistantInteractionModelObserver* observer) { - assistant_interaction_model_.AddObserver(observer); -} - -void AssistantController::RemoveInteractionModelObserver( - AssistantInteractionModelObserver* observer) { - assistant_interaction_model_.RemoveObserver(observer); -} - -void AssistantController::StartInteraction() { - if (!Shell::Get()->voice_interaction_controller()->setup_completed()) { - assistant_setup_->StartAssistantOptInFlow(); - return; - } - if (!Shell::Get()->voice_interaction_controller()->settings_enabled()) - return; - - if (!assistant_) { - ShowToast(kUnboundServiceToastId, IDS_ASH_ASSISTANT_ERROR_GENERIC); - return; - } - OnInteractionStarted(); -} - -void AssistantController::StopInteraction() { - assistant_interaction_model_.SetInteractionState(InteractionState::kInactive); -} - -void AssistantController::ToggleInteraction() { - if (assistant_interaction_model_.interaction_state() == - InteractionState::kInactive) { - StartInteraction(); - } else { - StopInteraction(); - } -} - -void AssistantController::OnInteractionStateChanged( - InteractionState interaction_state) { - if (interaction_state == InteractionState::kActive) - return; - - // When the user-facing interaction is dismissed, we instruct the service to - // terminate any listening, speaking, or pending query. - has_active_interaction_ = false; - assistant_->StopActiveInteraction(); - - assistant_interaction_model_.ClearInteraction(); - assistant_interaction_model_.SetInputModality(InputModality::kKeyboard); -} - -void AssistantController::OnCommittedQueryChanged( - const AssistantQuery& committed_query) { - // We clear the interaction when a query is committed, but need to retain - // the committed query as it is query that is currently being fulfilled. - assistant_interaction_model_.ClearInteraction( - /*retain_committed_query=*/true); -} - -void AssistantController::OnHighlighterEnabledChanged( - HighlighterEnabledState state) { - assistant_interaction_model_.SetInputModality(InputModality::kStylus); - if (state == HighlighterEnabledState::kEnabled) { - assistant_interaction_model_.SetInteractionState(InteractionState::kActive); - } else if (state == HighlighterEnabledState::kDisabledByUser) { - assistant_interaction_model_.SetInteractionState( - InteractionState::kInactive); - } -} - -void AssistantController::OnInputModalityChanged(InputModality input_modality) { - if (input_modality == InputModality::kVoice) - return; - - // When switching to a non-voice input modality we instruct the underlying - // service to terminate any listening, speaking, or pending voice query. We do - // not do this when switching to voice input modality because initiation of a - // voice interaction will automatically interrupt any pre-existing activity. - // Stopping the active interaction here for voice input modality would - // actually have the undesired effect of stopping the voice interaction. - if (assistant_interaction_model_.pending_query().type() == - AssistantQueryType::kVoice) { - has_active_interaction_ = false; - assistant_->StopActiveInteraction(); - assistant_interaction_model_.ClearPendingQuery(); - } -} - -void AssistantController::OnInteractionStarted() { - has_active_interaction_ = true; - assistant_interaction_model_.SetInteractionState(InteractionState::kActive); -} - -void AssistantController::OnInteractionFinished( - AssistantInteractionResolution resolution) { - has_active_interaction_ = false; - - // When a voice query is interrupted we do not receive any follow up speech - // recognition events but the mic is closed. - if (resolution == AssistantInteractionResolution::kInterruption) { - assistant_interaction_model_.SetMicState(MicState::kClosed); - } -} - -void AssistantController::OnHtmlResponse(const std::string& response) { - if (!has_active_interaction_) - return; - - assistant_interaction_model_.AddUiElement( - std::make_unique<AssistantCardElement>(response)); -} - -void AssistantController::OnSuggestionChipPressed(int id) { - const AssistantSuggestion* suggestion = - assistant_interaction_model_.GetSuggestionById(id); - - // If the suggestion contains a non-empty action url, we will handle the - // suggestion chip pressed event by launching the action url in the browser. - if (!suggestion->action_url.is_empty()) { - OpenUrl(suggestion->action_url); - return; - } - - // Otherwise, we will submit a simple text query using the suggestion text. - const std::string text = suggestion->text; - - assistant_interaction_model_.SetPendingQuery( - std::make_unique<AssistantTextQuery>(text)); - assistant_interaction_model_.CommitPendingQuery(); - - assistant_->SendTextQuery(text); -} - -void AssistantController::OnSuggestionsResponse( - std::vector<AssistantSuggestionPtr> response) { - if (!has_active_interaction_) - return; - - assistant_interaction_model_.AddSuggestions(std::move(response)); -} - -void AssistantController::OnTextResponse(const std::string& response) { - if (!has_active_interaction_) - return; - - assistant_interaction_model_.AddUiElement( - std::make_unique<AssistantTextElement>(response)); -} - -void AssistantController::OnSpeechRecognitionStarted() { - assistant_interaction_model_.SetInputModality(InputModality::kVoice); - assistant_interaction_model_.SetMicState(MicState::kOpen); - assistant_interaction_model_.SetPendingQuery( - std::make_unique<AssistantVoiceQuery>()); -} - -void AssistantController::OnSpeechRecognitionIntermediateResult( - const std::string& high_confidence_text, - const std::string& low_confidence_text) { - assistant_interaction_model_.SetPendingQuery( - std::make_unique<AssistantVoiceQuery>(high_confidence_text, - low_confidence_text)); -} - -void AssistantController::OnSpeechRecognitionEndOfUtterance() { - assistant_interaction_model_.SetMicState(MicState::kClosed); -} - -void AssistantController::OnSpeechRecognitionFinalResult( - const std::string& final_result) { - assistant_interaction_model_.SetPendingQuery( - std::make_unique<AssistantVoiceQuery>(final_result)); - assistant_interaction_model_.CommitPendingQuery(); -} - -void AssistantController::OnSpeechLevelUpdated(float speech_level) { - assistant_interaction_model_.SetSpeechLevel(speech_level); -} - -void AssistantController::OnOpenUrlResponse(const GURL& url) { - if (!has_active_interaction_) - return; - - OpenUrl(url); -} - -void AssistantController::OnOpenUrlFromTab(const GURL& url) { - OpenUrl(url); -} - +// TODO(dmblack): Update DialogPlate to accept multiple listeners and then +// remove this code from AssistantController. Use observer pattern. void AssistantController::OnDialogPlateButtonPressed(DialogPlateButtonId id) { - if (id == DialogPlateButtonId::kKeyboardInputToggle) { - assistant_interaction_model_.SetInputModality(InputModality::kKeyboard); - return; - } - - if (id == DialogPlateButtonId::kSettings) { - assistant_bubble_controller_->OnSettingsButtonPressed(); - return; - } - - DCHECK_EQ(id, DialogPlateButtonId::kVoiceInputToggle); - - switch (assistant_interaction_model_.mic_state()) { - case MicState::kClosed: - assistant_->StartVoiceInteraction(); - break; - case MicState::kOpen: - has_active_interaction_ = false; - assistant_->StopActiveInteraction(); - break; - } + assistant_interaction_controller_->OnDialogPlateButtonPressed(id); + assistant_ui_controller_->OnDialogPlateButtonPressed(id); } +// TODO(dmblack): Update DialogPlate to accept multiple listeners and then +// remove this code from AssistantController. Use observer pattern. void AssistantController::OnDialogPlateContentsCommitted( const std::string& text) { - // TODO(dmblack): This case no longer makes sense now that the DialogPlate has - // been rebuilt. Remove the ability to commit empty DialogPlate contents. - if (text.empty()) - return; - - assistant_interaction_model_.SetPendingQuery( - std::make_unique<AssistantTextQuery>(text)); - assistant_interaction_model_.CommitPendingQuery(); - - assistant_->SendTextQuery(text); -} - -void AssistantController::OpenUrl(const GURL& url) { - Shell::Get()->new_window_controller()->NewTabWithUrl(url); - StopInteraction(); + assistant_interaction_controller_->OnDialogPlateContentsCommitted(text); + assistant_ui_controller_->OnDialogPlateContentsCommitted(text); } } // namespace ash
diff --git a/ash/assistant/assistant_controller.h b/ash/assistant/assistant_controller.h index 41e3cd7..5a226c2 100644 --- a/ash/assistant/assistant_controller.h +++ b/ash/assistant/assistant_controller.h
@@ -9,17 +9,13 @@ #include <string> #include <vector> -#include "ash/assistant/model/assistant_interaction_model.h" -#include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/ui/dialog_plate/dialog_plate.h" -#include "ash/highlighter/highlighter_controller.h" #include "ash/public/interfaces/assistant_controller.mojom.h" #include "ash/public/interfaces/assistant_image_downloader.mojom.h" #include "ash/public/interfaces/assistant_setup.mojom.h" #include "ash/public/interfaces/web_contents_manager.mojom.h" #include "base/macros.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "ui/gfx/geometry/rect.h" @@ -29,42 +25,17 @@ namespace ash { -class AssistantBubbleController; -class AssistantInteractionModelObserver; +class AssistantInteractionController; +class AssistantUiController; -class AssistantController - : public mojom::AssistantController, - public chromeos::assistant::mojom::AssistantEventSubscriber, - public AssistantInteractionModelObserver, - public HighlighterController::Observer, - public DialogPlateDelegate, - public mojom::ManagedWebContentsOpenUrlDelegate { +class AssistantController : public mojom::AssistantController, + public DialogPlateDelegate { public: - using AssistantSuggestion = chromeos::assistant::mojom::AssistantSuggestion; - using AssistantSuggestionPtr = - chromeos::assistant::mojom::AssistantSuggestionPtr; - using AssistantInteractionResolution = - chromeos::assistant::mojom::AssistantInteractionResolution; - AssistantController(); ~AssistantController() override; void BindRequest(mojom::AssistantControllerRequest request); - // Returns a reference to the underlying interaction model. - const AssistantInteractionModel* interaction_model() const { - return &assistant_interaction_model_; - } - - // Registers the specified |observer| with the interaction model observer - // pool. - void AddInteractionModelObserver(AssistantInteractionModelObserver* observer); - - // Unregisters the specified |observer| from the interaction model observer - // pool. - void RemoveInteractionModelObserver( - AssistantInteractionModelObserver* observer); - // Requests that WebContents, uniquely identified by |id_token|, be created // and managed according to the specified |params|. When the WebContents is // ready for embedding, the supplied |callback| is run with an embed token. In @@ -89,86 +60,50 @@ const GURL& url, mojom::AssistantImageDownloader::DownloadCallback callback); - // Invoke to modify the Assistant interaction state. - void StartInteraction(); - void StopInteraction(); - void ToggleInteraction(); - - // Invoked on suggestion chip pressed event. - void OnSuggestionChipPressed(int id); - - // AssistantInteractionModelObserver: - void OnInputModalityChanged(InputModality input_modality) override; - void OnInteractionStateChanged(InteractionState interaction_state) override; - void OnCommittedQueryChanged(const AssistantQuery& committed_query) override; - - // HighlighterController::Observer: - void OnHighlighterEnabledChanged(HighlighterEnabledState state) override; - - // chromeos::assistant::mojom::AssistantEventSubscriber: - void OnInteractionStarted() override; - void OnInteractionFinished( - AssistantInteractionResolution resolution) override; - void OnHtmlResponse(const std::string& response) override; - void OnSuggestionsResponse( - std::vector<AssistantSuggestionPtr> response) override; - void OnTextResponse(const std::string& response) override; - void OnOpenUrlResponse(const GURL& url) override; - void OnSpeechRecognitionStarted() override; - void OnSpeechRecognitionIntermediateResult( - const std::string& high_confidence_text, - const std::string& low_confidence_text) override; - void OnSpeechRecognitionEndOfUtterance() override; - void OnSpeechRecognitionFinalResult(const std::string& final_result) override; - void OnSpeechLevelUpdated(float speech_level) override; - // mojom::AssistantController: // TODO(updowndota): Refactor Set() calls to use a factory pattern. void SetAssistant( chromeos::assistant::mojom::AssistantPtr assistant) override; void SetAssistantImageDownloader( mojom::AssistantImageDownloaderPtr assistant_image_downloader) override; + void SetAssistantSetup(mojom::AssistantSetupPtr assistant_setup) override; void SetWebContentsManager( mojom::WebContentsManagerPtr web_contents_manager) override; - void SetAssistantSetup(mojom::AssistantSetupPtr assistant_setup) override; void RequestScreenshot(const gfx::Rect& rect, RequestScreenshotCallback callback) override; - // mojom::ManagedWebContentsOpenUrlDelegate: - void OnOpenUrlFromTab(const GURL& url) override; - // DialogPlateDelegate: void OnDialogPlateButtonPressed(DialogPlateButtonId id) override; void OnDialogPlateContentsCommitted(const std::string& text) override; - AssistantBubbleController* bubble_controller() { - DCHECK(assistant_bubble_controller_); - return assistant_bubble_controller_.get(); + AssistantInteractionController* interaction_controller() { + DCHECK(assistant_interaction_controller_); + return assistant_interaction_controller_.get(); + } + + AssistantUiController* ui_controller() { + DCHECK(assistant_ui_controller_); + return assistant_ui_controller_.get(); } private: - void OpenUrl(const GURL& url); - mojo::BindingSet<mojom::AssistantController> assistant_controller_bindings_; - mojo::Binding<chromeos::assistant::mojom::AssistantEventSubscriber> - assistant_event_subscriber_binding_; mojo::BindingSet<mojom::ManagedWebContentsOpenUrlDelegate> web_contents_open_url_delegate_bindings_; - AssistantInteractionModel assistant_interaction_model_; - chromeos::assistant::mojom::AssistantPtr assistant_; + mojom::AssistantImageDownloaderPtr assistant_image_downloader_; - mojom::WebContentsManagerPtr web_contents_manager_; + mojom::AssistantSetupPtr assistant_setup_; - std::unique_ptr<AssistantBubbleController> assistant_bubble_controller_; + mojom::WebContentsManagerPtr web_contents_manager_; - // Indicates whether or not there is an active interaction in progress. If - // there is no active interaction, UI related service events should be - // discarded. - bool has_active_interaction_; + std::unique_ptr<AssistantInteractionController> + assistant_interaction_controller_; + + std::unique_ptr<AssistantUiController> assistant_ui_controller_; DISALLOW_COPY_AND_ASSIGN(AssistantController); };
diff --git a/ash/assistant/assistant_controller_unittest.cc b/ash/assistant/assistant_controller_unittest.cc index ec49f25..86b951f 100644 --- a/ash/assistant/assistant_controller_unittest.cc +++ b/ash/assistant/assistant_controller_unittest.cc
@@ -6,7 +6,7 @@ #include <memory> -#include "ash/assistant/assistant_bubble_controller.h" +#include "ash/assistant/assistant_ui_controller.h" #include "ash/highlighter/highlighter_controller.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -27,7 +27,9 @@ scoped_feature_list_.InitAndEnableFeature( chromeos::switches::kAssistantFeature); ASSERT_TRUE(chromeos::switches::IsAssistantEnabled()); + AshTestBase::SetUp(); + controller_ = Shell::Get()->assistant_controller(); DCHECK(controller_); @@ -40,50 +42,24 @@ assistant_binding_->Bind(mojo::MakeRequest(&assistant)); controller_->SetAssistant(std::move(assistant)); - ASSERT_FALSE(IsAssistantBubbleShown()); + ASSERT_FALSE(IsAssistantUiShown()); } - bool IsAssistantBubbleShown() { - return controller_->bubble_controller()->IsVisible(); - } - - const AssistantInteractionModel* interaction_model() { - return controller_->interaction_model(); + bool IsAssistantUiShown() { + return controller_->ui_controller()->IsVisible(); } private: base::test::ScopedFeatureList scoped_feature_list_; + AssistantController* controller_ = nullptr; std::unique_ptr<chromeos::assistant::MockAssistant> assistant_; + std::unique_ptr<mojo::Binding<chromeos::assistant::mojom::Assistant>> assistant_binding_; DISALLOW_COPY_AND_ASSIGN(AssistantControllerTest); }; -TEST_F(AssistantControllerTest, HighlighterEnabledStatus) { - HighlighterController* highlighter_controller = - Shell::Get()->highlighter_controller(); - highlighter_controller->UpdateEnabledState(HighlighterEnabledState::kEnabled); - EXPECT_EQ(InputModality::kStylus, interaction_model()->input_modality()); - EXPECT_EQ(InteractionState::kActive, - interaction_model()->interaction_state()); - EXPECT_TRUE(IsAssistantBubbleShown()); - - // Metalayer mode session end should keep interaction state active. - highlighter_controller->UpdateEnabledState( - HighlighterEnabledState::kDisabledBySessionEnd); - EXPECT_EQ(InteractionState::kActive, - interaction_model()->interaction_state()); - EXPECT_TRUE(IsAssistantBubbleShown()); - - // Disabling directly by user action should make interaction state inactive. - highlighter_controller->UpdateEnabledState( - HighlighterEnabledState::kDisabledByUser); - EXPECT_EQ(InteractionState::kInactive, - interaction_model()->interaction_state()); - EXPECT_FALSE(IsAssistantBubbleShown()); -} - } // namespace ash
diff --git a/ash/assistant/assistant_interaction_controller.cc b/ash/assistant/assistant_interaction_controller.cc new file mode 100644 index 0000000..e6517fe --- /dev/null +++ b/ash/assistant/assistant_interaction_controller.cc
@@ -0,0 +1,303 @@ +// 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/assistant/assistant_interaction_controller.h" + +#include "ash/assistant/model/assistant_interaction_model_observer.h" +#include "ash/assistant/model/assistant_query.h" +#include "ash/assistant/model/assistant_ui_element.h" +#include "ash/new_window_controller.h" +#include "ash/public/interfaces/assistant_setup.mojom.h" +#include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/system/toast/toast_data.h" +#include "ash/system/toast/toast_manager.h" +#include "ash/voice_interaction/voice_interaction_controller.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/base/l10n/l10n_util.h" + +namespace ash { + +namespace { + +// Toast ----------------------------------------------------------------------- + +constexpr int kToastDurationMs = 2500; +constexpr char kUnboundServiceToastId[] = + "assistant_controller_unbound_service"; + +void ShowToast(const std::string& id, int message_id) { + ToastData toast(id, l10n_util::GetStringUTF16(message_id), kToastDurationMs, + base::nullopt); + Shell::Get()->toast_manager()->Show(toast); +} + +} // namespace + +// AssistantInteractionController ---------------------------------------------- + +AssistantInteractionController::AssistantInteractionController() + : assistant_event_subscriber_binding_(this) { + AddModelObserver(this); + Shell::Get()->highlighter_controller()->AddObserver(this); +} + +AssistantInteractionController::~AssistantInteractionController() { + Shell::Get()->highlighter_controller()->RemoveObserver(this); + RemoveModelObserver(this); +} + +void AssistantInteractionController::SetAssistant( + chromeos::assistant::mojom::Assistant* assistant) { + assistant_ = assistant; + + // Subscribe to Assistant events. + chromeos::assistant::mojom::AssistantEventSubscriberPtr ptr; + assistant_event_subscriber_binding_.Bind(mojo::MakeRequest(&ptr)); + assistant_->AddAssistantEventSubscriber(std::move(ptr)); +} + +void AssistantInteractionController::SetAssistantSetup( + mojom::AssistantSetup* assistant_setup) { + assistant_setup_ = assistant_setup; +} + +void AssistantInteractionController::AddModelObserver( + AssistantInteractionModelObserver* observer) { + assistant_interaction_model_.AddObserver(observer); +} + +void AssistantInteractionController::RemoveModelObserver( + AssistantInteractionModelObserver* observer) { + assistant_interaction_model_.RemoveObserver(observer); +} + +void AssistantInteractionController::StartInteraction() { + if (!Shell::Get()->voice_interaction_controller()->setup_completed()) { + assistant_setup_->StartAssistantOptInFlow(); + return; + } + + if (!Shell::Get()->voice_interaction_controller()->settings_enabled()) + return; + + if (!assistant_) { + ShowToast(kUnboundServiceToastId, IDS_ASH_ASSISTANT_ERROR_GENERIC); + return; + } + + OnInteractionStarted(); +} + +void AssistantInteractionController::StopInteraction() { + assistant_interaction_model_.SetInteractionState(InteractionState::kInactive); +} + +void AssistantInteractionController::ToggleInteraction() { + if (assistant_interaction_model_.interaction_state() == + InteractionState::kInactive) { + StartInteraction(); + } else { + StopInteraction(); + } +} + +void AssistantInteractionController::OnInteractionStateChanged( + InteractionState interaction_state) { + if (interaction_state == InteractionState::kActive) + return; + + // When the user-facing interaction is dismissed, we instruct the service to + // terminate any listening, speaking, or pending query. + has_active_interaction_ = false; + assistant_->StopActiveInteraction(); + + assistant_interaction_model_.ClearInteraction(); + assistant_interaction_model_.SetInputModality(InputModality::kKeyboard); +} + +void AssistantInteractionController::OnCommittedQueryChanged( + const AssistantQuery& committed_query) { + // We clear the interaction when a query is committed, but need to retain + // the committed query as it is query that is currently being fulfilled. + assistant_interaction_model_.ClearInteraction( + /*retain_committed_query=*/true); +} + +void AssistantInteractionController::OnHighlighterEnabledChanged( + HighlighterEnabledState state) { + assistant_interaction_model_.SetInputModality(InputModality::kStylus); + if (state == HighlighterEnabledState::kEnabled) { + assistant_interaction_model_.SetInteractionState(InteractionState::kActive); + } else if (state == HighlighterEnabledState::kDisabledByUser) { + assistant_interaction_model_.SetInteractionState( + InteractionState::kInactive); + } +} + +void AssistantInteractionController::OnInputModalityChanged( + InputModality input_modality) { + if (input_modality == InputModality::kVoice) + return; + + // When switching to a non-voice input modality we instruct the underlying + // service to terminate any listening, speaking, or pending voice query. We do + // not do this when switching to voice input modality because initiation of a + // voice interaction will automatically interrupt any pre-existing activity. + // Stopping the active interaction here for voice input modality would + // actually have the undesired effect of stopping the voice interaction. + if (assistant_interaction_model_.pending_query().type() == + AssistantQueryType::kVoice) { + has_active_interaction_ = false; + assistant_->StopActiveInteraction(); + assistant_interaction_model_.ClearPendingQuery(); + } +} + +void AssistantInteractionController::OnInteractionStarted() { + has_active_interaction_ = true; + assistant_interaction_model_.SetInteractionState(InteractionState::kActive); +} + +void AssistantInteractionController::OnInteractionFinished( + AssistantInteractionResolution resolution) { + has_active_interaction_ = false; + + // When a voice query is interrupted we do not receive any follow up speech + // recognition events but the mic is closed. + if (resolution == AssistantInteractionResolution::kInterruption) { + assistant_interaction_model_.SetMicState(MicState::kClosed); + } +} + +void AssistantInteractionController::OnHtmlResponse( + const std::string& response) { + if (!has_active_interaction_) + return; + + assistant_interaction_model_.AddUiElement( + std::make_unique<AssistantCardElement>(response)); +} + +void AssistantInteractionController::OnSuggestionChipPressed(int id) { + const AssistantSuggestion* suggestion = + assistant_interaction_model_.GetSuggestionById(id); + + // If the suggestion contains a non-empty action url, we will handle the + // suggestion chip pressed event by launching the action url in the browser. + if (!suggestion->action_url.is_empty()) { + OpenUrl(suggestion->action_url); + return; + } + + // Otherwise, we will submit a simple text query using the suggestion text. + const std::string text = suggestion->text; + + assistant_interaction_model_.SetPendingQuery( + std::make_unique<AssistantTextQuery>(text)); + assistant_interaction_model_.CommitPendingQuery(); + + assistant_->SendTextQuery(text); +} + +void AssistantInteractionController::OnSuggestionsResponse( + std::vector<AssistantSuggestionPtr> response) { + if (!has_active_interaction_) + return; + + assistant_interaction_model_.AddSuggestions(std::move(response)); +} + +void AssistantInteractionController::OnTextResponse( + const std::string& response) { + if (!has_active_interaction_) + return; + + assistant_interaction_model_.AddUiElement( + std::make_unique<AssistantTextElement>(response)); +} + +void AssistantInteractionController::OnSpeechRecognitionStarted() { + assistant_interaction_model_.SetInputModality(InputModality::kVoice); + assistant_interaction_model_.SetMicState(MicState::kOpen); + assistant_interaction_model_.SetPendingQuery( + std::make_unique<AssistantVoiceQuery>()); +} + +void AssistantInteractionController::OnSpeechRecognitionIntermediateResult( + const std::string& high_confidence_text, + const std::string& low_confidence_text) { + assistant_interaction_model_.SetPendingQuery( + std::make_unique<AssistantVoiceQuery>(high_confidence_text, + low_confidence_text)); +} + +void AssistantInteractionController::OnSpeechRecognitionEndOfUtterance() { + assistant_interaction_model_.SetMicState(MicState::kClosed); +} + +void AssistantInteractionController::OnSpeechRecognitionFinalResult( + const std::string& final_result) { + assistant_interaction_model_.SetPendingQuery( + std::make_unique<AssistantVoiceQuery>(final_result)); + assistant_interaction_model_.CommitPendingQuery(); +} + +void AssistantInteractionController::OnSpeechLevelUpdated(float speech_level) { + assistant_interaction_model_.SetSpeechLevel(speech_level); +} + +void AssistantInteractionController::OnOpenUrlResponse(const GURL& url) { + if (!has_active_interaction_) + return; + + OpenUrl(url); +} + +void AssistantInteractionController::OnOpenUrlFromTab(const GURL& url) { + OpenUrl(url); +} + +void AssistantInteractionController::OnDialogPlateButtonPressed( + DialogPlateButtonId id) { + if (id == DialogPlateButtonId::kKeyboardInputToggle) { + assistant_interaction_model_.SetInputModality(InputModality::kKeyboard); + return; + } + + if (id != DialogPlateButtonId::kVoiceInputToggle) { + return; + } + + switch (assistant_interaction_model_.mic_state()) { + case MicState::kClosed: + assistant_->StartVoiceInteraction(); + break; + case MicState::kOpen: + has_active_interaction_ = false; + assistant_->StopActiveInteraction(); + break; + } +} + +void AssistantInteractionController::OnDialogPlateContentsCommitted( + const std::string& text) { + // TODO(dmblack): This case no longer makes sense now that the DialogPlate has + // been rebuilt. Remove the ability to commit empty DialogPlate contents. + if (text.empty()) + return; + + assistant_interaction_model_.SetPendingQuery( + std::make_unique<AssistantTextQuery>(text)); + assistant_interaction_model_.CommitPendingQuery(); + + assistant_->SendTextQuery(text); +} + +void AssistantInteractionController::OpenUrl(const GURL& url) { + Shell::Get()->new_window_controller()->NewTabWithUrl(url); + StopInteraction(); +} + +} // namespace ash
diff --git a/ash/assistant/assistant_interaction_controller.h b/ash/assistant/assistant_interaction_controller.h new file mode 100644 index 0000000..5a94297 --- /dev/null +++ b/ash/assistant/assistant_interaction_controller.h
@@ -0,0 +1,124 @@ +// 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_ASSISTANT_ASSISTANT_INTERACTION_CONTROLLER_H_ +#define ASH_ASSISTANT_ASSISTANT_INTERACTION_CONTROLLER_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "ash/assistant/model/assistant_interaction_model.h" +#include "ash/assistant/model/assistant_interaction_model_observer.h" +#include "ash/assistant/ui/dialog_plate/dialog_plate.h" +#include "ash/highlighter/highlighter_controller.h" +#include "ash/public/interfaces/web_contents_manager.mojom.h" +#include "base/macros.h" +#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace ash { + +class AssistantInteractionModelObserver; + +namespace mojom { +class AssistantSetup; +} // namespace mojom + +class AssistantInteractionController + : public chromeos::assistant::mojom::AssistantEventSubscriber, + public AssistantInteractionModelObserver, + public HighlighterController::Observer, + public DialogPlateDelegate, + public mojom::ManagedWebContentsOpenUrlDelegate { + public: + using AssistantSuggestion = chromeos::assistant::mojom::AssistantSuggestion; + using AssistantSuggestionPtr = + chromeos::assistant::mojom::AssistantSuggestionPtr; + using AssistantInteractionResolution = + chromeos::assistant::mojom::AssistantInteractionResolution; + + explicit AssistantInteractionController(); + ~AssistantInteractionController() override; + + // Provides a pointer to the |assistant| owned by AssistantController. + void SetAssistant(chromeos::assistant::mojom::Assistant* assistant); + + // Provides a pointer to the |assistant_setup| owned by AssistantController. + void SetAssistantSetup(mojom::AssistantSetup* assistant_setup); + + // Returns a reference to the underlying model. + const AssistantInteractionModel* model() const { + return &assistant_interaction_model_; + } + + // Adds/removes the specified interaction model |observer|. + void AddModelObserver(AssistantInteractionModelObserver* observer); + void RemoveModelObserver(AssistantInteractionModelObserver* observer); + + // Invoke to modify the Assistant interaction state. + void StartInteraction(); + void StopInteraction(); + void ToggleInteraction(); + + // Invoked on suggestion chip pressed event. + void OnSuggestionChipPressed(int id); + + // AssistantInteractionModelObserver: + void OnInputModalityChanged(InputModality input_modality) override; + void OnInteractionStateChanged(InteractionState interaction_state) override; + void OnCommittedQueryChanged(const AssistantQuery& committed_query) override; + + // HighlighterController::Observer: + void OnHighlighterEnabledChanged(HighlighterEnabledState state) override; + + // chromeos::assistant::mojom::AssistantEventSubscriber: + void OnInteractionStarted() override; + void OnInteractionFinished( + AssistantInteractionResolution resolution) override; + void OnHtmlResponse(const std::string& response) override; + void OnSuggestionsResponse( + std::vector<AssistantSuggestionPtr> response) override; + void OnTextResponse(const std::string& response) override; + void OnOpenUrlResponse(const GURL& url) override; + void OnSpeechRecognitionStarted() override; + void OnSpeechRecognitionIntermediateResult( + const std::string& high_confidence_text, + const std::string& low_confidence_text) override; + void OnSpeechRecognitionEndOfUtterance() override; + void OnSpeechRecognitionFinalResult(const std::string& final_result) override; + void OnSpeechLevelUpdated(float speech_level) override; + + // mojom::ManagedWebContentsOpenUrlDelegate: + void OnOpenUrlFromTab(const GURL& url) override; + + // DialogPlateDelegate: + void OnDialogPlateButtonPressed(DialogPlateButtonId id) override; + void OnDialogPlateContentsCommitted(const std::string& text) override; + + private: + void OpenUrl(const GURL& url); + + mojo::Binding<chromeos::assistant::mojom::AssistantEventSubscriber> + assistant_event_subscriber_binding_; + + AssistantInteractionModel assistant_interaction_model_; + + // Owned by AssistantController. + chromeos::assistant::mojom::Assistant* assistant_ = nullptr; + + // Owned by AssistantController. + mojom::AssistantSetup* assistant_setup_ = nullptr; + + // Indicates whether or not there is an active interaction in progress. If + // there is no active interaction, UI related service events should be + // discarded. + bool has_active_interaction_; + + DISALLOW_COPY_AND_ASSIGN(AssistantInteractionController); +}; + +} // namespace ash + +#endif // ASH_ASSISTANT_ASSISTANT_INTERACTION_CONTROLLER_H_
diff --git a/ash/assistant/assistant_ui_controller.cc b/ash/assistant/assistant_ui_controller.cc new file mode 100644 index 0000000..52908a2 --- /dev/null +++ b/ash/assistant/assistant_ui_controller.cc
@@ -0,0 +1,151 @@ +// 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/assistant/assistant_ui_controller.h" + +#include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" +#include "ash/assistant/ui/assistant_container_view.h" +#include "base/optional.h" + +namespace ash { + +AssistantUiController::AssistantUiController( + AssistantController* assistant_controller) + : assistant_controller_(assistant_controller) { + assistant_controller_->interaction_controller()->AddModelObserver(this); +} + +AssistantUiController::~AssistantUiController() { + assistant_controller_->interaction_controller()->RemoveModelObserver(this); + + if (container_view_) + container_view_->GetWidget()->RemoveObserver(this); +} + +void AssistantUiController::AddModelObserver( + AssistantUiModelObserver* observer) { + assistant_ui_model_.AddObserver(observer); +} + +void AssistantUiController::RemoveModelObserver( + AssistantUiModelObserver* observer) { + assistant_ui_model_.RemoveObserver(observer); +} + +void AssistantUiController::OnWidgetActivationChanged(views::Widget* widget, + bool active) { + if (active) + container_view_->RequestFocus(); +} + +void AssistantUiController::OnWidgetVisibilityChanged(views::Widget* widget, + bool visible) { + UpdateUiMode(); +} + +void AssistantUiController::OnWidgetDestroying(views::Widget* widget) { + // We need to be sure that the Assistant interaction is stopped when the + // widget is closed. Special cases, such as closing the widget via the |ESC| + // key might otherwise go unhandled, causing inconsistencies between the + // widget visibility state and the underlying interaction model state. + // TODO(dmblack): Clean this up. Sibling controllers shouldn't need to + // communicate to each other directly in this way. + assistant_controller_->interaction_controller()->StopInteraction(); + + container_view_->GetWidget()->RemoveObserver(this); + container_view_ = nullptr; +} + +void AssistantUiController::OnInputModalityChanged( + InputModality input_modality) { + UpdateUiMode(); +} + +void AssistantUiController::OnInteractionStateChanged( + InteractionState interaction_state) { + switch (interaction_state) { + case InteractionState::kActive: + Show(); + break; + case InteractionState::kInactive: + Dismiss(); + break; + } +} + +void AssistantUiController::OnMicStateChanged(MicState mic_state) { + UpdateUiMode(); +} + +bool AssistantUiController::OnCaptionButtonPressed(CaptionButtonId id) { + switch (id) { + case CaptionButtonId::kMinimize: + UpdateUiMode(AssistantUiMode::kMiniUi); + return true; + case CaptionButtonId::kClose: + return false; + } + return false; +} + +void AssistantUiController::OnDialogPlateButtonPressed(DialogPlateButtonId id) { + if (id != DialogPlateButtonId::kSettings) + return; + + UpdateUiMode(AssistantUiMode::kWebUi); +} + +bool AssistantUiController::IsVisible() const { + return container_view_ && container_view_->GetWidget()->IsVisible(); +} + +void AssistantUiController::Show() { + if (!container_view_) { + container_view_ = new AssistantContainerView(assistant_controller_); + container_view_->GetWidget()->AddObserver(this); + } + container_view_->GetWidget()->Show(); +} + +void AssistantUiController::Dismiss() { + if (container_view_) + container_view_->GetWidget()->Hide(); +} + +void AssistantUiController::UpdateUiMode( + base::Optional<AssistantUiMode> ui_mode) { + // If a UI mode is provided, we will use it in lieu of updating UI mode on the + // basis of interaction/widget visibility state. + if (ui_mode.has_value()) { + assistant_ui_model_.SetUiMode(ui_mode.value()); + return; + } + + // When Assistant UI is not visible, we should reset to main UI mode. + if (!IsVisible()) { + assistant_ui_model_.SetUiMode(AssistantUiMode::kMainUi); + return; + } + + const AssistantInteractionModel* interaction_model = + assistant_controller_->interaction_controller()->model(); + + // When the mic is open, we should be in main UI mode. + if (interaction_model->mic_state() == MicState::kOpen) { + assistant_ui_model_.SetUiMode(AssistantUiMode::kMainUi); + return; + } + + // When stylus input modality is selected, we should be in mini UI mode. + if (interaction_model->input_modality() == InputModality::kStylus) { + assistant_ui_model_.SetUiMode(AssistantUiMode::kMiniUi); + return; + } + + // By default, we will fall back to main UI mode. + assistant_ui_model_.SetUiMode(AssistantUiMode::kMainUi); +} + +} // namespace ash
diff --git a/ash/assistant/assistant_bubble_controller.h b/ash/assistant/assistant_ui_controller.h similarity index 63% rename from ash/assistant/assistant_bubble_controller.h rename to ash/assistant/assistant_ui_controller.h index 087efde9..c2c08c0 100644 --- a/ash/assistant/assistant_bubble_controller.h +++ b/ash/assistant/assistant_ui_controller.h
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_ASSISTANT_ASSISTANT_BUBBLE_CONTROLLER_H_ -#define ASH_ASSISTANT_ASSISTANT_BUBBLE_CONTROLLER_H_ +#ifndef ASH_ASSISTANT_ASSISTANT_UI_CONTROLLER_H_ +#define ASH_ASSISTANT_ASSISTANT_UI_CONTROLLER_H_ #include "ash/ash_export.h" -#include "ash/assistant/model/assistant_bubble_model.h" #include "ash/assistant/model/assistant_interaction_model_observer.h" +#include "ash/assistant/model/assistant_ui_model.h" #include "ash/assistant/ui/caption_bar.h" +#include "ash/assistant/ui/dialog_plate/dialog_plate.h" #include "base/macros.h" #include "ui/views/widget/widget_observer.h" @@ -18,23 +19,24 @@ namespace ash { -class AssistantBubbleView; +class AssistantContainerView; class AssistantController; -class ASH_EXPORT AssistantBubbleController +class ASH_EXPORT AssistantUiController : public views::WidgetObserver, public AssistantInteractionModelObserver, - public CaptionBarDelegate { + public CaptionBarDelegate, + public DialogPlateDelegate { public: - explicit AssistantBubbleController(AssistantController* assistant_controller); - ~AssistantBubbleController() override; + explicit AssistantUiController(AssistantController* assistant_controller); + ~AssistantUiController() override; // Returns the underlying model. - const AssistantBubbleModel* model() const { return &assistant_bubble_model_; } + const AssistantUiModel* model() const { return &assistant_ui_model_; } // Adds/removes the specified model |observer|. - void AddModelObserver(AssistantBubbleModelObserver* observer); - void RemoveModelObserver(AssistantBubbleModelObserver* observer); + void AddModelObserver(AssistantUiModelObserver* observer); + void RemoveModelObserver(AssistantUiModelObserver* observer); // views::WidgetObserver: void OnWidgetActivationChanged(views::Widget* widget, bool active) override; @@ -49,8 +51,8 @@ // CaptionBarDelegate: bool OnCaptionButtonPressed(CaptionButtonId id) override; - // Invoked on settings button pressed. - void OnSettingsButtonPressed(); + // DialogPlateDelegate: + void OnDialogPlateButtonPressed(DialogPlateButtonId id) override; // Returns true if assistant bubble is visible, otherwise false. bool IsVisible() const; @@ -63,14 +65,16 @@ // the basis of interaction/widget visibility state. void UpdateUiMode(base::Optional<AssistantUiMode> ui_mode = base::nullopt); - AssistantBubbleModel assistant_bubble_model_; AssistantController* const assistant_controller_; // Owned by Shell. - AssistantBubbleView* bubble_view_ = nullptr; // Owned by view hierarchy. + AssistantUiModel assistant_ui_model_; - DISALLOW_COPY_AND_ASSIGN(AssistantBubbleController); + AssistantContainerView* container_view_ = + nullptr; // Owned by view hierarchy. + + DISALLOW_COPY_AND_ASSIGN(AssistantUiController); }; } // namespace ash -#endif // ASH_ASSISTANT_ASSISTANT_BUBBLE_CONTROLLER_H_ +#endif // ASH_ASSISTANT_ASSISTANT_UI_CONTROLLER_H_
diff --git a/ash/assistant/model/assistant_bubble_model.cc b/ash/assistant/model/assistant_bubble_model.cc deleted file mode 100644 index d8484b8..0000000 --- a/ash/assistant/model/assistant_bubble_model.cc +++ /dev/null
@@ -1,37 +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. - -#include "ash/assistant/model/assistant_bubble_model.h" - -#include "ash/assistant/model/assistant_bubble_model_observer.h" - -namespace ash { - -AssistantBubbleModel::AssistantBubbleModel() = default; - -AssistantBubbleModel::~AssistantBubbleModel() = default; - -void AssistantBubbleModel::AddObserver(AssistantBubbleModelObserver* observer) { - observers_.AddObserver(observer); -} - -void AssistantBubbleModel::RemoveObserver( - AssistantBubbleModelObserver* observer) { - observers_.RemoveObserver(observer); -} - -void AssistantBubbleModel::SetUiMode(AssistantUiMode ui_mode) { - if (ui_mode == ui_mode_) - return; - - ui_mode_ = ui_mode; - NotifyUiModeChanged(); -} - -void AssistantBubbleModel::NotifyUiModeChanged() { - for (AssistantBubbleModelObserver& observer : observers_) - observer.OnUiModeChanged(ui_mode_); -} - -} // namespace ash
diff --git a/ash/assistant/model/assistant_bubble_model.h b/ash/assistant/model/assistant_bubble_model.h deleted file mode 100644 index 3ce0dc5b..0000000 --- a/ash/assistant/model/assistant_bubble_model.h +++ /dev/null
@@ -1,50 +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. - -#ifndef ASH_ASSISTANT_MODEL_ASSISTANT_BUBBLE_MODEL_H_ -#define ASH_ASSISTANT_MODEL_ASSISTANT_BUBBLE_MODEL_H_ - -#include "base/macros.h" -#include "base/observer_list.h" - -namespace ash { - -class AssistantBubbleModelObserver; - -// Enumeration of Assistant UI modes. -enum class AssistantUiMode { - kMainUi, - kMiniUi, - kWebUi, -}; - -// Models the Assistant bubble. -class AssistantBubbleModel { - public: - AssistantBubbleModel(); - ~AssistantBubbleModel(); - - // Adds/removes the specified |observer|. - void AddObserver(AssistantBubbleModelObserver* observer); - void RemoveObserver(AssistantBubbleModelObserver* observer); - - // Sets the UI mode. - void SetUiMode(AssistantUiMode ui_mode); - - // Returns the UI mode. - AssistantUiMode ui_mode() const { return ui_mode_; } - - private: - void NotifyUiModeChanged(); - - AssistantUiMode ui_mode_ = AssistantUiMode::kMainUi; - - base::ObserverList<AssistantBubbleModelObserver> observers_; - - DISALLOW_COPY_AND_ASSIGN(AssistantBubbleModel); -}; - -} // namespace ash - -#endif // ASH_ASSISTANT_MODEL_ASSISTANT_BUBBLE_MODEL_H_
diff --git a/ash/assistant/model/assistant_bubble_model_observer.h b/ash/assistant/model/assistant_bubble_model_observer.h deleted file mode 100644 index b9aec51f..0000000 --- a/ash/assistant/model/assistant_bubble_model_observer.h +++ /dev/null
@@ -1,30 +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. - -#ifndef ASH_ASSISTANT_MODEL_ASSISTANT_BUBBLE_MODEL_OBSERVER_H_ -#define ASH_ASSISTANT_MODEL_ASSISTANT_BUBBLE_MODEL_OBSERVER_H_ - -#include "base/macros.h" - -namespace ash { - -enum class AssistantUiMode; - -// An observer which receives notification of changes to the Assistant bubble -// model. -class AssistantBubbleModelObserver { - public: - // Invoked when the UI mode is changed. - virtual void OnUiModeChanged(AssistantUiMode ui_mode) {} - - protected: - AssistantBubbleModelObserver() = default; - virtual ~AssistantBubbleModelObserver() = default; - - DISALLOW_COPY_AND_ASSIGN(AssistantBubbleModelObserver); -}; - -} // namespace ash - -#endif // ASH_ASSISTANT_MODEL_ASSISTANT_BUBBLE_MODEL_OBSERVER_H_
diff --git a/ash/assistant/model/assistant_ui_model.cc b/ash/assistant/model/assistant_ui_model.cc new file mode 100644 index 0000000..a1ff517 --- /dev/null +++ b/ash/assistant/model/assistant_ui_model.cc
@@ -0,0 +1,36 @@ +// 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/assistant/model/assistant_ui_model.h" + +#include "ash/assistant/model/assistant_ui_model_observer.h" + +namespace ash { + +AssistantUiModel::AssistantUiModel() = default; + +AssistantUiModel::~AssistantUiModel() = default; + +void AssistantUiModel::AddObserver(AssistantUiModelObserver* observer) { + observers_.AddObserver(observer); +} + +void AssistantUiModel::RemoveObserver(AssistantUiModelObserver* observer) { + observers_.RemoveObserver(observer); +} + +void AssistantUiModel::SetUiMode(AssistantUiMode ui_mode) { + if (ui_mode == ui_mode_) + return; + + ui_mode_ = ui_mode; + NotifyUiModeChanged(); +} + +void AssistantUiModel::NotifyUiModeChanged() { + for (AssistantUiModelObserver& observer : observers_) + observer.OnUiModeChanged(ui_mode_); +} + +} // namespace ash
diff --git a/ash/assistant/model/assistant_ui_model.h b/ash/assistant/model/assistant_ui_model.h new file mode 100644 index 0000000..7501f33 --- /dev/null +++ b/ash/assistant/model/assistant_ui_model.h
@@ -0,0 +1,50 @@ +// 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_ASSISTANT_MODEL_ASSISTANT_UI_MODEL_H_ +#define ASH_ASSISTANT_MODEL_ASSISTANT_UI_MODEL_H_ + +#include "base/macros.h" +#include "base/observer_list.h" + +namespace ash { + +class AssistantUiModelObserver; + +// Enumeration of Assistant UI modes. +enum class AssistantUiMode { + kMainUi, + kMiniUi, + kWebUi, +}; + +// Models the Assistant UI. +class AssistantUiModel { + public: + AssistantUiModel(); + ~AssistantUiModel(); + + // Adds/removes the specified |observer|. + void AddObserver(AssistantUiModelObserver* observer); + void RemoveObserver(AssistantUiModelObserver* observer); + + // Sets the UI mode. + void SetUiMode(AssistantUiMode ui_mode); + + // Returns the UI mode. + AssistantUiMode ui_mode() const { return ui_mode_; } + + private: + void NotifyUiModeChanged(); + + AssistantUiMode ui_mode_ = AssistantUiMode::kMainUi; + + base::ObserverList<AssistantUiModelObserver> observers_; + + DISALLOW_COPY_AND_ASSIGN(AssistantUiModel); +}; + +} // namespace ash + +#endif // ASH_ASSISTANT_MODEL_ASSISTANT_UI_MODEL_H_
diff --git a/ash/assistant/model/assistant_ui_model_observer.h b/ash/assistant/model/assistant_ui_model_observer.h new file mode 100644 index 0000000..91cd81c0 --- /dev/null +++ b/ash/assistant/model/assistant_ui_model_observer.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 ASH_ASSISTANT_MODEL_ASSISTANT_UI_MODEL_OBSERVER_H_ +#define ASH_ASSISTANT_MODEL_ASSISTANT_UI_MODEL_OBSERVER_H_ + +#include "base/macros.h" + +namespace ash { + +enum class AssistantUiMode; + +// An observer which receives notification of changes to the Assistant UI model. +class AssistantUiModelObserver { + public: + // Invoked when the UI mode is changed. + virtual void OnUiModeChanged(AssistantUiMode ui_mode) {} + + protected: + AssistantUiModelObserver() = default; + virtual ~AssistantUiModelObserver() = default; + + DISALLOW_COPY_AND_ASSIGN(AssistantUiModelObserver); +}; + +} // namespace ash + +#endif // ASH_ASSISTANT_MODEL_ASSISTANT_UI_MODEL_OBSERVER_H_
diff --git a/ash/assistant/ui/assistant_bubble_view.cc b/ash/assistant/ui/assistant_container_view.cc similarity index 78% rename from ash/assistant/ui/assistant_bubble_view.cc rename to ash/assistant/ui/assistant_container_view.cc index 38da4426..23debd7 100644 --- a/ash/assistant/ui/assistant_bubble_view.cc +++ b/ash/assistant/ui/assistant_container_view.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/assistant/ui/assistant_bubble_view.h" +#include "ash/assistant/ui/assistant_container_view.h" -#include "ash/assistant/assistant_bubble_controller.h" #include "ash/assistant/assistant_controller.h" -#include "ash/assistant/model/assistant_bubble_model.h" +#include "ash/assistant/assistant_ui_controller.h" +#include "ash/assistant/model/assistant_ui_model.h" #include "ash/assistant/ui/assistant_main_view.h" #include "ash/assistant/ui/assistant_mini_view.h" #include "ash/assistant/ui/assistant_web_view.h" @@ -30,7 +30,7 @@ } // namespace -AssistantBubbleView::AssistantBubbleView( +AssistantContainerView::AssistantContainerView( AssistantController* assistant_controller) : assistant_controller_(assistant_controller) { set_accept_events(true); @@ -50,30 +50,30 @@ SetArrowPaintType(views::BubbleBorder::PAINT_NONE); // The AssistantController owns the view hierarchy to which - // AssistantBubbleView belongs so is guaranteed to outlive it. - assistant_controller_->bubble_controller()->AddModelObserver(this); + // AssistantContainerView belongs so is guaranteed to outlive it. + assistant_controller_->ui_controller()->AddModelObserver(this); } -AssistantBubbleView::~AssistantBubbleView() { - assistant_controller_->bubble_controller()->RemoveModelObserver(this); +AssistantContainerView::~AssistantContainerView() { + assistant_controller_->ui_controller()->RemoveModelObserver(this); } -void AssistantBubbleView::ChildPreferredSizeChanged(views::View* child) { +void AssistantContainerView::ChildPreferredSizeChanged(views::View* child) { PreferredSizeChanged(); } -void AssistantBubbleView::PreferredSizeChanged() { +void AssistantContainerView::PreferredSizeChanged() { views::View::PreferredSizeChanged(); if (GetWidget()) SizeToContents(); } -int AssistantBubbleView::GetDialogButtons() const { +int AssistantContainerView::GetDialogButtons() const { return ui::DIALOG_BUTTON_NONE; } -void AssistantBubbleView::OnBeforeBubbleWidgetInit( +void AssistantContainerView::OnBeforeBubbleWidgetInit( views::Widget::InitParams* params, views::Widget* widget) const { params->corner_radius = kCornerRadiusDip; @@ -82,7 +82,7 @@ params->shadow_elevation = wm::kShadowElevationActiveWindow; } -void AssistantBubbleView::Init() { +void AssistantContainerView::Init() { SetLayoutManager(std::make_unique<views::FillLayout>()); // Main view. @@ -100,16 +100,15 @@ assistant_web_view_->set_owned_by_client(); // Update the view state based on the current UI mode. - OnUiModeChanged( - assistant_controller_->bubble_controller()->model()->ui_mode()); + OnUiModeChanged(assistant_controller_->ui_controller()->model()->ui_mode()); } -void AssistantBubbleView::RequestFocus() { +void AssistantContainerView::RequestFocus() { if (assistant_main_view_) assistant_main_view_->RequestFocus(); } -void AssistantBubbleView::SetAnchor() { +void AssistantContainerView::SetAnchor() { // TODO(dmblack): Handle multiple displays, dynamic shelf repositioning, and // any other corner cases. // Anchors to bottom center of primary display's work area. @@ -123,7 +122,7 @@ SetAnchorRect(anchor); } -void AssistantBubbleView::OnUiModeChanged(AssistantUiMode ui_mode) { +void AssistantContainerView::OnUiModeChanged(AssistantUiMode ui_mode) { RemoveAllChildViews(/*delete_children=*/false); switch (ui_mode) {
diff --git a/ash/assistant/ui/assistant_bubble_view.h b/ash/assistant/ui/assistant_container_view.h similarity index 67% rename from ash/assistant/ui/assistant_bubble_view.h rename to ash/assistant/ui/assistant_container_view.h index b5773de..37e9424df 100644 --- a/ash/assistant/ui/assistant_bubble_view.h +++ b/ash/assistant/ui/assistant_container_view.h
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_ASSISTANT_UI_ASSISTANT_BUBBLE_VIEW_H_ -#define ASH_ASSISTANT_UI_ASSISTANT_BUBBLE_VIEW_H_ +#ifndef ASH_ASSISTANT_UI_ASSISTANT_CONTAINER_VIEW_H_ +#define ASH_ASSISTANT_UI_ASSISTANT_CONTAINER_VIEW_H_ #include <memory> -#include "ash/assistant/model/assistant_bubble_model_observer.h" +#include "ash/assistant/model/assistant_ui_model_observer.h" #include "base/macros.h" #include "ui/views/bubble/bubble_dialog_delegate.h" @@ -18,11 +18,11 @@ class AssistantMiniView; class AssistantWebView; -class AssistantBubbleView : public views::BubbleDialogDelegateView, - public AssistantBubbleModelObserver { +class AssistantContainerView : public views::BubbleDialogDelegateView, + public AssistantUiModelObserver { public: - explicit AssistantBubbleView(AssistantController* assistant_controller); - ~AssistantBubbleView() override; + explicit AssistantContainerView(AssistantController* assistant_controller); + ~AssistantContainerView() override; // views::BubbleDialogDelegateView: int GetDialogButtons() const override; @@ -33,7 +33,7 @@ void Init() override; void RequestFocus() override; - // AssistantBubbleModelObserver: + // AssistantUiModelObserver: void OnUiModeChanged(AssistantUiMode ui_mode) override; private: @@ -45,9 +45,9 @@ std::unique_ptr<AssistantMiniView> assistant_mini_view_; std::unique_ptr<AssistantWebView> assistant_web_view_; - DISALLOW_COPY_AND_ASSIGN(AssistantBubbleView); + DISALLOW_COPY_AND_ASSIGN(AssistantContainerView); }; } // namespace ash -#endif // ASH_ASSISTANT_UI_ASSISTANT_BUBBLE_VIEW_H_ +#endif // ASH_ASSISTANT_UI_ASSISTANT_CONTAINER_VIEW_H_
diff --git a/ash/assistant/ui/assistant_main_view.cc b/ash/assistant/ui/assistant_main_view.cc index 0a695720..5a49c12 100644 --- a/ash/assistant/ui/assistant_main_view.cc +++ b/ash/assistant/ui/assistant_main_view.cc
@@ -6,8 +6,9 @@ #include <memory> -#include "ash/assistant/assistant_bubble_controller.h" #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" +#include "ash/assistant/assistant_ui_controller.h" #include "ash/assistant/model/assistant_interaction_model.h" #include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/ui/caption_bar.h" @@ -30,15 +31,15 @@ InitLayout(); // Set delegates. - caption_bar_->set_delegate(assistant_controller_->bubble_controller()); + caption_bar_->set_delegate(assistant_controller_->ui_controller()); dialog_plate_->set_delegate(assistant_controller_); // Observe changes to interaction model. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } AssistantMainView::~AssistantMainView() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); } gfx::Size AssistantMainView::CalculatePreferredSize() const {
diff --git a/ash/assistant/ui/assistant_mini_view.cc b/ash/assistant/ui/assistant_mini_view.cc index 5db11a0..14589de 100644 --- a/ash/assistant/ui/assistant_mini_view.cc +++ b/ash/assistant/ui/assistant_mini_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" @@ -34,11 +35,11 @@ // AssistantController indirectly owns the view hierarchy to which // AssistantMiniView belongs so is guaranteed to outlive it. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } AssistantMiniView::~AssistantMiniView() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); } gfx::Size AssistantMiniView::CalculatePreferredSize() const { @@ -79,8 +80,9 @@ AddChildView(label_); // Trigger input modality changed event to initialize view state. - OnInputModalityChanged( - assistant_controller_->interaction_model()->input_modality()); + OnInputModalityChanged(assistant_controller_->interaction_controller() + ->model() + ->input_modality()); } void AssistantMiniView::OnInputModalityChanged(InputModality input_modality) {
diff --git a/ash/assistant/ui/dialog_plate/action_view.cc b/ash/assistant/ui/dialog_plate/action_view.cc index 975b87ef..363f0d0 100644 --- a/ash/assistant/ui/dialog_plate/action_view.cc +++ b/ash/assistant/ui/dialog_plate/action_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/ui/logo_view/base_logo_view.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ui/gfx/color_palette.h" @@ -34,11 +35,11 @@ // The Assistant controller indirectly owns the view hierarchy to which // ActionView belongs so is guaranteed to outlive it. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } ActionView::~ActionView() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); } gfx::Size ActionView::CalculatePreferredSize() const { @@ -102,7 +103,7 @@ void ActionView::UpdateState(bool animate) { const AssistantInteractionModel* interaction_model = - assistant_controller_->interaction_model(); + assistant_controller_->interaction_controller()->model(); InputModality input_modality = interaction_model->input_modality();
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.cc b/ash/assistant/ui/dialog_plate/dialog_plate.cc index ebc4af6..d9a6627 100644 --- a/ash/assistant/ui/dialog_plate/dialog_plate.cc +++ b/ash/assistant/ui/dialog_plate/dialog_plate.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h" @@ -55,11 +56,11 @@ // The Assistant controller indirectly owns the view hierarchy to which // DialogPlate belongs so is guaranteed to outlive it. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } DialogPlate::~DialogPlate() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); } gfx::Size DialogPlate::CalculatePreferredSize() const { @@ -86,8 +87,9 @@ InitVoiceLayoutContainer(); // Artificially trigger event to set initial state. - OnInputModalityChanged( - assistant_controller_->interaction_model()->input_modality()); + OnInputModalityChanged(assistant_controller_->interaction_controller() + ->model() + ->input_modality()); } void DialogPlate::InitKeyboardLayoutContainer() {
diff --git a/ash/assistant/ui/main_stage/assistant_header_view.cc b/ash/assistant/ui/main_stage/assistant_header_view.cc index eda414f..261df7f 100644 --- a/ash/assistant/ui/main_stage/assistant_header_view.cc +++ b/ash/assistant/ui/main_stage/assistant_header_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/model/assistant_interaction_model.h" #include "ash/assistant/model/assistant_query.h" #include "ash/assistant/ui/assistant_ui_constants.h" @@ -35,11 +36,11 @@ // The Assistant controller indirectly owns the view hierarchy to which // AssistantHeaderView belongs so is guaranteed to outlive it. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } AssistantHeaderView::~AssistantHeaderView() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); } gfx::Size AssistantHeaderView::CalculatePreferredSize() const {
diff --git a/ash/assistant/ui/main_stage/assistant_query_view.cc b/ash/assistant/ui/main_stage/assistant_query_view.cc index 24bbfc3..ff80153 100644 --- a/ash/assistant/ui/main_stage/assistant_query_view.cc +++ b/ash/assistant/ui/main_stage/assistant_query_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/model/assistant_interaction_model.h" #include "ash/assistant/model/assistant_query.h" #include "ash/assistant/ui/assistant_ui_constants.h" @@ -31,11 +32,11 @@ // The Assistant controller indirectly owns the view hierarchy to which // AssistantQueryView belongs so is guaranteed to outlive it. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } AssistantQueryView::~AssistantQueryView() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); } gfx::Size AssistantQueryView::CalculatePreferredSize() const { @@ -72,10 +73,13 @@ AddChildView(label_); // Artificially trigger event to initialize state. - OnPendingQueryChanged( - observed_query_state_ == ObservedQueryState::kCommitted - ? assistant_controller_->interaction_model()->committed_query() - : assistant_controller_->interaction_model()->pending_query()); + OnPendingQueryChanged(observed_query_state_ == ObservedQueryState::kCommitted + ? assistant_controller_->interaction_controller() + ->model() + ->committed_query() + : assistant_controller_->interaction_controller() + ->model() + ->pending_query()); } void AssistantQueryView::OnCommittedQueryChanged(
diff --git a/ash/assistant/ui/main_stage/suggestion_container_view.cc b/ash/assistant/ui/main_stage/suggestion_container_view.cc index 6977a824..9abb6bc8 100644 --- a/ash/assistant/ui/main_stage/suggestion_container_view.cc +++ b/ash/assistant/ui/main_stage/suggestion_container_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/ui/assistant_ui_constants.h" #include "base/strings/utf_string_conversions.h" #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" @@ -48,11 +49,11 @@ // The Assistant controller indirectly owns the view hierarchy to which // SuggestionContainerView belongs so is guaranteed to outlive it. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } SuggestionContainerView::~SuggestionContainerView() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); } gfx::Size SuggestionContainerView::CalculatePreferredSize() const { @@ -141,7 +142,8 @@ void SuggestionContainerView::OnSuggestionChipPressed( app_list::SuggestionChipView* suggestion_chip_view) { - assistant_controller_->OnSuggestionChipPressed(suggestion_chip_view->id()); + assistant_controller_->interaction_controller()->OnSuggestionChipPressed( + suggestion_chip_view->id()); } void SuggestionContainerView::UpdateContentsBounds() {
diff --git a/ash/assistant/ui/main_stage/ui_element_container_view.cc b/ash/assistant/ui/main_stage/ui_element_container_view.cc index b88d717..08227fb 100644 --- a/ash/assistant/ui/main_stage/ui_element_container_view.cc +++ b/ash/assistant/ui/main_stage/ui_element_container_view.cc
@@ -5,6 +5,7 @@ #include "ash/assistant/ui/main_stage/ui_element_container_view.h" #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/assistant/model/assistant_ui_element.h" #include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/ui/main_stage/assistant_header_view.h" @@ -34,11 +35,11 @@ // The Assistant controller indirectly owns the view hierarchy to which // UiElementContainerView belongs so is guaranteed to outlive it. - assistant_controller_->AddInteractionModelObserver(this); + assistant_controller_->interaction_controller()->AddModelObserver(this); } UiElementContainerView::~UiElementContainerView() { - assistant_controller_->RemoveInteractionModelObserver(this); + assistant_controller_->interaction_controller()->RemoveModelObserver(this); ReleaseAllCards(); }
diff --git a/ash/components/autoclick/autoclick_application.cc b/ash/components/autoclick/autoclick_application.cc index 60432fac..74afbef3 100644 --- a/ash/components/autoclick/autoclick_application.cc +++ b/ash/components/autoclick/autoclick_application.cc
@@ -93,11 +93,12 @@ AutoclickApplication::~AutoclickApplication() = default; void AutoclickApplication::OnStart() { - const bool register_path_provider = running_standalone_; - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS, - register_path_provider); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS; + params.register_path_provider = running_standalone_; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) { context()->QuitNow(); return;
diff --git a/ash/components/quick_launch/quick_launch_application.cc b/ash/components/quick_launch/quick_launch_application.cc index 3d5cb5b..8e9ff3f 100644 --- a/ash/components/quick_launch/quick_launch_application.cc +++ b/ash/components/quick_launch/quick_launch_application.cc
@@ -174,11 +174,12 @@ // If AuraInit was unable to initialize there is no longer a peer connection. // The ServiceManager is in the process of shutting down, however we haven't // been notified yet. Close our ServiceContext and shutdown. - const bool register_path_provider = running_standalone_; - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS2, - register_path_provider); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS2; + params.register_path_provider = running_standalone_; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) { context()->QuitNow(); return;
diff --git a/ash/components/shortcut_viewer/shortcut_viewer_application.cc b/ash/components/shortcut_viewer/shortcut_viewer_application.cc index 6f359b1..2522ed29 100644 --- a/ash/components/shortcut_viewer/shortcut_viewer_application.cc +++ b/ash/components/shortcut_viewer/shortcut_viewer_application.cc
@@ -33,10 +33,12 @@ } void ShortcutViewerApplication::OnStart() { - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS2, - false /*register_path_provider*/); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS2; + params.register_path_provider = false; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) { context()->QuitNow(); return;
diff --git a/ash/components/strings/ash_components_strings_hi.xtb b/ash/components/strings/ash_components_strings_hi.xtb index be5b311..3166191 100644 --- a/ash/components/strings/ash_components_strings_hi.xtb +++ b/ash/components/strings/ash_components_strings_hi.xtb
@@ -188,7 +188,7 @@ <translation id="8990356943438003669"><ph name="ALT" /><ph name="SEPARATOR" /> 1 से 8 तक</translation> <translation id="9005984960510803406">Crosh विंडो खोलें</translation> <translation id="9041599225465145264">क्लिपबोर्ड से सामग्री चिपकाएं</translation> -<translation id="9052808072970550123">अगले उपयोगकर्ता पर स्विच करें</translation> +<translation id="9052808072970550123">अगले उपयोगकर्ता पर जाएं</translation> <translation id="906458777597946297">विंडो को बड़ा करें</translation> <translation id="9106898733795143799">पेज और वेब ब्राउज़र</translation> <translation id="9162942292291287644"><ph name="QUERY" /> के लिए कोई सर्च नतीजा नहीं</translation>
diff --git a/ash/components/tap_visualizer/tap_visualizer_app.cc b/ash/components/tap_visualizer/tap_visualizer_app.cc index 5d29436..86efb11c 100644 --- a/ash/components/tap_visualizer/tap_visualizer_app.cc +++ b/ash/components/tap_visualizer/tap_visualizer_app.cc
@@ -45,11 +45,12 @@ } void TapVisualizerApp::OnStart() { - const bool register_path_provider = false; - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS2, - register_path_provider); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS2; + params.register_path_provider = false; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) { context()->QuitNow(); return;
diff --git a/ash/content/ash_with_content_export.h b/ash/content/ash_with_content_export.h index 65179a68..f234cc2 100644 --- a/ash/content/ash_with_content_export.h +++ b/ash/content/ash_with_content_export.h
@@ -5,8 +5,8 @@ #ifndef ASH_CONTENT_ASH_WITH_CONTENT_EXPORT_H_ #define ASH_CONTENT_ASH_WITH_CONTENT_EXPORT_H_ -// Defines ASH_EXPORT so that functionality implemented by the Ash module can -// be exported to consumers. +// Defines ASH_WITH_CONTENT_EXPORT so that functionality implemented by the Ash +// module can be exported to consumers. #if defined(COMPONENT_BUILD) #if defined(WIN32)
diff --git a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc index 753e05f..a30ed50 100644 --- a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc +++ b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <vector> +#include "ash/content/screen_orientation_delegate_chromeos.h" #include "ash/content/shell_content_state.h" #include "ash/display/screen_orientation_controller.h" #include "ash/display/screen_orientation_controller_test_api.h" @@ -109,13 +110,7 @@ ScreenOrientationControllerTest(); ~ScreenOrientationControllerTest() override; - content::ScreenOrientationDelegate* delegate() { - AshTestEnvironmentContent* test_environment_content = - static_cast<AshTestEnvironmentContent*>( - ash_test_helper()->ash_test_environment()); - return test_environment_content->test_shell_content_state() - ->screen_orientation_delegate(); - } + content::ScreenOrientationDelegate* delegate() { return &delegate_; } // Creates and initializes and empty content::WebContents that is backed by a // content::BrowserContext and that has an aura::Window. @@ -156,6 +151,8 @@ } private: + ScreenOrientationDelegateChromeos delegate_; + // Optional content::BrowserContext used for two window tests. std::unique_ptr<content::BrowserContext> secondary_browser_context_;
diff --git a/ash/content/screen_orientation_delegate_chromeos.h b/ash/content/screen_orientation_delegate_chromeos.h index d5fe51c0..67f40fe 100644 --- a/ash/content/screen_orientation_delegate_chromeos.h +++ b/ash/content/screen_orientation_delegate_chromeos.h
@@ -7,11 +7,11 @@ #include "content/public/browser/screen_orientation_delegate.h" -#include "base/macros.h" +#include "ash/content/ash_with_content_export.h" namespace ash { -class ScreenOrientationDelegateChromeos +class ASH_WITH_CONTENT_EXPORT ScreenOrientationDelegateChromeos : public content::ScreenOrientationDelegate { public: ScreenOrientationDelegateChromeos(); @@ -30,4 +30,4 @@ } // namespace ash -#endif // ASH_CONTENT_SCREEN_ORIENTATION_DELEGATE_CHROMEOS_H_ \ No newline at end of file +#endif // ASH_CONTENT_SCREEN_ORIENTATION_DELEGATE_CHROMEOS_H_
diff --git a/ash/content/shell_content_state.h b/ash/content/shell_content_state.h index 858eec1..0758ac4 100644 --- a/ash/content/shell_content_state.h +++ b/ash/content/shell_content_state.h
@@ -6,7 +6,6 @@ #define ASH_CONTENT_SHELL_CONTENT_STATE_H_ #include "ash/content/ash_with_content_export.h" -#include "ash/content/screen_orientation_delegate_chromeos.h" #include "ash/public/cpp/session_types.h" #include "base/macros.h" @@ -31,25 +30,10 @@ // current user scenario. Default implementation here returns nullptr. virtual content::BrowserContext* GetActiveBrowserContext() = 0; - // Returns the browser context for the user given by |index|. - virtual content::BrowserContext* GetBrowserContextByIndex( - UserIndex index) = 0; - - // Returns the browser context associated with the window. - virtual content::BrowserContext* GetBrowserContextForWindow( - aura::Window* window) = 0; - - // Returns the browser context on which the window is currently shown. NULL - // means the window will be shown for every user. - virtual content::BrowserContext* GetUserPresentingBrowserContextForWindow( - aura::Window* window) = 0; - protected: ShellContentState(); virtual ~ShellContentState(); - ScreenOrientationDelegateChromeos orientation_delegate_; - private: static ShellContentState* instance_;
diff --git a/ash/host/ash_window_tree_host.cc b/ash/host/ash_window_tree_host.cc index f06ea70..052276d 100644 --- a/ash/host/ash_window_tree_host.cc +++ b/ash/host/ash_window_tree_host.cc
@@ -20,6 +20,7 @@ #include "ui/events/event.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace ash { namespace { @@ -86,7 +87,7 @@ init_params.initial_bounds, init_params.mirroring_delegate); } return std::make_unique<AshWindowTreeHostPlatform>( - init_params.initial_bounds); + ui::PlatformWindowInitProperties{init_params.initial_bounds}); } } // namespace ash
diff --git a/ash/host/ash_window_tree_host_mirroring_unified.cc b/ash/host/ash_window_tree_host_mirroring_unified.cc index ec7531f..1be67b1 100644 --- a/ash/host/ash_window_tree_host_mirroring_unified.cc +++ b/ash/host/ash_window_tree_host_mirroring_unified.cc
@@ -8,6 +8,7 @@ #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/transform.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace ash { @@ -15,7 +16,8 @@ const gfx::Rect& initial_bounds, int64_t mirroring_display_id, AshWindowTreeHostMirroringDelegate* delegate) - : AshWindowTreeHostPlatform(initial_bounds), + : AshWindowTreeHostPlatform( + ui::PlatformWindowInitProperties{initial_bounds}), mirroring_display_id_(mirroring_display_id), delegate_(delegate) { DCHECK(delegate_);
diff --git a/ash/host/ash_window_tree_host_platform.cc b/ash/host/ash_window_tree_host_platform.cc index 3c88256..9307849 100644 --- a/ash/host/ash_window_tree_host_platform.cc +++ b/ash/host/ash_window_tree_host_platform.cc
@@ -28,13 +28,15 @@ #include "ui/platform_window/mojo/ime_type_converters.h" #include "ui/platform_window/platform_ime_controller.h" #include "ui/platform_window/platform_window.h" +#include "ui/platform_window/platform_window_init_properties.h" #include "ui/platform_window/text_input_state.h" namespace ash { AshWindowTreeHostPlatform::AshWindowTreeHostPlatform( - const gfx::Rect& initial_bounds) - : aura::WindowTreeHostPlatform(initial_bounds), transformer_helper_(this) { + ui::PlatformWindowInitProperties properties) + : aura::WindowTreeHostPlatform(std::move(properties)), + transformer_helper_(this) { transformer_helper_.Init(); InitInputMethodIfNecessary(); }
diff --git a/ash/host/ash_window_tree_host_platform.h b/ash/host/ash_window_tree_host_platform.h index 253da8a..5acb94c 100644 --- a/ash/host/ash_window_tree_host_platform.h +++ b/ash/host/ash_window_tree_host_platform.h
@@ -17,6 +17,10 @@ class InputMethodMus; } +namespace ui { +struct PlatformWindowInitProperties; +} + namespace ash { class ASH_EXPORT AshWindowTreeHostPlatform @@ -24,7 +28,9 @@ public aura::WindowTreeHostPlatform, public aura::InputMethodMusDelegate { public: - explicit AshWindowTreeHostPlatform(const gfx::Rect& initial_bounds); + explicit AshWindowTreeHostPlatform( + ui::PlatformWindowInitProperties properties); + ~AshWindowTreeHostPlatform() override; protected:
diff --git a/ash/keyboard/virtual_keyboard_controller.cc b/ash/keyboard/virtual_keyboard_controller.cc index d1f2623..bbdfbc2 100644 --- a/ash/keyboard/virtual_keyboard_controller.cc +++ b/ash/keyboard/virtual_keyboard_controller.cc
@@ -146,12 +146,13 @@ TRACE_EVENT0("vk", "MoveKeyboardToDisplay"); - aura::Window* container = - keyboard::KeyboardController::Get()->GetContainerWindow(); - DCHECK(container); + aura::Window* keyboard_window = + keyboard::KeyboardController::Get()->GetContentsWindow(); + DCHECK(keyboard_window); + const display::Screen* screen = display::Screen::GetScreen(); const display::Display current_display = - screen->GetDisplayNearestWindow(container); + screen->GetDisplayNearestWindow(keyboard_window); if (display.id() != current_display.id()) MoveKeyboardToDisplayInternal(display); @@ -162,15 +163,15 @@ TRACE_EVENT0("vk", "MoveKeyboardToTouchableDisplay"); - aura::Window* container = - keyboard::KeyboardController::Get()->GetContainerWindow(); - DCHECK(container != nullptr); + aura::Window* keyboard_window = + keyboard::KeyboardController::Get()->GetContentsWindow(); + DCHECK(keyboard_window); const display::Screen* screen = display::Screen::GetScreen(); const display::Display current_display = - screen->GetDisplayNearestWindow(container); + screen->GetDisplayNearestWindow(keyboard_window); - if (wm::GetFocusedWindow() != nullptr) { + if (wm::GetFocusedWindow()) { // Move the virtual keyboard to the focused display if that display has // touch capability or keyboard is locked const display::Display focused_display =
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc index 46c6679..b711a33b 100644 --- a/ash/login/login_screen_controller.cc +++ b/ash/login/login_screen_controller.cc
@@ -193,6 +193,12 @@ login_screen_client_->ShowGaiaSignin(can_close, prefilled_account); } +void LoginScreenController::ShowResetScreen() { + if (!login_screen_client_) + return; + login_screen_client_->ShowResetScreen(); +} + void LoginScreenController::OnRemoveUserWarningShown() { if (!login_screen_client_) return;
diff --git a/ash/login/login_screen_controller.h b/ash/login/login_screen_controller.h index c9c39b8e..40fcca9 100644 --- a/ash/login/login_screen_controller.h +++ b/ash/login/login_screen_controller.h
@@ -71,6 +71,7 @@ void FocusLockScreenApps(bool reverse); void ShowGaiaSignin(bool can_close, const base::Optional<AccountId>& prefilled_account); + void ShowResetScreen(); void OnRemoveUserWarningShown(); void RemoveUser(const AccountId& account_id); void LaunchPublicSession(const AccountId& account_id,
diff --git a/ash/login/mock_login_screen_client.h b/ash/login/mock_login_screen_client.h index e9632fa..e18e9de 100644 --- a/ash/login/mock_login_screen_client.h +++ b/ash/login/mock_login_screen_client.h
@@ -69,6 +69,7 @@ void(const AccountId& account_id, const std::string& locale)); MOCK_METHOD0(ShowFeedback, void()); MOCK_METHOD1(LaunchKioskApp, void(const std::string& app_id)); + MOCK_METHOD0(ShowResetScreen, void()); private: bool authenticate_user_callback_result_ = true;
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index a6d16f1..b39d083 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -38,10 +38,13 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "components/user_manager/user_type.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/base/accelerators/accelerator.h" #include "ui/base/l10n/l10n_util.h" #include "ui/display/display.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" +#include "ui/events/event_constants.h" +#include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -1338,6 +1341,9 @@ // TODO: Add more accelerators that are applicable to login screen. accel_map_[ui::Accelerator(ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)] = AcceleratorAction::kShowFeedback; + accel_map_[ui::Accelerator( + ui::VKEY_R, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] = + AcceleratorAction::kShowReset; AcceleratorController* controller = Shell::Get()->accelerator_controller(); for (const auto& item : accel_map_) @@ -1349,6 +1355,9 @@ case AcceleratorAction::kShowFeedback: Shell::Get()->login_screen_controller()->ShowFeedback(); return; + case AcceleratorAction::kShowReset: + Shell::Get()->login_screen_controller()->ShowResetScreen(); + return; default: NOTREACHED(); }
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h index 46939a0..34e4b732 100644 --- a/ash/login/ui/lock_contents_view.h +++ b/ash/login/ui/lock_contents_view.h
@@ -102,6 +102,7 @@ enum class AcceleratorAction { kShowFeedback, + kShowReset, }; // Number of login attempts before a login dialog is shown. For example, if
diff --git a/ash/login/ui/lock_screen.cc b/ash/login/ui/lock_screen.cc index b177b75..ef3884d 100644 --- a/ash/login/ui/lock_screen.cc +++ b/ash/login/ui/lock_screen.cc
@@ -73,7 +73,7 @@ CHECK(!instance_); instance_ = new LockScreen(type); - instance_->window_ = new LockWindow(Shell::GetAshConfig()); + instance_->window_ = new LockWindow(); instance_->window_->SetBounds( display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
diff --git a/ash/login/ui/lock_window.cc b/ash/login/ui/lock_window.cc index d2dc278..dfe1567 100644 --- a/ash/login/ui/lock_window.cc +++ b/ash/login/ui/lock_window.cc
@@ -11,7 +11,7 @@ namespace ash { -LockWindow::LockWindow(Config config) { +LockWindow::LockWindow() { ui::GestureRecognizer::Get()->CancelActiveTouchesExcept(nullptr); views::Widget::InitParams params(
diff --git a/ash/login/ui/lock_window.h b/ash/login/ui/lock_window.h index 78e2529e..7852c36 100644 --- a/ash/login/ui/lock_window.h +++ b/ash/login/ui/lock_window.h
@@ -18,13 +18,11 @@ namespace ash { -enum class Config; - // Shows the widget for the lock screen. class ASH_EXPORT LockWindow : public views::Widget, public views::WidgetDelegate { public: - explicit LockWindow(Config config); + LockWindow(); ~LockWindow() override; LoginDataDispatcher* data_dispatcher() const {
diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc index b590dc8..342cb2d 100644 --- a/ash/magnifier/magnification_controller.cc +++ b/ash/magnifier/magnification_controller.cc
@@ -928,7 +928,7 @@ // Reduce the viewport bounds if the keyboard is up. if (keyboard::KeyboardController::Get()->enabled()) { gfx::Rect keyboard_rect = keyboard::KeyboardController::Get() - ->GetContainerWindow() + ->GetContentsWindow() ->GetBoundsInScreen(); window_rect.set_height(window_rect.height() - keyboard_rect.height() / scale_);
diff --git a/ash/magnifier/magnification_controller_unittest.cc b/ash/magnifier/magnification_controller_unittest.cc index d0df6564..206c2f6 100644 --- a/ash/magnifier/magnification_controller_unittest.cc +++ b/ash/magnifier/magnification_controller_unittest.cc
@@ -1026,7 +1026,7 @@ keyboard_controller->ShowKeyboard(true); gfx::Rect keyboard_bounds = gfx::Rect(0, 300, 800, 300); - keyboard_controller->GetContainerWindow()->SetBounds(keyboard_bounds); + keyboard_controller->GetContentsWindow()->SetBounds(keyboard_bounds); // Focus on the text input field. text_input_helper_.FocusOnTextInputView();
diff --git a/ash/multi_device_setup/multi_device_notification_presenter.cc b/ash/multi_device_setup/multi_device_notification_presenter.cc index add67bc..9483390 100644 --- a/ash/multi_device_setup/multi_device_notification_presenter.cc +++ b/ash/multi_device_setup/multi_device_notification_presenter.cc
@@ -157,7 +157,7 @@ } void MultiDeviceNotificationPresenter::ObserveMultiDeviceSetupIfPossible() { - // If already observing, there is nothing else to do. + // If already the delegate, there is nothing else to do. if (multidevice_setup_ptr_) return; @@ -185,11 +185,12 @@ chromeos::multidevice_setup::mojom::kServiceName, service_user_id), &multidevice_setup_ptr_); - // Start observing the MultiDeviceSetup Service. - chromeos::multidevice_setup::mojom::MultiDeviceSetupObserverPtr observer_ptr; - binding_.Bind(mojo::MakeRequest(&observer_ptr)); - multidevice_setup_ptr_->SetObserver(std::move(observer_ptr), - base::DoNothing()); + // Add this object as the delegate of the MultiDeviceSetup Service. + chromeos::multidevice_setup::mojom::AccountStatusChangeDelegatePtr + delegate_ptr; + binding_.Bind(mojo::MakeRequest(&delegate_ptr)); + multidevice_setup_ptr_->SetAccountStatusChangeDelegate( + std::move(delegate_ptr), base::DoNothing()); } void MultiDeviceNotificationPresenter::OnNotificationClicked() {
diff --git a/ash/multi_device_setup/multi_device_notification_presenter.h b/ash/multi_device_setup/multi_device_notification_presenter.h index 1cdb774f..84bc3d3c 100644 --- a/ash/multi_device_setup/multi_device_notification_presenter.h +++ b/ash/multi_device_setup/multi_device_notification_presenter.h
@@ -43,7 +43,7 @@ // Note that if one notification is showing and another one is triggered, the // old text is replaced (if it's different) and the notification pops up again. class ASH_EXPORT MultiDeviceNotificationPresenter - : public chromeos::multidevice_setup::mojom::MultiDeviceSetupObserver, + : public chromeos::multidevice_setup::mojom::AccountStatusChangeDelegate, public SessionObserver { public: MultiDeviceNotificationPresenter( @@ -57,7 +57,7 @@ void RemoveMultiDeviceSetupNotification(); protected: - // multidevice_setup::mojom::MultiDeviceSetupObserver: + // multidevice_setup::mojom::AccountStatusChangeDelegate: void OnPotentialHostExistsForNewUser() override; void OnConnectedHostSwitchedForExistingUser() override; void OnNewChromebookAddedForExistingUser() override; @@ -128,7 +128,7 @@ chromeos::multidevice_setup::mojom::MultiDeviceSetupPtr multidevice_setup_ptr_; - mojo::Binding<chromeos::multidevice_setup::mojom::MultiDeviceSetupObserver> + mojo::Binding<chromeos::multidevice_setup::mojom::AccountStatusChangeDelegate> binding_; std::unique_ptr<OpenUiDelegate> open_ui_delegate_;
diff --git a/ash/multi_device_setup/multi_device_notification_presenter_unittest.cc b/ash/multi_device_setup/multi_device_notification_presenter_unittest.cc index 3e006e8..df1b14b 100644 --- a/ash/multi_device_setup/multi_device_notification_presenter_unittest.cc +++ b/ash/multi_device_setup/multi_device_notification_presenter_unittest.cc
@@ -80,16 +80,17 @@ }; // Fake for the MultiDeviceSetup service. This class only implements the -// SetObserver() interface function since it's the only one that is used by -// MultiDeviceNotificationPresenter. +// SetAccountStatusChangeDelegate() interface function since it's the only one +// that is used by MultiDeviceNotificationPresenter. class FakeMultiDeviceSetup : public chromeos::multidevice_setup::mojom::MultiDeviceSetup { public: FakeMultiDeviceSetup() : binding_(this) {} ~FakeMultiDeviceSetup() override = default; - chromeos::multidevice_setup::mojom::MultiDeviceSetupObserverPtr& observer() { - return observer_; + chromeos::multidevice_setup::mojom::AccountStatusChangeDelegatePtr& + delegate() { + return delegate_; } void Bind(mojo::ScopedMessagePipeHandle handle) { @@ -98,10 +99,11 @@ } // mojom::MultiDeviceSetup: - void SetObserver( - chromeos::multidevice_setup::mojom::MultiDeviceSetupObserverPtr observer, - SetObserverCallback callback) override { - observer_ = std::move(observer); + void SetAccountStatusChangeDelegate( + chromeos::multidevice_setup::mojom::AccountStatusChangeDelegatePtr + delegate, + SetAccountStatusChangeDelegateCallback callback) override { + delegate_ = std::move(delegate); std::move(callback).Run(); } @@ -112,7 +114,7 @@ } private: - chromeos::multidevice_setup::mojom::MultiDeviceSetupObserverPtr observer_; + chromeos::multidevice_setup::mojom::AccountStatusChangeDelegatePtr delegate_; mojo::Binding<chromeos::multidevice_setup::mojom::MultiDeviceSetup> binding_; }; @@ -206,25 +208,25 @@ AccountId::FromUserEmail(kTestUserEmail)); InvokePendingMojoCalls(); - EXPECT_TRUE(fake_multidevice_setup_->observer().is_bound()); + EXPECT_TRUE(fake_multidevice_setup_->delegate().is_bound()); } void ShowNewUserNotification() { - EXPECT_TRUE(fake_multidevice_setup_->observer().is_bound()); - fake_multidevice_setup_->observer()->OnPotentialHostExistsForNewUser(); + EXPECT_TRUE(fake_multidevice_setup_->delegate().is_bound()); + fake_multidevice_setup_->delegate()->OnPotentialHostExistsForNewUser(); InvokePendingMojoCalls(); } void ShowExistingUserHostSwitchedNotification() { - EXPECT_TRUE(fake_multidevice_setup_->observer().is_bound()); - fake_multidevice_setup_->observer() + EXPECT_TRUE(fake_multidevice_setup_->delegate().is_bound()); + fake_multidevice_setup_->delegate() ->OnConnectedHostSwitchedForExistingUser(); InvokePendingMojoCalls(); } void ShowExistingUserNewChromebookNotification() { - EXPECT_TRUE(fake_multidevice_setup_->observer().is_bound()); - fake_multidevice_setup_->observer()->OnNewChromebookAddedForExistingUser(); + EXPECT_TRUE(fake_multidevice_setup_->delegate().is_bound()); + fake_multidevice_setup_->delegate()->OnNewChromebookAddedForExistingUser(); InvokePendingMojoCalls(); } @@ -348,15 +350,15 @@ session_manager::SessionState::LOGIN_SECONDARY}; // For each of the states which is not ACTIVE, set the session state. None of - // these should trigger a SetObserver() call. + // these should trigger a SetAccountStatusChangeDelegate() call. for (const auto state : kNonActiveStates) { GetSessionControllerClient()->SetSessionState(state); InvokePendingMojoCalls(); - EXPECT_FALSE(fake_multidevice_setup_->observer().is_bound()); + EXPECT_FALSE(fake_multidevice_setup_->delegate().is_bound()); } SignIntoAccount(); - EXPECT_TRUE(fake_multidevice_setup_->observer().is_bound()); + EXPECT_TRUE(fake_multidevice_setup_->delegate().is_bound()); } TEST_F(MultiDeviceNotificationPresenterTest,
diff --git a/ash/public/interfaces/login_screen.mojom b/ash/public/interfaces/login_screen.mojom index ff72751..bb5f3ee 100644 --- a/ash/public/interfaces/login_screen.mojom +++ b/ash/public/interfaces/login_screen.mojom
@@ -194,6 +194,9 @@ // sign-in dialog so the user does not need to type the account email. ShowGaiaSignin(bool can_close, signin.mojom.AccountId? prefilled_account); + // Show the Reset (Powerwash) screen. + ShowResetScreen(); + // Notification that the remove user warning was shown. OnRemoveUserWarningShown();
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index ed66ee1..16de6bd 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -80,6 +80,7 @@ #include "ui/display/types/display_constants.h" #include "ui/events/event_utils.h" #include "ui/keyboard/keyboard_controller.h" +#include "ui/keyboard/keyboard_layout_manager.h" #include "ui/keyboard/keyboard_util.h" #include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" @@ -567,13 +568,10 @@ if (keyboard_controller->GetRootWindow() == GetRootWindow()) return; - aura::Window* keyboard_window = keyboard_controller->GetContainerWindow(); - DCHECK(!keyboard_window->parent()); - aura::Window* vk_container = GetContainer(kShellWindowId_VirtualKeyboardContainer); DCHECK(vk_container); - vk_container->AddChild(keyboard_window); + keyboard_controller->ActivateKeyboardInContainer(vk_container); keyboard_controller->LoadKeyboardUiInBackground(); } @@ -585,18 +583,8 @@ return; // If the VK is under the root window of this controller. - if (keyboard_controller->GetRootWindow() == GetRootWindow()) { - aura::Window* keyboard_window = keyboard_controller->GetContainerWindow(); - - // Virtual keyboard may be deactivated while still showing, hide the - // keyboard before removing it from view hierarchy. - keyboard_controller->HideKeyboardExplicitlyBySystem(); - aura::Window* vk_container = - GetContainer(kShellWindowId_VirtualKeyboardContainer); - DCHECK(vk_container); - DCHECK_EQ(vk_container, keyboard_window->parent()); - vk_container->RemoveChild(keyboard_window); - } + if (keyboard_controller->GetRootWindow() == GetRootWindow()) + keyboard_controller->DeactivateKeyboard(); } void RootWindowController::SetTouchAccessibilityAnchorPoint( @@ -991,6 +979,8 @@ wm::SetSnapsChildrenToPhysicalPixelBoundary(virtual_keyboard_container); virtual_keyboard_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true); + virtual_keyboard_container->SetLayoutManager( + new keyboard::KeyboardLayoutManager(keyboard::KeyboardController::Get())); aura::Window* menu_container = CreateContainer(kShellWindowId_MenuContainer, "MenuContainer",
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc index 9420a873..11a98173 100644 --- a/ash/root_window_controller_unittest.cc +++ b/ash/root_window_controller_unittest.cc
@@ -740,7 +740,7 @@ keyboard_container->Show(); aura::Window* contents_window = - keyboard::KeyboardController::Get()->ui()->GetContentsWindow(); + keyboard::KeyboardController::Get()->GetContentsWindow(); contents_window->SetBounds(gfx::Rect()); contents_window->Show(); @@ -766,20 +766,21 @@ root_window->RemovePreTargetHandler(&handler); } -// Test for http://crbug.com/299787. RootWindowController should delete -// the old container since the keyboard controller creates a new window in -// GetWindowContainer(). +// Test for http://crbug.com/299787. RootWindowController should remove +// the old keyboard window when we activate it elsewhere. +// TODO(https://crbug.com/849995): This test no longer belongs here, but in +// KeyboardController. TEST_F(VirtualKeyboardRootWindowControllerTest, DeleteOldContainerOnVirtualKeyboardInit) { auto* controller = keyboard::KeyboardController::Get(); - aura::Window* keyboard_container = controller->GetContainerWindow(); - // Track the keyboard container window. + aura::Window* keyboard_window = controller->GetContentsWindow(); + // Track the keyboard contents window. aura::WindowTracker tracker; - tracker.Add(keyboard_container); + tracker.Add(keyboard_window); // Reinitialize the keyboard. Shell::Get()->EnableKeyboard(); - // keyboard_container should no longer be present. - EXPECT_FALSE(tracker.Contains(keyboard_container)); + // keyboard_window should no longer be present. + EXPECT_FALSE(tracker.Contains(keyboard_window)); } // Test for crbug.com/342524. After user login, the work space should restore to @@ -790,7 +791,7 @@ Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer); keyboard_container->Show(); auto* controller = keyboard::KeyboardController::Get(); - aura::Window* contents_window = controller->ui()->GetContentsWindow(); + aura::Window* contents_window = controller->GetContentsWindow(); contents_window->SetBounds( keyboard::KeyboardBoundsFromRootBounds(root_window->bounds(), 100)); contents_window->Show(); @@ -820,15 +821,13 @@ TEST_F(VirtualKeyboardRootWindowControllerTest, ClickWithActiveModalDialog) { auto* controller = keyboard::KeyboardController::Get(); aura::Window* root_window = Shell::GetPrimaryRootWindow(); - aura::Window* container_window = controller->GetContainerWindow(); - ASSERT_TRUE(container_window); ASSERT_EQ(root_window, controller->GetRootWindow()); - container_window->Show(); - aura::Window* contents_window = controller->ui()->GetContentsWindow(); + aura::Window* contents_window = controller->GetContentsWindow(); contents_window->SetName("KeyboardContentsWindow"); contents_window->SetBounds( keyboard::KeyboardBoundsFromRootBounds(root_window->bounds(), 100)); + contents_window->Show(); ui::test::TestEventHandler handler; root_window->AddPreTargetHandler(&handler); @@ -867,8 +866,6 @@ input_method->SetFocusedTextInputClient(&text_input_client); aura::Window* root_window = Shell::GetPrimaryRootWindow(); - ASSERT_TRUE(keyboard_controller->GetContainerWindow()); - keyboard_controller->GetContainerWindow()->Show(); const int keyboard_height = 100; aura::Window* contents_window = ui->GetContentsWindow(); @@ -908,9 +905,6 @@ const int keyboard_height = 100; // Check that the keyboard on the primary screen doesn't cover the window on // the secondary screen. - aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); - ASSERT_TRUE(keyboard_container); - keyboard_container->Show(); aura::Window* contents_window = ui->GetContentsWindow(); contents_window->SetBounds(keyboard::KeyboardBoundsFromRootBounds( primary_root_window->bounds(), keyboard_height)); @@ -947,15 +941,11 @@ TEST_F(VirtualKeyboardRootWindowControllerTest, ZOrderTest) { UpdateDisplay("800x600"); auto* keyboard_controller = keyboard::KeyboardController::Get(); - keyboard::KeyboardUI* ui = keyboard_controller->ui(); aura::Window* root_window = Shell::GetPrimaryRootWindow(); - aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); - ASSERT_TRUE(keyboard_container); - keyboard_container->Show(); const int keyboard_height = 200; - aura::Window* contents_window = ui->GetContentsWindow(); + aura::Window* contents_window = keyboard_controller->GetContentsWindow(); gfx::Rect keyboard_bounds = keyboard::KeyboardBoundsFromRootBounds( root_window->bounds(), keyboard_height); contents_window->SetBounds(keyboard_bounds); @@ -1026,14 +1016,81 @@ TEST_F(VirtualKeyboardRootWindowControllerTest, DisplayRotation) { UpdateDisplay("800x600"); auto* keyboard_controller = keyboard::KeyboardController::Get(); - aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); keyboard_controller->ShowKeyboard(false); - keyboard_controller->ui()->GetContentsWindow()->SetBounds( - gfx::Rect(0, 400, 800, 200)); - EXPECT_EQ("0,400 800x200", keyboard_container->bounds().ToString()); + + aura::Window* keyboard_window = keyboard_controller->GetContentsWindow(); + + keyboard_window->SetBounds(gfx::Rect(0, 400, 800, 200)); + EXPECT_EQ("0,400 800x200", keyboard_window->bounds().ToString()); UpdateDisplay("600x800"); - EXPECT_EQ("0,600 600x200", keyboard_container->bounds().ToString()); + EXPECT_EQ("0,600 600x200", keyboard_window->bounds().ToString()); +} + +// Keeps a count of all the events a window receives. +class EventObserver : public ui::EventHandler { + public: + EventObserver() = default; + ~EventObserver() override = default; + + int GetEventCount(ui::EventType type) { return event_counts_[type]; } + void ResetAllEventCounts() { event_counts_.clear(); } + + private: + // Overridden from ui::EventHandler: + void OnEvent(ui::Event* event) override { + ui::EventHandler::OnEvent(event); + event_counts_[event->type()]++; + } + + std::map<ui::EventType, int> event_counts_; + + DISALLOW_COPY_AND_ASSIGN(EventObserver); +}; + +// Tests that tapping/clicking inside the keyboard does not give it focus. +TEST_F(VirtualKeyboardRootWindowControllerTest, ClickDoesNotFocusKeyboard) { + aura::Window* root_window = Shell::GetPrimaryRootWindow(); + + // Create a test window in the background with the same size as the screen. + aura::test::EventCountDelegate delegate; + std::unique_ptr<aura::Window> background_window( + CreateTestWindowInShellWithDelegate(&delegate, 0, root_window->bounds())); + background_window->Focus(); + EXPECT_TRUE(background_window->IsVisible()); + EXPECT_TRUE(background_window->HasFocus()); + + auto* keyboard_controller = keyboard::KeyboardController::Get(); + keyboard_controller->ShowKeyboard(false); + keyboard_controller->NotifyContentsLoaded(); + + aura::Window* keyboard_window = keyboard_controller->GetContentsWindow(); + keyboard_window->SetBounds(gfx::Rect(100, 100, 100, 100)); + EXPECT_TRUE(keyboard_window->IsVisible()); + EXPECT_FALSE(keyboard_window->HasFocus()); + + // Click on the keyboard. Make sure the keyboard receives the event, but does + // not get focus. + EventObserver observer; + keyboard_window->AddPreTargetHandler(&observer); + + ui::test::EventGenerator generator(root_window); + generator.MoveMouseTo(keyboard_window->bounds().CenterPoint()); + generator.ClickLeftButton(); + EXPECT_TRUE(background_window->HasFocus()); + EXPECT_FALSE(keyboard_window->HasFocus()); + EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset()); + EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_PRESSED)); + EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_RELEASED)); + + // Click outside of the keyboard. It should reach the window behind. + observer.ResetAllEventCounts(); + generator.MoveMouseTo(gfx::Point()); + generator.ClickLeftButton(); + EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset()); + EXPECT_EQ(0, observer.GetEventCount(ui::ET_MOUSE_PRESSED)); + EXPECT_EQ(0, observer.GetEventCount(ui::ET_MOUSE_RELEASED)); + keyboard_window->RemovePreTargetHandler(&observer); } } // namespace ash
diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc index 4de3ca3..4ca6fce 100644 --- a/ash/shelf/app_list_button.cc +++ b/ash/shelf/app_list_button.cc
@@ -10,6 +10,7 @@ #include "ash/app_list/app_list_controller_impl.h" #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/assistant_interaction_controller.h" #include "ash/public/cpp/shelf_types.h" #include "ash/session/session_controller.h" #include "ash/shelf/assistant_overlay.h" @@ -137,7 +138,10 @@ assistant_overlay_->BurstAnimation(); event->SetHandled(); if (chromeos::switches::IsAssistantEnabled()) { - Shell::Get()->assistant_controller()->StartInteraction(); + Shell::Get() + ->assistant_controller() + ->interaction_controller() + ->StartInteraction(); } else { Shell::Get()->app_list_controller()->StartVoiceInteractionSession(); }
diff --git a/ash/shelf/shelf_menu_model_adapter.cc b/ash/shelf/shelf_menu_model_adapter.cc index 4c168d9..88b08d1 100644 --- a/ash/shelf/shelf_menu_model_adapter.cc +++ b/ash/shelf/shelf_menu_model_adapter.cc
@@ -26,7 +26,7 @@ void ShelfMenuModelAdapter::RecordHistogram() { base::TimeDelta user_journey_time = base::TimeTicks::Now() - menu_open_time(); // If the menu is for a ShelfButton. - if (app_id().empty()) { + if (!app_id().empty()) { UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.ShelfButton", user_journey_time); UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.ShelfButton", @@ -34,8 +34,8 @@ return; } - // TODO(newcomer): Add Apps.ContextMenuUserJourneyTime.Shelf metric. - // https://crbug.com/845273. + UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.Shelf", + user_journey_time); UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.Shelf", source_type(), ui::MENU_SOURCE_TYPE_LAST); }
diff --git a/ash/shell/content/shell_content_state_impl.cc b/ash/shell/content/shell_content_state_impl.cc index ee94713a..05b7b053 100644 --- a/ash/shell/content/shell_content_state_impl.cc +++ b/ash/shell/content/shell_content_state_impl.cc
@@ -16,20 +16,4 @@ return browser_context_; } -content::BrowserContext* ShellContentStateImpl::GetBrowserContextByIndex( - UserIndex index) { - return browser_context_; -} - -content::BrowserContext* ShellContentStateImpl::GetBrowserContextForWindow( - aura::Window* window) { - return browser_context_; -} - -content::BrowserContext* -ShellContentStateImpl::GetUserPresentingBrowserContextForWindow( - aura::Window* window) { - return browser_context_; -} - } // namespace ash
diff --git a/ash/shell/content/shell_content_state_impl.h b/ash/shell/content/shell_content_state_impl.h index 3559cdc..7515532 100644 --- a/ash/shell/content/shell_content_state_impl.h +++ b/ash/shell/content/shell_content_state_impl.h
@@ -19,11 +19,6 @@ // Overridden from ShellContentState: content::BrowserContext* GetActiveBrowserContext() override; - content::BrowserContext* GetBrowserContextByIndex(UserIndex index) override; - content::BrowserContext* GetBrowserContextForWindow( - aura::Window* window) override; - content::BrowserContext* GetUserPresentingBrowserContextForWindow( - aura::Window* window) override; content::BrowserContext* browser_context_;
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb index 69f13c04..2080496 100644 --- a/ash/strings/ash_strings_am.xtb +++ b/ash/strings/ash_strings_am.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C መሣሪያ (የፊት ወደብ)</translation> <translation id="1013923882670373915">የብሉቱዝ መሣሪያ «<ph name="DEVICE_NAME" />» ለመጣመር ፍቃድ ይፈልጋል። እባክዎ ይህን የፒን ኮድ በዚህ መሣሪያ ላይ ያስገቡ፦ <ph name="PINCODE" /></translation> <translation id="1032891413405719768">የStylus ባትሪ ዝቅተኛ ነው</translation> +<translation id="1056775291175587022">ምንም አውታረ መረቦች የሉም</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />፦ <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">መደርደሪያን በራስ ሰር ደብቅ</translation> <translation id="1153356358378277386">የተጣመሩ መሣሪያዎች</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">ቀኝ</translation> <translation id="1383876407941801731">ፍለጋ </translation> <translation id="1467432559032391204">ግራ</translation> +<translation id="1479743070547893297">ለመምረጥ በእርስዎ ስታይለስ ይሳሉ</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">ማስጀመሪያ</translation> <translation id="1525508553941733066">አሰናብት</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">የእርስዎን ቋንቋ ያቀናብሩ</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">ስለቅርብ ጊዜው የ<ph name="SYSTEM_APP_NAME" /> ዝማኔ የበለጠ ይረዱ</translation> <translation id="1995660704900986789">ኃይል አጥፋ</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">መልእክት ይተይቡ</translation> <translation id="2049639323467105390">ይህ መሣሪያ በ<ph name="DOMAIN" /> ነው የሚቀናበረው።</translation> <translation id="2050339315714019657">በቁመት</translation> <translation id="2067602449040652523">የቁልፍ ሰሌዳ ብሩህነት</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">ቀጥል</translation> <translation id="2365393535144473978">የተንቀሳቃሽ ስልክ ውሂብን ማንቃት ብሉቱዝን ያነቃል።</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">ዝማኔ ይገኛል</translation> <translation id="2429753432712299108">የብሉቱዝ መሣሪያ «<ph name="DEVICE_NAME" />» ለመጣመር ፍቃድ ይፈልጋል። ከመቀበልዎ በፊት እባክዎ ይህ የይለፍ ቃል በዚያ መሣሪያ ላይ የሚታይ መሆኑን ያረጋግጡ፦ <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">ማስታወቂያዎች</translation> <translation id="2484513351006226581">የቁልፍ ሰሌዳ አቀማመጥን ለመቀየር <ph name="KEYBOARD_SHORTCUT" />ን ይጫኑ</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK በርቷል</translation> <translation id="2532589005999780174">ባለከፍተኛ ንፅፅር ሁነታ</translation> <translation id="2575685495496069081">በበርካታ መለያ መግባት ነቅቷል</translation> +<translation id="2582112259361606227">ለማዘመን ዳግም ያስነሱ</translation> <translation id="2597972630681408282">የሌሊት ብርሃን፦ <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">ሲም ካርድ ተዘግቷል</translation> <translation id="2653659639078652383">አስገባ</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">አሁን ማያ ገጽዎን እያጋሩ ነው</translation> <translation id="2942516765047364088">የመደርደሪያ አቀማመጥ</translation> <translation id="2946119680249604491">ግንኑነት ያክሉ</translation> +<translation id="2961963223658824723">የሆነ ስህተት ተከስቷል። በጥቂት ሰከንዶች ውስጥ እንደገና ይሞክሩ።</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> በ<ph name="DOMAIN" /> የሚቀናበር ይፋዊ ክፍለ ጊዜ ነው</translation> <translation id="3000461861112256445">ሞኖ ኦዲዮ</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">ግርጌ</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (ብሉቱዝ)</translation> -<translation id="3112378005171663295">ሰብስብ</translation> <translation id="3126069444801937830">ለማዘመን ዳግም ያስጀምሩ</translation> <translation id="3147142846278915599">ማስጀመሪያ (መተግበሪያዎችን በማመሳሰል ላይ...)</translation> <translation id="315116470104423982">የተንቀሳቃሽ ስልክ ውሂብ</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">ቆልፍ</translation> <translation id="3798670284305777884">ድምጽ ማጉያ (ውስጣዊ)</translation> +<translation id="380165613292957338">ጤና ይስጥልኝ፣ እንዴት ልርዳዎት?</translation> <translation id="3846575436967432996">ምንም የአውታረ መረብ መረጃ አይገኝም</translation> <translation id="385051799172605136">ተመለስ</translation> <translation id="3891340733213178823">ዘግተው ለመውጣት Ctrl+Shift+Qን ሁለቴ ይጫኑ።</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">የUSB-C መሣሪያ (የቀኝ ጎን የኋላ ወደብ)</translation> <translation id="4017989525502048489">የሌዘር ጨረር</translation> <translation id="4072264167173457037">መካከለኛ ሲግናል</translation> +<translation id="4200057768455216496">የተተከለውን የማጉያ አቋራጭ ተጭነዋል። ሊያበሩት ይፈልጋሉ?</translation> <translation id="4217571870635786043">በቃል ማስጻፍ</translation> <translation id="4279490309300973883">በማንጸባረቅ ላይ</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google ረዳቱ በአስተዳዳሪዎ ተሰናክሏል።</translation> <translation id="4895488851634969361">ባትሪው ሙሉ ነው።</translation> <translation id="4905614135390995787">ባለከፍተኛ ንፅፅር ሁነታ የሚቀይረው አቋራጭ ተለውጧል። እባክዎ በ<ph name="OLD_SHORTCUT" /> ምትክ <ph name="NEW_SHORTCUT" />ን ይጠቀሙ።</translation> +<translation id="4917385247580444890">ጠንካራ</translation> <translation id="4918086044614829423">ይቀበሉ</translation> <translation id="4961318399572185831">የCast ማያ ገጽ</translation> <translation id="5136175204352732067">የተለየ የቁልፍ ሰሌዳ ተገናኝቷል</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />፣ <ph name="DATE" /></translation> <translation id="5600837773213129531">የሚነገር ግብረመልስን ለማሰናከል Ctrl + Alt + Z ይጫኑ።</translation> <translation id="5648021990716966815">የማይክሮፎን መሰኪያ</translation> +<translation id="5669267381087807207">በማግበር ላይ</translation> <translation id="5673434351075758678">ከ«<ph name="FROM_LOCALE" />» ወደ «<ph name="TO_LOCALE" />» የእርስዎን ቅንብሮች ከማመሳሰል በኋላ።</translation> +<translation id="574392208103952083">መካከለኛ</translation> <translation id="5744083938413354016">መታ አድርጎ መጎተት</translation> <translation id="5777841717266010279">ማያ ገጽ ማጋራት ይቁም?</translation> <translation id="57838592816432529">ድምጽ ይዝጉ</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">አይቀበሉ</translation> <translation id="6453179446719226835">ቋንቋ ተለውጧል</translation> <translation id="6459472438155181876">ማያ ገጽ ወደ <ph name="DISPLAY_NAME" /> በመቀጠል ላይ</translation> +<translation id="6482559668224714696">የሙሉ ማያ ገጽ ማጉያ</translation> <translation id="6490471652906364588">USB-C መሣሪያ (የቀኝ ወደብ)</translation> <translation id="6501401484702599040">ማያ ገጹን ወደ <ph name="RECEIVER_NAME" /> Cast በማድረግ ላይ</translation> <translation id="6521655319214113338">የእጅ ጽሑፍ ግቤት</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">እረፍት ይውሰዱ!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" />ን አግብር</translation> +<translation id="6910714959251846841">ይህ ዝማኔ የመሣሪያዎን powerwashing ይጠይቃል። ስለቅርብ ጊዜው <ph name="SYSTEM_APP_NAME" /> ዝማኔ የበለጠ ይረዱ።</translation> <translation id="6911468394164995108">ሌላ ይቀላቀሉ...</translation> <translation id="6981982820502123353">ተደራሽነት</translation> <translation id="698231206551913481">አንዴ ይህ ተጠቃሚ ከተወገደ በኋላ ከዚህ ተጠቃሚ ጋር የተጎዳኙ ሁሉም ፋይሎች እና አካባቢያዊ ውሂብ በቋሚነት ይሰረዛሉ።</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" /> ላይ ተመልሰው ይምጡ።</translation> <translation id="7029814467594812963">ከክፍለ-ጊዜ ውጣ</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" />ን ወደ <ph name="RECEIVER_NAME" /> Cast በማድረግ ላይ</translation> +<translation id="7037152028959403492">የከፍተኛ ንጽጽር አቋራጩን ተጭነዋል። ሊያበሩት ይፈልጋሉ?</translation> <translation id="7066646422045619941">ይህ አውታረ መረብ በአስተዳዳሪዎ ነው የተሰናከለው።</translation> <translation id="7067196344162293536">በራስ-አሽከርክር</translation> <translation id="7076293881109082629">በመግባት ላይ</translation> <translation id="7098389117866926363">USB-C መሣሪያ (የግራ ወደብ ከኋላ በኩል)</translation> <translation id="7131634465328662194">በራስሰር ዘግተው እንዲወጡ ይደረጋሉ።</translation> +<translation id="7143207342074048698">በመያያዝ ላይ</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">በ<ph name="TIMEOUT_SECONDS" /> ውስጥ ወደ ቀድሞው ጥራት በመመለስ ላይ</translation> <translation id="7256634071279256947">የኋላ ማይክሮፎን</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">ከ<ph name="NAME" /> ጋር ተገናኝቷል</translation> <translation id="813913629614996137">በማስጀመር ላይ…</translation> <translation id="8142699993796781067">የግል አውታረ መረብ</translation> +<translation id="8152119955266188852">የሙሉ ማያ ገጽ ማጉያውን አቋራጭ ተጭነዋል። ሊያበሩት ይፈልጋሉ?</translation> <translation id="8180896103888046100">ወደ ያልታወቀ ተቀባይ cast ማድረግን አስቁም</translation> <translation id="8190698733819146287">ቋንቋዎችን እና ግብአቶችን አብጅ...</translation> <translation id="8261506727792406068">ሰርዝ</translation> +<translation id="8297006494302853456">ደካማ</translation> <translation id="8308637677604853869">ቀዳሚ ምናሌ</translation> <translation id="8351131234907093545">ማስታወሻን ይፍጠሩ</translation> <translation id="8392451568018454956">የ<ph name="USER_EMAIL_ADDRESS" /> አማራጮች ምናሌ</translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">የተመለስ አዝራር</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።</translation> +<translation id="8874184842967597500">አልተገናኘም</translation> <translation id="8878886163241303700">ማያ ገጽ በማስቀጠል ላይ</translation> <translation id="8921624153894383499">የGoogle ረዳቱ ይህን ቋንቋ አይናገርም።</translation> <translation id="8938800817013097409">USB-C መሣሪያ (የቀኝ ወደብ ከኋላ በኩል)</translation> <translation id="8940956008527784070">ባትሪ ዝቅተኛ ነው (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">ፈጣን ማስጀመሪያ</translation> <translation id="8995603266996330174">የተቀናበረው በ<ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">የAdobe Flash Player ዝማኔ ይገኛል</translation> <translation id="9033907480196064950">በአሁኑ ጊዜ <ph name="TAB_NAME" />ን cast እያደረጉ ነዎት</translation> <translation id="9074739597929991885">ብሉቱዝ</translation> <translation id="9079731690316798640">Wi-Fi፦ <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">ሌላ ተጠቃሚ በመለያ አስገባ...</translation> <translation id="9201131092683066720">ባትሪው <ph name="PERCENTAGE" />% ሙሉ ነው።</translation> <translation id="9210037371811586452">ከተዋሃደ የዴስክቶፕ ሁነታ በመውጣት ላይ</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">ልጣፍ ያዘጋጁ</translation> <translation id="923686485342484400">ዘግተው ለመውጣት Ctrl Shift Qን ሁለቴ ይጫኑ።</translation> <translation id="945522503751344254">ግብረ መልስ ላክ</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb index 5526609..8b3518d 100644 --- a/ash/strings/ash_strings_ar.xtb +++ b/ash/strings/ash_strings_ar.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">جهاز USB-C (المنفذ الأمامي)</translation> <translation id="1013923882670373915">يريد جهاز بلوتوث "<ph name="DEVICE_NAME" />" الحصول على إذن للإقران. يُرجى إدخال رقم التعريف الشخصي هذا في هذا الجهاز: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">بطارية قلم الشاشة منخفضة</translation> +<translation id="1056775291175587022">لم يتم العثور على أي شبكات.</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">الإخفاء التلقائي للرف</translation> <translation id="1153356358378277386">الأجهزة المقترنة</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">يمين</translation> <translation id="1383876407941801731">البحث</translation> <translation id="1467432559032391204">اليسار</translation> +<translation id="1479743070547893297">الرسم باستخدام قلم الشاشة للاختيار.</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">المشغّل</translation> <translation id="1525508553941733066">رفض</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0 درجة</translation> <translation id="1957958912175573503">تعيين اللغة</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">مزيد من المعلومات حول آخر تحديث لـ <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">إيقاف التشغيل</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">كتابة رسالة</translation> <translation id="2049639323467105390">تتم إدارة هذا الجهاز بواسطة <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">رأسي</translation> <translation id="2067602449040652523">سطوع لوحة المفاتيح</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">المتابعة</translation> <translation id="2365393535144473978">سيؤدي تفعيل ميزة بيانات الجوّال إلى تفعيل البلوتوث.</translation> <translation id="2391579633712104609">180 درجة</translation> +<translation id="2412593942846481727">هناك تحديث متاح</translation> <translation id="2429753432712299108">يريد جهاز بلوتوث "<ph name="DEVICE_NAME" />" الحصول على إذن للإقران. قبل القبول، يُرجى التأكد أن مفتاح المرور هذا يظهر في هذا الجهاز: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">الاشعارات</translation> <translation id="2484513351006226581">انقر على <ph name="KEYBOARD_SHORTCUT" /> لتبديل تنسيق لوحة المفاتيح.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">مفتاح CAPS LOCK قيد التشغيل</translation> <translation id="2532589005999780174">وضع التباين العالي</translation> <translation id="2575685495496069081">تمّ إيقاف الدخول المتعدّد</translation> +<translation id="2582112259361606227">إعادة التشغيل للتحديث</translation> <translation id="2597972630681408282">إضاءة ليلية: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">تم قفل شريحة SIM</translation> <translation id="2653659639078652383">إرسال</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">أنت تشارك شاشتك حاليًا</translation> <translation id="2942516765047364088">وضع الرف</translation> <translation id="2946119680249604491">إضافة اتصال</translation> +<translation id="2961963223658824723">حدث خطأ ما. يُرجى إعادة المحاولة خلال بضع ثوانٍ.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> هي جلسة عامة يديرها <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">صوت أحادي</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">أسفل</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (بلوتوث)</translation> -<translation id="3112378005171663295">تصغير</translation> <translation id="3126069444801937830">إعادة التشغيل للتحديث</translation> <translation id="3147142846278915599">Launcher (مزامنة التطبيقات...)</translation> <translation id="315116470104423982">بيانات الجوال</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">قفل</translation> <translation id="3798670284305777884">سماعة (داخلية)</translation> +<translation id="380165613292957338">مرحبًا، كيف يمكنني مساعدتك؟</translation> <translation id="3846575436967432996">لا توجد معلومات متاحة حول الشبكة</translation> <translation id="385051799172605136">الرجوع إلى الوراء</translation> <translation id="3891340733213178823">للخروج اضغط على Ctrl+Shift+Q مرتين.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">جهاز USB-C (المنفذ الخلفي الأيمن)</translation> <translation id="4017989525502048489">مؤشر الليزر</translation> <translation id="4072264167173457037">إشارة متوسطة</translation> +<translation id="4200057768455216496">لقد ضغطت على اختصار المُكبِّر الذي تم إرساؤه. هل ترغب في تفعيله؟</translation> <translation id="4217571870635786043">إملاء</translation> <translation id="4279490309300973883">النسخ المطابق</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">تم إيقاف مساعد Google من قِبل المشرف.</translation> <translation id="4895488851634969361">البطارية مملوءة.</translation> <translation id="4905614135390995787">تم تغيير اختصار تشغيل وضع التباين العالي. يُرجى استخدام <ph name="NEW_SHORTCUT" /> بدلاً من <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">قوية</translation> <translation id="4918086044614829423">قبول</translation> <translation id="4961318399572185831">إرسال الشاشة</translation> <translation id="5136175204352732067">تم توصيل لوحة مفاتيح مختلفة</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />، <ph name="DATE" /></translation> <translation id="5600837773213129531">اضغط على Ctrl + Alt + Z لإيقاف التعليقات والملاحظات المنطوقة</translation> <translation id="5648021990716966815">مقبس الميكروفون</translation> +<translation id="5669267381087807207">تفعيل</translation> <translation id="5673434351075758678">من "<ph name="FROM_LOCALE" />" إلى "<ph name="TO_LOCALE" />" بعد مزامنة الإعدادات.</translation> +<translation id="574392208103952083">متوسط</translation> <translation id="5744083938413354016">السحب بعد النقر</translation> <translation id="5777841717266010279">هل ترغب في إيقاف مشاركة الشاشة؟</translation> <translation id="57838592816432529">كتم الصوت</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">رفض</translation> <translation id="6453179446719226835">تم تغيير اللغة</translation> <translation id="6459472438155181876">تمديد الشاشة إلى <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">مُكبِّر بملء الشاشة</translation> <translation id="6490471652906364588">جهاز USB-C (المنفذ الأيمن)</translation> <translation id="6501401484702599040">إرسال الشاشة إلى <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">الإدخال بالكتابة اليدوية</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">حان وقت الاستراحة</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">تفعيل <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">يتطلَّب هذا التحديث إجراء عملية Powerwash لجهازك. مزيد من المعلومات حول آخر تحديث لـ <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">الانضمام إلى شبكة أخرى...</translation> <translation id="6981982820502123353">إمكانية الدخول</translation> <translation id="698231206551913481">سيتم حذف جميع الملفات والبيانات المحلية المرتبطة بهذا المستخدم نهائيًا بمجرد إزالة هذا المستخدم.</translation> <translation id="7015766095477679451">يمكنك العودة لاستخدام الجهاز في <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">إنهاء الجلسة</translation> <translation id="7034339000180558234">إرسال <ph name="TAB_NAME" /> إلى <ph name="RECEIVER_NAME" />.</translation> +<translation id="7037152028959403492">لقد ضغطت على اختصار التباين العالي. هل ترغب في تفعيله؟</translation> <translation id="7066646422045619941">تم إيقاف هذه الشبكة من قِبل مشرفك.</translation> <translation id="7067196344162293536">تدوير تلقائي</translation> <translation id="7076293881109082629">تسجيل الدخول</translation> <translation id="7098389117866926363">جهاز USB-C (المنفذ الأيسر في الخلف)</translation> <translation id="7131634465328662194">سيتم تسجيل خروجك تلقائيًا.</translation> +<translation id="7143207342074048698">اتصال</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">سيتم الرجوع إلى درجة الدقة القديمة في غضون <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">الميكروفون الخلفي</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">تم الاتصال بالموقع <ph name="NAME" /></translation> <translation id="813913629614996137">جارٍ التهيئة...</translation> <translation id="8142699993796781067">الشبكة الخاصة</translation> +<translation id="8152119955266188852">لقد ضغطت على اختصار المُكبِّر بملء الشاشة. هل ترغب في تفعيله؟</translation> <translation id="8180896103888046100">إيقاف الإرسال إلى مستلم غير معروف</translation> <translation id="8190698733819146287">تخصيص اللغات والإدخال...</translation> <translation id="8261506727792406068">حذف</translation> +<translation id="8297006494302853456">ضعيفة</translation> <translation id="8308637677604853869">القائمة السابقة</translation> <translation id="8351131234907093545">إنشاء ملاحظة</translation> <translation id="8392451568018454956">قائمة الخيارات لـ <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">زر الرجوع</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">التطبيق لا يتيح تقسيم الشاشة.</translation> +<translation id="8874184842967597500">غير متصل</translation> <translation id="8878886163241303700">توسيع الشاشة</translation> <translation id="8921624153894383499">لا يتحدث مساعد Google هذه اللغة.</translation> <translation id="8938800817013097409">جهاز USB-C (المنفذ الأيمن في الخلف)</translation> <translation id="8940956008527784070">طاقة البطارية منخفضة (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">التشغيل السريع</translation> <translation id="8995603266996330174">مدار بواسطة <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">تحديث Adobe Flash Player متاح</translation> <translation id="9033907480196064950">أنت حاليًا تبث <ph name="TAB_NAME" />.</translation> <translation id="9074739597929991885">بلوتوث</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">تسجيل دخول مستخدم آخر...</translation> <translation id="9201131092683066720">اكتمل شحن <ph name="PERCENTAGE" />% من البطارية.</translation> <translation id="9210037371811586452">جارٍ الخروج من وضع سطح المكتب الموحد</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">تعيين خلفية</translation> <translation id="923686485342484400">للخروج اضغط على Ctrl Shift Q مرتين.</translation> <translation id="945522503751344254">إرسال تعليقات</translation>
diff --git a/ash/strings/ash_strings_bg.xtb b/ash/strings/ash_strings_bg.xtb index e866ac0..4dd9baa 100644 --- a/ash/strings/ash_strings_bg.xtb +++ b/ash/strings/ash_strings_bg.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C устройство (предният порт)</translation> <translation id="1013923882670373915">Устройството с Bluetooth „<ph name="DEVICE_NAME" />“ иска разрешение за сдвояване. Моля, въведете на него следния ПИН код: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Батериите на писалката са изтощени</translation> +<translation id="1056775291175587022">Няма мрежи</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Автоматично скриване на лавицата</translation> <translation id="1153356358378277386">Сдвоени устройства</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Надясно</translation> <translation id="1383876407941801731">Търсене</translation> <translation id="1467432559032391204">Наляво</translation> +<translation id="1479743070547893297">Изберете, като използвате писалката</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Стартов панел</translation> <translation id="1525508553941733066">ОТХВЪРЛЯНЕ</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Задайте език</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Научете повече за най-новата актуализация на <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Изключване</translation> <translation id="2012624427112548395">Ctrl + клавиш „Търсене“ + H</translation> +<translation id="2016340657076538683">Въведете съобщение</translation> <translation id="2049639323467105390">Това устройство се управлява от <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Вертикално</translation> <translation id="2067602449040652523">Яркост на клавиатурата</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Напред</translation> <translation id="2365393535144473978">Активирането на мобилните данни ще включи Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Налице е актуализация</translation> <translation id="2429753432712299108">Устройството с Bluetooth „<ph name="DEVICE_NAME" />“ иска разрешение за сдвояване. Преди да приемете, моля, уверете се, че на него се показва следният ключ за достъп: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Известия</translation> <translation id="2484513351006226581">Натиснете <ph name="KEYBOARD_SHORTCUT" /> за превключване на клавиатурната подредба.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">„CAPS LOCK“ е включен</translation> <translation id="2532589005999780174">Режим на висок контраст</translation> <translation id="2575685495496069081">Централизираният вход е деактивиран</translation> +<translation id="2582112259361606227">Рестартирайте, за да актуализирате</translation> <translation id="2597972630681408282">Нощно осветление: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM картата е заключена</translation> <translation id="2653659639078652383">Изпращане</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Споделяте екрана си</translation> <translation id="2942516765047364088">Позиция на лавицата</translation> <translation id="2946119680249604491">Добавяне на връзка</translation> +<translation id="2961963223658824723">Нещо се обърка. Опитайте отново след няколко секунди.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416">„<ph name="DISPLAY_NAME" />“ е обществена сесия, управлявана от <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Монозвук</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Най-долу</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Свиване</translation> <translation id="3126069444801937830">Рестартирайте, за да актуализирате</translation> <translation id="3147142846278915599">Стартов панел (приложенията се синхронизират...)</translation> <translation id="315116470104423982">Мобилни данни</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Заключване</translation> <translation id="3798670284305777884">Високоговорител (вътрешен)</translation> +<translation id="380165613292957338">Здравейте, как мога да помогна?</translation> <translation id="3846575436967432996">Не е налице информация за мрежата</translation> <translation id="385051799172605136">Назад</translation> <translation id="3891340733213178823">Натиснете два пъти „Ctrl+Shift+Q“ за изход.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">устройство с USB-C (задният десен порт)</translation> <translation id="4017989525502048489">Лазерна показалка</translation> <translation id="4072264167173457037">умерен сигнал</translation> +<translation id="4200057768455216496">Използвахте клавишната комбинация за лупата в прикрепен режим. Искате ли да включите функцията?</translation> <translation id="4217571870635786043">Диктуване</translation> <translation id="4279490309300973883">Дублиране</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Администраторът ви е деактивирал Google Асистент.</translation> <translation id="4895488851634969361">Батерията е пълна.</translation> <translation id="4905614135390995787">Клавишната комбинация за превключване на режима на висок контраст е променена. Моля, използвайте <ph name="NEW_SHORTCUT" /> вместо <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Силен</translation> <translation id="4918086044614829423">Приемам</translation> <translation id="4961318399572185831">Предаване на екрана</translation> <translation id="5136175204352732067">Свързана е различна клавиатура</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Натиснете Ctrl + Alt + Z, за да деактивирате обратната връзка с говор.</translation> <translation id="5648021990716966815">Жак за микрофон</translation> +<translation id="5669267381087807207">Активира се</translation> <translation id="5673434351075758678">От <ph name="FROM_LOCALE" /> към <ph name="TO_LOCALE" /> след синхронизиране на настройките ви.</translation> +<translation id="574392208103952083">Среден</translation> <translation id="5744083938413354016">Преместване чрез докосване</translation> <translation id="5777841717266010279">Да се спре ли споделянето на екрана?</translation> <translation id="57838592816432529">Заглушаване</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Отхвърляне</translation> <translation id="6453179446719226835">Езикът е променен</translation> <translation id="6459472438155181876">Екранът се разширява на „<ph name="DISPLAY_NAME" />“</translation> +<translation id="6482559668224714696">Лупа за увеличаване на целия екран</translation> <translation id="6490471652906364588">USB-C устройство (десният порт)</translation> <translation id="6501401484702599040">Екранът се предава към „<ph name="RECEIVER_NAME" />“</translation> <translation id="6521655319214113338">Ръкописно въвеждане</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Време е за почивка!</translation> <translation id="683971173229319003">търсене + L</translation> <translation id="6857811139397017780">Активиране на <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Тази актуализация изисква Powerwash на устройството ви. Научете повече за най-новата актуализация на <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Присъединяване другаде...</translation> <translation id="6981982820502123353">Достъпност</translation> <translation id="698231206551913481">След като този потребител бъде премахнат, всички свързани с него файлове и локални данни ще се изтрият за постоянно.</translation> <translation id="7015766095477679451">Ще бъда отново на ваше разположение в <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Изход от сесията</translation> <translation id="7034339000180558234">„<ph name="TAB_NAME" />“ се предава към „<ph name="RECEIVER_NAME" />“</translation> +<translation id="7037152028959403492">Използвахте клавишната комбинация за режима на висок контраст. Искате ли да го включите?</translation> <translation id="7066646422045619941">Тази мрежа е деактивирана от администратора ви.</translation> <translation id="7067196344162293536">Автоматично завъртане</translation> <translation id="7076293881109082629">Влизате</translation> <translation id="7098389117866926363">Устройство с USB-C (левият порт на гърба)</translation> <translation id="7131634465328662194">Ще излезете автоматично.</translation> +<translation id="7143207342074048698">Свързва се</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Старата разделителна способност ще се възстанови след <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Заден микрофон</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Установена е връзка с/ъс <ph name="NAME" /></translation> <translation id="813913629614996137">Подготвя се за работа...</translation> <translation id="8142699993796781067">Частна мрежа</translation> +<translation id="8152119955266188852">Използвахте клавишната комбинация за лупата за увеличаване на целия екран. Искате ли да включите функцията?</translation> <translation id="8180896103888046100">Спиране на предаването към неизвестен приемник</translation> <translation id="8190698733819146287">Персонализиране на езиците и въвеждането...</translation> <translation id="8261506727792406068">Изтриване</translation> +<translation id="8297006494302853456">Слаб</translation> <translation id="8308637677604853869">Предишно меню</translation> <translation id="8351131234907093545">Създаване на бележка</translation> <translation id="8392451568018454956">Меню с опции за <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Бутон за връщане назад</translation> <translation id="8850991929411075241">търсене + Esc</translation> <translation id="8870509716567206129">Приложението не поддържа разделен екран.</translation> +<translation id="8874184842967597500">Няма връзка</translation> <translation id="8878886163241303700">Разгъване на екрана</translation> <translation id="8921624153894383499">Google Асистент не поддържа този език.</translation> <translation id="8938800817013097409">Устройство с USB-C (десният порт на гърба)</translation> <translation id="8940956008527784070">Батерията е изтощена (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Бързо стартиране</translation> <translation id="8995603266996330174">Управлявано от <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Налице е актуализация на Adobe Flash Player</translation> <translation id="9033907480196064950">Понастоящем предавате „<ph name="TAB_NAME" />“</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Влизане в профила на друг потребител...</translation> <translation id="9201131092683066720">Батерията е <ph name="PERCENTAGE" />% пълна.</translation> <translation id="9210037371811586452">Излиза се от режима на обединен работен плот</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Задаване на тапета</translation> <translation id="923686485342484400">Натиснете два пъти „Control+Shift+Q“ за изход.</translation> <translation id="945522503751344254">Изпращане на отзиви</translation>
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb index a484f5f..f5e9668 100644 --- a/ash/strings/ash_strings_bn.xtb +++ b/ash/strings/ash_strings_bn.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C ডিভাইস (সামনের পোর্ট)</translation> <translation id="1013923882670373915">ব্লুটুথ ডিভাইস "<ph name="DEVICE_NAME" />" যুক্ত করার অনুমতি চাইছে। দয়া করে ডিভাইসটিতে এই পিন কোড প্রবেশ করুন: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">স্টাইলাসের চার্জ কমে গেছে</translation> +<translation id="1056775291175587022">কোনও নেটওয়ার্ক নেই</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">তাককে স্বয়ংক্রিয়ভাবে লুকান</translation> <translation id="1153356358378277386">যুক্ত করা ডিভাইসগুলি</translation> @@ -111,7 +112,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">নিচে</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (ব্লুটুথ)</translation> -<translation id="3112378005171663295">সঙ্কুচিত করুন</translation> <translation id="3126069444801937830">আপডেট করার জন্য পুনরারম্ভ করুন</translation> <translation id="3147142846278915599">লঞ্চার (অ্যাপ সিঙ্ক করা হচ্ছে...)</translation> <translation id="315116470104423982">মোবাইল ডেটা</translation> @@ -187,6 +187,7 @@ <translation id="4890187583552566966">আপনার প্রশাসকের দ্বারা Google সহায়ক অক্ষম করা হয়েছে।</translation> <translation id="4895488851634969361">ব্যাটারি পূর্ণ৷</translation> <translation id="4905614135390995787">উচ্চ কনট্রাস্ট মোড টগল করার শর্টকাটটি পরিবর্তিত হয়েছে। <ph name="OLD_SHORTCUT" /> এর পরিবর্তে অনুগ্রহ করে <ph name="NEW_SHORTCUT" /> ব্যবহার করুন।</translation> +<translation id="4917385247580444890">জোরালো</translation> <translation id="4918086044614829423">স্বীকার</translation> <translation id="4961318399572185831">স্ক্রিন কাস্ট করুন</translation> <translation id="5136175204352732067">বিভিন্ন কীবোর্ড কানেক্ট করা হয়েছে</translation> @@ -210,7 +211,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">কথ্য প্রতিক্রিয়া অক্ষম করতে Ctrl + Alt + Z টিপুন।</translation> <translation id="5648021990716966815">মাইক জ্যাক</translation> +<translation id="5669267381087807207">সক্রিয় করা হচ্ছে</translation> <translation id="5673434351075758678">সেটিংস সিঙ্ক করার পরে "<ph name="FROM_LOCALE" />" থেকে "<ph name="TO_LOCALE" />" সেট করা হয়েছে।</translation> +<translation id="574392208103952083">মাঝারি</translation> <translation id="5744083938413354016">ট্যাপ করে টেনে আনা</translation> <translation id="5777841717266010279">স্ক্রিন শেয়ার করা থামাবেন?</translation> <translation id="57838592816432529">নিঃশব্দ করুন</translation> @@ -286,6 +289,7 @@ <translation id="7076293881109082629">প্রবেশ করুন হচ্ছে</translation> <translation id="7098389117866926363">USB-C ডিভাইস (পিছনের বাঁ পোর্ট)</translation> <translation id="7131634465328662194">আপনি নিজে থেকেই সাইন-আউট হয়ে যাবেন।</translation> +<translation id="7143207342074048698">সংযুক্ত হচ্ছে</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" /> এ পুরানো রেসুলিউশানে ফেরানো হচ্ছে</translation> <translation id="7256634071279256947">পেছনের মাইক্রোফোন</translation> @@ -334,6 +338,7 @@ <translation id="8180896103888046100">অজানা রিসিভারে কাস্ট করা বন্ধ করুন</translation> <translation id="8190698733819146287">ভাষা এবং ইনপুট কাস্টমাইজ করুন...</translation> <translation id="8261506727792406068">মুছুন</translation> +<translation id="8297006494302853456">দুর্বল</translation> <translation id="8308637677604853869">পূর্ববর্তী মেনু</translation> <translation id="8351131234907093545">নোট তৈরি করুন</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> এর জন্য বিকল্পগুলির মেনু</translation> @@ -359,6 +364,7 @@ <translation id="8841375032071747811">ফিরে যাওয়ার বোতাম</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">অ্যাপ্লিকেশনটি বিভক্ত-স্ক্রিন সমর্থন করে না৷</translation> +<translation id="8874184842967597500">সংযুক্ত নয়</translation> <translation id="8878886163241303700">স্ক্রিন সম্প্রসারণ করা হচ্ছে</translation> <translation id="8921624153894383499">Google সহায়ক এই ভাষায় কথা বলে না।</translation> <translation id="8938800817013097409">USB-C ডিভাইস (পিছনের ডান পোর্ট)</translation>
diff --git a/ash/strings/ash_strings_ca.xtb b/ash/strings/ash_strings_ca.xtb index 5a342c4b..eb481b5 100644 --- a/ash/strings/ash_strings_ca.xtb +++ b/ash/strings/ash_strings_ca.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Dispositiu USB-C (port frontal)</translation> <translation id="1013923882670373915">El dispositiu Bluetooth "<ph name="DEVICE_NAME" />" sol·licita permís per emparellar-se. Introduïu aquest codi PIN al dispositiu: <ph name="PINCODE" />.</translation> <translation id="1032891413405719768">El llapis òptic té poca bateria</translation> +<translation id="1056775291175587022">Cap xarxa</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Amaga el prestatge automàticament</translation> <translation id="1153356358378277386">Dispositius vinculats</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">maj</translation> <translation id="3087734570205094154">Part inferior</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Redueix</translation> <translation id="3126069444801937830">Reinicia per actualitzar</translation> <translation id="3147142846278915599">Launcher (s'estan sincronitzant les aplicacions...)</translation> <translation id="315116470104423982">Dades mòbils</translation> @@ -197,6 +197,7 @@ <translation id="4890187583552566966">L'administrador ha desactivat l'Assistent de Google.</translation> <translation id="4895488851634969361">La bateria està carregada.</translation> <translation id="4905614135390995787">La drecera per activar/desactivar el mode d'alt contrast ha canviat. A partir d'ara, utilitza <ph name="NEW_SHORTCUT" /> en lloc de la drecera <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Forta</translation> <translation id="4918086044614829423">Accepta</translation> <translation id="4961318399572185831">Emet la pantalla</translation> <translation id="5136175204352732067">S'ha connectat un altre teclat</translation> @@ -220,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Prem Ctrl+Alt+Z per desactivar els comentaris de veu.</translation> <translation id="5648021990716966815">Connector per al micròfon</translation> +<translation id="5669267381087807207">S'està activant</translation> <translation id="5673434351075758678">Després de sincronitzar la configuració, canvia <ph name="FROM_LOCALE" /> per <ph name="TO_LOCALE" />.</translation> +<translation id="574392208103952083">Mitjà</translation> <translation id="5744083938413354016">Tocar i arrossegar</translation> <translation id="5777841717266010279">Voleu deixar de compartir la pantalla?</translation> <translation id="57838592816432529">Silencia</translation> @@ -303,6 +306,7 @@ <translation id="7076293881109082629">Inicia la sessió</translation> <translation id="7098389117866926363">Dispositiu USB-C (port posterior esquerre)</translation> <translation id="7131634465328662194">La sessió es tancarà automàticament.</translation> +<translation id="7143207342074048698">S'està connectant</translation> <translation id="7165278925115064263">Alt+Maj+K</translation> <translation id="7168224885072002358">Es revertirà a la resolució anterior d'aquí a <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Micròfon posterior</translation> @@ -352,6 +356,7 @@ <translation id="8180896103888046100">Deixa d'emetre a un receptor desconegut</translation> <translation id="8190698733819146287">Personalitza idiomes i introducció de text...</translation> <translation id="8261506727792406068">Suprimeix</translation> +<translation id="8297006494302853456">Feble</translation> <translation id="8308637677604853869">Menú anterior</translation> <translation id="8351131234907093545">Crea una nota</translation> <translation id="8392451568018454956">Menú d'opcions per a <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -379,6 +384,7 @@ <translation id="8841375032071747811">Botó Enrere</translation> <translation id="8850991929411075241">Cerca + Esc</translation> <translation id="8870509716567206129">L'aplicació no admet la pantalla dividida.</translation> +<translation id="8874184842967597500">No connectat</translation> <translation id="8878886163241303700">Ampliació de la pantalla</translation> <translation id="8921624153894383499">L'Assistent de Google no parla aquest idioma.</translation> <translation id="8938800817013097409">Dispositiu USB-C (port posterior dret)</translation>
diff --git a/ash/strings/ash_strings_cs.xtb b/ash/strings/ash_strings_cs.xtb index cef899d..696c051 100644 --- a/ash/strings/ash_strings_cs.xtb +++ b/ash/strings/ash_strings_cs.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Zařízení USB Type-C (přední port)</translation> <translation id="1013923882670373915">Zařízení Bluetooth „<ph name="DEVICE_NAME" />“ žádá o povolení ke spárování. Zadejte prosím v zařízení tento kód PIN: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Baterie dotykového pera je slabá</translation> +<translation id="1056775291175587022">Žádné sítě</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Automaticky skrývat poličku</translation> <translation id="1153356358378277386">Spárovaná zařízení</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Až dolů</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Sbalit</translation> <translation id="3126069444801937830">Restartovat a aktualizovat</translation> <translation id="3147142846278915599">Spouštěč (synchronizace aplikací...)</translation> <translation id="315116470104423982">Mobilní datové přenosy</translation> @@ -197,6 +197,7 @@ <translation id="4890187583552566966">Váš administrátor Asistenta Google zakázal.</translation> <translation id="4895488851634969361">Baterie je plně nabita.</translation> <translation id="4905614135390995787">Zkratka k přepínání režimu vysokého kontrastu se změnila. Namísto zkratky <ph name="OLD_SHORTCUT" /> používejte zkratku <ph name="NEW_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Silný</translation> <translation id="4918086044614829423">Přijmout</translation> <translation id="4961318399572185831">Odesílání obrazovky</translation> <translation id="5136175204352732067">Je připojena jiná klávesnice</translation> @@ -220,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Hlasovou odezvu vypnete stisknutím kláves Ctrl + Alt + Z.</translation> <translation id="5648021990716966815">Konektor mikrofonu</translation> +<translation id="5669267381087807207">Probíhá aktivace</translation> <translation id="5673434351075758678">Po synchronizaci nastavení se oznámení změní z jazyka <ph name="FROM_LOCALE" /> na jazyk <ph name="TO_LOCALE" />.</translation> +<translation id="574392208103952083">Střední</translation> <translation id="5744083938413354016">Přetažení klepnutím</translation> <translation id="5777841717266010279">Ukončit sdílení obrazovky?</translation> <translation id="57838592816432529">Ztlumit</translation> @@ -303,6 +306,7 @@ <translation id="7076293881109082629">Přihlášení</translation> <translation id="7098389117866926363">Zařízení USB Type-C (levý zadní port)</translation> <translation id="7131634465328662194">Budete automaticky odhlášeni.</translation> +<translation id="7143207342074048698">Připojování</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Původní rozlišení bude obnoveno za <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Zadní mikrofon</translation> @@ -352,6 +356,7 @@ <translation id="8180896103888046100">Ukončit odesílání do neznámého přijímače</translation> <translation id="8190698733819146287">Personalizovat jazyky a zadávání...</translation> <translation id="8261506727792406068">Smazat</translation> +<translation id="8297006494302853456">Slabý</translation> <translation id="8308637677604853869">Předchozí nabídka</translation> <translation id="8351131234907093545">Vytvořit poznámku</translation> <translation id="8392451568018454956">Nabídka možností pro uživatele <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -379,6 +384,7 @@ <translation id="8841375032071747811">Tlačítko Zpět</translation> <translation id="8850991929411075241">Hledat+Esc</translation> <translation id="8870509716567206129">Aplikace nepodporuje režim rozdělené obrazovky.</translation> +<translation id="8874184842967597500">Nepřipojeno</translation> <translation id="8878886163241303700">Rozšíření obrazovky</translation> <translation id="8921624153894383499">Tímto jazykem Asistent Google nehovoří.</translation> <translation id="8938800817013097409">Zařízení USB Type-C (pravý zadní port)</translation>
diff --git a/ash/strings/ash_strings_da.xtb b/ash/strings/ash_strings_da.xtb index 4ede244e..e9102039a 100644 --- a/ash/strings/ash_strings_da.xtb +++ b/ash/strings/ash_strings_da.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C-enhed (port foran)</translation> <translation id="1013923882670373915">Bluetooth-enheden "<ph name="DEVICE_NAME" />" vil gerne have parringstilladelse. Angiv denne pinkode på den pågældende enhed: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Styluspennen er ved at løbe tør for batteri</translation> +<translation id="1056775291175587022">Der er ingen netværk</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Skjul hylde automatisk</translation> <translation id="1153356358378277386">Parrede enheder</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Højre</translation> <translation id="1383876407941801731">Søg</translation> <translation id="1467432559032391204">Venstre</translation> +<translation id="1479743070547893297">Vælg ved at tegne med din styluspen</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Appliste</translation> <translation id="1525508553941733066">AFVIS</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Angiv dit sprog</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Få flere oplysninger om den nyeste <ph name="SYSTEM_APP_NAME" />-opdatering</translation> <translation id="1995660704900986789">Sluk</translation> <translation id="2012624427112548395">Ctrl+Søg+H</translation> +<translation id="2016340657076538683">Skriv en besked</translation> <translation id="2049639323467105390">Denne enhed administreres af <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Stående</translation> <translation id="2067602449040652523">Lysstyrke for tastatur</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Fortsæt</translation> <translation id="2365393535144473978">Bluetooth aktiveres, når du aktiverer mobildata.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Der er en tilgængelig opdatering</translation> <translation id="2429753432712299108">Bluetooth-enheden "<ph name="DEVICE_NAME" />" vil gerne have parringstilladelse. Inden du accepterer, skal du bekræfte, at denne adgangsnøgle er vist på den pågældende enhed: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Underretninger</translation> <translation id="2484513351006226581">Tryk på <ph name="KEYBOARD_SHORTCUT" /> for at skifte tastaturlayout.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK er slået til</translation> <translation id="2532589005999780174">Tilstanden Høj kontrast</translation> <translation id="2575685495496069081">Samlet login fra flere konti er deaktiveret</translation> +<translation id="2582112259361606227">Genstart for at opdatere</translation> <translation id="2597972630681408282">Nattelys: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM-kortet er låst</translation> <translation id="2653659639078652383">Indsend</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Du deler din skærm</translation> <translation id="2942516765047364088">Hyldeplacering</translation> <translation id="2946119680249604491">Tilføj forbindelse</translation> +<translation id="2961963223658824723">Der opstod en fejl. Prøv igen om et par sekunder.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> er en offentlig session administreret af <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Monolyd</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Bund</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Skjul</translation> <translation id="3126069444801937830">Genstart for at opdatere</translation> <translation id="3147142846278915599">Starter (synkronisering af apps...)</translation> <translation id="315116470104423982">Mobildata</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Lås</translation> <translation id="3798670284305777884">Højttaler (indbygget)</translation> +<translation id="380165613292957338">Hej, hvad kan jeg hjælpe med?</translation> <translation id="3846575436967432996">Der er ingen tilgængelige netværksoplysninger</translation> <translation id="385051799172605136">Tilbage</translation> <translation id="3891340733213178823">Tryk på Ctrl+Shift+Q to gange for at logge ud.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C-enhed (porten bagpå i højre side)</translation> <translation id="4017989525502048489">Laserpegepind</translation> <translation id="4072264167173457037">Middel signal</translation> +<translation id="4200057768455216496">Du trykkede på genvejen for det fastgjorte lupvindue. Vil du aktivere indstillingen?</translation> <translation id="4217571870635786043">Diktering</translation> <translation id="4279490309300973883">Spejling</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google Assistent er deaktiveret af din administrator.</translation> <translation id="4895488851634969361">Batteriet er helt opladet.</translation> <translation id="4905614135390995787">Genvejen til at aktivere eller deaktivere tilstanden Høj kontrast er ændret. Brug <ph name="NEW_SHORTCUT" /> i stedet for <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Stærk</translation> <translation id="4918086044614829423">Accepter</translation> <translation id="4961318399572185831">Cast skærm</translation> <translation id="5136175204352732067">Du har tilsluttet et andet tastatur</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" /> d. <ph name="DATE" /></translation> <translation id="5600837773213129531">Tryk på Ctrl+Alt+Z for at deaktivere oplæsning.</translation> <translation id="5648021990716966815">Stik til mikrofon</translation> +<translation id="5669267381087807207">Aktiverer</translation> <translation id="5673434351075758678">Fra "<ph name="FROM_LOCALE" />" til "<ph name="TO_LOCALE" />", efter at du har synkroniseret dine indstillinger.</translation> +<translation id="574392208103952083">Mellem</translation> <translation id="5744083938413354016">Tryk og træk</translation> <translation id="5777841717266010279">Vil du afslutte skærmdeling?</translation> <translation id="57838592816432529">Slå lyden fra</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Afvis</translation> <translation id="6453179446719226835">Sproget er blevet ændret</translation> <translation id="6459472438155181876">Udvider skærmen til <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Forstørrelse af fuld skærm</translation> <translation id="6490471652906364588">USB-C-enhed (højre port)</translation> <translation id="6501401484702599040">Caster skærmen til <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Indtastning via håndskrift</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Hold en pause</translation> <translation id="683971173229319003">Søg+L</translation> <translation id="6857811139397017780">Aktivér <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Denne opdatering kræver, at der udføres en powerwash på din enhed. Få flere oplysninger om den nyeste <ph name="SYSTEM_APP_NAME" />-opdatering.</translation> <translation id="6911468394164995108">Vælg et andet...</translation> <translation id="6981982820502123353">Hjælpefunktioner</translation> <translation id="698231206551913481">Alle filer og lokale data, der er knyttet til denne bruger, slettes permanent, når brugeren fjernes.</translation> <translation id="7015766095477679451">Vend tilbage kl. <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Afslut session</translation> <translation id="7034339000180558234">Caster <ph name="TAB_NAME" /> til <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Du trykkede på genvejen for høj kontrast. Vil du aktivere indstillingen?</translation> <translation id="7066646422045619941">Din administrator har deaktiveret dette netværk.</translation> <translation id="7067196344162293536">Automatisk rotering</translation> <translation id="7076293881109082629">Login</translation> <translation id="7098389117866926363">USB-C-enhed (porten bagpå i venstre side)</translation> <translation id="7131634465328662194">Du logges automatisk ud.</translation> +<translation id="7143207342074048698">Opretter forbindelse</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Fortryder og vender tilbage til den gamle opløsning om <ph name="TIMEOUT_SECONDS" /> sekunder.</translation> <translation id="7256634071279256947">Mikrofon på bagsiden</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Forbundet til <ph name="NAME" /></translation> <translation id="813913629614996137">Initialiserer...</translation> <translation id="8142699993796781067">Privat netværk</translation> +<translation id="8152119955266188852">Du trykkede på genvejen for forstørrelse af fuld skærm. Vil du aktivere indstillingen?</translation> <translation id="8180896103888046100">Stop med at caste til en ukendt modtager</translation> <translation id="8190698733819146287">Tilpas sprog og indtastning...</translation> <translation id="8261506727792406068">Slet</translation> +<translation id="8297006494302853456">Svag</translation> <translation id="8308637677604853869">Forrige menu</translation> <translation id="8351131234907093545">Opret note</translation> <translation id="8392451568018454956">Menuen Indstillinger for <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Knappen Tilbage</translation> <translation id="8850991929411075241">Søg+Esc</translation> <translation id="8870509716567206129">Appen understøtter ikke delt skærm.</translation> +<translation id="8874184842967597500">Ikke tilsluttet</translation> <translation id="8878886163241303700">Udvider skærm</translation> <translation id="8921624153894383499">Google-assistenten taler ikke dette sprog.</translation> <translation id="8938800817013097409">USB-C-enhed (porten bagpå i højre side)</translation> <translation id="8940956008527784070">Batteriniveauet er lavt (<ph name="PERCENTAGE" /> %)</translation> <translation id="8984179138335769204">Hurtig start</translation> <translation id="8995603266996330174">Administreres af <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Der er en tilgængelig Adobe Flash Player-opdatering</translation> <translation id="9033907480196064950">Du caster i øjeblikket <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Log ind med en anden bruger...</translation> <translation id="9201131092683066720">Batteriet er <ph name="PERCENTAGE" /> % opladet.</translation> <translation id="9210037371811586452">Lukker tilstanden Kombineret skrivebord</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Vælg baggrund</translation> <translation id="923686485342484400">Tryk på Control+Shift+Q to gange for at logge ud.</translation> <translation id="945522503751344254">Send feedback</translation>
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb index 1139731..5e1029e 100644 --- a/ash/strings/ash_strings_de.xtb +++ b/ash/strings/ash_strings_de.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C-Gerät (Port vorne)</translation> <translation id="1013923882670373915">Das Bluetooth-Gerät "<ph name="DEVICE_NAME" />" bittet um Erlaubnis für Kopplung. Geben Sie folgenden PIN-Code auf dem Gerät ein: <ph name="PINCODE" />.</translation> <translation id="1032891413405719768">Die Batterie des Eingabestifts ist schwach</translation> +<translation id="1056775291175587022">Keine Netzwerke</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Ablage automatisch ausblenden</translation> <translation id="1153356358378277386">Gekoppelte Geräte</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Rechts</translation> <translation id="1383876407941801731">Suchen</translation> <translation id="1467432559032391204">Links</translation> +<translation id="1479743070547893297">Zum Auswählen mit dem Eingabestift zeichnen</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Übersicht</translation> <translation id="1525508553941733066">SCHLIESSEN</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Sprache festlegen</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Weitere Informationen zum aktuellen <ph name="SYSTEM_APP_NAME" />-Update</translation> <translation id="1995660704900986789">Ausschalten</translation> <translation id="2012624427112548395">Strg + Suche + H</translation> +<translation id="2016340657076538683">Nachricht eingeben</translation> <translation id="2049639323467105390">Dieses Gerät wird durch <ph name="DOMAIN" /> verwaltet.</translation> <translation id="2050339315714019657">Hochformat</translation> <translation id="2067602449040652523">Tastaturhelligkeit</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Weiter</translation> <translation id="2365393535144473978">Bei Aktivierung der mobilen Daten wird auch Bluetooth aktiviert.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Update verfügbar</translation> <translation id="2429753432712299108">Das Bluetooth-Gerät "<ph name="DEVICE_NAME" />" bittet um Erlaubnis für Kopplung. Bevor Sie akzeptieren, überprüfen Sie, ob folgender Zugangscode auf dem Gerät angezeigt wird: <ph name="PASSKEY" />.</translation> <translation id="2482878487686419369">Benachrichtigungen</translation> <translation id="2484513351006226581">Drücken Sie <ph name="KEYBOARD_SHORTCUT" />, um das Tastaturlayout zu ändern.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Feststelltaste An</translation> <translation id="2532589005999780174">Modus mit hohem Kontrast</translation> <translation id="2575685495496069081">Mehrfachanmeldung wurde deaktiviert</translation> +<translation id="2582112259361606227">Zum Aktualisieren neu starten</translation> <translation id="2597972630681408282">Nachtlicht: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM-Karte ist gesperrt</translation> <translation id="2653659639078652383">Senden</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Ihr Bildschirm ist momentan freigegeben</translation> <translation id="2942516765047364088">Ablageposition</translation> <translation id="2946119680249604491">Verbindung hinzufügen</translation> +<translation id="2961963223658824723">Ein Fehler ist aufgetreten. Bitte versuchen Sie es in ein paar Sekunden noch einmal.</translation> <translation id="2963773877003373896">Mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> ist eine öffentliche Sitzung, die von <ph name="DOMAIN" /> verwaltet wird.</translation> <translation id="3000461861112256445">Mono-Audio</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">Umschalttaste</translation> <translation id="3087734570205094154">Unten</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Minimieren</translation> <translation id="3126069444801937830">Zum Aktualisieren neu starten</translation> <translation id="3147142846278915599">Launcher (Apps werden synchronisiert...)</translation> <translation id="315116470104423982">Mobilfunk</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">Alt</translation> <translation id="3784455785234192852">Sperren</translation> <translation id="3798670284305777884">Lautsprecher (intern)</translation> +<translation id="380165613292957338">Hallo, wie kann ich dir helfen?</translation> <translation id="3846575436967432996">Keine Netzwerkinformationen verfügbar</translation> <translation id="385051799172605136">Zurück</translation> <translation id="3891340733213178823">Drücken Sie zum Abmelden zweimal Strg + Umschalttaste + Q.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C-Gerät (Port hinten rechts)</translation> <translation id="4017989525502048489">Laserpointer</translation> <translation id="4072264167173457037">Durchschnittliches Signal</translation> +<translation id="4200057768455216496">Sie haben die Tastenkombination für die angedockte Lupe gedrückt. Möchten Sie sie aktivieren?</translation> <translation id="4217571870635786043">Spracheingabe</translation> <translation id="4279490309300973883">Spiegelung</translation> <translation id="4321179778687042513">Strg</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google Assistant wurde von Ihrem Administrator deaktiviert.</translation> <translation id="4895488851634969361">Akku ist vollständig geladen.</translation> <translation id="4905614135390995787">Die Tastenkombination zum Deaktivieren des Modus mit hohem Kontrast hat sich geändert. Bitte drücken Sie <ph name="NEW_SHORTCUT" /> statt <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Stark</translation> <translation id="4918086044614829423">Annehmen</translation> <translation id="4961318399572185831">Bildschirmübertragung</translation> <translation id="5136175204352732067">Andere Tastatur angeschlossen</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Zum Deaktivieren des gesprochenen Feedbacks drücken Sie Strg + Alt + Z.</translation> <translation id="5648021990716966815">Mikrofonanschluss</translation> +<translation id="5669267381087807207">Wird aktiviert...</translation> <translation id="5673434351075758678">Nach der Synchronisierung der Einstellungen von "<ph name="FROM_LOCALE" />" zu "<ph name="TO_LOCALE" />" geändert.</translation> +<translation id="574392208103952083">Mittel</translation> <translation id="5744083938413354016">Antippen und Ziehen</translation> <translation id="5777841717266010279">Bildschirmfreigabe beenden?</translation> <translation id="57838592816432529">Stummschalten</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Ablehnen</translation> <translation id="6453179446719226835">Die Sprache wurde geändert</translation> <translation id="6459472438155181876">Bildschirm wird auf <ph name="DISPLAY_NAME" /> erweitert...</translation> +<translation id="6482559668224714696">Vollbildlupe</translation> <translation id="6490471652906364588">USB-C-Gerät (Port rechts)</translation> <translation id="6501401484702599040">Bildschirm wird an <ph name="RECEIVER_NAME" /> gestreamt</translation> <translation id="6521655319214113338">Handschrifteingabe</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Zeit für eine Pause.</translation> <translation id="683971173229319003">Suche + L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> aktivieren</translation> +<translation id="6910714959251846841">Damit dieses Update installiert werden kann, muss auf Ihrem Gerät ein Powerwash durchgeführt werden. Informieren Sie sich über das aktuelle <ph name="SYSTEM_APP_NAME" />-Update.</translation> <translation id="6911468394164995108">Andere Netzwerke...</translation> <translation id="6981982820502123353">Bedienungshilfen</translation> <translation id="698231206551913481">Durch das Entfernen des Nutzers werden alle mit ihm verknüpften Dateien und lokalen Daten endgültig gelöscht.</translation> <translation id="7015766095477679451">Um <ph name="COME_BACK_TIME" /> können Sie weitermachen.</translation> <translation id="7029814467594812963">Sitzung beenden</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> wird an <ph name="RECEIVER_NAME" /> gestreamt</translation> +<translation id="7037152028959403492">Sie haben die Tastenkombination für hohen Kontrast gedrückt. Möchten Sie ihn aktivieren?</translation> <translation id="7066646422045619941">Dieses Netzwerk wurde von Ihrem Administrator deaktiviert.</translation> <translation id="7067196344162293536">Automatisch drehen</translation> <translation id="7076293881109082629">Anmeldung</translation> <translation id="7098389117866926363">USB-C-Gerät (linker Port hinten)</translation> <translation id="7131634465328662194">Sie werden automatisch abgemeldet.</translation> +<translation id="7143207342074048698">Verbindung wird hergestellt.</translation> <translation id="7165278925115064263">Alt + Umschalttaste + K</translation> <translation id="7168224885072002358">Alte Auflösung wird in <ph name="TIMEOUT_SECONDS" /> wiederhergestellt.</translation> <translation id="7256634071279256947">Mikrofon auf der Rückseite</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Verbunden mit <ph name="NAME" /></translation> <translation id="813913629614996137">Initialisierung…</translation> <translation id="8142699993796781067">Privates Netzwerk</translation> +<translation id="8152119955266188852">Sie haben die Tastenkombination für die Vollbildlupe gedrückt. Möchten Sie sie aktivieren?</translation> <translation id="8180896103888046100">Streamen an unbekannten Empfänger beenden</translation> <translation id="8190698733819146287">Sprache und Eingabe anpassen...</translation> <translation id="8261506727792406068">Löschen</translation> +<translation id="8297006494302853456">Schwach</translation> <translation id="8308637677604853869">Vorheriges Menü</translation> <translation id="8351131234907093545">Notiz erstellen</translation> <translation id="8392451568018454956">Optionsmenü für <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Schaltfläche "Zurück"</translation> <translation id="8850991929411075241">Suche + Esc</translation> <translation id="8870509716567206129">Das Teilen des Bildschirms wird in dieser App nicht unterstützt.</translation> +<translation id="8874184842967597500">Nicht verbunden</translation> <translation id="8878886163241303700">Bildschirmerweiterung</translation> <translation id="8921624153894383499">Google Assistant spricht diese Sprache nicht.</translation> <translation id="8938800817013097409">USB-C-Gerät (rechter Port hinten)</translation> <translation id="8940956008527784070">Niedriger Akkustand (<ph name="PERCENTAGE" /> %)</translation> <translation id="8984179138335769204">Schnellstart</translation> <translation id="8995603266996330174">Verwaltet von <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Update für den Adobe Flash Player verfügbar</translation> <translation id="9033907480196064950">Sie streamen gerade <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">WLAN: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Anderen Nutzer anmelden...</translation> <translation id="9201131092683066720">Akku ist zu <ph name="PERCENTAGE" /> % geladen.</translation> <translation id="9210037371811586452">Unified Desktop-Modus wird beendet</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Hintergrund festlegen</translation> <translation id="923686485342484400">Drücken Sie zum Abmelden zweimal Steuerung - Umschalttaste - Q.</translation> <translation id="945522503751344254">Feedback geben</translation>
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb index 36605af..767f2353 100644 --- a/ash/strings/ash_strings_el.xtb +++ b/ash/strings/ash_strings_el.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Συσκευή USB-C (μπροστινή θύρα)</translation> <translation id="1013923882670373915">Η συσκευή Bluetooth "<ph name="DEVICE_NAME" />" ζητά δικαιώματα σύζευξης. Καταχωρίστε αυτόν τον κωδικό PIN στη συγκεκριμένη συσκευή: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Το επίπεδο της μπαταρίας της γραφίδας είναι χαμηλό</translation> +<translation id="1056775291175587022">Δεν βρέθηκαν δίκτυα</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Αυτόματη απόκρυψη ραφιού</translation> <translation id="1153356358378277386">Συσκευές σε σύζευξη</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Δεξιά</translation> <translation id="1383876407941801731">Αναζήτηση</translation> <translation id="1467432559032391204">Αριστερά</translation> +<translation id="1479743070547893297">Σχεδιάστε με τη γραφίδα σας για να επιλέξετε στοιχεία</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Λειτουργία εκκίνησης</translation> <translation id="1525508553941733066">ΑΠΟΡΡΙΨΗ</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Ρύθμιση της γλώσσας σας</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Μάθετε περισσότερα σχετικά με την πιο πρόσφατη ενημέρωση της εφαρμογής <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Απενεργοποίηση</translation> <translation id="2012624427112548395">Ctrl+Πλήκτρο αναζήτησης+H</translation> +<translation id="2016340657076538683">Πληκτρολογήστε ένα μήνυμα</translation> <translation id="2049639323467105390">Η διαχείριση της συσκευής γίνεται από τον τομέα <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Κάθετα</translation> <translation id="2067602449040652523">Φωτεινότητα πληκτρολογίου</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Συνέχεια</translation> <translation id="2365393535144473978">Με την ενεργοποίηση των δεδομένων κινητής τηλεφωνίας θα ενεργοποιηθεί και το Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Υπάρχει διαθέσιμη ενημέρωση</translation> <translation id="2429753432712299108">Η συσκευή Bluetooth "<ph name="DEVICE_NAME" />" ζητά δικαιώματα σύζευξης. Προτού αποδεχτείτε, επιβεβαιώστε ότι αυτό το κλειδί πρόσβασης εμφανίζεται στη συγκεκριμένη συσκευή: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Ειδοποιήσεις</translation> <translation id="2484513351006226581">Πατήστε <ph name="KEYBOARD_SHORTCUT" />, για να αλλάξετε διάταξη πληκτρολογίου.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Το CAPS LOCK είναι ενεργοποιημένο</translation> <translation id="2532589005999780174">Λειτουργία υψηλής αντίθεσης</translation> <translation id="2575685495496069081">Η σύνδεση σε πολλούς λογαριασμούς απενεργοποιήθηκε</translation> +<translation id="2582112259361606227">Επανεκκίνηση για ενημέρωση</translation> <translation id="2597972630681408282">Νυχτερινός φωτισμός: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Η κάρτα SIM είναι κλειδωμένη</translation> <translation id="2653659639078652383">Υποβολή</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Αυτήν τη στιγμή μοιράζεστε την οθόνη σας</translation> <translation id="2942516765047364088">Θέση ραφιού</translation> <translation id="2946119680249604491">Προσθήκη σύνδεσης</translation> +<translation id="2961963223658824723">Δυστυχώς, παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε ξανά σε λίγα δευτερόλεπτα.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416">Το <ph name="DISPLAY_NAME" /> είναι μια δημόσια περίοδος σύνδεσης που διαχειρίζεται το <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Μονοφωνικός ήχος</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Κάτω</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Σύμπτυξη</translation> <translation id="3126069444801937830">Επανεκκίνηση για ενημέρωση</translation> <translation id="3147142846278915599">Εφαρμογή εκκίνησης (συγχρονισμός εφαρμογών…)</translation> <translation id="315116470104423982">Δεδομένα κινητής τηλεφωνίας</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Κλείδωμα</translation> <translation id="3798670284305777884">Ηχείο (εσωτερικό)</translation> +<translation id="380165613292957338">Γεια, πώς μπορώ να βοηθήσω;</translation> <translation id="3846575436967432996">Δεν υπάρχουν διαθέσιμες πληροφορίες δικτύου</translation> <translation id="385051799172605136">Πίσω</translation> <translation id="3891340733213178823">Πατήστε Ctrl + Shift + Q δύο φορές για να αποσυνδεθείτε.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Συσκευή USB-C (πίσω δεξιά θύρα)</translation> <translation id="4017989525502048489">Δείκτης λέιζερ</translation> <translation id="4072264167173457037">Μεσαίο σήμα</translation> +<translation id="4200057768455216496">Πατήσατε τη συντόμευση για τον μεγεθυντικό φακό σε παράθυρο. Θέλετε να τον ενεργοποιήσετε;</translation> <translation id="4217571870635786043">Υπαγόρευση</translation> <translation id="4279490309300973883">Κατοπτρισμός</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Ο Βοηθός Google είναι απενεργοποιημένος από τον διαχειριστή σας.</translation> <translation id="4895488851634969361">Η μπαταρία είναι πλήρης.</translation> <translation id="4905614135390995787">Η συντόμευση για την εναλλαγή της Λειτουργίας υψηλής αντίθεσης άλλαξε. Χρησιμοποιήστε τη συντόμευση <ph name="NEW_SHORTCUT" /> αντί για τη συντόμευση <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Ισχυρό</translation> <translation id="4918086044614829423">Αποδοχή</translation> <translation id="4961318399572185831">Μετάδοση οθόνης</translation> <translation id="5136175204352732067">Συνδέθηκε διαφορετικό πληκτρολόγιο</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Πιέστε Ctrl + Alt + Z, για να απενεργοποιήσετε τα εκφωνημένα σχόλια.</translation> <translation id="5648021990716966815">Υποδοχή μικροφώνου</translation> +<translation id="5669267381087807207">Ενεργοποίηση</translation> <translation id="5673434351075758678">Από "<ph name="FROM_LOCALE" />" σε "<ph name="TO_LOCALE" />" μετά τον συγχρονισμό των ρυθμίσεων.</translation> +<translation id="574392208103952083">Μέτριο</translation> <translation id="5744083938413354016">Μεταφορά με πάτημα</translation> <translation id="5777841717266010279">Θέλετε να σταματήσετε να μοιράζεστε την οθόνη;</translation> <translation id="57838592816432529">Σίγαση</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Απόρριψη</translation> <translation id="6453179446719226835">Η γλώσσα άλλαξε</translation> <translation id="6459472438155181876">Επέκταση οθόνης σε <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Μεγεθυντικός φακός πλήρους οθόνης</translation> <translation id="6490471652906364588">Συσκευή USB-C (δεξιά θύρα)</translation> <translation id="6501401484702599040">Μετάδοση οθόνης σε <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Είσοδος με γραφή</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Κάντε ένα διάλειμμα!</translation> <translation id="683971173229319003">Πλήκτρο αναζήτησης+L</translation> <translation id="6857811139397017780">Ενεργοποίηση <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Αυτή η ενημέρωση απαιτεί την εκτέλεση powerwash στη συσκευή σας. Μάθετε περισσότερα σχετικά με την πιο πρόσφατη ενημέρωση της εφαρμογής <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Συμμετοχή σε άλλο…</translation> <translation id="6981982820502123353">Προσβασιμότητα</translation> <translation id="698231206551913481">Όλα τα αρχεία και τα τοπικά δεδομένα που σχετίζονται με τον χρήστη θα διαγραφούν οριστικά μόλις καταργηθεί ο χρήστης.</translation> <translation id="7015766095477679451">Επιστρέψτε ξανά στις <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Έξοδος από συνεδρία</translation> <translation id="7034339000180558234">Μετάδοση <ph name="TAB_NAME" /> σε <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Πατήσατε τη συντόμευση για την υψηλή αντίθεση. Θέλετε να την ενεργοποιήσετε;</translation> <translation id="7066646422045619941">Το δίκτυο αυτό έχει απενεργοποιηθεί από το διαχειριστή σας.</translation> <translation id="7067196344162293536">Αυτόματη περιστροφή</translation> <translation id="7076293881109082629">Σύνδεση</translation> <translation id="7098389117866926363">Συσκευή USB-C (πίσω αριστερή θύρα)</translation> <translation id="7131634465328662194">Θα αποσυνδεθείτε αυτόματα.</translation> +<translation id="7143207342074048698">Σύνδεση</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Επαναφορά στην προηγούμενη ανάλυση σε <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Πίσω μικρόφωνο</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Έγινε σύνδεση με το δίκτυο <ph name="NAME" /></translation> <translation id="813913629614996137">Εκκίνηση…</translation> <translation id="8142699993796781067">Ιδιωτικό δίκτυο</translation> +<translation id="8152119955266188852">Πατήσατε τη συντόμευση για τον μεγεθυντικό φακό πλήρους οθόνης. Θέλετε να τον ενεργοποιήσετε;</translation> <translation id="8180896103888046100">Διακοπή μετάδοσης σε άγνωστο δέκτη</translation> <translation id="8190698733819146287">Προσαρμογή γλωσσών και εισόδου...</translation> <translation id="8261506727792406068">Διαγραφή</translation> +<translation id="8297006494302853456">Αδύναμο</translation> <translation id="8308637677604853869">Προηγούμενο μενού</translation> <translation id="8351131234907093545">Δημιουργία σημείωσης</translation> <translation id="8392451568018454956">Μενού επιλογών για τη διεύθυνση <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Κουμπί "Πίσω"</translation> <translation id="8850991929411075241">Πλήκτρο αναζήτησης+Esc</translation> <translation id="8870509716567206129">Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης.</translation> +<translation id="8874184842967597500">Δεν υπάρχει σύνδεση</translation> <translation id="8878886163241303700">Επέκταση οθόνης</translation> <translation id="8921624153894383499">Ο Βοηθός Google δεν είναι διαθέσιμος σε αυτήν τη γλώσσα.</translation> <translation id="8938800817013097409">Συσκευή USB-C (πίσω δεξιά θύρα)</translation> <translation id="8940956008527784070">Χαμηλή στάθμη μπαταρίας (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Γρήγορη εκκίνηση</translation> <translation id="8995603266996330174">Έγινε διαχείριση από <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Υπάρχει διαθέσιμη ενημέρωση για το Adobe Flash Player</translation> <translation id="9033907480196064950">Αυτήν τη στιγμή κάνετε μετάδοση της καρτέλας <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Σύνδεση με άλλον χρήστη...</translation> <translation id="9201131092683066720">Η μπαταρία είναι πλήρης <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Έξοδος από λειτουργία ενοποιημένης επιφάνειας εργασίας</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Ορισμός ταπετσαρίας</translation> <translation id="923686485342484400">Πατήστε Ctrl + Shift + Q δύο φορές για να αποσυνδεθείτε.</translation> <translation id="945522503751344254">Αποστολή σχολίων</translation>
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb index dd5f99e9..d1da498 100644 --- a/ash/strings/ash_strings_en-GB.xtb +++ b/ash/strings/ash_strings_en-GB.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C device (front port)</translation> <translation id="1013923882670373915">Bluetooth device "<ph name="DEVICE_NAME" />" would like permission to pair. Please enter this PIN code on that device: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Stylus battery is low</translation> +<translation id="1056775291175587022">No networks</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Autohide shelf</translation> <translation id="1153356358378277386">Paired devices</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Bottom</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Collapse</translation> <translation id="3126069444801937830">Restart to update</translation> <translation id="3147142846278915599">Launcher (syncing apps...)</translation> <translation id="315116470104423982">Mobile data</translation> @@ -197,6 +197,7 @@ <translation id="4890187583552566966">The Google Assistant is disabled by your administrator.</translation> <translation id="4895488851634969361">Battery is full.</translation> <translation id="4905614135390995787">The shortcut to toggle high contrast mode has changed. Please use <ph name="NEW_SHORTCUT" /> instead of <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Strong</translation> <translation id="4918086044614829423">Accept</translation> <translation id="4961318399572185831">Cast screen</translation> <translation id="5136175204352732067">Different keyboard connected</translation> @@ -220,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Press Ctrl + Alt + Z to disable spoken feedback.</translation> <translation id="5648021990716966815">Mic jack</translation> +<translation id="5669267381087807207">Activating</translation> <translation id="5673434351075758678">From '<ph name="FROM_LOCALE" />' to '<ph name="TO_LOCALE" />' after syncing your settings.</translation> +<translation id="574392208103952083">Medium</translation> <translation id="5744083938413354016">Tap dragging</translation> <translation id="5777841717266010279">Stop screen sharing?</translation> <translation id="57838592816432529">Mute</translation> @@ -303,6 +306,7 @@ <translation id="7076293881109082629">Signing in</translation> <translation id="7098389117866926363">USB-C device (left port in the back)</translation> <translation id="7131634465328662194">You will automatically be signed out.</translation> +<translation id="7143207342074048698">Connecting ...</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Reverting to old resolution in <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Rear microphone</translation> @@ -352,6 +356,7 @@ <translation id="8180896103888046100">Stop casting to an unknown receiver</translation> <translation id="8190698733819146287">Customise languages and input...</translation> <translation id="8261506727792406068">Delete</translation> +<translation id="8297006494302853456">Weak</translation> <translation id="8308637677604853869">Previous menu</translation> <translation id="8351131234907093545">Create note</translation> <translation id="8392451568018454956">Options menu for <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -379,6 +384,7 @@ <translation id="8841375032071747811">Back button</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">App does not support split-screen.</translation> +<translation id="8874184842967597500">Not connected</translation> <translation id="8878886163241303700">Extending screen</translation> <translation id="8921624153894383499">The Google Assistant doesn’t speak this language.</translation> <translation id="8938800817013097409">USB-C device (right port in the back)</translation>
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb index 6ab7c04..ce42ca8 100644 --- a/ash/strings/ash_strings_es-419.xtb +++ b/ash/strings/ash_strings_es-419.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Dispositivo USB-C (puerto delantero)</translation> <translation id="1013923882670373915">El dispositivo Bluetooth "<ph name="DEVICE_NAME" />" solicita permiso para sincronizarse. Ingresa el siguiente código de PIN en el dispositivo: <ph name="PINCODE" />.</translation> <translation id="1032891413405719768">El nivel de la batería de la pluma stylus está bajo</translation> +<translation id="1056775291175587022">No hay redes</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Ocultar la biblioteca automáticamente</translation> <translation id="1153356358378277386">Dispositivos sincronizados</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Derecha</translation> <translation id="1383876407941801731">Buscar</translation> <translation id="1467432559032391204">Izquierda</translation> +<translation id="1479743070547893297">Dibuja con la pluma stylus para seleccionar</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Selector</translation> <translation id="1525508553941733066">IGNORAR</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Establecer el idioma</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Más información sobre la actualización más reciente de <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Apagar</translation> <translation id="2012624427112548395">Ctrl+Buscar+H</translation> +<translation id="2016340657076538683">Escribe un mensaje</translation> <translation id="2049639323467105390"><ph name="DOMAIN" /> administra esta cuenta.</translation> <translation id="2050339315714019657">Vertical</translation> <translation id="2067602449040652523">Brillo del teclado</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Continuar</translation> <translation id="2365393535144473978">Si habilitas los datos móviles, se habilitará Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Actualización disponible</translation> <translation id="2429753432712299108">El dispositivo Bluetooth "<ph name="DEVICE_NAME" />" solicita permiso para sincronizarse. Antes de aceptar, debes confirmar que aparece la siguiente clave de contraseña en el dispositivo: <ph name="PASSKEY" />.</translation> <translation id="2482878487686419369">Notificaciones</translation> <translation id="2484513351006226581">Presiona <ph name="KEYBOARD_SHORTCUT" /> para cambiar de diseño de teclado.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">BLOQ MAYÚS está activado.</translation> <translation id="2532589005999780174">Modo de contraste alto</translation> <translation id="2575685495496069081">Se inhabilitó el acceso múltiple</translation> +<translation id="2582112259361606227">Reiniciar para actualizar</translation> <translation id="2597972630681408282">Luz nocturna: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">La tarjeta SIM está bloqueada</translation> <translation id="2653659639078652383">Enviar</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Estás compartiendo la pantalla</translation> <translation id="2942516765047364088">Posición de la biblioteca</translation> <translation id="2946119680249604491">Agregar conexión</translation> +<translation id="2961963223658824723">Se produjo un error. Vuelve a intentarlo en unos segundos.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> es una sesión pública administrada por <ph name="DOMAIN" />.</translation> <translation id="3000461861112256445">Audio mono</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Inferior</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Ocultar</translation> <translation id="3126069444801937830">Reinicia para actualizar.</translation> <translation id="3147142846278915599">Selector (sincronizando aplicaciones…)</translation> <translation id="315116470104423982">Datos móviles</translation> @@ -148,6 +154,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Bloquear</translation> <translation id="3798670284305777884">Altavoz (interno)</translation> +<translation id="380165613292957338">Hola, ¿cómo puedo ayudarte?</translation> <translation id="3846575436967432996">No hay información de red disponible.</translation> <translation id="385051799172605136">Atrás</translation> <translation id="3891340733213178823">Presiona Ctrl + Mayús + Q dos veces para salir.</translation> @@ -160,6 +167,7 @@ <translation id="3995138139523574647">Dispositivo USB-C (puerto lateral derecho trasero)</translation> <translation id="4017989525502048489">Puntero láser</translation> <translation id="4072264167173457037">Señal media</translation> +<translation id="4200057768455216496">Presionaste la combinación de teclas para activar la lupa con vista acoplada. ¿Quieres activarla?</translation> <translation id="4217571870635786043">Dictado</translation> <translation id="4279490309300973883">Duplicando</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">Tu administrador inhabilitó el Asistente de Google.</translation> <translation id="4895488851634969361">La batería está completa.</translation> <translation id="4905614135390995787">Se cambió el acceso directo para activar o desactivar el Modo de contraste alto. Usa <ph name="NEW_SHORTCUT" /> en lugar de <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Fuerte</translation> <translation id="4918086044614829423">Aceptar</translation> <translation id="4961318399572185831">Transmitir pantalla</translation> <translation id="5136175204352732067">Se conectó otro teclado</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Presiona Ctrl + Alt + Z para inhabilitar los comentarios por voz.</translation> <translation id="5648021990716966815">Conector para micrófono</translation> +<translation id="5669267381087807207">Activando</translation> <translation id="5673434351075758678">De "<ph name="FROM_LOCALE" />" a "<ph name="TO_LOCALE" />" después de sincronizar tu configuración</translation> +<translation id="574392208103952083">Mediano</translation> <translation id="5744083938413354016">Función tocar y arrastrar</translation> <translation id="5777841717266010279">¿Dejar de compartir la pantalla?</translation> <translation id="57838592816432529">Silenciar</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Rechazar</translation> <translation id="6453179446719226835">Se cambió el idioma</translation> <translation id="6459472438155181876">Ampliando pantalla para <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Lupa de pantalla completa</translation> <translation id="6490471652906364588">Dispositivo USB-C (puerto derecho)</translation> <translation id="6501401484702599040">Transmitiendo pantalla a <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Entrada de escritura a mano</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Toma un descanso</translation> <translation id="683971173229319003">Tecla de búsqueda + L</translation> <translation id="6857811139397017780">Activar <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Esta actualización requiere que apliques la función "Powerwash" en tu dispositivo. Obtén más información sobre la actualización más reciente de <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Conectarte a otra red...</translation> <translation id="6981982820502123353">Accesibilidad</translation> <translation id="698231206551913481">Todos los archivos y datos locales asociados a este usuario se borrarán de forma permanente una vez que se quite este usuario.</translation> <translation id="7015766095477679451">Regresa a las <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Salir de la sesión</translation> <translation id="7034339000180558234">Transmitiendo <ph name="TAB_NAME" /> a <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Presionaste la combinación de teclas para activar el modo de contraste alto. ¿Quieres activarlo?</translation> <translation id="7066646422045619941">El administrador inhabilitó esta red.</translation> <translation id="7067196344162293536">Rotación automática</translation> <translation id="7076293881109082629">Accediendo</translation> <translation id="7098389117866926363">Dispositivo USB-C (puerto izquierdo en la parte posterior)</translation> <translation id="7131634465328662194">Tu sesión se cerrará automáticamente.</translation> +<translation id="7143207342074048698">Conectando</translation> <translation id="7165278925115064263">Alt+mayúscula+K</translation> <translation id="7168224885072002358">Se revertirá a la resolución anterior en <ph name="TIMEOUT_SECONDS" />.</translation> <translation id="7256634071279256947">Micrófono posterior</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Conectado a <ph name="NAME" /></translation> <translation id="813913629614996137">Inicializando…</translation> <translation id="8142699993796781067">Red privada</translation> +<translation id="8152119955266188852">Presionaste la combinación de teclas para activar la lupa de pantalla completa. ¿Quieres activarla?</translation> <translation id="8180896103888046100">Detener la transmisión a un receptor desconocido</translation> <translation id="8190698733819146287">Personalizar idiomas y la entrada de datos</translation> <translation id="8261506727792406068">Borrar</translation> +<translation id="8297006494302853456">Débil</translation> <translation id="8308637677604853869">Menú anterior</translation> <translation id="8351131234907093545">Crear nota</translation> <translation id="8392451568018454956">Menú de opciones para <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Botón Atrás</translation> <translation id="8850991929411075241">Tecla de búsqueda + Esc</translation> <translation id="8870509716567206129">La app no es compatible con la función de pantalla dividida.</translation> +<translation id="8874184842967597500">No conectado</translation> <translation id="8878886163241303700">Ampliando pantalla</translation> <translation id="8921624153894383499">El Asistente de Google no habla este idioma</translation> <translation id="8938800817013097409">Dispositivo USB-C (puerto derecho en la parte posterior)</translation> <translation id="8940956008527784070">Batería baja (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Inicio rápido</translation> <translation id="8995603266996330174">Administrado por <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Está disponible la actualización de Adobe Flash Player</translation> <translation id="9033907480196064950">Estás transmitiendo <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Acceder con otro usuario…</translation> <translation id="9201131092683066720">La batería tiene un <ph name="PERCENTAGE" /> % de carga.</translation> <translation id="9210037371811586452">Saliendo del modo de escritorio unificado</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Establecer fondo de pantalla</translation> <translation id="923686485342484400">Presiona Control Mayús Q dos veces para salir.</translation> <translation id="945522503751344254">Enviar comentarios</translation>
diff --git a/ash/strings/ash_strings_es.xtb b/ash/strings/ash_strings_es.xtb index e107237..f58783d 100644 --- a/ash/strings/ash_strings_es.xtb +++ b/ash/strings/ash_strings_es.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Dispositivo USB-C (puerto frontal)</translation> <translation id="1013923882670373915">El dispositivo Bluetooth "<ph name="DEVICE_NAME" />" solicita permiso para vincularse. Introduce el código PIN <ph name="PINCODE" /> en el dispositivo</translation> <translation id="1032891413405719768">El lápiz óptico tiene poca batería</translation> +<translation id="1056775291175587022">No hay redes</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Ocultar estantería automáticamente</translation> <translation id="1153356358378277386">Dispositivos vinculados</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">mayús</translation> <translation id="3087734570205094154">Inferior</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Contraer</translation> <translation id="3126069444801937830">Reinicia el sistema para actualizarlo.</translation> <translation id="3147142846278915599">Menú de aplicaciones (sincronizando aplicaciones...)</translation> <translation id="315116470104423982">Redes móviles</translation> @@ -198,6 +198,7 @@ <translation id="4890187583552566966">Tu administrador ha inhabilitado el Asistente de Google.</translation> <translation id="4895488851634969361">La batería está llena.</translation> <translation id="4905614135390995787">La combinación de teclas para activar el modo de contraste alto ha cambiado. Utiliza <ph name="NEW_SHORTCUT" /> en lugar de <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Buena</translation> <translation id="4918086044614829423">Aceptar</translation> <translation id="4961318399572185831">Enviar pantalla</translation> <translation id="5136175204352732067">Se ha conectado otro teclado</translation> @@ -221,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Pulsa Ctrl + Alt + Z para inhabilitar los mensajes de voz.</translation> <translation id="5648021990716966815">Clavija para micrófono</translation> +<translation id="5669267381087807207">Activando</translation> <translation id="5673434351075758678">De "<ph name="FROM_LOCALE" />" a "<ph name="TO_LOCALE" />" después de sincronizar tu configuración.</translation> +<translation id="574392208103952083">Mediano</translation> <translation id="5744083938413354016">Tocar y arrastrar</translation> <translation id="5777841717266010279">¿Dejar de compartir la pantalla?</translation> <translation id="57838592816432529">Silenciar</translation> @@ -304,6 +307,7 @@ <translation id="7076293881109082629">Iniciando sesión</translation> <translation id="7098389117866926363">Dispositivo USB tipo C (puerto izquierdo situado en la parte trasera)</translation> <translation id="7131634465328662194">Tu sesión se cerrará automáticamente.</translation> +<translation id="7143207342074048698">Conectando</translation> <translation id="7165278925115064263">Alt + Mayús + K</translation> <translation id="7168224885072002358">Restableciendo la resolución anterior en <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Micrófono trasero</translation> @@ -353,6 +357,7 @@ <translation id="8180896103888046100">Dejar de enviar contenido a un receptor desconocido</translation> <translation id="8190698733819146287">Personalizar idiomas...</translation> <translation id="8261506727792406068">Eliminar</translation> +<translation id="8297006494302853456">Débil</translation> <translation id="8308637677604853869">Menú anterior</translation> <translation id="8351131234907093545">Crear nota</translation> <translation id="8392451568018454956">Menú de opciones de <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -380,6 +385,7 @@ <translation id="8841375032071747811">Botón Atrás</translation> <translation id="8850991929411075241">Buscar+Esc</translation> <translation id="8870509716567206129">La aplicación no admite la pantalla dividida.</translation> +<translation id="8874184842967597500">No conectado</translation> <translation id="8878886163241303700">Ampliando pantalla</translation> <translation id="8921624153894383499">El Asistente de Google no habla este idioma.</translation> <translation id="8938800817013097409">Dispositivo USB tipo C (puerto derecho situado en la parte trasera)</translation>
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb index 2358ebba..e472c55 100644 --- a/ash/strings/ash_strings_et.xtb +++ b/ash/strings/ash_strings_et.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">C-tüüpi USB-seade (eesmine port)</translation> <translation id="1013923882670373915">Bluetoothi seade „<ph name="DEVICE_NAME" />” küsib luba sidumiseks. Sisestage seadmes järgmine PIN-kood: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Elektronpliiatsi aku hakkab tühjaks saama</translation> +<translation id="1056775291175587022">Võrke ei ole</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Riiuli automaatne peitmine</translation> <translation id="1153356358378277386">Seotud seadmed</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Paremale</translation> <translation id="1383876407941801731">Otsi</translation> <translation id="1467432559032391204">Vasakule</translation> +<translation id="1479743070547893297">Valimiseks joonistage elektronpliiatsiga</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Käivitaja</translation> <translation id="1525508553941733066">LOOBU</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Valige keel</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Vaadake lisateavet operatsioonisüsteemi <ph name="SYSTEM_APP_NAME" /> uusima värskenduse kohta</translation> <translation id="1995660704900986789">Lülita välja</translation> <translation id="2012624427112548395">Ctrl + otsinguklahv + H</translation> +<translation id="2016340657076538683">Sisestage sõnum</translation> <translation id="2049639323467105390">Seadet haldab <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Vertikaalpaigutus</translation> <translation id="2067602449040652523">Klaviatuuri eredus</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Jätka</translation> <translation id="2365393535144473978">Mobiilse andmeside lubamisel lubatakse Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Värskendus on saadaval</translation> <translation id="2429753432712299108">Bluetoothi seade „<ph name="DEVICE_NAME" />” küsib luba sidumiseks. Enne nõustumist veenduge, et selles seadmes oleks kuvatud see parool: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Märguanded</translation> <translation id="2484513351006226581">Klaviatuuripaigutuse muutmiseks vajutage klahvikombinatsiooni <ph name="KEYBOARD_SHORTCUT" />.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">SUURTÄHELUKK on sisse lülitatud</translation> <translation id="2532589005999780174">Suure kontrastsusega režiim</translation> <translation id="2575685495496069081">Mitmele kontole sisselogimine on keelatud</translation> +<translation id="2582112259361606227">Taaskäivitage värskendamiseks</translation> <translation id="2597972630681408282">Öövalgus: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM-kaart on lukustatud</translation> <translation id="2653659639078652383">Esita</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Jagate oma ekraani</translation> <translation id="2942516765047364088">Riiuli positsioon</translation> <translation id="2946119680249604491">Lisa ühendus</translation> +<translation id="2961963223658824723">Midagi läks valesti. Proovige mõne sekundi pärast uuesti.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> on avalik seanss, mida haldab <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Monoheli</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">tõstuklahv</translation> <translation id="3087734570205094154">Alaserv</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Ahenda</translation> <translation id="3126069444801937830">Taaskäivitage värskendamiseks</translation> <translation id="3147142846278915599">Käivitusprogramm (rakenduste sünkroonimine ...)</translation> <translation id="315116470104423982">Mobiilne andmeside</translation> @@ -148,6 +154,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Lukusta</translation> <translation id="3798670284305777884">Kõlar (sisemine)</translation> +<translation id="380165613292957338">Tere! Kuidas saan aidata?</translation> <translation id="3846575436967432996">Võrguteave ei ole saadaval</translation> <translation id="385051799172605136">Tagasi</translation> <translation id="3891340733213178823">Väljalogimiseks vajutage kaks korda klahvikombinatsiooni Ctrl + tõstuklahv + Q.</translation> @@ -160,6 +167,7 @@ <translation id="3995138139523574647">C-tüüpi USB-seade (tagumine parempoolne port)</translation> <translation id="4017989525502048489">Laserkursor</translation> <translation id="4072264167173457037">Keskmine signaal</translation> +<translation id="4200057768455216496">Vajutasite dokitud luubi otseteed. Kas soovite luubi sisse lülitada?</translation> <translation id="4217571870635786043">Dikteerimine</translation> <translation id="4279490309300973883">Peegeldamine</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">Administraator on Google'i assistendi keelanud.</translation> <translation id="4895488851634969361">Aku on täis.</translation> <translation id="4905614135390995787">Suure kontrastsusega režiimi aktiveerimise otsetee on muutunud. Kasutage edaspidi otseteed <ph name="NEW_SHORTCUT" />, mitte <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Tugev</translation> <translation id="4918086044614829423">Nõustu</translation> <translation id="4961318399572185831">Ekraani ülekandmine</translation> <translation id="5136175204352732067">Ühendatud on teine klaviatuur</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Vajutage suulise tagasiside keelamiseks klahvikombinatsiooni Ctrl + Alt + Z.</translation> <translation id="5648021990716966815">Mikrofoni pistikupesa</translation> +<translation id="5669267381087807207">Aktiveerimine</translation> <translation id="5673434351075758678">Pärast seadete sünkroonimist lokaadist „<ph name="FROM_LOCALE" />” lokaati „<ph name="TO_LOCALE" />”.</translation> +<translation id="574392208103952083">Keskmine</translation> <translation id="5744083938413354016">Puudutusega lohistamine</translation> <translation id="5777841717266010279">Kas peatada ekraani jagamine?</translation> <translation id="57838592816432529">Vaigista</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Lükka tagasi</translation> <translation id="6453179446719226835">Keelt muudeti</translation> <translation id="6459472438155181876">Ekraani laiendamine seadmesse <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Täisekraani luup</translation> <translation id="6490471652906364588">C-tüüpi USB-seade (parempoolne port)</translation> <translation id="6501401484702599040">Ekraani ülekandmine seadmesse <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Käsitsikirjasisend</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Tehke paus!</translation> <translation id="683971173229319003">Otsing + L</translation> <translation id="6857811139397017780">Aktiveeri <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Värskenduse jaoks on vajalik seadme powerwash. Vaadake lisateavet operatsioonisüsteemi <ph name="SYSTEM_APP_NAME" /> uusima värskenduse kohta.</translation> <translation id="6911468394164995108">Liitu muu võrguga ...</translation> <translation id="6981982820502123353">Juurdepääsetavus</translation> <translation id="698231206551913481">Kõik selle kasutajaga seotud failid ja kohalikud andmed kustutatakse jäädavalt kohe, kui see kasutaja eemaldatakse.</translation> <translation id="7015766095477679451">Tulge tagasi kell <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Välju seansist</translation> <translation id="7034339000180558234">Vahelehe <ph name="TAB_NAME" /> ülekandmine seadmesse <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Vajutasite suure kontrastsusega režiimi otseteed. Kas soovite režiimi sisse lülitada?</translation> <translation id="7066646422045619941">Teie administraator on selle võrgu keelanud.</translation> <translation id="7067196344162293536">Automaatne pööramine</translation> <translation id="7076293881109082629">Sisselogimine</translation> <translation id="7098389117866926363">C-tüüpi USB-seade (vasakpoolne port taga)</translation> <translation id="7131634465328662194">Teid logitakse automaatselt välja.</translation> +<translation id="7143207342074048698">Ühendamine</translation> <translation id="7165278925115064263">Alt + Tõstuklahv + K</translation> <translation id="7168224885072002358">Ekraan ennistatakse vanale eraldusvõimele <ph name="TIMEOUT_SECONDS" /> pärast</translation> <translation id="7256634071279256947">Tagumine mikrofon</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Ühendus <ph name="NAME" />iga</translation> <translation id="813913629614996137">Lähtestamine …</translation> <translation id="8142699993796781067">Privaatvõrk</translation> +<translation id="8152119955266188852">Vajutasite täisekraani luubi otseteed. Kas soovite luubi sisse lülitada?</translation> <translation id="8180896103888046100">Peata ülekandmine tundmatusse vastuvõtjasse</translation> <translation id="8190698733819146287">Keelte ja sisendi kohandamine...</translation> <translation id="8261506727792406068">Kustuta</translation> +<translation id="8297006494302853456">Nõrk</translation> <translation id="8308637677604853869">Eelmine menüü</translation> <translation id="8351131234907093545">Märkme loomine</translation> <translation id="8392451568018454956">Konto <ph name="USER_EMAIL_ADDRESS" /> valikute menüü</translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Nupp Tagasi</translation> <translation id="8850991929411075241">Otsing + ESC</translation> <translation id="8870509716567206129">Rakendus ei toeta jagatud ekraani.</translation> +<translation id="8874184842967597500">Ühendus puudub</translation> <translation id="8878886163241303700">Ekraani laiendamine</translation> <translation id="8921624153894383499">Google'i assistent ei räägi selles keeles.</translation> <translation id="8938800817013097409">C-tüüpi USB-seade (parempoolne port taga)</translation> <translation id="8940956008527784070">Aku tühjeneb (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Kiirkäivitus</translation> <translation id="8995603266996330174">Haldaja: <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Saadaval on Adobe Flash Playeri värskendus</translation> <translation id="9033907480196064950">Kannate praegu üle vahelehte <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">WiFi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Logi sisse teine kasutaja ...</translation> <translation id="9201131092683066720">Aku on <ph name="PERCENTAGE" />% täis.</translation> <translation id="9210037371811586452">Ühendatud töölaua režiimist väljumine</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Taustapildi määramine</translation> <translation id="923686485342484400">Väljalogimiseks vajutage kaks korda klahvikombinatsiooni Ctrl + tõstuklahv + Q.</translation> <translation id="945522503751344254">Saada tagasisidet</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb index fcacf183..dcd55a2 100644 --- a/ash/strings/ash_strings_fa.xtb +++ b/ash/strings/ash_strings_fa.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">دستگاه USB-C (درگاه جلو)</translation> <translation id="1013923882670373915">دستگاه بلوتوث «<ph name="DEVICE_NAME" />» برای مرتبطسازی به مجوز نیاز دارد. لطفاً این کد پین را در آن دستگاه وارد کنید: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">شارژ باتری قلم کم است</translation> +<translation id="1056775291175587022">شبکهای وجود ندارد</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">پنهان کردن خودکار قفسه</translation> <translation id="1153356358378277386">دستگاههای مرتبطشده</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">راست</translation> <translation id="1383876407941801731">جستجو</translation> <translation id="1467432559032391204">چپ</translation> +<translation id="1479743070547893297">برای انتخاب کردن، با قلم طرحی بکشید</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">راهانداز</translation> <translation id="1525508553941733066">رد کردن</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">۰ درجه</translation> <translation id="1957958912175573503">تنظیم زبان</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">درباره جدیدترین بهروزرسانی <ph name="SYSTEM_APP_NAME" /> بیشتر بدانید.</translation> <translation id="1995660704900986789">خاموش کردن</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">پیامی تایپ کنید</translation> <translation id="2049639323467105390">این دستگاه توسط <ph name="DOMAIN" /> مدیریت میشود.</translation> <translation id="2050339315714019657">عمودی</translation> <translation id="2067602449040652523">روشنایی صفحهکلید</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">ادامه</translation> <translation id="2365393535144473978">فعال کردن داده تلفن همراه، بلوتوث را فعال میکند.</translation> <translation id="2391579633712104609">۱۸۰°</translation> +<translation id="2412593942846481727">بهروزرسانی دردسترس است</translation> <translation id="2429753432712299108">دستگاه بلوتوث «<ph name="DEVICE_NAME" />» برای مرتبطسازی به مجوز نیاز دارد. قبل از پذیرش، لطفاً تأیید کنید که این کلیدواژه در آن دستگاه نشان داده میشود: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">اعلانها</translation> <translation id="2484513351006226581">برای تغییر طرحبندی صفحهکلید، <ph name="KEYBOARD_SHORTCUT" /> را فشار دهید.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK روشن است</translation> <translation id="2532589005999780174">حالت کنتراست بالا</translation> <translation id="2575685495496069081">ورود چندگانه به سیستم غیرفعال شده است</translation> +<translation id="2582112259361606227">بازراهاندازی برای بهروزرسانی</translation> <translation id="2597972630681408282">«نور شب»: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">سیمکارت قفل است</translation> <translation id="2653659639078652383">ارائه</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">شما در حال همرسانی صفحهتان هستید</translation> <translation id="2942516765047364088">موقعیت قفسه</translation> <translation id="2946119680249604491">افزودن اتصال</translation> +<translation id="2961963223658824723">مشکلی پیش آمد. چند ثانیه دیگر دوباره امتحان کنید.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> یک جلسه عمومی مدیریتشده توسط <ph name="DOMAIN" /> است</translation> <translation id="3000461861112256445">صدای مونو</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">تبدیل</translation> <translation id="3087734570205094154">پایین</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (بلوتوث)</translation> -<translation id="3112378005171663295">کوچک کردن</translation> <translation id="3126069444801937830">راهاندازی مجدد برای بهروزرسانی</translation> <translation id="3147142846278915599">راه انداز (همگامسازی برنامهها...)</translation> <translation id="315116470104423982">دادههای تلفن همراه</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">دگرساز</translation> <translation id="3784455785234192852">قفل</translation> <translation id="3798670284305777884">بلندگو (داخلی)</translation> +<translation id="380165613292957338">سلام، چه کمکی میتوانم بکنم؟</translation> <translation id="3846575436967432996">اطلاعات شبکه در دسترس نیست</translation> <translation id="385051799172605136">بازگشت</translation> <translation id="3891340733213178823">برای خروج از سیستم Ctrl+Shift+Q را دو بار فشار دهید.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">دستگاه USB-C (درگاه عقب سمت راست)</translation> <translation id="4017989525502048489">اشارهگر لیزری</translation> <translation id="4072264167173457037">سیگنال متوسط</translation> +<translation id="4200057768455216496">میانبر مربوط به ذرهبین متصل را فشار دادید. میخواهید آن را روشن کنید؟</translation> <translation id="4217571870635786043">املا</translation> <translation id="4279490309300973883">بازتاب میشود</translation> <translation id="4321179778687042513">مهار</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">سرپرستتان «دستیار Google» را غیرفعال کرده است.</translation> <translation id="4895488851634969361">باتری پر است.</translation> <translation id="4905614135390995787">میانبر روشن/خاموش کردن «حالت تضاد بالا» تغییر کرده است. لطفاً بهجای <ph name="OLD_SHORTCUT" /> از <ph name="NEW_SHORTCUT" /> استفاده کنید.</translation> +<translation id="4917385247580444890">قوی</translation> <translation id="4918086044614829423">میپذیرم</translation> <translation id="4961318399572185831">فرستادن صفحه</translation> <translation id="5136175204352732067">صفحهکلید دیگری متصل شد</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />، <ph name="DATE" /></translation> <translation id="5600837773213129531">برای غیرفعال کردن بازخورد گفتاری، Ctrl + Alt + Z را فشار دهید.</translation> <translation id="5648021990716966815">فیش میکروفون</translation> +<translation id="5669267381087807207">فعالسازی</translation> <translation id="5673434351075758678">از «<ph name="FROM_LOCALE" />» به «<ph name="TO_LOCALE" />» بعد از همگامسازی تنظیمات.</translation> +<translation id="574392208103952083">متوسط</translation> <translation id="5744083938413354016">کشیدن با ضربه زدن</translation> <translation id="5777841717266010279">اشتراکگذاری صفحه نمایش متوقف شود؟</translation> <translation id="57838592816432529">بیصدا کردن</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">عدم پذیرش</translation> <translation id="6453179446719226835">زبان تغییر کرد</translation> <translation id="6459472438155181876">گسترش صفحه به <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">ذرهبین تمامصفحه</translation> <translation id="6490471652906364588">دستگاه USB-C (درگاه سمت راست)</translation> <translation id="6501401484702599040">ارسال محتوای صفحه به <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">ورودی دستنویس</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">استراحت کنید!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">فعال سازی <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">این بهروزرسانی نیاز به انجام powerwash دستگاهتان دارد. درباره جدیدترین بهروزرسانی <ph name="SYSTEM_APP_NAME" /> بیشتر بدانید.</translation> <translation id="6911468394164995108">پیوستن به شبکه دیگر…</translation> <translation id="6981982820502123353">قابلیت دسترسی</translation> <translation id="698231206551913481">اگر کاربر حذف شود، همه فایلها و دادههای محلی مربوط به او بهطور دائم حذف خواهند شد.</translation> <translation id="7015766095477679451">ساعت <ph name="COME_BACK_TIME" /> دوباره برگردید.</translation> <translation id="7029814467594812963">خروج از جلسه</translation> <translation id="7034339000180558234">ارسال محتوای <ph name="TAB_NAME" /> به <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">میانبر مربوط به کنتراست بالا را فشار دادید. میخواهید آن را روشن کنید؟</translation> <translation id="7066646422045619941">این شبکه توسط سرپرست شما غیرفعال شده است.</translation> <translation id="7067196344162293536">چرخش خودکار</translation> <translation id="7076293881109082629">در حال ورود به سیستم</translation> <translation id="7098389117866926363">دستگاه USB-C (درگاه عقب سمت چپ)</translation> <translation id="7131634465328662194">بهطور خودکار از سیستم خارج خواهید شد.</translation> +<translation id="7143207342074048698">در حال اتصال</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">برگرداندن به وضوح قدیمی در <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">میکروفون پشت</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">متصل به <ph name="NAME" /></translation> <translation id="813913629614996137">درحال مقداردهی اولیه…</translation> <translation id="8142699993796781067">شبکههای خصوصی</translation> +<translation id="8152119955266188852">میانبر مربوط به ذرهبین تمامصفحه را فشار دادید. میخواهید آن را روشن کنید؟</translation> <translation id="8180896103888046100">توقف ارسال محتوا به گیرنده ناشناس</translation> <translation id="8190698733819146287">سفارشی کردن زبانها و ورودی...</translation> <translation id="8261506727792406068">حذف</translation> +<translation id="8297006494302853456">ضعیف</translation> <translation id="8308637677604853869">منوی قبلی</translation> <translation id="8351131234907093545">یادداشت ایجاد کنید</translation> <translation id="8392451568018454956">منوی گزینهها برای <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">دکمه برگشت</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">برنامه از تقسیم صفحه پشتیبانی نمیکند.</translation> +<translation id="8874184842967597500">متصل نیست</translation> <translation id="8878886163241303700">صفحه گسترش یافته است</translation> <translation id="8921624153894383499">«دستیار Google» به این زبان صحبت نمیکند.</translation> <translation id="8938800817013097409">دستگاه USB-C (درگاه عقب سمت راست)</translation> <translation id="8940956008527784070">باتری ضعیف است (<ph name="PERCENTAGE" />٪)</translation> <translation id="8984179138335769204">راهاندازی سریع</translation> <translation id="8995603266996330174">مدیریت شده توسط <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">بهروزرسانی Adobe Flash Player دردسترس است</translation> <translation id="9033907480196064950">درحال ارسال محتوای <ph name="TAB_NAME" /> هستید</translation> <translation id="9074739597929991885">بلوتوث</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">ورود به سیستم حسابی دیگر...</translation> <translation id="9201131092683066720">باتری <ph name="PERCENTAGE" /> درصد پر است.</translation> <translation id="9210037371811586452">خروج از حالت میزکار یکپارچه</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">تنظیم کاغذدیواری</translation> <translation id="923686485342484400">برای خروج از سیستم Control Shift Q را دو بار فشار دهید.</translation> <translation id="945522503751344254">ارسال بازخورد</translation>
diff --git a/ash/strings/ash_strings_fi.xtb b/ash/strings/ash_strings_fi.xtb index bf27ce3..cb04518 100644 --- a/ash/strings/ash_strings_fi.xtb +++ b/ash/strings/ash_strings_fi.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">C-tyypin USB-laite (etuportti)</translation> <translation id="1013923882670373915">Bluetooth-laite <ph name="DEVICE_NAME" /> pyytää lupaa laiteparin muodostamiseen. Anna tämä PIN-koodi kyseisellä laitteella: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Näyttökynän akku on vähissä</translation> +<translation id="1056775291175587022">Ei verkkoja</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Piilota hylly automaattisesti</translation> <translation id="1153356358378277386">Laiteparit</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Alaosa</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Tiivistä</translation> <translation id="3126069444801937830">Päivitä käynnistämällä uudelleen</translation> <translation id="3147142846278915599">Käynnistysohjelma (synkronoidaan sovelluksia…)</translation> <translation id="315116470104423982">Mobiilitiedonsiirto</translation> @@ -198,6 +198,7 @@ <translation id="4890187583552566966">Järjestelmänvalvoja on poistanut Google Assistantin käytöstä.</translation> <translation id="4895488851634969361">Akku on täynnä.</translation> <translation id="4905614135390995787">Suuren kontrastin tilan pikanäppäin on muuttunut. Käytä uutta pikanäppäintä <ph name="NEW_SHORTCUT" /> vanhan (<ph name="OLD_SHORTCUT" />) sijaan.</translation> +<translation id="4917385247580444890">Vahva</translation> <translation id="4918086044614829423">Hyväksy</translation> <translation id="4961318399572185831">Suoratoista näyttö</translation> <translation id="5136175204352732067">Eri näppäimistö kytketty</translation> @@ -221,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Poista äänipalaute käytöstä painamalla Ctrl+Alt+Z.</translation> <translation id="5648021990716966815">Mikrofoniliitäntä</translation> +<translation id="5669267381087807207">Aktivoidaan</translation> <translation id="5673434351075758678">Muutos asetusten synkronoinnin yhteydessä: <ph name="FROM_LOCALE" /> – <ph name="TO_LOCALE" /></translation> +<translation id="574392208103952083">Keskikoko</translation> <translation id="5744083938413354016">Napauttamalla vetäminen</translation> <translation id="5777841717266010279">Lopetetaanko näytön jakaminen?</translation> <translation id="57838592816432529">Mykistä</translation> @@ -306,6 +309,7 @@ <translation id="7076293881109082629">Kirjautuminen</translation> <translation id="7098389117866926363">C-tyypin USB-laite (vasemmanpuoleinen takaportti)</translation> <translation id="7131634465328662194">Sinut kirjataan automaattisesti ulos.</translation> +<translation id="7143207342074048698">Yhdistetään</translation> <translation id="7165278925115064263">Alt+Vaihto+K</translation> <translation id="7168224885072002358">Palautetaan vanha tarkkuus, aikaa palautukseen <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Takamikrofoni</translation> @@ -355,6 +359,7 @@ <translation id="8180896103888046100">Lopeta suoratoisto tuntemattomaan kohteeseen</translation> <translation id="8190698733819146287">Muokkaa kieliä ja syötettä...</translation> <translation id="8261506727792406068">Poista</translation> +<translation id="8297006494302853456">Heikko</translation> <translation id="8308637677604853869">Edellinen valikko</translation> <translation id="8351131234907093545">Luo muistiinpano</translation> <translation id="8392451568018454956">Tilin <ph name="USER_EMAIL_ADDRESS" /> vaihtoehtovalikko</translation> @@ -382,6 +387,7 @@ <translation id="8841375032071747811">Takaisin-painike</translation> <translation id="8850991929411075241">Haku+Esc</translation> <translation id="8870509716567206129">Sovellus ei tue jaetun näytön tilaa.</translation> +<translation id="8874184842967597500">Ei yhdistetty</translation> <translation id="8878886163241303700">Laajennettu näyttö</translation> <translation id="8921624153894383499">Google Assistant ei ole käytettävissä tällä kielellä.</translation> <translation id="8938800817013097409">C-tyypin USB-laite (oikeanpuoleinen takaportti)</translation>
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb index b80e34b..c2cdb94f 100644 --- a/ash/strings/ash_strings_fil.xtb +++ b/ash/strings/ash_strings_fil.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C device (port sa harap)</translation> <translation id="1013923882670373915">Gusto ng bluetooth device na "<ph name="DEVICE_NAME" />" ng pahintulot na magpares. Pakilagay ang PIN na ito sa device na iyon: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Mahina na ang baterya ng stylus</translation> +<translation id="1056775291175587022">Walang network</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Awtomatikong itago ang shelf</translation> <translation id="1153356358378277386">Mga nakapares na device</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Kanan</translation> <translation id="1383876407941801731">Hanapin</translation> <translation id="1467432559032391204">Kaliwa</translation> +<translation id="1479743070547893297">Gumuhit gamit ang iyong stylus para pumili</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Launcher</translation> <translation id="1525508553941733066">I-DISMISS</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Itakda ang iyong wika</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Matuto pa tungkol sa pinakabagong update sa <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">I-off</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">Mag-type ng mensahe</translation> <translation id="2049639323467105390">Pinamamahalaan ng <ph name="DOMAIN" /> ang device na ito.</translation> <translation id="2050339315714019657">Portrait</translation> <translation id="2067602449040652523">Liwanag ng keyboard</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Magpatuloy</translation> <translation id="2365393535144473978">Kapag na-enable ang mobile data, mae-enable din ang Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">May available na update</translation> <translation id="2429753432712299108">Gusto ng bluetooth device na "<ph name="DEVICE_NAME" />" ng pahintulot na magpares . Bago tanggapin, pakikumpirma na ipinapakita ang passkey na ito sa device na iyon: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Mga Abiso</translation> <translation id="2484513351006226581">Pindutin ang <ph name="KEYBOARD_SHORTCUT" /> upang palitan ang layout ng keyboard.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Naka-on ang CAPS LOCK</translation> <translation id="2532589005999780174">High contrast mode</translation> <translation id="2575685495496069081">Na-disable ang maraming pag-sign in</translation> +<translation id="2582112259361606227">I-restart para mag-update</translation> <translation id="2597972630681408282">Night Light: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Naka-lock ang SIM card</translation> <translation id="2653659639078652383">Isumite</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Ibinabahagi mo ang iyong screen</translation> <translation id="2942516765047364088">Posisyon ng shelf</translation> <translation id="2946119680249604491">Magdagdag ng koneksyon</translation> +<translation id="2961963223658824723">Nagkaproblema. Subukang muli sa loob ng ilang segundo.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416">Ang <ph name="DISPLAY_NAME" /> ay isang pampublikong session na pinamamahalaan ng <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Mono audio</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Sa ilalim</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Tiklupin</translation> <translation id="3126069444801937830">I-restart upang mag-update</translation> <translation id="3147142846278915599">Launcher (nagsi-sync ng mga app...)</translation> <translation id="315116470104423982">Data sa mobile</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">I-lock</translation> <translation id="3798670284305777884">Speaker (internal)</translation> +<translation id="380165613292957338">Kumusta, ano ang maitutulong ko?</translation> <translation id="3846575436967432996">Walang available na impormasyon sa network</translation> <translation id="385051799172605136">Bumalik</translation> <translation id="3891340733213178823">Pindutin ang Ctrl+Shift+Q nang dalawang beses upang mag-sign out.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C device (port sa kanang bahagi sa likod)</translation> <translation id="4017989525502048489">Laser pointer</translation> <translation id="4072264167173457037">Katamtaman ang signal</translation> +<translation id="4200057768455216496">Napindot mo ang shortcut para sa naka-dock na magnifier. Gusto mo ba itong i-on?</translation> <translation id="4217571870635786043">Pagdidikta</translation> <translation id="4279490309300973883">Nagmi-mirror</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Na-disable ng iyong administrator ang Google Assistant.</translation> <translation id="4895488851634969361">Puno na ang baterya.</translation> <translation id="4905614135390995787">Nagbago ang shortcut upang i-toggle ang High Contrast Mode. Pakigamit ang <ph name="NEW_SHORTCUT" /> sa halip na <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Malakas</translation> <translation id="4918086044614829423">Tanggapin</translation> <translation id="4961318399572185831">I-cast ang screen</translation> <translation id="5136175204352732067">Ibang keyboard ang nakakonekta</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Pindutin ang Ctrl + Alt + Z upang i-disable ang pasalitang feedback.</translation> <translation id="5648021990716966815">Jack ng mikropono</translation> +<translation id="5669267381087807207">Ina-activate</translation> <translation id="5673434351075758678">Gagawing "<ph name="TO_LOCALE" />" mula "<ph name="FROM_LOCALE" />" pagkatapos i-sync ang iyong mga setting.</translation> +<translation id="574392208103952083">Katamtaman</translation> <translation id="5744083938413354016">Pag-tap upang mag-drag</translation> <translation id="5777841717266010279">Itigil ang screen sharing?</translation> <translation id="57838592816432529">I-mute</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Tanggihan</translation> <translation id="6453179446719226835">Napalitan na ang wika</translation> <translation id="6459472438155181876">Pinapalawak ang screen sa <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Full-screen magnifier</translation> <translation id="6490471652906364588">USB-C device (port sa kanan)</translation> <translation id="6501401484702599040">Kina-cast ang screen sa <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Input ng handwriting</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Magpahinga!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">I-activate <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Kinakailangang i-powerwash ang iyong device para sa update na ito. Matuto pa tungkol sa pinakabagong update sa <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Sumali sa iba...</translation> <translation id="6981982820502123353">Pagiging Maa-access</translation> <translation id="698231206551913481">Permanenteng made-delete ang lahat ng file at lokal na data na nauugnay sa user na ito kapag inalis na ang user na ito.</translation> <translation id="7015766095477679451">Bumalik nang <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Lumabas sa session</translation> <translation id="7034339000180558234">Kina-cast ang <ph name="TAB_NAME" /> sa <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Napindot mo ang shortcut para sa mataas na contrast. Gusto mo ba itong i-on?</translation> <translation id="7066646422045619941">Na-disable ng iyong administrator ang network na ito.</translation> <translation id="7067196344162293536">Awtomatikong pag-rotate</translation> <translation id="7076293881109082629">Nagsa-sign in</translation> <translation id="7098389117866926363">USB-C device (kaliwang port sa likod)</translation> <translation id="7131634465328662194">Awtomatiko kang masa-sign out.</translation> +<translation id="7143207342074048698">Kumokonekta</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Magre-revert sa lumang resolution sa loob ng <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Mikropono sa likod</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Kumukonekta sa <ph name="NAME" /></translation> <translation id="813913629614996137">Sinisimulan...</translation> <translation id="8142699993796781067">Pribadong network</translation> +<translation id="8152119955266188852">Napindot mo ang shortcut para sa full-screen magnifier. Gusto mo ba itong i-on?</translation> <translation id="8180896103888046100">Ihinto ang pag-cast sa isang hindi kilalang receiver</translation> <translation id="8190698733819146287">I-customize ang mga wika at input...</translation> <translation id="8261506727792406068">I-delete</translation> +<translation id="8297006494302853456">Mahina</translation> <translation id="8308637677604853869">Nakaraang menu</translation> <translation id="8351131234907093545">Gumawa ng tala</translation> <translation id="8392451568018454956">Menu ng mga pagpipilian para sa <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Button na Bumalik</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">Hindi sinusuportahan ng app ang split-screen.</translation> +<translation id="8874184842967597500">Hindi nakakonekta</translation> <translation id="8878886163241303700">Pinapalawak ang screen</translation> <translation id="8921624153894383499">Hindi nagsasalita ng ganitong wika ang Google Assistant.</translation> <translation id="8938800817013097409">USB-C device (kanang port sa likod)</translation> <translation id="8940956008527784070">Mahina na ang baterya (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Mabilisang paglunsad</translation> <translation id="8995603266996330174">Pinamamahalaan ni <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Available ang update sa Adobe Flash Player</translation> <translation id="9033907480196064950">Kasalukuyan kang nagka-cast ng <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Mag-sign in ng isa pang user...</translation> <translation id="9201131092683066720">Ang baterya ay <ph name="PERCENTAGE" />% na puno.</translation> <translation id="9210037371811586452">Lumalabas sa unified desktop mode</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Magtakda ng wallpaper</translation> <translation id="923686485342484400">Pindutin ang Control Shift Q nang dalawang beses upang mag-sign out.</translation> <translation id="945522503751344254">Magpadala ng feedback...</translation>
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb index 0b04c1a..c153b7c 100644 --- a/ash/strings/ash_strings_fr.xtb +++ b/ash/strings/ash_strings_fr.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Appareil USB de type C (port situé sur l'avant de l'appareil)</translation> <translation id="1013923882670373915">L'appareil Bluetooth "<ph name="DEVICE_NAME" />" demande l'autorisation de s'associer. Veuillez saisir le code suivant sur l'appareil : <ph name="PINCODE" />.</translation> <translation id="1032891413405719768">Le niveau de charge des piles du stylet est faible</translation> +<translation id="1056775291175587022">Aucun réseau</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" /> : <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Masquer automatiquement l'étagère</translation> <translation id="1153356358378277386">Appareils associés</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Vers la droite</translation> <translation id="1383876407941801731">Rechercher</translation> <translation id="1467432559032391204">Vers la gauche</translation> +<translation id="1479743070547893297">Dessinez avec votre stylet pour effectuer une sélection</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Lanceur d'applications</translation> <translation id="1525508553941733066">IGNORER</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Définir la langue</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">En savoir plus sur la dernière mise à jour <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Éteindre</translation> <translation id="2012624427112548395">Ctrl+Recherche+H</translation> +<translation id="2016340657076538683">Saisissez un message</translation> <translation id="2049639323467105390">Cet appareil est géré par <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Portrait</translation> <translation id="2067602449040652523">Luminosité du clavier</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Continuer</translation> <translation id="2365393535144473978">L'activation des données mobiles active également le Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Mise à jour disponible</translation> <translation id="2429753432712299108">L'appareil Bluetooth "<ph name="DEVICE_NAME" />" demande l'autorisation de s'associer. Avant d'accepter, veuillez confirmer que le code d'authentification suivant s'affiche sur l'appareil : <ph name="PASSKEY" />.</translation> <translation id="2482878487686419369">Notifications</translation> <translation id="2484513351006226581">Appuyez sur <ph name="KEYBOARD_SHORTCUT" /> pour changer la disposition du clavier.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Touche VERR MAJ activée</translation> <translation id="2532589005999780174">Mode Contraste élevé</translation> <translation id="2575685495496069081">La connexion multicompte a été désactivée</translation> +<translation id="2582112259361606227">Redémarrer pour mettre à jour</translation> <translation id="2597972630681408282">Éclairage nocturne : <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">La carte SIM est verrouillée</translation> <translation id="2653659639078652383">Valider</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Vous partagez votre écran</translation> <translation id="2942516765047364088">Position de l'étagère</translation> <translation id="2946119680249604491">Ajouter une connexion</translation> +<translation id="2961963223658824723">Une erreur s'est produite. Veuillez réessayer dans quelques secondes.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> est une session publique gérée par <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Audio mono</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">maj</translation> <translation id="3087734570205094154">Bas</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Réduire</translation> <translation id="3126069444801937830">Redémarrer pour mettre à jour</translation> <translation id="3147142846278915599">Lanceur d'applications (synchronisation des applications en cours…)</translation> <translation id="315116470104423982">Données mobiles</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Verrouiller</translation> <translation id="3798670284305777884">Haut-parleur (interne)</translation> +<translation id="380165613292957338">Bonjour, comment puis-je vous aider ?</translation> <translation id="3846575436967432996">Aucune information disponible concernant le réseau</translation> <translation id="385051799172605136">Retour</translation> <translation id="3891340733213178823">Appuyez deux fois sur Ctrl + Maj + Q pour vous déconnecter.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Appareil USB de type C (port situé sur la droite de l'appareil, à l'arrière)</translation> <translation id="4017989525502048489">Pointeur laser</translation> <translation id="4072264167173457037">Signal de moyenne intensité</translation> +<translation id="4200057768455216496">Vous avez utilisé le raccourci de la loupe ancrée. Voulez-vous l'activer ?</translation> <translation id="4217571870635786043">Dictée</translation> <translation id="4279490309300973883">Mise en miroir</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">L'administrateur a désactivé l'Assistant Google.</translation> <translation id="4895488851634969361">La batterie est pleine.</translation> <translation id="4905614135390995787">Le raccourci permettant d'activer ou de désactiver le mode Contraste élevé a été modifié. Veuillez utiliser "<ph name="NEW_SHORTCUT" />" au lieu de "<ph name="OLD_SHORTCUT" />".</translation> +<translation id="4917385247580444890">Très bon</translation> <translation id="4918086044614829423">Accepter</translation> <translation id="4961318399572185831">Diffuser l'écran</translation> <translation id="5136175204352732067">Clavier différent branché</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" /> <ph name="DATE" /></translation> <translation id="5600837773213129531">Appuyez sur Ctrl+Alt+Z pour désactiver les commentaires audio.</translation> <translation id="5648021990716966815">Connecteur micro</translation> +<translation id="5669267381087807207">Activation</translation> <translation id="5673434351075758678">La langue utilisée est passée de "<ph name="FROM_LOCALE" />" à "<ph name="TO_LOCALE" />" après la synchronisation de vos paramètres.</translation> +<translation id="574392208103952083">Moyenne</translation> <translation id="5744083938413354016">Déplacement tactile</translation> <translation id="5777841717266010279">Arrêter le partage d'écran ?</translation> <translation id="57838592816432529">Couper le son</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Refuser</translation> <translation id="6453179446719226835">La langue a été modifiée</translation> <translation id="6459472438155181876">Extension de l'écran pour <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Loupe plein écran</translation> <translation id="6490471652906364588">Appareil USB de type C (port situé sur la droite de l'appareil)</translation> <translation id="6501401484702599040">Diffusion de l'écran sur "<ph name="RECEIVER_NAME" />"</translation> <translation id="6521655319214113338">Écriture manuscrite</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Faites une pause !</translation> <translation id="683971173229319003">Recherche+L</translation> <translation id="6857811139397017780">Activer <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Cette mise à jour nécessite que vous utilisiez la fonctionnalité Powerwash sur votre appareil. Obtenez de plus amples informations sur la dernière mise à jour <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Autre réseau…</translation> <translation id="6981982820502123353">Accessibilité</translation> <translation id="698231206551913481">L'ensemble des données locales et des fichiers associés à cet utilisateur seront définitivement supprimés en même temps que ce dernier.</translation> <translation id="7015766095477679451">Revenez à <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Quitter la session</translation> <translation id="7034339000180558234">Diffusion de l'onglet "<ph name="TAB_NAME" />" sur "<ph name="RECEIVER_NAME" />"</translation> +<translation id="7037152028959403492">Vous avez utilisé le raccourci du contraste élevé. Voulez-vous l'activer ?</translation> <translation id="7066646422045619941">Votre administrateur a désactivé ce réseau.</translation> <translation id="7067196344162293536">Rotation automatique</translation> <translation id="7076293881109082629">Connexion</translation> <translation id="7098389117866926363">Appareil USB de type C (port situé sur l'arrière de l'appareil, à gauche)</translation> <translation id="7131634465328662194">Vous allez être déconnecté automatiquement.</translation> +<translation id="7143207342074048698">Connexion en cours</translation> <translation id="7165278925115064263">Alt+Maj+K</translation> <translation id="7168224885072002358">Rétablissement de la résolution précédente dans <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Micro arrière</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Connecté à <ph name="NAME" /></translation> <translation id="813913629614996137">Initialisation…</translation> <translation id="8142699993796781067">Réseau privé</translation> +<translation id="8152119955266188852">Vous avez utilisé le raccourci de la loupe plein écran. Voulez-vous l'activer ?</translation> <translation id="8180896103888046100">Arrêter la diffusion sur un destinataire inconnu</translation> <translation id="8190698733819146287">Personnaliser les langues et la saisie...</translation> <translation id="8261506727792406068">Supprimer</translation> +<translation id="8297006494302853456">Faible</translation> <translation id="8308637677604853869">Menu précédent</translation> <translation id="8351131234907093545">Créer une note</translation> <translation id="8392451568018454956">Menu "Options" de l'adresse e-mail <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Bouton Retour</translation> <translation id="8850991929411075241">Recherche+Échap</translation> <translation id="8870509716567206129">Application incompatible avec l'écran partagé.</translation> +<translation id="8874184842967597500">Non connecté</translation> <translation id="8878886163241303700">Extension de l'écran</translation> <translation id="8921624153894383499">L'Assistant Google ne parle pas cette langue.</translation> <translation id="8938800817013097409">Appareil USB de type C (port situé sur l'arrière de l'appareil, à droite)</translation> <translation id="8940956008527784070">Batterie faible (<ph name="PERCENTAGE" /> %)</translation> <translation id="8984179138335769204">Lancement rapide</translation> <translation id="8995603266996330174">Géré par <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Mise à jour Adobe Flash Player disponible</translation> <translation id="9033907480196064950">Vous êtes actuellement en train de caster <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi : <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Se connecter avec un autre compte utilisateur…</translation> <translation id="9201131092683066720">La batterie est chargée à <ph name="PERCENTAGE" /> %.</translation> <translation id="9210037371811586452">Sortie du mode Bureau unifié</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Définir le fond d'écran</translation> <translation id="923686485342484400">Appuyez deux fois sur Contrôle + Maj + Q pour vous déconnecter.</translation> <translation id="945522503751344254">Envoyer le commentaire</translation>
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb index 8e02f49b..cf097f2 100644 --- a/ash/strings/ash_strings_gu.xtb +++ b/ash/strings/ash_strings_gu.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C ઉપકરણ (આગળનું પોર્ટ)</translation> <translation id="1013923882670373915">Bluetooth ઉપકરણ "<ph name="DEVICE_NAME" />" ને જોડી બનાવવા માટે પરવાનગી જોઈએ છે. કૃપા કરીને તે ઉપકરણ પર આ PIN કોડ દાખલ કરો: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">સ્ટાઇલસની બૅટરી ઓછી છે</translation> +<translation id="1056775291175587022">કોઈ નેટવર્ક નથી</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">સ્વતઃછુપાવો શેલ્ફ</translation> <translation id="1153356358378277386">જોડી કરેલા ઉપકરણો</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">જમણે</translation> <translation id="1383876407941801731">શોધો</translation> <translation id="1467432559032391204">ડાબું</translation> +<translation id="1479743070547893297">પસંદ કરવા માટે તમારા સ્ટાઇલસ વડે દોરો</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">લૉન્ચર</translation> <translation id="1525508553941733066">છોડી દો</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">તમારી ભાષા સેટ કરો</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">નવીનતમ <ph name="SYSTEM_APP_NAME" /> અપડેટ વિશે વધુ જાણો</translation> <translation id="1995660704900986789">પાવર બંધ કરો</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">એક સંદેશ લખો</translation> <translation id="2049639323467105390">આ ઉપકરણને <ph name="DOMAIN" /> દ્વારા મેનેજ કરવામાં આવેલું છે.</translation> <translation id="2050339315714019657">પોર્ટ્રેટ</translation> <translation id="2067602449040652523">કીબોર્ડનું તેજ</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">ચાલુ રાખો</translation> <translation id="2365393535144473978">મોબાઇલ ડેટા સક્ષમ કરવાથી બ્લૂટૂથ સક્ષમ થશે.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">અપડેટ ઉપલબ્ધ છે</translation> <translation id="2429753432712299108">Bluetooth ઉપકરણ "<ph name="DEVICE_NAME" />" ને જોડી બનાવવા માટે પરવાનગી જોઈએ છે. સ્વીકારતાં પહેલાં, કૃપા કરીને તે ઉપકરણ પર બતાવેલ આ પાસકીની પુષ્ટિ કરો: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">સૂચનાઓ</translation> <translation id="2484513351006226581">કીબોર્ડ લેઆઉટ સ્વિચ કરવા માટે <ph name="KEYBOARD_SHORTCUT" />ને દબાવો.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK ચાલુ છે</translation> <translation id="2532589005999780174">ઉચ્ચ કોન્ટ્રાસ્ટ મોડ</translation> <translation id="2575685495496069081">એકથી વધુ સાઇન ઇનને બંધ કરવામાં આવેલ છે</translation> +<translation id="2582112259361606227">અપડેટ કરવા માટે ફરી શરૂ કરો</translation> <translation id="2597972630681408282">રાત્રિ પ્રકાશ: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM કાર્ડ લૉક કરેલ છે</translation> <translation id="2653659639078652383">સબમિટ કરો</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">તમે તમારી સ્ક્રીનને શેર કરી રહ્યાં છો</translation> <translation id="2942516765047364088">શેલ્ફ સ્થિતી</translation> <translation id="2946119680249604491">કનેક્શન ઉમેરો</translation> +<translation id="2961963223658824723">કંઈક ખોટું થયું. થોડીવારમાં ફરીથી પ્રયાસ કરો.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> એ <ph name="DOMAIN" /> દ્વારા સંચાલિત સાર્વજનિક સત્ર છે</translation> <translation id="3000461861112256445">મૉનો ઑડિઓ</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">તળિયું</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">સંકુચિત કરો</translation> <translation id="3126069444801937830">અપડેટ કરવા માટે પુનઃપ્રારંભ કરો</translation> <translation id="3147142846278915599">લોન્ચર (એપ્લિકેશન્સને સમન્વયિત કરી રહ્યું છે..)</translation> <translation id="315116470104423982">મોબાઇલ ડેટા</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">લૉક</translation> <translation id="3798670284305777884">સ્પીકર (આંતરિક)</translation> +<translation id="380165613292957338">નમસ્કાર, હું કેવી રીતે સહાય કરી શકું?</translation> <translation id="3846575436967432996">કોઈ નેટવર્ક માહિતી ઉપલબ્ધ નથી</translation> <translation id="385051799172605136">પાછળ</translation> <translation id="3891340733213178823">સાઇન આઉટ કરવા માટે બે વાર Ctrl+Shift+Q દબાવો.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C ઉપકરણ (જમણી બાજુનું પાછળનું પોર્ટ)</translation> <translation id="4017989525502048489">લેઝર પૉઇન્ટર</translation> <translation id="4072264167173457037">મધ્યમ સિગ્નલ</translation> +<translation id="4200057768455216496">તમે ડૉક કરેલ મૅગ્નિફાયર માટેનો શૉર્ટકટ દબાવેલ છે. શું તમે તે ચાલુ કરવા માગો છો?</translation> <translation id="4279490309300973883">પ્રતિબિંબત થઈ રહ્યું છે</translation> <translation id="4321179778687042513">ctrl</translation> <translation id="4331809312908958774">Chrome OS</translation> @@ -187,6 +195,7 @@ <translation id="4890187583552566966">તમારા વ્યવસ્થાપકે Google સહાયક બંધ કરેલું છે.</translation> <translation id="4895488851634969361">બેટરી સંપૂર્ણ છે.</translation> <translation id="4905614135390995787">હાઇ કોન્ટ્રાસ્ટ મોડને ટૉગલ કરવાનો શૉર્ટકટ બદલાઇ ગયો છો. <ph name="OLD_SHORTCUT" />ને બદલે કૃપા કરીને <ph name="NEW_SHORTCUT" />નો ઉપયોગ કરો.</translation> +<translation id="4917385247580444890">સશક્ત</translation> <translation id="4918086044614829423">સ્વીકારો</translation> <translation id="4961318399572185831">સ્ક્રીનને કાસ્ટ કરો</translation> <translation id="5136175204352732067">અલગ કીબોર્ડ કનેક્ટ કર્યું</translation> @@ -210,7 +219,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">બોલાયેલ પ્રતિસાદને અક્ષમ કરવા માટે Ctrl + Alt + Z દબાવો.</translation> <translation id="5648021990716966815">માઇક જેક</translation> +<translation id="5669267381087807207">સક્રિય કરી રહ્યું છે</translation> <translation id="5673434351075758678">તમારી સેટિંગને સિંક કર્યા પછી "<ph name="FROM_LOCALE" />" થી "<ph name="TO_LOCALE" />"માં ફેરવો.</translation> +<translation id="574392208103952083">મધ્યમ</translation> <translation id="5744083938413354016">ખેંચવાને ટૅપ કરો</translation> <translation id="5777841717266010279">સ્ક્રીન શેરિંગ રોકીએ?</translation> <translation id="57838592816432529">અવાજ બંધ કરો</translation> @@ -255,6 +266,7 @@ <translation id="6452181791372256707">નકારો</translation> <translation id="6453179446719226835">ભાષા બદલવામાં આવી છે</translation> <translation id="6459472438155181876">સ્ક્રીનને <ph name="DISPLAY_NAME" /> પર વિસ્તૃત કરી રહ્યાં છે</translation> +<translation id="6482559668224714696">પૂર્ણ-સ્ક્રીન મૅગ્નિફાયર</translation> <translation id="6490471652906364588">USB-C ઉપકરણ (જમણું પોર્ટ)</translation> <translation id="6501401484702599040"><ph name="RECEIVER_NAME" /> પર સ્ક્રીન કાસ્ટ કરી રહ્યાં છીએ</translation> <translation id="6521655319214113338">હસ્તલેખન ઇનપુટ</translation> @@ -279,17 +291,20 @@ <translation id="6820676911989879663">વિરામ લો!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">સક્રિય કરો <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">આ અપડેટ માટે તમારા ઉપકરણને પાવરવોશ કરવું જરૂરી છે. નવીનતમ <ph name="SYSTEM_APP_NAME" /> અપડેટ વિશે વધુ જાણો.</translation> <translation id="6911468394164995108">અન્યથી જોડાઓ...</translation> <translation id="6981982820502123353">ઍક્સેસિબિલિટી</translation> <translation id="698231206551913481">આ વપરાશકર્તા દૂર કરી દેવામાં આવે તે પછી આ વપરાશકર્તા સાથે સંકળાયેલ તમામ ફાઇલો અને સ્થાનિક ડેટા કાયમીરૂપે કાઢી નાખવામાં આવશે.</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" /> વાગ્યે પાછા આવો.</translation> <translation id="7029814467594812963">સત્રમાંથી બહાર નીકળો</translation> <translation id="7034339000180558234"><ph name="RECEIVER_NAME" /> પર <ph name="TAB_NAME" /> ને કાસ્ટ કરી રહ્યાં છીએ</translation> +<translation id="7037152028959403492">તમે હાઇ કોન્ટ્રાસ્ટ માટેનો શૉર્ટકટ દબાવેલ છે. શું તમે તે ચાલુ કરવા માગો છો?</translation> <translation id="7066646422045619941">આ નેટવર્ક તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ છે.</translation> <translation id="7067196344162293536">સ્વતઃ ફેરવો</translation> <translation id="7076293881109082629">સાઇન ઇન કરી રહ્યું છે</translation> <translation id="7098389117866926363">USB-C ઉપકરણ (પાછળની બાજુએ ડાબું પોર્ટ)</translation> <translation id="7131634465328662194">તમે આપમેળે સાઇન આઉટ થઈ જશો.</translation> +<translation id="7143207342074048698">કનેક્ટ કરી રહ્યું છે</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">જૂના રિઝોલ્યુશન પર પાછા ફરી રહ્યાં છે <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">પાછળનો માઇક્રોફોન</translation> @@ -334,9 +349,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> થી કનેક્ટેડ છે</translation> <translation id="813913629614996137">પ્રારંભ કરી રહ્યું છે...</translation> <translation id="8142699993796781067">ખાનગી નેટવર્ક</translation> +<translation id="8152119955266188852">તમે પૂર્ણ-સ્ક્રીન મૅગ્નિફાયર માટેનો શૉર્ટકટ દબાવેલ છે. શું તમે તે ચાલુ કરવા માગો છો?</translation> <translation id="8180896103888046100">અજાણ્યાં પ્રાપ્તકર્તા પર કાસ્ટ કરવાનું રોકો</translation> <translation id="8190698733819146287">ભાષાઓ અને ઇનપુટને કસ્ટમાઇઝ કરો...</translation> <translation id="8261506727792406068">કાઢી નાખો</translation> +<translation id="8297006494302853456">નબળું</translation> <translation id="8308637677604853869">પહેલાનું મેનૂ</translation> <translation id="8351131234907093545">નોંધ બનાવો</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> માટે વિકલ્પો મેનૂ</translation> @@ -364,12 +381,14 @@ <translation id="8841375032071747811">પાછળ બટન</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">ઍપ સ્ક્રીન-વિભાજનને સહાય કરતી નથી.</translation> +<translation id="8874184842967597500">કનેક્ટેડ નથી</translation> <translation id="8878886163241303700">સ્ક્રીનને વિસ્તૃત કરી રહ્યું છે</translation> <translation id="8921624153894383499">Google સહાયક આ ભાષા બોલતું નથી.</translation> <translation id="8938800817013097409">USB-C ઉપકરણ (પાછળની બાજુએ જમણું પોર્ટ)</translation> <translation id="8940956008527784070">બૅટરી ઓછી (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">ઝડપી લૉન્ચ</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> દ્વારા સંચાલિત</translation> +<translation id="9029474291399787231">Adobe Flash Player અપડેટ ઉપલબ્ધ છે</translation> <translation id="9033907480196064950">તમે હાલમાં <ph name="TAB_NAME" />ને કાસ્ટ કરી રહ્યા છો</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -382,6 +401,7 @@ <translation id="9194617393863864469">અન્ય વપરાશકર્તા સાઇન ઇન કરો...</translation> <translation id="9201131092683066720">બેટરી <ph name="PERCENTAGE" /> % પૂર્ણ છે.</translation> <translation id="9210037371811586452">એકીકૃત ડેસ્કટૉપ મોડથી બહાર નીકળે છે</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">વૉલપેપર સેટ કરો</translation> <translation id="923686485342484400">સાઇન આઉટ કરવા માટે બે વાર Control Shift Q દબાવો.</translation> <translation id="945522503751344254">પ્રતિસાદ મોકલો</translation>
diff --git a/ash/strings/ash_strings_hi.xtb b/ash/strings/ash_strings_hi.xtb index 7d7044f..d9e77ab4 100644 --- a/ash/strings/ash_strings_hi.xtb +++ b/ash/strings/ash_strings_hi.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C डिवाइस (सामने वाला पोर्ट)</translation> <translation id="1013923882670373915">ब्लूटूथ डिवाइस "<ph name="DEVICE_NAME" />" युग्मित करने की अनुमति चाहता है. कृपया उस डिवाइस पर यह पिन कोड डालें: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">स्टाइलस की बैटरी कम हो गई है</translation> +<translation id="1056775291175587022">कोई नेटवर्क नहीं</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">अलमारी को स्वत: छिपाएं</translation> <translation id="1153356358378277386">युग्मित डिवाइस</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">दाएं</translation> <translation id="1383876407941801731">खोज</translation> <translation id="1467432559032391204">बाएं</translation> +<translation id="1479743070547893297">चुनने के लिए अपने स्टाइलस से ड्रॉ करें</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">लॉन्चर</translation> <translation id="1525508553941733066">ख़ारिज करें</translation> @@ -27,7 +29,7 @@ <translation id="15373452373711364">बड़ा माउस कर्सर</translation> <translation id="1550523713251050646">अधिक विकल्पों के लिए क्लिक करें</translation> <translation id="1567387640189251553">आपके पिछली बार डाले गए पासवर्ड के बाद से एक अलग कीबोर्ड कनेक्ट किया गया है. यह आपके कीस्ट्रोक चुराने की कोशिश कर सकता है.</translation> -<translation id="1608626060424371292">इस उपयोगकर्ता को निकालें</translation> +<translation id="1608626060424371292">इस उपयोगकर्ता को हटाएं</translation> <translation id="1621499497873603021">बैटरी के खाली होने में शेष समय, <ph name="TIME_LEFT" /></translation> <translation id="1658406695958299976">माफ़ करें, आपके पासवर्ड की अभी भी पुष्टि नहीं हो पाई है. नोट: अगर आपने हाल ही में अपना पासवर्ड बदला है, तो आपके साइन आउट होते ही आपका नया पासवर्ड लागू हो जाएगा, कृपया यहां पुराने पासवर्ड का इस्तेमाल करें.</translation> <translation id="1677472565718498478"><ph name="TIME" /> शेष</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">अपनी भाषा सेट करें</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854"><ph name="SYSTEM_APP_NAME" /> के नए अपडेट के बारे में ज़्यादा जानें</translation> <translation id="1995660704900986789">पावर बंद करें</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">कोई मैसेज लिखें</translation> <translation id="2049639323467105390">यह डिवाइस <ph name="DOMAIN" /> द्वारा प्रबंधित है.</translation> <translation id="2050339315714019657">पोर्ट्रेट</translation> <translation id="2067602449040652523">कीबोर्ड की रोशनी</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">जारी रखें</translation> <translation id="2365393535144473978">मोबाइल डेटा सक्षम करने से ब्लूटूथ सक्षम हो जाएगा.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">अपडेट मौजूद है</translation> <translation id="2429753432712299108">ब्लूटूथ डिवाइस "<ph name="DEVICE_NAME" />" युग्मित करने की अनुमति चाहता है. स्वीकार करने से पहले, कृपया दुबारा पूछें कि यह पासकुंजी उस डिवाइस पर दिखाई जा रही है: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">अधिसूचनाएं</translation> <translation id="2484513351006226581">कीबोर्ड लेआउट स्विच करने के लिए <ph name="KEYBOARD_SHORTCUT" /> दबाएं.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK चालू है</translation> <translation id="2532589005999780174">उच्च कंट्रास्ट मोड</translation> <translation id="2575685495496069081">एक से ज़्यादा 'साइन इन' को बंद कर दिया गया है</translation> +<translation id="2582112259361606227">अपडेट करने के लिए रीस्टार्ट करें</translation> <translation id="2597972630681408282">नाइट लाइट: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">सिम कार्ड लॉक है</translation> <translation id="2653659639078652383">सबमिट करें</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">आप अपनी स्क्रीन शेयर कर रहे हैं</translation> <translation id="2942516765047364088">अलमारी की स्थिति</translation> <translation id="2946119680249604491">कनेक्शन जोड़ें</translation> +<translation id="2961963223658824723">कुछ गड़बड़ी हो गई. कुछ सेकंड में फिर से कोशिश करें.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" />, <ph name="DOMAIN" /> के द्वारा प्रबंधित एक सार्वजनिक सत्र है</translation> <translation id="3000461861112256445">मोनो ऑडियो</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">नीचे</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (ब्लूटूथ)</translation> -<translation id="3112378005171663295">संक्षिप्त करें</translation> <translation id="3126069444801937830">अपडेट करने के लिए पुनरारंभ करें</translation> <translation id="3147142846278915599">लॉन्चर (ऐप्स समन्वयित किए जा रहे हैं...)</translation> <translation id="315116470104423982">मोबाइल डेटा</translation> @@ -148,6 +154,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">लॉक करें</translation> <translation id="3798670284305777884">स्पीकर (आंतरिक)</translation> +<translation id="380165613292957338">नमस्ते, मैं आपके लिए क्या कर सकती हूं?</translation> <translation id="3846575436967432996">कोई नेटवर्क जानकारी उपलब्ध नहीं</translation> <translation id="385051799172605136">वापस</translation> <translation id="3891340733213178823">साइन आउट करने के लिए दो बार Ctrl+Shift+Q दबाएं.</translation> @@ -160,6 +167,7 @@ <translation id="3995138139523574647">USB-C डिवाइस (दायां पिछला पोर्ट)</translation> <translation id="4017989525502048489">लेज़र पॉइंटर</translation> <translation id="4072264167173457037">मध्यम सिग्नल</translation> +<translation id="4200057768455216496">आपने डॉक किए हुए आवर्धक का शॉर्टकट दबाया है. क्या आप इसे चालू करना चाहते हैं?</translation> <translation id="4217571870635786043">लिखवाना</translation> <translation id="4279490309300973883">मिरर करना</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">आपके एडमिन ने Google Assistant को बंद कर दिया है.</translation> <translation id="4895488851634969361">बैटरी भरी हुई है.</translation> <translation id="4905614135390995787">उच्च कंट्रास्ट मोड को टॉगल करने का शॉर्टकट बदल गया है. कृपया<ph name="OLD_SHORTCUT" /> के बजाय <ph name="NEW_SHORTCUT" /> का उपयोग करें.</translation> +<translation id="4917385247580444890">सशक्त</translation> <translation id="4918086044614829423">स्वीकार करें</translation> <translation id="4961318399572185831">स्क्रीन कास्ट करें</translation> <translation id="5136175204352732067">अलग कीबोर्ड कनेक्ट किया गया</translation> @@ -199,7 +208,7 @@ <translation id="523505283826916779">पहुंच-योग्यता विकल्प</translation> <translation id="5313326810920013265">ब्लूटूथ सेटिंग</translation> <translation id="5331975486040154427">USB-C डिवाइस (बायां पिछला पोर्ट)</translation> -<translation id="5397578532367286026">इस उपयोगकर्ता के उपयोग और इतिहास की प्रबंधक (<ph name="MANAGER_EMAIL" />) द्वारा chrome.com पर समीक्षा की जा सकती है.</translation> +<translation id="5397578532367286026">chrome.com पर इस उपयोगकर्ता के उपयोग और इतिहास से जुड़ी जानकारी की प्रबंधक (<ph name="MANAGER_EMAIL" />) समीक्षा कर सकता है.</translation> <translation id="5430931332414098647">इंस्टैंट टेदरिंग</translation> <translation id="5431825016875453137">OpenVPN / L2TP</translation> <translation id="544691375626129091">सभी उपलब्ध उपयोगकर्ता पहले से इस सत्र में जोड़ दिए गए हैं.</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">बोलकर दिया गया फ़ीडबैक बंद करने के लिए Ctrl + Alt + Z दबाएं.</translation> <translation id="5648021990716966815">माइक जैक</translation> +<translation id="5669267381087807207">सक्रिय कर रहा है</translation> <translation id="5673434351075758678">अपनी सेटिंग सिंक करने के बाद "<ph name="FROM_LOCALE" />" से "<ph name="TO_LOCALE" />".</translation> +<translation id="574392208103952083">मध्यम</translation> <translation id="5744083938413354016">टैप करके खींचना</translation> <translation id="5777841717266010279">स्क्रीन साझाकरण बंद करें?</translation> <translation id="57838592816432529">म्यूट करें</translation> @@ -245,7 +256,7 @@ <translation id="607652042414456612">आपका कंप्यूर आस-पास के ब्लूटूथ डिवाइस के लिए खोजे जाने योग्य है और वह "<ph name="NAME" />" के रूप में <ph name="ADDRESS" /> पते के साथ दिखाई देगा</translation> <translation id="6106745654298855237"><ph name="POWER_SOURCE" /> चार्ज हो रहा है</translation> <translation id="615957422585914272">ऑन-स्क्रीन कीबोर्ड दिखाएं</translation> -<translation id="6164005077879661055">इस निगरानी में रखे गए उपयोगकर्ता को निकाले जाने के बाद, निगरानी में रखे गए उपयोगकर्ता से संबद्ध सभी फ़ाइलें और स्थानीय डेटा को स्थायी रूप से हटा दिया जाएगा. प्रबंधक द्वारा अब भी इस निगरानी में रखे गए उपयोगकर्ता द्वारा देखी गईं वेबसाइटें और सेटिंग <ph name="MANAGEMENT_URL" /> पर देखी जा सकेंगी.</translation> +<translation id="6164005077879661055">'निगरानी में रखे गए इस उपयोगकर्ता' को हटाने के बाद, निगरानी में रखे गए उपयोगकर्ता से जुड़ीं सभी फ़ाइलें और 'स्थानीय डेटा' हमेशा के लिए मिट जाएंगे. 'निगरानी में रखे गए इस उपयोगकर्ता' की देखी गईं वेबसाइटें और सेटिंग <ph name="MANAGEMENT_URL" /> पर प्रबंधक को अब भी दिखेंगी.</translation> <translation id="6165508094623778733">अधिक जानें</translation> <translation id="6267036997247669271"><ph name="NAME" />: सक्रिय हो रहा है...</translation> <translation id="6284232397434400372">रिज़ॉल्यूशन बदला गया</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">अस्वीकार करें</translation> <translation id="6453179446719226835">भाषा बदल दी गई है</translation> <translation id="6459472438155181876"><ph name="DISPLAY_NAME" /> पर स्क्रीन विस्तृत कर रहा है</translation> +<translation id="6482559668224714696">फ़ुल-स्क्रीन पर सामग्री को बड़ा दिखाने वाला</translation> <translation id="6490471652906364588">USB-C डिवाइस (दायां पोर्ट)</translation> <translation id="6501401484702599040">स्क्रीन को <ph name="RECEIVER_NAME" /> पर कास्ट किया जा रहा है</translation> <translation id="6521655319214113338">हस्तलेखन इनपुट</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">आज के लिए इतना ही!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> को सक्रिय करें</translation> +<translation id="6910714959251846841">इस अपडेट के लिए आपके डिवाइस को पावरवॉश करना ज़रूरी है. <ph name="SYSTEM_APP_NAME" /> के नए अपडेट के बारे में ज़्यादा जानें.</translation> <translation id="6911468394164995108">अन्य में शामिल हों...</translation> <translation id="6981982820502123353">पहुंच क्षमता</translation> -<translation id="698231206551913481">इस उपयोगकर्ता को निकाल दिए जाने पर, इस उपयोगकर्ता से संबद्ध सभी फ़ाइलों और स्थानीय डेटा को स्थायी रूप से हटा दिया जाएगा.</translation> +<translation id="698231206551913481">इस उपयोगकर्ता को हटाए जाने पर, इससे जुड़ीं सभी फ़ाइलों और स्थानीय डेटा को हमेशा के लिए मिटा दिया जाएगा.</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" /> बजे फिर से देखें.</translation> <translation id="7029814467594812963">सत्र से बाहर निकलें</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> को <ph name="RECEIVER_NAME" /> पर कास्ट किया जा रहा है</translation> +<translation id="7037152028959403492">आपने हाई कंट्रास्ट का शॉर्टकट दबाया है. क्या आप इसे चालू करना चाहते हैं?</translation> <translation id="7066646422045619941">यह नेटवर्क आपके व्यवस्थापक द्वारा अक्षम किया गया है.</translation> <translation id="7067196344162293536">स्वत: घुमाएं</translation> <translation id="7076293881109082629">प्रवेश किया जा रहा है...</translation> <translation id="7098389117866926363">USB-C डिवाइस (पीछे बायां पोर्ट)</translation> <translation id="7131634465328662194">आप अपने आप साइन आउट कर जाएंगे.</translation> +<translation id="7143207342074048698">कनेक्ट हो रहा है</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" /> में पुराने रिज़ॉल्यूशन में वापस लौट रहा है</translation> <translation id="7256634071279256947">पीछे वाला माइक्रोफ़ोन</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> से कनेक्ट है</translation> <translation id="813913629614996137">शुरू हो रहा है...</translation> <translation id="8142699993796781067">निजी नेटवर्क</translation> +<translation id="8152119955266188852">आपने सामग्री को फ़ुल-स्क्रीन पर बड़ा दिखाने वाली सेवा का शॉर्टकट दबाया है. क्या आप इसे चालू करना चाहते हैं?</translation> <translation id="8180896103888046100">अज्ञात प्राप्तकर्ता को कास्ट करना बंद करें</translation> <translation id="8190698733819146287">भाषाएं और इनपुट कस्टमाइज़ करें...</translation> <translation id="8261506727792406068">हटाएं</translation> +<translation id="8297006494302853456">कमज़ोर</translation> <translation id="8308637677604853869">पिछला मेनू</translation> <translation id="8351131234907093545">नोट बनाएं</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> के लिए विकल्प मेनू</translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">वापस जाएं बटन</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">ऐप दो-स्क्रीन मोड में काम नहीं करता है.</translation> +<translation id="8874184842967597500">कनेक्ट नहीं है</translation> <translation id="8878886163241303700">स्क्रीन का विस्तार करना</translation> <translation id="8921624153894383499">Google Assistant सेवा इस भाषा में उपलब्ध नहीं है.</translation> <translation id="8938800817013097409">USB-C डिवाइस (पीछे की ओर दायां पोर्ट)</translation> <translation id="8940956008527784070">बैटरी कम (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">झटपट लॉन्च</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> द्वारा प्रबंधित</translation> +<translation id="9029474291399787231">Adobe Flash Player का अपडेट मौजूद है</translation> <translation id="9033907480196064950">आप इस समय <ph name="TAB_NAME" /> कास्ट कर रहे हैं</translation> <translation id="9074739597929991885">ब्लूटूथ</translation> <translation id="9079731690316798640">वाई-फ़ाई: <ph name="ADDRESS" /></translation> @@ -382,10 +401,11 @@ <translation id="9091626656156419976">प्रदर्शन <ph name="DISPLAY_NAME" /> निकाला जा रहा है</translation> <translation id="9111102763498581341">अनलॉक करें</translation> <translation id="9151726767154816831">अपडेट करने के लिए पुनः प्रारंभ करें और पावरवॉश करें</translation> -<translation id="9179259655489829027">यह फ़ीचर आपको पासवर्ड की ज़रूरत के बिना किसी भी साइन इन किए हुए उपयोगकर्ता को जल्दी से एक्सेस करने देता है. इस फ़ीचर का इस्तेमाल सिर्फ़ अपने भरोसेमंद खातों के साथ करें.</translation> -<translation id="9194617393863864469">किसी अन्य उपयोगकर्ता में प्रवेश करें...</translation> +<translation id="9179259655489829027">यह फ़ीचर आपको पासवर्ड के बिना किसी भी साइन इन किए हुए उपयोगकर्ता को जल्दी से एक्सेस करने देता है. इस फ़ीचर का इस्तेमाल सिर्फ़ अपने भरोसेमंद खातों के साथ करें.</translation> +<translation id="9194617393863864469">किसी अन्य उपयोगकर्ता में रूप में साइन इन करें...</translation> <translation id="9201131092683066720">बैटरी <ph name="PERCENTAGE" />% भरी हुई है.</translation> <translation id="9210037371811586452">संयुक्त डेस्कटॉप मोड से बाहर निकाला जा रहा है</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">वॉलपेपर सेट करें</translation> <translation id="923686485342484400">साइन आउट करने के लिए दो बार Control Shift Q दबाएं.</translation> <translation id="945522503751344254">सुझाव भेजें</translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb index 248f5af..a57b1ec 100644 --- a/ash/strings/ash_strings_hr.xtb +++ b/ash/strings/ash_strings_hr.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C uređaj (prednji priključak)</translation> <translation id="1013923882670373915">Bluetooth uređaj "<ph name="DEVICE_NAME" />" traži dopuštenje za uparivanje. Unesite ovaj PIN na tom uređaju: <ph name="PINCODE" />.</translation> <translation id="1032891413405719768">Baterija pisaljke gotovo je prazna</translation> +<translation id="1056775291175587022">Nema mreža</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Automatski sakrij policu</translation> <translation id="1153356358378277386">Upareni uređaji</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Donji</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Sažmi</translation> <translation id="3126069444801937830">Ponovo pokrenite za ažuriranje</translation> <translation id="3147142846278915599">Pokretač (sinkronizacija aplikacija...)</translation> <translation id="315116470104423982">Mobilni podaci</translation> @@ -197,6 +197,7 @@ <translation id="4890187583552566966">Vaš je administrator onemogućio Google asistent.</translation> <translation id="4895488851634969361">Baterija je puna.</translation> <translation id="4905614135390995787">Promijenio se prečac za uključivanje i isključivanje načina visokog kontrasta. Upotrebljavajte <ph name="NEW_SHORTCUT" /> umjesto <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Jak</translation> <translation id="4918086044614829423">Prihvati</translation> <translation id="4961318399572185831">Emitiranje zaslona</translation> <translation id="5136175204352732067">Povezana je neka druga tipkovnica</translation> @@ -220,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Pritisnite Ctrl + Alt + Z da biste onemogućili govorne povratne informacije.</translation> <translation id="5648021990716966815">Utičnica mikrofona</translation> +<translation id="5669267381087807207">Aktivacija</translation> <translation id="5673434351075758678">"<ph name="FROM_LOCALE" />" je promijenjen u "<ph name="TO_LOCALE" />" nakon sinkronizacije postavki.</translation> +<translation id="574392208103952083">Srednje</translation> <translation id="5744083938413354016">Povlačenje dodirom</translation> <translation id="5777841717266010279">Prekinuti dijeljenje zaslona?</translation> <translation id="57838592816432529">Isključi zvuk</translation> @@ -303,6 +306,7 @@ <translation id="7076293881109082629">Prijava</translation> <translation id="7098389117866926363">USB-C uređaj (lijevi priključak sa stražnje strane)</translation> <translation id="7131634465328662194">Odjavit ćete se automatski.</translation> +<translation id="7143207342074048698">Povezivanje</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Vraćanje na staru razlučivost za <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Stražnji mikrofon</translation> @@ -352,6 +356,7 @@ <translation id="8180896103888046100">Zaustavi emitiranje na nepoznatom prijamniku</translation> <translation id="8190698733819146287">Prilagodi jezike i unos...</translation> <translation id="8261506727792406068">Izbriši</translation> +<translation id="8297006494302853456">Slab</translation> <translation id="8308637677604853869">Prethodni izbornik</translation> <translation id="8351131234907093545">Izrada bilješke</translation> <translation id="8392451568018454956">Izbornik opcija za korisnika <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -379,6 +384,7 @@ <translation id="8841375032071747811">Gumb Natrag</translation> <translation id="8850991929411075241">Pretraživanje + Esc</translation> <translation id="8870509716567206129">Aplikacija ne podržava podijeljeni zaslon.</translation> +<translation id="8874184842967597500">Niste povezani</translation> <translation id="8878886163241303700">Produljenje zaslona</translation> <translation id="8921624153894383499">Google asistent ne govori taj jezik.</translation> <translation id="8938800817013097409">USB-C uređaj (desni priključak sa stražnje strane)</translation>
diff --git a/ash/strings/ash_strings_hu.xtb b/ash/strings/ash_strings_hu.xtb index 252b292..ca1bfdb 100644 --- a/ash/strings/ash_strings_hu.xtb +++ b/ash/strings/ash_strings_hu.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">C típusú USB-vel kompatibilis eszköz (elülső port)</translation> <translation id="1013923882670373915">A(z) „<ph name="DEVICE_NAME" />” Bluetooth-eszköz engedélyt kér a párosításra. Kérjük, adja meg ezt a PIN kódot azon az eszközön: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Az érintőceruza töltöttségi szintje alacsony</translation> +<translation id="1056775291175587022">Nincs hálózat</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Polc automatikus elrejtése</translation> <translation id="1153356358378277386">Párosított eszközök</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Jobbra</translation> <translation id="1383876407941801731">Keresés</translation> <translation id="1467432559032391204">Balra</translation> +<translation id="1479743070547893297">A kijelöléshez rajzoljon az érintőceruzával</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Indító</translation> <translation id="1525508553941733066">ELVETÉS</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Nyelv beállítása</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">További információ a legújabb <ph name="SYSTEM_APP_NAME" />-frissítésről</translation> <translation id="1995660704900986789">Kikapcsolás</translation> <translation id="2012624427112548395">Ctrl+Keresés+H</translation> +<translation id="2016340657076538683">Írja be az üzenetet</translation> <translation id="2049639323467105390">Ezt az eszközt a(z) <ph name="DOMAIN" /> domain kezeli.</translation> <translation id="2050339315714019657">Álló</translation> <translation id="2067602449040652523">Billentyűzet világossága</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Folytatás</translation> <translation id="2365393535144473978">A mobiladat-kapcsolat engedélyezésével a Bluetooth is bekapcsol.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Rendelkezésre áll frissítés</translation> <translation id="2429753432712299108">A(z) „<ph name="DEVICE_NAME" />” Bluetooth-eszköz engedélyt kér a párosításra. Mielőtt elfogadná, ellenőrizze, hogy ez a biztonsági kód látható-e azon az eszközön is: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Értesítések</translation> <translation id="2484513351006226581">A billentyűzetkiosztás átváltásához nyomja meg a(z) <ph name="KEYBOARD_SHORTCUT" /> billentyűparancsot.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">A CAPS LOCK be van kapcsolva</translation> <translation id="2532589005999780174">Nagy kontrasztú mód</translation> <translation id="2575685495496069081">A többfiókos bejelentkezés le van tiltva</translation> +<translation id="2582112259361606227">Újraindítás és frissítés</translation> <translation id="2597972630681408282">Éjszakai fény: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">A SIM-kártya zárolva van</translation> <translation id="2653659639078652383">Elküldés</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">A képernyője meg van osztva</translation> <translation id="2942516765047364088">Polc pozíciója</translation> <translation id="2946119680249604491">Kapcsolat hozzáadása</translation> +<translation id="2961963223658824723">Valami nem sikerült. Próbálja újra néhány másodperc múlva.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416">A(z) <ph name="DISPLAY_NAME" /> egy <ph name="DOMAIN" /> által kezelt nyilvános munkamenet</translation> <translation id="3000461861112256445">Monó hang</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Alja</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Listanézet</translation> <translation id="3126069444801937830">Indítsa újra a frissítéshez</translation> <translation id="3147142846278915599">Indító (alkalmazások szinkronizálása…)</translation> <translation id="315116470104423982">Mobiladatok</translation> @@ -148,6 +154,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Zárolás</translation> <translation id="3798670284305777884">Hangszóró (belső)</translation> +<translation id="380165613292957338">Üdvözlöm. Miben segíthetek?</translation> <translation id="3846575436967432996">Nem áll rendelkezésre hálózati információ</translation> <translation id="385051799172605136">Vissza</translation> <translation id="3891340733213178823">Nyomja meg a Ctrl+Shift+Q billentyűkombinációt kétszer a kijelentkezéshez.</translation> @@ -160,6 +167,7 @@ <translation id="3995138139523574647">C típusú USB-vel kompatibilis eszköz (jobb hátsó port)</translation> <translation id="4017989525502048489">Lézermutató</translation> <translation id="4072264167173457037">Közepes jel</translation> +<translation id="4200057768455216496">Lenyomta a dokkolt nagyító billentyűparancsát. Bekapcsolja a funkciót?</translation> <translation id="4217571870635786043">Diktálás</translation> <translation id="4279490309300973883">Tükrözés</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">A rendszergazda letiltotta a Google Segédet.</translation> <translation id="4895488851634969361">Az akkumulátor feltöltve.</translation> <translation id="4905614135390995787">Módosult a nagy kontrasztú mód billentyűparancsa. Használja a(z) <ph name="NEW_SHORTCUT" /> billentyűparancsot a(z) <ph name="OLD_SHORTCUT" /> helyett.</translation> +<translation id="4917385247580444890">Erős</translation> <translation id="4918086044614829423">Elfogadás</translation> <translation id="4961318399572185831">Képernyő átküldése</translation> <translation id="5136175204352732067">Új billentyűzet lett csatlakoztatva</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">A hangos visszajelzés kikapcsolásához nyomja meg a Ctrl+Alt+Z billentyűkombinációt.</translation> <translation id="5648021990716966815">Mikrofon jack csatlakozója</translation> +<translation id="5669267381087807207">Aktiválás</translation> <translation id="5673434351075758678">Módosítás <ph name="FROM_LOCALE" /> nyelvről <ph name="TO_LOCALE" /> nyelvre a beállítások szinkronizálása után.</translation> +<translation id="574392208103952083">Közepes</translation> <translation id="5744083938413354016">Érintéssel húzás</translation> <translation id="5777841717266010279">Leállítja a képernyőmegosztást?</translation> <translation id="57838592816432529">Némítás</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Elutasítás</translation> <translation id="6453179446719226835">A nyelv módosult</translation> <translation id="6459472438155181876">Képernyő kiterjesztése erre: <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Teljes képernyős nagyító</translation> <translation id="6490471652906364588">C típusú USB-vel kompatibilis eszköz (jobb oldali port)</translation> <translation id="6501401484702599040">Képernyő átküldése ide: <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Kézírásos bevitel</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Tartson egy kis szünetet!</translation> <translation id="683971173229319003">Keresés+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> aktiválása</translation> +<translation id="6910714959251846841">Eszköze frissítéséhez powerwash szükséges. További információ a legújabb <ph name="SYSTEM_APP_NAME" />-frissítésről.</translation> <translation id="6911468394164995108">Csatlakozás másik hálózathoz...</translation> <translation id="6981982820502123353">Kisegítő lehetőségek</translation> <translation id="698231206551913481">A felhasználó eltávolításakor az összes hozzá tartozó fájl és helyi adat is véglegesen törlődik.</translation> <translation id="7015766095477679451">Térjen vissza ekkor: <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Kilépés a munkamenetből</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> átküldése ide: <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Lenyomta a nagy kontraszt billentyűparancsát. Bekapcsolja a funkciót?</translation> <translation id="7066646422045619941">Ezt a hálózatot letiltotta a rendszergazda.</translation> <translation id="7067196344162293536">Automatikus forgatás</translation> <translation id="7076293881109082629">Bejelentkezés</translation> <translation id="7098389117866926363">C típusú USB-vel kompatibilis eszköz (bal hátsó port)</translation> <translation id="7131634465328662194">A rendszer automatikusan kijelentkezteti.</translation> +<translation id="7143207342074048698">Csatlakozás</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Visszaállítás a régi felbontásra <ph name="TIMEOUT_SECONDS" /> mp múlva</translation> <translation id="7256634071279256947">Hátulsó mikrofon</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Csatlakozás a következőhöz megtörtént: <ph name="NAME" /></translation> <translation id="813913629614996137">Indítás…</translation> <translation id="8142699993796781067">Privát hálózat</translation> +<translation id="8152119955266188852">Lenyomta a teljes képernyős nagyító billentyűparancsát. Bekapcsolja a funkciót?</translation> <translation id="8180896103888046100">Ismeretlen fogadó eszközre történő átküldés leállítása</translation> <translation id="8190698733819146287">Nyelvek és beviteli módok személyre szabása...</translation> <translation id="8261506727792406068">Törlés</translation> +<translation id="8297006494302853456">Gyenge</translation> <translation id="8308637677604853869">Előző menü</translation> <translation id="8351131234907093545">Jegyzet létrehozása</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> beállításainak menüje</translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Vissza gomb</translation> <translation id="8850991929411075241">Keresés+Esc</translation> <translation id="8870509716567206129">Az alkalmazás nem támogatja az osztott képernyős nézetet.</translation> +<translation id="8874184842967597500">Nincs csatlakozva</translation> <translation id="8878886163241303700">Kibővített képernyő</translation> <translation id="8921624153894383499">A Google Segéd nem beszél ezen a nyelven.</translation> <translation id="8938800817013097409">C típusú USB-vel kompatibilis eszköz (jobb hátsó port)</translation> <translation id="8940956008527784070">Alacsony akkumulátortöltöttség (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Gyorsindítás</translation> <translation id="8995603266996330174">Kezelő: <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Rendelkezésre áll az Adobe Flash Player frissítése</translation> <translation id="9033907480196064950">Folyamatban van a következő átküldése: <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Bejelentkezés másik felhasználóként…</translation> <translation id="9201131092683066720">Az akkumulátor töltöttsége: <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Kilépés az Egységes asztali módból</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Háttérkép beállítása</translation> <translation id="923686485342484400">Nyomja meg a Ctrl Shift Q billentyűkombinációt kétszer a kijelentkezéshez.</translation> <translation id="945522503751344254">Visszajelzés küldése</translation>
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb index 680f64e..c4309fd 100644 --- a/ash/strings/ash_strings_id.xtb +++ b/ash/strings/ash_strings_id.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Perangkat USB-C (port depan)</translation> <translation id="1013923882670373915">Perangkat Bluetooth "<ph name="DEVICE_NAME" />" meminta izin untuk bersanding. Masukan kode PIN ini pada perangkat tersebut: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Baterai stilus lemah</translation> +<translation id="1056775291175587022">Tidak ada jaringan</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Sembunyikan otomatis rak</translation> <translation id="1153356358378277386">Perangkat dihubungkan</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Bawah</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Ciutkan</translation> <translation id="3126069444801937830">Mulai ulang untuk memperbarui</translation> <translation id="3147142846278915599">Peluncur (menyinkronkan aplikasi...)</translation> <translation id="315116470104423982">Data seluler</translation> @@ -197,6 +197,7 @@ <translation id="4890187583552566966">Asisten Google dinonaktifkan oleh administrator</translation> <translation id="4895488851634969361">Baterai penuh.</translation> <translation id="4905614135390995787">Pintasan untuk beralih Mode Kontras Tinggi telah berubah. Gunakan <ph name="NEW_SHORTCUT" /> sebagai ganti <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Kuat</translation> <translation id="4918086044614829423">Terima</translation> <translation id="4961318399572185831">Transmisikan layar</translation> <translation id="5136175204352732067">Keyboard yang berbeda terhubung</translation> @@ -220,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Tekan Ctrl + Alt + Z untuk menonaktifkan masukan lisan.</translation> <translation id="5648021990716966815">Colokan mikrofon</translation> +<translation id="5669267381087807207">Mengaktifkan</translation> <translation id="5673434351075758678">Dari "<ph name="FROM_LOCALE" />" ke "<ph name="TO_LOCALE" />" setelah menyinkronkan setelan Anda.</translation> +<translation id="574392208103952083">Sedang</translation> <translation id="5744083938413354016">Tap tarik</translation> <translation id="5777841717266010279">Berhenti membagikan layar?</translation> <translation id="57838592816432529">Bisukan</translation> @@ -303,6 +306,7 @@ <translation id="7076293881109082629">Sedang masuk</translation> <translation id="7098389117866926363">Perangkat USB-C (port belakang sebelah kiri)</translation> <translation id="7131634465328662194">Anda akan logout otomatis.</translation> +<translation id="7143207342074048698">Menyambungkan</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Mengembalikan ke resolusi lama dalam <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Mikrofon belakang</translation> @@ -352,6 +356,7 @@ <translation id="8180896103888046100">Hentikan casting ke penerima tak dikenal</translation> <translation id="8190698733819146287">Sesuaikan bahasa dan masukan...</translation> <translation id="8261506727792406068">Hapus</translation> +<translation id="8297006494302853456">Lemah</translation> <translation id="8308637677604853869">Menu sebelumnya</translation> <translation id="8351131234907093545">Buat catatan</translation> <translation id="8392451568018454956">Menu opsi untuk <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -379,6 +384,7 @@ <translation id="8841375032071747811">Tombol kembali</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">Aplikasi tidak mendukung layar terpisah.</translation> +<translation id="8874184842967597500">Tidak tersambung</translation> <translation id="8878886163241303700">Memperluas layar</translation> <translation id="8921624153894383499">Asisten Google tidak berbicara dalam bahasa ini.</translation> <translation id="8938800817013097409">Perangkat USB-C (port belakang sebelah kanan)</translation>
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb index 7067c3b6c..8ac553a2 100644 --- a/ash/strings/ash_strings_it.xtb +++ b/ash/strings/ash_strings_it.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Dispositivo USB-C (porta anteriore)</translation> <translation id="1013923882670373915">Il dispositivo Bluetooth "<ph name="DEVICE_NAME" />" chiede l'autorizzazione per essere accoppiato. Inserisci questo codice PIN sul dispositivo: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Batteria dello stilo in esaurimento</translation> +<translation id="1056775291175587022">Nessuna rete</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Nascondi automaticamente shelf</translation> <translation id="1153356358378277386">Dispositivi accoppiati</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Destra</translation> <translation id="1383876407941801731">Cerca</translation> <translation id="1467432559032391204">Sinistra</translation> +<translation id="1479743070547893297">Disegna con la tua stilo per selezionare</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Avvio applicazioni</translation> <translation id="1525508553941733066">IGNORA</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Imposta la lingua</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Leggi ulteriori informazioni sull'ultimo aggiornamento di <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Spegni</translation> <translation id="2012624427112548395">CTRL + tasto per la ricerca + H</translation> +<translation id="2016340657076538683">Digita un messaggio</translation> <translation id="2049639323467105390">Questo dispositivo è gestito da <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Verticale</translation> <translation id="2067602449040652523">Luminosità della tastiera</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Continua</translation> <translation id="2365393535144473978">Se attivi i dati mobili verrà attivato anche il Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Aggiornamento disponibile</translation> <translation id="2429753432712299108">Il dispositivo Bluetooth "<ph name="DEVICE_NAME" />" chiede l'autorizzazione per essere accoppiato. Prima di accettare, conferma che questa passkey viene visualizzata sul dispositivo: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Notifiche</translation> <translation id="2484513351006226581">Premi <ph name="KEYBOARD_SHORTCUT" /> per cambiare il layout della tastiera.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">BLOC MAIUSC è attivo</translation> <translation id="2532589005999780174">Modalità ad alto contrasto</translation> <translation id="2575685495496069081">L'accesso simultaneo è stato disattivato</translation> +<translation id="2582112259361606227">Riavvia per aggiornare</translation> <translation id="2597972630681408282">Luminosità notturna: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">La scheda SIM è bloccata</translation> <translation id="2653659639078652383">Invia</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Stai condividendo lo schermo</translation> <translation id="2942516765047364088">Posizione shelf</translation> <translation id="2946119680249604491">Aggiungi connessione</translation> +<translation id="2961963223658824723">Si è verificato un problema. Riprova tra qualche secondo.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> è una sessione pubblica gestita da <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Audio in formato mono</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">maiusc</translation> <translation id="3087734570205094154">In basso</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Comprimi</translation> <translation id="3126069444801937830">Riavvia per aggiornare</translation> <translation id="3147142846278915599">Avvio applicazioni (sincronizzazione delle app...)</translation> <translation id="315116470104423982">Dati mobili</translation> @@ -148,6 +154,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Blocca</translation> <translation id="3798670284305777884">Altoparlante (interno)</translation> +<translation id="380165613292957338">Ciao, come posso aiutarti?</translation> <translation id="3846575436967432996">Nessuna informazione di rete disponibile</translation> <translation id="385051799172605136">Indietro</translation> <translation id="3891340733213178823">Premi due volte Ctrl+Maiusc+Q per uscire.</translation> @@ -160,6 +167,7 @@ <translation id="3995138139523574647">Dispositivo USB-C (porta posteriore destra)</translation> <translation id="4017989525502048489">Puntatore laser</translation> <translation id="4072264167173457037">Segnale medio</translation> +<translation id="4200057768455216496">Hai premuto la scorciatoia per la lente d'ingrandimento ancorata. Vuoi attivarla?</translation> <translation id="4217571870635786043">Dettatura</translation> <translation id="4279490309300973883">Mirroring</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">L'Assistente Google è stato disattivato dall'amministratore.</translation> <translation id="4895488851634969361">La batteria è carica.</translation> <translation id="4905614135390995787">La scorciatoia per attivare/disattivare la modalità ad alto contrasto è cambiata. Usa <ph name="NEW_SHORTCUT" /> anziché <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Forte</translation> <translation id="4918086044614829423">Accetto</translation> <translation id="4961318399572185831">Trasmetti schermo</translation> <translation id="5136175204352732067">Tastiera diversa collegata</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Premi CTRL + ALT + Z per disattivare la funzione di lettura vocale.</translation> <translation id="5648021990716966815">Jack per microfono</translation> +<translation id="5669267381087807207">In fase di attivazione</translation> <translation id="5673434351075758678">Da "<ph name="FROM_LOCALE" />" a "<ph name="TO_LOCALE" />" dopo la sincronizzazione delle impostazioni.</translation> +<translation id="574392208103952083">Medie</translation> <translation id="5744083938413354016">Trascinamento al tocco</translation> <translation id="5777841717266010279">Interrompere la condivisione dello schermo?</translation> <translation id="57838592816432529">Disattiva audio</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Rifiuto</translation> <translation id="6453179446719226835">La lingua è stata modificata</translation> <translation id="6459472438155181876">Estensione dello schermo su <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Lente d'ingrandimento a schermo intero</translation> <translation id="6490471652906364588">Dispositivo USB-C (porta a destra)</translation> <translation id="6501401484702599040">Trasmissione dello schermo a <ph name="RECEIVER_NAME" /> in corso</translation> <translation id="6521655319214113338">Scrittura a mano libera</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Fai una pausa!</translation> <translation id="683971173229319003">Tasto di ricerca+L</translation> <translation id="6857811139397017780">Attiva <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Questo aggiornamento richiede il powerwash del dispositivo. Leggi ulteriori informazioni sull'ultimo aggiornamento di <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Connetti a un'altra...</translation> <translation id="6981982820502123353">Accessibilità</translation> <translation id="698231206551913481">Tutti i file e i dati locali associati a questo utente verranno eliminati definitivamente in seguito alla rimozione dell'utente.</translation> <translation id="7015766095477679451">Ritorna alle ore <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Esci da sessione</translation> <translation id="7034339000180558234">Trasmissione di <ph name="TAB_NAME" /> a <ph name="RECEIVER_NAME" /> in corso</translation> +<translation id="7037152028959403492">Hai premuto la scorciatoia per l'alto contrasto. Vuoi attivarlo?</translation> <translation id="7066646422045619941">Questa rete è stata disattivata dall'amministratore.</translation> <translation id="7067196344162293536">Ruota in modo automatico</translation> <translation id="7076293881109082629">Accesso</translation> <translation id="7098389117866926363">Dispositivo USB-C (porta posteriore sinistra)</translation> <translation id="7131634465328662194">Verrai disconnesso automaticamente.</translation> +<translation id="7143207342074048698">Connessione</translation> <translation id="7165278925115064263">ALT + MAIUSC + K</translation> <translation id="7168224885072002358">Ripristino della risoluzione precedente tra <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Microfono posteriore</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Connesso a <ph name="NAME" /></translation> <translation id="813913629614996137">Inizializzazione...</translation> <translation id="8142699993796781067">Rete privata</translation> +<translation id="8152119955266188852">Hai premuto la scorciatoia per la lente d'ingrandimento a schermo intero. Vuoi attivarla?</translation> <translation id="8180896103888046100">Interrompi la trasmissione su ricevitore sconosciuto</translation> <translation id="8190698733819146287">Personalizza lingue e immissione...</translation> <translation id="8261506727792406068">Elimina</translation> +<translation id="8297006494302853456">Debole</translation> <translation id="8308637677604853869">Menu precedente</translation> <translation id="8351131234907093545">Crea nota</translation> <translation id="8392451568018454956">Menu Opzioni per <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Pulsante Indietro</translation> <translation id="8850991929411075241">Tasto di ricerca+ESC</translation> <translation id="8870509716567206129">L'app non supporta la modalità Schermo diviso.</translation> +<translation id="8874184842967597500">Non connessa</translation> <translation id="8878886163241303700">Estensione schermo</translation> <translation id="8921624153894383499">L'Assistente Google non parla questa lingua.</translation> <translation id="8938800817013097409">Dispositivo USB-C (porta posteriore destra)</translation> <translation id="8940956008527784070">Batteria in esaurimento (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Avvio rapido</translation> <translation id="8995603266996330174">Gestito da <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Aggiornamento di Adobe Flash Player disponibile</translation> <translation id="9033907480196064950">Al momento stai trasmettendo <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Accedi con un altro account utente...</translation> <translation id="9201131092683066720">Percentuale di caricamento della batteria: <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Uscita dalla modalità Desktop unificato</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Imposta sfondo</translation> <translation id="923686485342484400">Premi due volte Control Maiusc Q per uscire.</translation> <translation id="945522503751344254">Invia feedback</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb index afc03fa..d4c777f8 100644 --- a/ash/strings/ash_strings_iw.xtb +++ b/ash/strings/ash_strings_iw.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">מכשיר עם יציאת USB-C (יציאה קדמית)</translation> <translation id="1013923882670373915">מכשיר ה-Bluetooth "<ph name="DEVICE_NAME" />" מבקש הרשאה לבצע התאמה. הזן את קוד ה-PIN הבא במכשיר הזה: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">סוללת הסטיילוס חלשה</translation> +<translation id="1056775291175587022">אין רשתות</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">הסתרה אוטומטית של המדף</translation> <translation id="1153356358378277386">מכשירים מותאמים</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">ימינה</translation> <translation id="1383876407941801731">חפש</translation> <translation id="1467432559032391204">שמאלה</translation> +<translation id="1479743070547893297">כדי לבחור, צריך לצייר בעזרת הסטיילוס</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">מפעיל</translation> <translation id="1525508553941733066">סגור</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">בחירת שפה</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">מידע נוסף על העדכון האחרון של <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">כיבוי</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">כאן מקלידים את ההודעה</translation> <translation id="2049639323467105390">מכשיר זה מנוהל על ידי <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">לאורך</translation> <translation id="2067602449040652523">בהירות מקלדת</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">המשך</translation> <translation id="2365393535144473978">כשמפעילים את חבילת הגלישה, מופעלת גם תקשורת Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">יש עדכון זמין</translation> <translation id="2429753432712299108">מכשיר ה-Bluetooth "<ph name="DEVICE_NAME" />" מבקש הרשאה לבצע התאמה. לפני שתאשר, ודא שמפתח הסיסמה הבא מוצג במכשיר הזה: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">התראות</translation> <translation id="2484513351006226581">צריך להקיש על <ph name="KEYBOARD_SHORTCUT" /> כדי להחליף פריסת מקלדת.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK מופעל</translation> <translation id="2532589005999780174">מצב ניגודיות גבוהה</translation> <translation id="2575685495496069081">הכניסה עם מספר חשבונות הושבתה</translation> +<translation id="2582112259361606227">צריך להפעיל מחדש כדי לעדכן</translation> <translation id="2597972630681408282">תאורת לילה: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">כרטיס ה-SIM נעול</translation> <translation id="2653659639078652383">שלח</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">בחרת לשתף את המסך שלך</translation> <translation id="2942516765047364088">מיקום המדף</translation> <translation id="2946119680249604491">הוסף חיבור</translation> +<translation id="2961963223658824723">משהו השתבש. אפשר לנסות שוב בעוד כמה שניות.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> היא הפעלה ציבורית המנוהלת על ידי <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">אודיו במונו</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">תחתית</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">כווץ</translation> <translation id="3126069444801937830">הפעל מחדש כדי לעדכן</translation> <translation id="3147142846278915599">מפעיל היישומים (מסנכרן יישומים...)</translation> <translation id="315116470104423982">נתוני נייד</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">נעילה</translation> <translation id="3798670284305777884">רמקול (פנימי)</translation> +<translation id="380165613292957338">היי, איך אפשר לעזור?</translation> <translation id="3846575436967432996">אין מידע רשת זמין</translation> <translation id="385051799172605136">חזור</translation> <translation id="3891340733213178823">הקש פעמיים על Ctrl+Shift+Q כדי לצאת.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">מכשיר עם יציאת USB-C (יציאה ימנית-אחורית)</translation> <translation id="4017989525502048489">סמן לייזר</translation> <translation id="4072264167173457037">אות בינוני</translation> +<translation id="4200057768455216496">לחצת על מקש הקיצור של זכוכית מגדלת במצב עגינה. להפעיל אותה?</translation> <translation id="4217571870635786043">הכתבה</translation> <translation id="4279490309300973883">שיקוף</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google Assistant הושבת על-ידי מנהל המערכת.</translation> <translation id="4895488851634969361">הסוללה טעונה במלואה.</translation> <translation id="4905614135390995787">מקש הקיצור להפעלה או כיבוי של מצב ניגודיות גבוהה השתנה. השתמש ב-<ph name="NEW_SHORTCUT" /> במקום ב-<ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">חזק</translation> <translation id="4918086044614829423">אשר</translation> <translation id="4961318399572185831">העברת מסך</translation> <translation id="5136175204352732067">חוברה מקלדת אחרת</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">הקש על Ctrl + Alt + Z כדי להשבית את המשוב הקולי.</translation> <translation id="5648021990716966815">שקע מיקרופון</translation> +<translation id="5669267381087807207">מפעיל</translation> <translation id="5673434351075758678">מ"<ph name="FROM_LOCALE" />" ל"<ph name="TO_LOCALE" />" אחרי סנכרון ההגדרות.</translation> +<translation id="574392208103952083">בינוני</translation> <translation id="5744083938413354016">הקשה וגרירה</translation> <translation id="5777841717266010279">להפסיק את שיתוף המסך?</translation> <translation id="57838592816432529">השתק</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">דחה</translation> <translation id="6453179446719226835">שינוי השפה הסתיים</translation> <translation id="6459472438155181876">מרחיב את המסך אל <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">זכוכית מגדלת במסך מלא</translation> <translation id="6490471652906364588">מכשיר עם יציאת USB-C (יציאה ימנית)</translation> <translation id="6501401484702599040">מעביר את המסך אל <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">קלט בכתב-יד</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">הגיע הזמן להפסקה</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">הפעל את <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">כדי להתקין את העדכון הזה צריך לבצע Powerwash של המכשיר. אפשר לקרוא מידע נוסף על העדכון האחרון של <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">הצטרף לרשת אחרת...</translation> <translation id="6981982820502123353">נגישות</translation> <translation id="698231206551913481">כל הקבצים והנתונים המשויכים למשתמש זה יימחקו לצמיתות ברגע שהמשתמש יוסר.</translation> <translation id="7015766095477679451">אפשר לחזור בשעה <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">צא מההפעלה</translation> <translation id="7034339000180558234">מעביר את <ph name="TAB_NAME" /> אל <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">לחצת על מקש הקיצור של ניגודיות גבוהה. להפעיל אותה?</translation> <translation id="7066646422045619941">מנהל המערכת השבית את הרשת הזו.</translation> <translation id="7067196344162293536">סיבוב אוטומטי</translation> <translation id="7076293881109082629">כניסה</translation> <translation id="7098389117866926363">מכשיר עם יציאת USB-C (יציאה שמאלית מאחור)</translation> <translation id="7131634465328662194">המערכת תוציא אותך מהחשבון באופן אוטומטי.</translation> +<translation id="7143207342074048698">מתחבר</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">חוזר לרזולוציה הקודמת בעוד <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">מיקרופון אחורי</translation> @@ -339,9 +354,11 @@ <translation id="8132793192354020517">מחובר ל<ph name="NAME" /></translation> <translation id="813913629614996137">מאתחל...</translation> <translation id="8142699993796781067">רשת פרטית</translation> +<translation id="8152119955266188852">לחצת על מקש הקיצור של זכוכית מגדלת במסך מלא. להפעיל אותה?</translation> <translation id="8180896103888046100">הפסק להעביר למקלט לא ידוע</translation> <translation id="8190698733819146287">התאם אישית שפה וקלט...</translation> <translation id="8261506727792406068">מחיקה</translation> +<translation id="8297006494302853456">חלש</translation> <translation id="8308637677604853869">התפריט הקודם</translation> <translation id="8351131234907093545">יצירת הערה</translation> <translation id="8392451568018454956">תפריט אפשרויות עבור <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -369,12 +386,14 @@ <translation id="8841375032071747811">לחצן 'הקודם'</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">האפליקציה אינה תומכת במסך מפוצל.</translation> +<translation id="8874184842967597500">לא מחובר</translation> <translation id="8878886163241303700">מסך מתרחב</translation> <translation id="8921624153894383499">Google Assistant לא מדבר בשפה הזאת.</translation> <translation id="8938800817013097409">מכשיר עם יציאת USB-C (יציאה ימנית מאחור)</translation> <translation id="8940956008527784070">סוללה חלשה (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">פתיחה מהירה</translation> <translation id="8995603266996330174">מנוהל על ידי <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">יש עדכון בשביל Adobe Flash Player</translation> <translation id="9033907480196064950">מתבצעת עכשיו העברה של הכרטיסייה <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -389,6 +408,7 @@ <translation id="9194617393863864469">הוסף משתמש אחר...</translation> <translation id="9201131092683066720">הסוללה טעונה ברמה של <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">יציאה ממצב Unified Desktop</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">הגדר טפט</translation> <translation id="923686485342484400">הקש פעמיים על Control Shift Q כדי לצאת.</translation> <translation id="945522503751344254"> שליחת משוב</translation>
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb index 6833599..ee94aff 100644 --- a/ash/strings/ash_strings_ja.xtb +++ b/ash/strings/ash_strings_ja.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C デバイス(前面のポート)</translation> <translation id="1013923882670373915">Bluetooth デバイス「<ph name="DEVICE_NAME" />」がペア設定の権限をリクエストしています。このデバイスに次の PIN コードを入力してください: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">タッチペンのバッテリー残量が少なくなっています</translation> +<translation id="1056775291175587022">ネットワークが見つかりません</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">シェルフを自動的に隠す</translation> <translation id="1153356358378277386">ペア設定されたデバイス</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">右</translation> <translation id="1383876407941801731">検索</translation> <translation id="1467432559032391204">左</translation> +<translation id="1479743070547893297">タッチペンを使って選択できます</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" />(HDMI / DP)</translation> <translation id="1510238584712386396">ランチャー</translation> <translation id="1525508553941733066">閉じる</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">言語を設定</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" />(USB)</translation> +<translation id="1993072747612765854"><ph name="SYSTEM_APP_NAME" /> の最新アップデートの詳細をご確認ください</translation> <translation id="1995660704900986789">電源を切る</translation> <translation id="2012624427112548395">Ctrl+検索+H</translation> +<translation id="2016340657076538683">メッセージを入力</translation> <translation id="2049639323467105390">この端末は <ph name="DOMAIN" /> によって管理されています。</translation> <translation id="2050339315714019657">縦</translation> <translation id="2067602449040652523">キーボードの明るさ</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">続行</translation> <translation id="2365393535144473978">モバイルデータ通信を有効にすると、Bluetooth も有効になります。</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">アップデートが利用可能</translation> <translation id="2429753432712299108">Bluetooth デバイス「<ph name="DEVICE_NAME" />」がペア設定の権限をリクエストしています。許可するにあたっては、このデバイスで次のパスキーが表示されることを確認してください: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">通知</translation> <translation id="2484513351006226581">キーボード レイアウトを切り替えるには <ph name="KEYBOARD_SHORTCUT" /> キーを押します。</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Caps Lock がオンになっています</translation> <translation id="2532589005999780174">ハイコントラスト モード</translation> <translation id="2575685495496069081">マルチログインは無効にされています</translation> +<translation id="2582112259361606227">再起動して更新</translation> <translation id="2597972630681408282">読書灯: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM カードはロックされています</translation> <translation id="2653659639078652383">送信</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">画面を共有中です</translation> <translation id="2942516765047364088">シェルフの位置</translation> <translation id="2946119680249604491">接続を追加</translation> +<translation id="2961963223658824723">エラーが発生しました。数秒後にもう一度お試しください。</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> は <ph name="DOMAIN" /> が管理する公開セッションです</translation> <translation id="3000461861112256445">モノラル音声</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">下</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" />(Bluetooth)</translation> -<translation id="3112378005171663295">折りたたむ</translation> <translation id="3126069444801937830">再起動して更新</translation> <translation id="3147142846278915599">ランチャー(アプリを同期中...)</translation> <translation id="315116470104423982">モバイル データ</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">ロック</translation> <translation id="3798670284305777884">スピーカー(内蔵)</translation> +<translation id="380165613292957338">はい、どんなご用でしょう?</translation> <translation id="3846575436967432996">利用可能なネットワーク情報がありません</translation> <translation id="385051799172605136">戻る</translation> <translation id="3891340733213178823">ログアウトするには、Ctrl+Shift+Q を 2 回押します。</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C デバイス(右奥のポート)</translation> <translation id="4017989525502048489">レーザー ポインタ</translation> <translation id="4072264167173457037">電波: 中程度</translation> +<translation id="4200057768455216496">拡大鏡(ドッキング)のショートカットを押しました。この機能をオンにしますか?</translation> <translation id="4217571870635786043">音声入力</translation> <translation id="4279490309300973883">ミラーリング</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google アシスタントは管理者によって無効にされています。</translation> <translation id="4895488851634969361">バッテリー残量: 満。</translation> <translation id="4905614135390995787">ハイ コントラスト モードを切り替えるショートカットが変わりました。これまでの <ph name="OLD_SHORTCUT" /> キーではなく <ph name="NEW_SHORTCUT" /> キーを使用してください。</translation> +<translation id="4917385247580444890">強い</translation> <translation id="4918086044614829423">承諾</translation> <translation id="4961318399572185831">画面をキャスト</translation> <translation id="5136175204352732067">別のキーボードが接続されています</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="DATE" /> (<ph name="SHORT_WEEKDAY" />)</translation> <translation id="5600837773213129531">音声フィードバックを無効にするには Ctrl+Alt+Z を押してください。</translation> <translation id="5648021990716966815">マイク差込口</translation> +<translation id="5669267381087807207">有効にしています</translation> <translation id="5673434351075758678">設定の同期後に「<ph name="FROM_LOCALE" />」から「<ph name="TO_LOCALE" />」に変更されました。</translation> +<translation id="574392208103952083">中</translation> <translation id="5744083938413354016">タップによるドラッグ</translation> <translation id="5777841717266010279">画面の共有を解除しますか?</translation> <translation id="57838592816432529">ミュート</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">拒否</translation> <translation id="6453179446719226835">言語が変更されました</translation> <translation id="6459472438155181876"><ph name="DISPLAY_NAME" /> へ画面を拡張しています</translation> +<translation id="6482559668224714696">拡大鏡(全画面)</translation> <translation id="6490471652906364588">USB-C デバイス(右側面のポート)</translation> <translation id="6501401484702599040">画面を <ph name="RECEIVER_NAME" /> にキャスト中</translation> <translation id="6521655319214113338">手書き入力</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">休憩の時間です!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> を有効にする</translation> +<translation id="6910714959251846841">このアップデートを適用するには端末で Powerwash を実行する必要があります。<ph name="SYSTEM_APP_NAME" /> の最新アップデートの詳細をご確認ください。</translation> <translation id="6911468394164995108">他のネットワークに接続...</translation> <translation id="6981982820502123353">ユーザー補助機能</translation> <translation id="698231206551913481">このユーザーを削除すると、このユーザーに関連付けられているファイルとローカルデータもすべて完全に削除されます。</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" /> になったら利用を再開できます。</translation> <translation id="7029814467594812963">セッションを終了</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> を <ph name="RECEIVER_NAME" /> にキャスト中</translation> +<translation id="7037152028959403492">ハイ コントラストのショートカットを押しました。この機能をオンにしますか?</translation> <translation id="7066646422045619941">このネットワークは管理者によって無効にされています。</translation> <translation id="7067196344162293536">自動回転</translation> <translation id="7076293881109082629">ログイン中</translation> <translation id="7098389117866926363">USB-C デバイス(背面左のポート)</translation> <translation id="7131634465328662194">制限時間になると自動的にログアウトします。</translation> +<translation id="7143207342074048698">接続中</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" /> 秒後に元の解像度に戻ります</translation> <translation id="7256634071279256947">後方のマイク</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> に接続しました</translation> <translation id="813913629614996137">初期化しています...</translation> <translation id="8142699993796781067">プライベート ネットワーク</translation> +<translation id="8152119955266188852">拡大鏡(全画面)のショートカットを押しました。この機能をオンにしますか?</translation> <translation id="8180896103888046100">不明な受信デバイスへのキャストを停止する</translation> <translation id="8190698733819146287">言語と入力方法をカスタマイズ...</translation> <translation id="8261506727792406068">削除</translation> +<translation id="8297006494302853456">弱い</translation> <translation id="8308637677604853869">前のメニュー</translation> <translation id="8351131234907093545">メモを作成</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> のオプション メニュー</translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">戻るボタン</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">アプリで分割画面がサポートされていません。</translation> +<translation id="8874184842967597500">未接続</translation> <translation id="8878886163241303700">画面を拡張しています</translation> <translation id="8921624153894383499">Google アシスタントはこの言語に対応していません。</translation> <translation id="8938800817013097409">USB-C デバイス(背面右のポート)</translation> <translation id="8940956008527784070">バッテリー残量: 少(<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">クイック起動</translation> <translation id="8995603266996330174">管理ドメイン: <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Adobe Flash Player のアップデートが利用可能</translation> <translation id="9033907480196064950">現在「<ph name="TAB_NAME" />」をキャストしています</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">別のユーザーとしてログイン...</translation> <translation id="9201131092683066720">バッテリー残量: <ph name="PERCENTAGE" />%。</translation> <translation id="9210037371811586452">デスクトップ統合モードの終了中</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">壁紙を設定</translation> <translation id="923686485342484400">ログアウトするには、Ctrl Shift Q を 2 回押します。</translation> <translation id="945522503751344254">フィードバックを送信</translation>
diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb index c3021eb..158d812 100644 --- a/ash/strings/ash_strings_kn.xtb +++ b/ash/strings/ash_strings_kn.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C ಸಾಧನ (ಮುಂದಿನ ಪೋರ್ಟ್)</translation> <translation id="1013923882670373915">ಬ್ಲೂಟೂತ್ ಸಾಧನವು "<ph name="DEVICE_NAME" />" ಜೋಡಣೆಗಾಗಿ ಅನುಮತಿಯನ್ನು ಬಯಸುತ್ತದೆ. ದಯವಿಟ್ಟು ಆ ಸಾಧನದಲ್ಲಿ ಈ PIN ಕೋಡ್ ನಮೂದಿಸಿ: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">ಸ್ಟೈಲಸ್ ಬ್ಯಾಟರಿ ಕಡಿಮೆಯಾಗಿದೆ</translation> +<translation id="1056775291175587022">ಯಾವುದೇ ನೆಟ್ವರ್ಕ್ಗಳಿಲ್ಲ</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">ಶೆಲ್ಫ್ ಅನ್ನು ಸ್ವಯಂಮರೆಮಾಡು</translation> <translation id="1153356358378277386">ಜೋಡಿ ಮಾಡಲಾದ ಸಾಧನಗಳು</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">ಬಲಕ್ಕೆ</translation> <translation id="1383876407941801731">ಹುಡುಕಾಟ</translation> <translation id="1467432559032391204">ಎಡಕ್ಕೆ</translation> +<translation id="1479743070547893297">ಆಯ್ಕೆ ಮಾಡಲು, ನಿಮ್ಮ ಸ್ಟೈಲಸ್ ಮೂಲಕ ಚಿತ್ರಿಸಿ</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">ಲಾಂಚರ್</translation> <translation id="1525508553941733066">ವಜಾಗೊಳಿಸಿ</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">ನಿಮ್ಮ ಭಾಷೆಯನ್ನು ಹೊಂದಿಸಿ</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">ಇತ್ತೀಚಿನ <ph name="SYSTEM_APP_NAME" /> ಅಪ್ಡೇಟ್ ಕುರಿತು ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ</translation> <translation id="1995660704900986789">ಪವರ್ ಆಫ್</translation> <translation id="2012624427112548395">Ctrl+ಹುಡುಕಾಟ+H</translation> +<translation id="2016340657076538683">ಸಂದೇಶವನ್ನು ಟೈಪ್ ಮಾಡಿ</translation> <translation id="2049639323467105390">ಈ ಸಾಧನವು <ph name="DOMAIN" /> ನಿಂದ ನಿರ್ವಹಿಸಲ್ಪಟ್ಟಿದೆ.</translation> <translation id="2050339315714019657">ಪೋಟ್ರೇಟ್</translation> <translation id="2067602449040652523">ಕೀಬೋರ್ಡ್ ಪ್ರಖರತೆ</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">ಮುಂದುವರಿಸು</translation> <translation id="2365393535144473978">ಮೊಬೈಲ್ ಡೇಟಾವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುವುದರಿಂದ ಬ್ಲೂಟೂತ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">ಅಪ್ಡೇಟ್ ಲಭ್ಯವಿದೆ</translation> <translation id="2429753432712299108">ಬ್ಲೂಟೂತ್ ಸಾಧನವು "<ph name="DEVICE_NAME" />" ಜೋಡಣೆಗಾಗಿ ಅನುಮತಿಯನ್ನು ಬಯಸುತ್ತದೆ. ಸಮ್ಮತಿಸುವುದಕ್ಕೂ ಮೊದಲು, ದಯವಿಟ್ಟು ಆ ಸಾಧನದಲ್ಲಿ ಈ ಪಾಸ್ಕೀಲಿಯನ್ನು ತೋರಿಸಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಾತರಿಪಡಿಸಿಕೊಳ್ಳಿ: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">ಸೂಚನೆಗಳು</translation> <translation id="2484513351006226581">ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಬದಲಾಯಿಸಲು <ph name="KEYBOARD_SHORTCUT" /> ಒತ್ತಿರಿ.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK ಆನ್ ಆಗಿದೆ</translation> <translation id="2532589005999780174">ಹೆಚ್ಚಿನ ಕಾಂಟ್ರಾಸ್ಟ್ ಮೋಡ್</translation> <translation id="2575685495496069081">ಬಹು ಸೈನ್-ಇನ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation> +<translation id="2582112259361606227">ಅಪ್ಡೇಟ್ ಮಾಡಲು, ಮರುಪ್ರಾರಂಭಿಸಿ</translation> <translation id="2597972630681408282">ನೈಟ್ ಲೈಟ್: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">ಸಿಮ್ ಕಾರ್ಡ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="2653659639078652383">ಸಲ್ಲಿಸು</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">ನಿಮ್ಮ ಪರದೆಯನ್ನು ನೀವು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಿರಿ</translation> <translation id="2942516765047364088">ಶೆಲ್ಫ್ ಸ್ಥಳ</translation> <translation id="2946119680249604491">ಸಂಪರ್ಕ ಸೇರಿಸಿ</translation> +<translation id="2961963223658824723">ಏನೋ ಸಮಸ್ಯೆಯಾಗಿದೆ. ಕೆಲವು ನಿಮಿಷಗಳಲ್ಲಿ ಮತ್ತೊಮ್ಮೆ ಪ್ರಯತ್ನಿಸಿ.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DOMAIN" /> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾದ ಸಾರ್ವಜನಿಕ ಸೆಶನ್ <ph name="DISPLAY_NAME" /> ಆಗಿದೆ</translation> <translation id="3000461861112256445">ಮೊನೊ ಆಡಿಯೊ</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">ಕೆಳಗೆ</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (ಬ್ಲೂಟೂತ್)</translation> -<translation id="3112378005171663295">ಸಂಕುಚಿಸಿ</translation> <translation id="3126069444801937830">ನವೀಕರಿಸಲು ಮರುಪ್ರಾರಂಭಿಸಿ</translation> <translation id="3147142846278915599">ಲಾಂಚರ್ (ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸಿಂಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ...)</translation> <translation id="315116470104423982">ಮೊಬೈಲ್ ಡೇಟಾ</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">ಲಾಕ್ ಮಾಡಿ</translation> <translation id="3798670284305777884">ಸ್ಪೀಕರ್ (ಆಂತರಿಕ)</translation> +<translation id="380165613292957338">ಹಾಯ್, ನಾನು ಹೇಗೆ ಸಹಾಯ ಮಾಡಬಹುದು?</translation> <translation id="3846575436967432996">ನೆಟ್ವರ್ಕ್ ಮಾಹಿತಿ ಲಭ್ಯವಿಲ್ಲ</translation> <translation id="385051799172605136">ಹಿಂದೆ</translation> <translation id="3891340733213178823">ಸೈನ್ ಔಟ್ ಮಾಡಲು Ctrl+Shift+Q ಅನ್ನು ಎರಡುಬಾರಿ ಒತ್ತಿರಿ.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C ಸಾಧನ (ಬಲ ಭಾಗದ ಹಿಂದಿನ ಪೋರ್ಟ್)</translation> <translation id="4017989525502048489">ಲೇಸರ್ ಪಾಯಿಂಟರ್</translation> <translation id="4072264167173457037">ಮಧ್ಯಮ ಸಿಗ್ನಲ್</translation> +<translation id="4200057768455216496">ಡಾಕ್ ಮಾಡಿದ ವರ್ಧಕದ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ನೀವು ಒತ್ತಿದಿರಿ. ಅದನ್ನು ಆನ್ ಮಾಡಲು ಬಯಸುವಿರಾ?</translation> <translation id="4217571870635786043">ಉಕ್ತಲೇಖನ</translation> <translation id="4279490309300973883">ಪ್ರತಿಬಿಂಬಿಸುವಿಕೆ</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು Google ಸಹಾಯಕವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ.</translation> <translation id="4895488851634969361">ಬ್ಯಾಟರಿ ತುಂಬಿದೆ.</translation> <translation id="4905614135390995787">ಹೆಚ್ಚು ಕಾಂಟ್ರಾಸ್ಟ್ ಮೋಡ್ ಅನ್ನು ಟಾಗಲ್ ಮಾಡಲು ಶಾರ್ಟ್ಕಟ್ ಬದಲಾಗಿದೆ. <ph name="OLD_SHORTCUT" /> ಬದಲಿಗೆ <ph name="NEW_SHORTCUT" /> ಅನ್ನು ಬಳಸಿ.</translation> +<translation id="4917385247580444890">ಪ್ರಬಲ</translation> <translation id="4918086044614829423">ಸಮ್ಮತಿಸು</translation> <translation id="4961318399572185831">ಪರದೆಯನ್ನು ಬಿತ್ತರಿಸಿ</translation> <translation id="5136175204352732067">ವಿವಿಧ ಕೀಬೋರ್ಡ್ ಸಂಪರ್ಕಗೊಂಡಿದೆ</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">ಮಾತಿನ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು Ctrl + Alt + Z ಒತ್ತಿ.</translation> <translation id="5648021990716966815">ಮೈಕ್ ಜ್ಯಾಕ್</translation> +<translation id="5669267381087807207">ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತಿದೆ</translation> <translation id="5673434351075758678">ನಿಮ್ಮ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಸಿಂಕ್ ಮಾಡಿದ ಬಳಿಕ "<ph name="FROM_LOCALE" />" ನಿಂದ "<ph name="TO_LOCALE" />" ಗೆ.</translation> +<translation id="574392208103952083">ಮಧ್ಯಮ</translation> <translation id="5744083938413354016">ಟ್ಯಾಪ್ ಎಳೆಯುವಿಕೆ</translation> <translation id="5777841717266010279">ಸ್ಕ್ರೀನ್ ಹಂಚಿಕೆ ನಿಲ್ಲಿಸುವುದೇ?</translation> <translation id="57838592816432529">ಮ್ಯೂಟ್</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">ತಿರಸ್ಕರಿಸಿ</translation> <translation id="6453179446719226835">ಭಾಷೆಯನ್ನು ಬದಲಿಸಲಾಗಿದೆ</translation> <translation id="6459472438155181876"><ph name="DISPLAY_NAME" /> ಗೆ ಪರದೆಯನ್ನು ವಿಸ್ತರಿಸಲಾಗುತ್ತಿದೆ</translation> +<translation id="6482559668224714696">ಪೂರ್ಣಪರದೆ ವರ್ಧಕ</translation> <translation id="6490471652906364588">USB-C ಸಾಧನ (ಬಲ ಪೋರ್ಟ್)</translation> <translation id="6501401484702599040">ಪರದೆಯನ್ನು <ph name="RECEIVER_NAME" /> ಗೆ ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ</translation> <translation id="6521655319214113338">ಕೈಬರಹ ಇನ್ಪುಟ್</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">ವಿರಾಮ ತೆಗೆದುಕೊಳ್ಳಿ!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">ಸಕ್ರಿಯಗೊಳಿಸಿ<ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">ಈ ಅಪ್ಡೇಟ್ಗಾಗಿ ನಿಮ್ಮ ಸಾಧನವನ್ನು ಪವರ್ವಾಷ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ. ಇತ್ತೀಚಿನ <ph name="SYSTEM_APP_NAME" /> ಅಪ್ಡೇಟ್ ಕುರಿತು ಇನ್ನಷ್ಟು ತಿಳಿದುಕೊಳ್ಳಿ.</translation> <translation id="6911468394164995108">ಇತರರನ್ನು ಸೇರಿ...</translation> <translation id="6981982820502123353">ಪ್ರವೇಶ</translation> <translation id="698231206551913481">ಒಮ್ಮೆ ಈ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಿದಾಗ ಈ ಬಳಕೆದಾರರೊಂದಿಗೆ ಸಂಯೋಜಿತವಾಗಿರುವ ಎಲ್ಲಾ ಫೈಲ್ಗಳು ಮತ್ತು ಸ್ಥಳೀಯ ಡೇಟಾವನ್ನು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸಲಾಗುತ್ತದೆ.</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" /> ಸಮಯಕ್ಕೆ ಹಿಂತಿರುಗಿ</translation> <translation id="7029814467594812963">ಸೆಶನ್ನಿಂದ ನಿರ್ಗಮಿಸಿ</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> ಅನ್ನು <ph name="RECEIVER_NAME" /> ಗೆ ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ</translation> +<translation id="7037152028959403492">ನೀವು ಅಧಿಕ ಕಾಂಟ್ರಾಸ್ಟ್ನ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಒತ್ತಿದಿರಿ. ಅದನ್ನು ಆನ್ ಮಾಡಲು ಬಯಸುವಿರಾ?</translation> <translation id="7066646422045619941">ಈ ನೆಟ್ವರ್ಕ್ ಅನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ.</translation> <translation id="7067196344162293536">ಸ್ವಯಂ ತಿರುಗಿಸು</translation> <translation id="7076293881109082629">ಸೈನ್ ಇನ್ ಮಾಡಲಾಗುತ್ತಿದೆ</translation> <translation id="7098389117866926363">USB-C ಸಾಧನ (ಹಿಂಭಾಗದಲ್ಲಿ ಎಡ ಪೋರ್ಟ್)</translation> <translation id="7131634465328662194">ನೀವು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೈನ್ಔಟ್ ಆಗುತ್ತೀರಿ.</translation> +<translation id="7143207342074048698">ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" /> ನಲ್ಲಿ ಹಳೆಯ ರೆಸಲ್ಯೂಷನ್ಗೆ ಹಿಂತಿರುಗಿಸಲಾಗುತ್ತಿದೆ</translation> <translation id="7256634071279256947">ಹಿಂಭಾಗದ ಮೈಕ್ರೊಫೋನ್</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ</translation> <translation id="813913629614996137">ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ...</translation> <translation id="8142699993796781067">ಖಾಸಗಿ ನೆಟ್ವರ್ಕ್</translation> +<translation id="8152119955266188852">ನೀವು ಪೂರ್ಣಪರದೆ ವರ್ಧಕದ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಒತ್ತಿದಿರಿ. ಅದನ್ನು ಆನ್ ಮಾಡಲು ಬಯಸುವಿರಾ?</translation> <translation id="8180896103888046100">ಅಪರಿಚಿತ ಸ್ವೀಕರಿಸುವವರಿಗೆ ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ</translation> <translation id="8190698733819146287">ಭಾಷೆಗಳು ಮತ್ತು ಇನ್ಪುಟ್ ಅನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ...</translation> <translation id="8261506727792406068">ಅಳಿಸಿ</translation> +<translation id="8297006494302853456">ದುರ್ಬಲ</translation> <translation id="8308637677604853869">ಹಿಂದಿನ ಮೆನು</translation> <translation id="8351131234907093545">ಟಿಪ್ಪಣಿ ರಚಿಸಿ</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> ಅವರಿಗಾಗಿ ಆಯ್ಕೆಗಳ ಮೆನು</translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">ಹಿಂದೆ ಬಟನ್</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ.</translation> +<translation id="8874184842967597500">ಸಂಪರ್ಕಗೊಳಿಸಿಲ್ಲ</translation> <translation id="8878886163241303700">ಪರದೆಯನ್ನು ವಿಸ್ತರಿಸಲಾಗುತ್ತಿದೆ</translation> <translation id="8921624153894383499">Google ಸಹಾಯಕವು ಈ ಭಾಷೆಯನ್ನು ಮಾತನಾಡುವುದಿಲ್ಲ.</translation> <translation id="8938800817013097409">USB-C ಸಾಧನ (ಹಿಂಭಾಗದಲ್ಲಿನ ಬಲ ಪೋರ್ಟ್)</translation> <translation id="8940956008527784070">ಬ್ಯಾಟರಿ ಕಡಿಮೆ (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">ಶೀಘ್ರ ಬಿಡುಗಡೆ</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> ನಿಂದ ನಿರ್ವಹಿಸಲಾಗಿದೆ</translation> +<translation id="9029474291399787231">Adobe Flash Player ಅಪ್ಡೇಟ್ ಲಭ್ಯವಿದೆ</translation> <translation id="9033907480196064950">ನೀವು ಪ್ರಸ್ತುತ <ph name="TAB_NAME" /> ಬಿತ್ತರಿಸುತ್ತಿದ್ದೀರಿ</translation> <translation id="9074739597929991885">ಬ್ಲೂಟೂತ್</translation> <translation id="9079731690316798640">ವೈ-ಫೈ: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">ಮತ್ತೊಂದು ಬಳಕೆದಾರರಾಗಿ ಸೈನ್ ಇನ್ ಮಾಡಿ...</translation> <translation id="9201131092683066720">ಬ್ಯಾಟರಿ <ph name="PERCENTAGE" />% ಪೂರ್ಣವಾಗಿದೆ.</translation> <translation id="9210037371811586452">ಏಕೀಕೃತ ಡೆಸ್ಕ್ಟಾಪ್ ಮೋಡ್ನಿಂದ ನಿರ್ಗಮಿಸಲಾಗುತ್ತಿದೆ</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">ವಾಲ್ಪೇಪರ್ ಹೊಂದಿಸಿ</translation> <translation id="923686485342484400">ಸೈನ್ ಔಟ್ ಮಾಡಲು Control Shift Q ಅನ್ನು ಎರಡುಬಾರಿ ಒತ್ತಿರಿ.</translation> <translation id="945522503751344254">ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಕಳುಹಿಸಿ</translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb index 1a52622..13a84980 100644 --- a/ash/strings/ash_strings_ko.xtb +++ b/ash/strings/ash_strings_ko.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C 기기(전면 포트)</translation> <translation id="1013923882670373915">블루투스 기기 '<ph name="DEVICE_NAME" />'에서 페어링 허가를 요청합니다. 기기에서 다음 PIN 코드를 입력하세요. <ph name="PINCODE" /></translation> <translation id="1032891413405719768">스타일러스 배터리 부족</translation> +<translation id="1056775291175587022">네트워크 없음</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">실행기 자동 숨김</translation> <translation id="1153356358378277386">페어링된 기기</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">오른쪽</translation> <translation id="1383876407941801731">검색</translation> <translation id="1467432559032391204">왼쪽</translation> +<translation id="1479743070547893297">선택하려면 스타일러스로 그림을 그리세요.</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" />(HDMI/DP)</translation> <translation id="1510238584712386396">런처</translation> <translation id="1525508553941733066">닫기</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">언어 설정</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" />(USB)</translation> +<translation id="1993072747612765854">최신 <ph name="SYSTEM_APP_NAME" /> 업데이트에 관해 자세히 알아보세요.</translation> <translation id="1995660704900986789">끄기</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">메시지 입력</translation> <translation id="2049639323467105390">기기는 <ph name="DOMAIN" />에서 관리합니다.</translation> <translation id="2050339315714019657">세로 방향</translation> <translation id="2067602449040652523">키보드 밝기</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">계속</translation> <translation id="2365393535144473978">모바일 데이터를 사용 설정하면 블루투스가 사용 설정됩니다.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">업데이트 가능</translation> <translation id="2429753432712299108">블루투스 기기 '<ph name="DEVICE_NAME" />'에서 페어링 허가를 요청합니다. 허가하기 전에 다음 패스키가 기기에 표시되는지 확인하세요. <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">알림</translation> <translation id="2484513351006226581">키보드 레이아웃을 전환하려면 <ph name="KEYBOARD_SHORTCUT" />을(를) 누르세요.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK이 켜져 있습니다.</translation> <translation id="2532589005999780174">고대비 모드</translation> <translation id="2575685495496069081">멀티 로그인이 사용 중지됨</translation> +<translation id="2582112259361606227">업데이트하려면 다시 시작</translation> <translation id="2597972630681408282">야간 조명: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM 카드가 잠겨 있습니다.</translation> <translation id="2653659639078652383">제출</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">화면 공유 중</translation> <translation id="2942516765047364088">실행기 위치</translation> <translation id="2946119680249604491">연결 추가</translation> +<translation id="2961963223658824723">문제가 발생했습니다. 잠시 후 다시 시도해 주세요.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" />은(는) <ph name="DOMAIN" />에서 관리하는 공개 세션입니다.</translation> <translation id="3000461861112256445">모노 오디오</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">Shift</translation> <translation id="3087734570205094154">맨 아래</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" />(블루투스)</translation> -<translation id="3112378005171663295">접기</translation> <translation id="3126069444801937830">업데이트하려면 다시 시작</translation> <translation id="3147142846278915599">런처(앱 동기화 중...)</translation> <translation id="315116470104423982">모바일 데이터</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">잠금</translation> <translation id="3798670284305777884">스피커(내부)</translation> +<translation id="380165613292957338">안녕하세요, 무엇을 도와드릴까요?</translation> <translation id="3846575436967432996">네트워크 정보 없음</translation> <translation id="385051799172605136">뒤로</translation> <translation id="3891340733213178823">로그아웃하려면 Ctrl+Shift+Q를 두 번 누릅니다.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C 기기(우측 후면 포트)</translation> <translation id="4017989525502048489">레이저 포인터</translation> <translation id="4072264167173457037">신호 보통</translation> +<translation id="4200057768455216496">고정 돋보기 단축키를 누르셨습니다. 사용 설정할까요?</translation> <translation id="4217571870635786043">음성기록</translation> <translation id="4279490309300973883">미러링</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">관리자가 Google 어시스턴트를 사용 중지했습니다.</translation> <translation id="4895488851634969361">배터리 충전이 완료되었습니다.</translation> <translation id="4905614135390995787">고대비 모드 전환 단축키가 변경되었습니다. <ph name="OLD_SHORTCUT" /> 대신 <ph name="NEW_SHORTCUT" />을(를) 사용하세요.</translation> +<translation id="4917385247580444890">강력</translation> <translation id="4918086044614829423">수락</translation> <translation id="4961318399572185831">화면 전송</translation> <translation id="5136175204352732067">다른 키보드 연결됨</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="DATE" /> <ph name="SHORT_WEEKDAY" /></translation> <translation id="5600837773213129531">음성 피드백을 사용 중지하려면 Ctrl + Alt + Z를 누르세요.</translation> <translation id="5648021990716966815">마이크 잭</translation> +<translation id="5669267381087807207">활성화 중</translation> <translation id="5673434351075758678">설정 동기화 후 ‘<ph name="FROM_LOCALE" />’에서 ‘<ph name="TO_LOCALE" />’(으)로 변경합니다.</translation> +<translation id="574392208103952083">보통</translation> <translation id="5744083938413354016">탭 드래그</translation> <translation id="5777841717266010279">화면 공유를 중단하시겠습니까?</translation> <translation id="57838592816432529">음소거</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">거부</translation> <translation id="6453179446719226835">언어가 변경됨</translation> <translation id="6459472438155181876">화면을 <ph name="DISPLAY_NAME" />(으)로 확장</translation> +<translation id="6482559668224714696">전체 화면 돋보기</translation> <translation id="6490471652906364588">USB-C 기기(오른쪽 포트)</translation> <translation id="6501401484702599040"><ph name="RECEIVER_NAME" />(으)로 화면 전송 중</translation> <translation id="6521655319214113338">필기 입력</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">잠시 쉬어 가세요.</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> 활성화</translation> +<translation id="6910714959251846841">업데이트하려면 기기에서 파워워시를 실행해야 합니다. 최신 <ph name="SYSTEM_APP_NAME" /> 업데이트에 관해 자세히 알아보세요.</translation> <translation id="6911468394164995108">다른 네트워크에 연결</translation> <translation id="6981982820502123353">접근성</translation> <translation id="698231206551913481">이 사용자를 제거하면 해당 사용자와 연결되어 있는 모든 파일 및 로컬 데이터가 영구적으로 삭제됩니다.</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" />에 다시 사용해 주세요.</translation> <translation id="7029814467594812963">세션 종료</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" />을(를) <ph name="RECEIVER_NAME" />(으)로 전송 중</translation> +<translation id="7037152028959403492">고대비 단축키를 누르셨습니다. 사용 설정할까요?</translation> <translation id="7066646422045619941">관리자가 사용 중지한 네트워크입니다.</translation> <translation id="7067196344162293536">자동 회전</translation> <translation id="7076293881109082629">로그인</translation> <translation id="7098389117866926363">USB-C 기기(좌측 후면 포트)</translation> <translation id="7131634465328662194">자동으로 로그아웃됩니다.</translation> +<translation id="7143207342074048698">연결 중</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" />초 후 기존 해상도로 돌아갑니다.</translation> <translation id="7256634071279256947">후면 마이크</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517"><ph name="NAME" />에 연결됨</translation> <translation id="813913629614996137">초기화 중...</translation> <translation id="8142699993796781067">사설 네트워크</translation> +<translation id="8152119955266188852">전체 화면 돋보기 단축키를 누르셨습니다. 사용 설정할까요?</translation> <translation id="8180896103888046100">알 수 없는 수신자로 전송 중지</translation> <translation id="8190698733819146287">언어 및 입력 설정...</translation> <translation id="8261506727792406068">삭제</translation> +<translation id="8297006494302853456">약함</translation> <translation id="8308637677604853869">이전 메뉴</translation> <translation id="8351131234907093545">메모 만들기</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" />의 옵션 메뉴</translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">뒤로 버튼</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">앱이 화면 분할을 지원하지 않습니다.</translation> +<translation id="8874184842967597500">연결되지 않음</translation> <translation id="8878886163241303700">화면 확대</translation> <translation id="8921624153894383499">Google 어시스턴트가 이 언어를 지원하지 않음</translation> <translation id="8938800817013097409">USB-C 기기(우측 후면 포트)</translation> <translation id="8940956008527784070">배터리 부족(<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">빠른 실행</translation> <translation id="8995603266996330174">관리자: <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Adobe Flash Player 업데이트 가능</translation> <translation id="9033907480196064950">현재 <ph name="TAB_NAME" />을(를) 전송하고 있습니다.</translation> <translation id="9074739597929991885">블루투스</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">다른 사용자로 로그인...</translation> <translation id="9201131092683066720">배터리가 <ph name="PERCENTAGE" />% 남았습니다.</translation> <translation id="9210037371811586452">통합 바탕화면 모드 종료 중</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">배경화면 설정</translation> <translation id="923686485342484400">로그아웃하려면 Ctrl+Shift+Q를 두 번 누릅니다.</translation> <translation id="945522503751344254">의견 보내기</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb index 7384c3b..13f5a48 100644 --- a/ash/strings/ash_strings_lt.xtb +++ b/ash/strings/ash_strings_lt.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C įrenginys (prievadas priekyje)</translation> <translation id="1013923882670373915">„Bluetooth“ įrenginys „<ph name="DEVICE_NAME" />“ prašo leidimo susieti. Šiame įrenginyje įveskite šį PIN kodą: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Rašiklio akumuliatorius senka</translation> +<translation id="1056775291175587022">Nėra tinklų</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Automatiškai slėpti lentyną</translation> <translation id="1153356358378277386">Susieti įrenginiai</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Apačia</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> („Bluetooth“)</translation> -<translation id="3112378005171663295">Sutraukti</translation> <translation id="3126069444801937830">Paleisti iš naujo, kad būtų atnaujinta</translation> <translation id="3147142846278915599">Paleidimo priemonė (sinchronizuojamos programos...)</translation> <translation id="315116470104423982">Duomenys mobiliesiems</translation> @@ -198,6 +198,7 @@ <translation id="4890187583552566966">„Google“ padėjėją išjungė administratorius.</translation> <translation id="4895488851634969361">Akumuliatorius visiškai įkrautas.</translation> <translation id="4905614135390995787">Spartusis klavišas, kurį naudojant perjungiamas didelio kontrasto režimas, pakeistas. Naudokite <ph name="NEW_SHORTCUT" /> vietoj <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Stiprus</translation> <translation id="4918086044614829423">Priimti</translation> <translation id="4961318399572185831">Perduoti ekraną</translation> <translation id="5136175204352732067">Prijungta kita klaviatūra</translation> @@ -221,7 +222,9 @@ <translation id="5597451508971090205"><ph name="DATE" />, <ph name="SHORT_WEEKDAY" /></translation> <translation id="5600837773213129531">Paspauskite „Ctrl“ + „Alt“ + Z, kad išjungtumėte ekrano skaitymą balsu.</translation> <translation id="5648021990716966815">Mikrofono jungtis</translation> +<translation id="5669267381087807207">Aktyvinama</translation> <translation id="5673434351075758678">Po nustatymų sinchronizavimo kalba pakeista iš „<ph name="FROM_LOCALE" />“ į „<ph name="TO_LOCALE" />“.</translation> +<translation id="574392208103952083">Vidutinis</translation> <translation id="5744083938413354016">Vilkimas palietus</translation> <translation id="5777841717266010279">Nutraukti ekrano bendrinimą?</translation> <translation id="57838592816432529">Nutildyti</translation> @@ -304,6 +307,7 @@ <translation id="7076293881109082629">Prisijungimas</translation> <translation id="7098389117866926363">USB-C įrenginys (prievadas kairėje, užpakalinėje dalyje)</translation> <translation id="7131634465328662194">Būsite automatiškai atjungti.</translation> +<translation id="7143207342074048698">Jungiama</translation> <translation id="7165278925115064263">„Alt“ + „Shift“ + K</translation> <translation id="7168224885072002358">Po <ph name="TIMEOUT_SECONDS" /> bus grąžinta sena skyra</translation> <translation id="7256634071279256947">Užpakalinis mikrofonas</translation> @@ -353,6 +357,7 @@ <translation id="8180896103888046100">Sustabdyti perdavimą į nežinomą imtuvą</translation> <translation id="8190698733819146287">Tinkinti kalbas ir įvestį...</translation> <translation id="8261506727792406068">Ištrinti</translation> +<translation id="8297006494302853456">Silpnas</translation> <translation id="8308637677604853869">Ankstesnis meniu</translation> <translation id="8351131234907093545">Sukurti užrašą</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> skirtų parinkčių meniu</translation> @@ -380,6 +385,7 @@ <translation id="8841375032071747811">Mygtukas „Atgal“</translation> <translation id="8850991929411075241">Paieškos klavišas + „Esc“</translation> <translation id="8870509716567206129">Programoje nepalaikomas skaidytas ekranas.</translation> +<translation id="8874184842967597500">Neprisijungta</translation> <translation id="8878886163241303700">Išplečiamas ekranas</translation> <translation id="8921624153894383499">„Google“ padėjėjas nekalba šia kalba.</translation> <translation id="8938800817013097409">USB-C įrenginys (prievadas dešinėje, užpakalinėje dalyje)</translation>
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb index 891615d..059baeb 100644 --- a/ash/strings/ash_strings_lv.xtb +++ b/ash/strings/ash_strings_lv.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C ierīce (priekšējā pieslēgvieta)</translation> <translation id="1013923882670373915">Bluetooth ierīce “<ph name="DEVICE_NAME" />” vēlas saņemt atļauju, lai izveidotu savienojumu pārī. Lūdzu, ierīcē ievadiet šo PIN: <ph name="PINCODE" />.</translation> <translation id="1032891413405719768">Skārienekrāna pildspalvas akumulatora līmenis ir zems</translation> +<translation id="1056775291175587022">Nav tīklu</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Automātiski slēpt plauktu</translation> <translation id="1153356358378277386">Pārī savienotās ierīces</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Pa labi</translation> <translation id="1383876407941801731">Meklēt</translation> <translation id="1467432559032391204">Pa kreisi</translation> +<translation id="1479743070547893297">Zīmējiet ar skārienekrāna pildspalvu, lai atlasītu</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Lietojumprogrammu palaidējs</translation> <translation id="1525508553941733066">NERĀDĪT</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Iestatiet savu valodu.</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Uzzināt vairāk par pēdējo <ph name="SYSTEM_APP_NAME" /> atjauninājumu</translation> <translation id="1995660704900986789">Izslēgt</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">Ierakstiet ziņojumu</translation> <translation id="2049639323467105390">Šo ierīci pārvalda vietne <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Portrets</translation> <translation id="2067602449040652523">Tastatūras spilgtums</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Turpināt</translation> <translation id="2365393535144473978">Iespējojot mobilos datus, tiks iespējots Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Ir pieejams atjauninājums</translation> <translation id="2429753432712299108">Bluetooth ierīce “<ph name="DEVICE_NAME" />” vēlas saņemt atļauju, lai izveidotu savienojumu pārī. Pirms piekrītat, lūdzu, pārliecinieties, vai ierīcē tiek parādīta šī ieejas atslēga: <ph name="PASSKEY" />.</translation> <translation id="2482878487686419369">Paziņojumi</translation> <translation id="2484513351006226581">Nospiediet īsinājumtaustiņu <ph name="KEYBOARD_SHORTCUT" />, lai pārslēgtu tastatūras izkārtojumu.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Funkcija Caps Lock ir ieslēgta</translation> <translation id="2532589005999780174">Augsta kontrasta režīms</translation> <translation id="2575685495496069081">Vairākkārtēja pierakstīšanās ir atspējota</translation> +<translation id="2582112259361606227">Restartēt, lai atjauninātu</translation> <translation id="2597972630681408282">Nakts režīms: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM karte ir bloķēta.</translation> <translation id="2653659639078652383">Iesniegt</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Jūs pašlaik kopīgojat savu ekrānu</translation> <translation id="2942516765047364088">Plaukta pozīcija</translation> <translation id="2946119680249604491">Pievienot savienojumu</translation> +<translation id="2961963223658824723">Radās problēma. Pēc dažām sekundēm mēģiniet vēlreiz.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> ir publiska sesija, kas tiek pārvaldīta domēnā <ph name="DOMAIN" />.</translation> <translation id="3000461861112256445">Mono audio</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Apakšā</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Sakļaut</translation> <translation id="3126069444801937830">Restartēt, lai atjauninātu</translation> <translation id="3147142846278915599">Palaišanas programma (notiek lietotņu sinhronizēšana...)</translation> <translation id="315116470104423982">Mobilie dati</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Bloķēt</translation> <translation id="3798670284305777884">Skaļrunis (iebūvētais)</translation> +<translation id="380165613292957338">Sveicināti! Kā varu palīdzēt?</translation> <translation id="3846575436967432996">Tīkla informācija nav pieejama.</translation> <translation id="385051799172605136">Atpakaļ</translation> <translation id="3891340733213178823">Lai izrakstītos, divas reizes nospiediet taustiņu kombināciju Ctrl+Shift+Q.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C ierīce (pieslēgvieta labajā pusē aizmugurē)</translation> <translation id="4017989525502048489">Lāzera rādītājs</translation> <translation id="4072264167173457037">Vidēji spēcīgs signāls</translation> +<translation id="4200057768455216496">Jūs nospiedāt dokotās lupas īsinājumtaustiņu. Vai vēlaties to ieslēgt?</translation> <translation id="4217571870635786043">Diktēšana</translation> <translation id="4279490309300973883">Spoguļošana</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Jūsu administrators ir atspējojis Google asistentu.</translation> <translation id="4895488851634969361">Akumulators ir pilnībā uzlādēts.</translation> <translation id="4905614135390995787">Īsinājumtaustiņi, ar kuriem pārslēgt augsta kontrasta režīmu, ir mainījušies. Lūdzu, izmantojiet <ph name="NEW_SHORTCUT" />, nevis <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Spēcīgs</translation> <translation id="4918086044614829423">Pieņemt</translation> <translation id="4961318399572185831">Ekrāna apraide</translation> <translation id="5136175204352732067">Ir pievienota cita tastatūra</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Nospiediet Ctrl+Alt+Z, lai atspējotu balss komentārus.</translation> <translation id="5648021990716966815">Mikrofona ligzda</translation> +<translation id="5669267381087807207">Notiek aktivizācija</translation> <translation id="5673434351075758678">Pēc iestatījumu sinhronizēšanas valoda tika mainīta no “<ph name="FROM_LOCALE" />” uz “<ph name="TO_LOCALE" />”.</translation> +<translation id="574392208103952083">Vidējs</translation> <translation id="5744083938413354016">Vilkšana pieskaroties</translation> <translation id="5777841717266010279">Vai apturēt ekrāna koplietošanu?</translation> <translation id="57838592816432529">Izslēgt skaņu</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Noraidīt</translation> <translation id="6453179446719226835">Valodas maiņa</translation> <translation id="6459472438155181876">Paplašina ekrānu uz: <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Pilnekrāna lupa</translation> <translation id="6490471652906364588">USB-C ierīce (pieslēgvieta pa labi)</translation> <translation id="6501401484702599040">Notiek ekrāna apraide šādā vietā: <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Rokraksta ievade</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Laiks pārtraukumam</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">Aktivizēt <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Lai atjauninātu sistēmu, ierīcē jāizmanto funkcija Powerwash. Uzziniet vairāk par pēdējo <ph name="SYSTEM_APP_NAME" /> atjauninājumu.</translation> <translation id="6911468394164995108">Pievienoties citam...</translation> <translation id="6981982820502123353">Pieejamība</translation> <translation id="698231206551913481">Visi faili un lokālie dati, kas ir saistīti ar šo lietotāju, tiks neatgriezeniski dzēsti, tiklīdz šis lietotājs tiks noņemts.</translation> <translation id="7015766095477679451">Atgriezieties plkst. <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Iziet no sesijas</translation> <translation id="7034339000180558234">Notiek cilnes <ph name="TAB_NAME" /> apraide šādā vietā: <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Jūs nospiedāt augsta kontrasta īsinājumtaustiņu. Vai vēlaties to ieslēgt?</translation> <translation id="7066646422045619941">Jūsu administrators atspējoja šo tīklu.</translation> <translation id="7067196344162293536">Pagriezt automātiski</translation> <translation id="7076293881109082629">Pierakstīšanās</translation> <translation id="7098389117866926363">USB-C ierīce (pieslēgvieta aizmugurē pa kreisi)</translation> <translation id="7131634465328662194">Jūs tiksiet automātiski izrakstīts.</translation> +<translation id="7143207342074048698">Notiek savienojuma izveide</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Iepriekšējā izšķirtspēja tiks atgriezta pēc <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Aizmugurējais mikrofons</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Savienots ar <ph name="NAME" /></translation> <translation id="813913629614996137">Notiek inicializēšana...</translation> <translation id="8142699993796781067">Privāts tīkls</translation> +<translation id="8152119955266188852">Jūs nospiedāt pilnekrāna lupas īsinājumtaustiņu. Vai vēlaties to ieslēgt?</translation> <translation id="8180896103888046100">Apturēt apraidi nezināmā uztvērējā</translation> <translation id="8190698733819146287">Pielāgot valodas un ievadi...</translation> <translation id="8261506727792406068">Dzēst</translation> +<translation id="8297006494302853456">Vājš</translation> <translation id="8308637677604853869">Iepriekšējā izvēlne</translation> <translation id="8351131234907093545">Izveidot piezīmi</translation> <translation id="8392451568018454956">Opciju izvēlne kontam <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Poga Atpakaļ</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">Lietotnē netiek atbalstīta ekrāna sadalīšana.</translation> +<translation id="8874184842967597500">Savienojums nav izveidots</translation> <translation id="8878886163241303700">Notiek ekrāna izvēršana</translation> <translation id="8921624153894383499">Google asistents nav pieejams šajā valodā.</translation> <translation id="8938800817013097409">USB-C ierīce (pieslēgvieta aizmugurē pa labi)</translation> <translation id="8940956008527784070">Akumulators gandrīz tukšs (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Ātrā palaišana</translation> <translation id="8995603266996330174">Pārvalda domēnu <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Ir pieejams Adobe Flash Player atjauninājums</translation> <translation id="9033907480196064950">Jūs šobrīd apraidāt, izmantojot cilni <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi adrese: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Pierakstīties kā citam lietotājam...</translation> <translation id="9201131092683066720">Akumulatora uzlādes līmenis: <ph name="PERCENTAGE" />%</translation> <translation id="9210037371811586452">Notiek iziešana no vienotās darbvirsmas režīma</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Iestatīt fona tapeti</translation> <translation id="923686485342484400">Lai izrakstītos, divas reizes nospiediet taustiņu kombināciju Ctrl+Shift+Q.</translation> <translation id="945522503751344254">Sūtīt atsauksmes</translation>
diff --git a/ash/strings/ash_strings_ml.xtb b/ash/strings/ash_strings_ml.xtb index 0441672..51d2668 100644 --- a/ash/strings/ash_strings_ml.xtb +++ b/ash/strings/ash_strings_ml.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C ഉപകരണം (മുൻവശത്തെ പോർട്ട്)</translation> <translation id="1013923882670373915">"<ph name="DEVICE_NAME" />" എന്ന Bluetooth ഉപകരണം ജോടിയാക്കുന്നതിനുള്ള അനുമതി ആവശ്യപ്പെടുന്നു. ആ ഉപകരണത്തിൽ ഈ പിൻ കോഡ് നൽകുക: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">സ്റ്റൈലസ് ബാറ്ററി കുറവാണ്</translation> +<translation id="1056775291175587022">നെറ്റ്വർക്കുകളൊന്നും ഇല്ല</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">ഷെൽഫ് സ്വയമേവ മറയ്ക്കുക</translation> <translation id="1153356358378277386">ജോടിയാക്കിയ ഉപകരണങ്ങൾ</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">ശരി</translation> <translation id="1383876407941801731">തിരയൂ</translation> <translation id="1467432559032391204">ഇടത്</translation> +<translation id="1479743070547893297">തിരഞ്ഞെടുക്കാൻ നിങ്ങളുടെ സ്റ്റൈലസ് ഉപയോഗിച്ച് വരയ്ക്കുക</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">ലോഞ്ചർ</translation> <translation id="1525508553941733066">നിരാകരിക്കുക</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">നിങ്ങളുടെ ഭാഷ സജ്ജീകരിക്കുക</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">ഏറ്റവും പുതിയ <ph name="SYSTEM_APP_NAME" /> അപ്ഡേറ്റിനെ കുറിച്ച് കൂടുതലറിയുക</translation> <translation id="1995660704900986789">പവർ ഓഫാക്കുക</translation> <translation id="2012624427112548395">Ctrl+തിരയൽ+H</translation> +<translation id="2016340657076538683">ഒരു സന്ദേശം ടൈപ്പ് ചെയ്യുക</translation> <translation id="2049639323467105390">ഈ ഉപകരണം നിയന്ത്രിക്കുന്നത് <ph name="DOMAIN" /> ആണ്.</translation> <translation id="2050339315714019657">ഛായാചിത്രം</translation> <translation id="2067602449040652523">കീബോർഡ് തെളിച്ചം</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">തുടരൂ</translation> <translation id="2365393535144473978">മൊബൈൽ ഡാറ്റ പ്രവർത്തനക്ഷമമാക്കുമ്പോൾ Bluetooth-ഉം പ്രവർത്തനക്ഷമമാകും.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">അപ്ഡേറ്റ് ലഭ്യമാണ്</translation> <translation id="2429753432712299108">"<ph name="DEVICE_NAME" />" എന്ന Bluetooth ഉപകരണം ജോടിയാക്കുന്നതിനുള്ള അനുമതി ആവശ്യപ്പെടുന്നു. അനുമതി നൽകുന്നതിനുമുമ്പ്, ആ ഉപകരണത്തിൽ ഈ പാസ്കീ കാണിച്ചിരിക്കുന്നുവെന്ന് സ്ഥിരീകരിക്കുക: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">വിജ്ഞാപനങ്ങള്</translation> <translation id="2484513351006226581">കീബോര്ഡ് ലേഔട്ട് മാറാൻ <ph name="KEYBOARD_SHORTCUT" /> അമർത്തുക.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK ഓൺ ആണ്</translation> <translation id="2532589005999780174">ഉയർന്ന ദൃശ്യതീവ്രത മോഡ്</translation> <translation id="2575685495496069081">ഒന്നിലധികം സൈൻ ഇൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു</translation> +<translation id="2582112259361606227">അപ്ഡേറ്റ് ചെയ്യാൻ റീസ്റ്റാർട്ട് ചെയ്യുക</translation> <translation id="2597972630681408282">നൈറ്റ് ലൈറ്റ്: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">സിം കാർഡ് ലോക്കുചെയ്തു</translation> <translation id="2653659639078652383">സമര്പ്പിക്കൂ</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">നിങ്ങൾ സ്ക്രീൻ പങ്കിടുകയാണ്</translation> <translation id="2942516765047364088">ഷെൽഫ് സ്ഥാനം</translation> <translation id="2946119680249604491">കണക്ഷൻ ചേർക്കുക</translation> +<translation id="2961963223658824723">എന്തോ കുഴപ്പം സംഭവിച്ചു. അൽപ്പസമയത്തിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DOMAIN" /> നിയന്ത്രിക്കുന്ന എല്ലാവർക്കുമുള്ള ഒരു സെഷനാണ് <ph name="DISPLAY_NAME" /></translation> <translation id="3000461861112256445">മോണോ ഓഡിയോ</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">താഴെ</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">ചുരുക്കുക</translation> <translation id="3126069444801937830">അപ്ഡേറ്റുചെയ്യുന്നതിന് പുനരാരംഭിക്കുക</translation> <translation id="3147142846278915599">ലോഞ്ചർ (അപ്ലിക്കേഷൻ സമന്വയിപ്പിക്കുന്നു...)</translation> <translation id="315116470104423982">മൊബൈല് ഡാറ്റ</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">ലോക്കുചെയ്യുക</translation> <translation id="3798670284305777884">സ്പീക്കർ (ഇന്റേണൽ)</translation> +<translation id="380165613292957338">ഹായ്, എന്ത് സഹായമാണ് വേണ്ടത്?</translation> <translation id="3846575436967432996">നെറ്റ്വർക്ക് വിവരങ്ങളൊന്നും ലഭ്യമല്ല</translation> <translation id="385051799172605136">പിന്നോട്ട്</translation> <translation id="3891340733213178823">സൈൻ ഔട്ട് ചെയ്യുന്നതിന് രണ്ടുതവണ Ctrl+Shift+Q അമർത്തുക.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C ഉപകരണം (വലതുവശത്ത് പിന്നിലെ പോർട്ട്)</translation> <translation id="4017989525502048489">ലേസർ പോയിന്റർ</translation> <translation id="4072264167173457037">ഇടത്തരം സിഗ്നൽ</translation> +<translation id="4200057768455216496">നിങ്ങൾ ഡോക്ക് ചെയ്ത മാഗ്നിഫയറിനുള്ള കുറുക്കുവഴി അമർത്തി. അത് ഓണാക്കണോ?</translation> <translation id="4217571870635786043">പറഞ്ഞ് കൊടുക്കൽ</translation> <translation id="4279490309300973883">മിററിംഗ്</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google സഹായിയെ നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ പ്രവർത്തനരഹിതമാക്കി.</translation> <translation id="4895488851634969361">ബാറ്ററി ചാർജുചെയ്യൽ പൂർണ്ണമായി.</translation> <translation id="4905614135390995787">ഉയർന്ന ദൃശ്യതീവ്രത മോഡ് ടോഗിൾ ചെയ്യാനുള്ള കുറുക്കുവഴി മാറ്റി. <ph name="OLD_SHORTCUT" /> എന്നതിനുപകരം <ph name="NEW_SHORTCUT" /> ഉപയോഗിക്കുക.</translation> +<translation id="4917385247580444890">ശക്തം</translation> <translation id="4918086044614829423">സ്വീകരിക്കുക</translation> <translation id="4961318399572185831">സ്ക്രീൻ കാസ്റ്റുചെയ്യുക</translation> <translation id="5136175204352732067">വ്യത്യസ്ത കീബോർഡ് കണക്റ്റ് ചെയ്തു</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">സംഭാഷണ ഫീഡ്ബാക്ക് പ്രവർത്തനരഹിതമാക്കാൻ Ctrl + Alt + Z അമർത്തുക.</translation> <translation id="5648021990716966815">Mic jack</translation> +<translation id="5669267381087807207">സജീവമാക്കുന്നു</translation> <translation id="5673434351075758678">നിങ്ങളുടെ ക്രമീകരണം സമന്വയിപ്പിച്ചതിന് ശേഷം, "<ph name="FROM_LOCALE" />" എന്നതിൽ നിന്ന്"<ph name="TO_LOCALE" />" എന്നതിലേക്ക്.</translation> +<translation id="574392208103952083">ഇടത്തരം</translation> <translation id="5744083938413354016">ടാപ്പുചെയ്ത് വലിച്ചിടൽ</translation> <translation id="5777841717266010279">സ്ക്രീൻ പങ്കിടൽ നിർത്തണോ?</translation> <translation id="57838592816432529">മ്യൂട്ടുചെയ്യുക</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">നിരസിക്കുക</translation> <translation id="6453179446719226835">ഭാഷ മാറ്റിയിരിക്കുന്നു</translation> <translation id="6459472438155181876">സ്ക്രീൻ <ph name="DISPLAY_NAME" /> എന്നതിലേക്ക് വികസിപ്പിക്കുന്നു</translation> +<translation id="6482559668224714696">പൂർണ്ണസ്ക്രീൻ മാഗ്നിഫയർ</translation> <translation id="6490471652906364588">USB-C ഉപകരണം (വലത് പോർട്ട്)</translation> <translation id="6501401484702599040"><ph name="RECEIVER_NAME" /> എന്നതിലേക്ക് സ്ക്രീൻ കാസ്റ്റുചെയ്യുന്നു</translation> <translation id="6521655319214113338">കൈയ്യക്ഷര ഇൻപുട്ട്</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">ഒരു ഇടവേള എടുക്കൂ!</translation> <translation id="683971173229319003">തിരയൽ+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> സജീവമാക്കുക</translation> +<translation id="6910714959251846841">ഈ അപ്ഡേറ്റിന് നിങ്ങളുടെ ഉപകരണം powerwash ചെയ്യേണ്ടതുണ്ട്. ഏറ്റവും പുതിയ <ph name="SYSTEM_APP_NAME" /> അപ്ഡേറ്റിനെ കുറിച്ച് കൂടുതലറിയുക.</translation> <translation id="6911468394164995108">മറ്റുള്ളവ ചേർക്കുക...</translation> <translation id="6981982820502123353">ഉപയോഗസഹായി</translation> <translation id="698231206551913481">ഈ ഉപയോക്താവിനെ നീക്കംചെയ്യുമ്പോൾ അതോടൊപ്പം അയാളുമായി ബന്ധപ്പെട്ട എല്ലാ ഫയലുകളും പ്രാദേശിക വിവരങ്ങളും ശാശ്വതമായി ഇല്ലാതാക്കപ്പെടും.</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" />-ന് തിരികെ വരിക.</translation> <translation id="7029814467594812963">സെഷനിൽ നിന്ന് പുറത്തുകടക്കുക</translation> <translation id="7034339000180558234"><ph name="RECEIVER_NAME" /> എന്നതിലേക്ക് <ph name="TAB_NAME" /> കാസ്റ്റുചെയ്യുന്നു</translation> +<translation id="7037152028959403492">നിങ്ങൾ ഉയർന്ന ദൃശ്യ തീവ്രതയ്ക്കുള്ള കുറുക്കുവഴി അമർത്തി. അത് ഓണാക്കണോ?</translation> <translation id="7066646422045619941">നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ ഈ നെറ്റ്വർക്ക് പ്രവർത്തനരഹിതമാക്കി.</translation> <translation id="7067196344162293536">സ്വയമേവ തിരിക്കുക</translation> <translation id="7076293881109082629">സൈൻ ഇൻ ചെയ്യുന്നു</translation> <translation id="7098389117866926363">USB-C ഉപകരണം (പുറകിൽ ഇടതുവശത്തെ പോർട്ട്)</translation> <translation id="7131634465328662194">നിങ്ങൾ സ്വമേധയാ സൈൻ ഔട്ടാകും.</translation> +<translation id="7143207342074048698">കണക്റ്റുചെയ്യുന്നു</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" />-ൽ പഴയ മിഴിവിലേക്ക് പഴയപടിയാക്കുന്നു</translation> <translation id="7256634071279256947">പിൻഭാഗത്തെ മൈക്രോഫോൺ</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> എന്നതിലേക്ക് ബന്ധിപ്പിച്ചു</translation> <translation id="813913629614996137">ആരംഭിക്കുന്നു...</translation> <translation id="8142699993796781067">സ്വകാര്യ നെറ്റ്വര്ക്ക്</translation> +<translation id="8152119955266188852">നിങ്ങൾ പൂർണ്ണ സ്ക്രീൻ മാഗ്നിഫയറിനുള്ള കുറുക്കുവഴി അമർത്തി. അത് ഓണാക്കണോ?</translation> <translation id="8180896103888046100">അറിഞ്ഞുകൂടാത്ത റിസീവറിലേക്ക് കാസ്റ്റുചെയ്യുന്നത് നിർത്തുക</translation> <translation id="8190698733819146287">ഭാഷകൾ ഇച്ഛാനുസൃതമാക്കി നല്കുക...</translation> <translation id="8261506727792406068">ഇല്ലാതാക്കുക</translation> +<translation id="8297006494302853456">ദുര്ബലം</translation> <translation id="8308637677604853869">മുൻ മെനു</translation> <translation id="8351131234907093545">കുറിപ്പ് സൃഷ്ടിക്കുക</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> എന്നതിനുള്ള ഓപ്ഷനുകൾ മെനു</translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">ബാക്ക് ബട്ടൺ</translation> <translation id="8850991929411075241">തിരയൽ+Esc</translation> <translation id="8870509716567206129">സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല.</translation> +<translation id="8874184842967597500">കണക്റ്റുചെയ്തിട്ടില്ല</translation> <translation id="8878886163241303700">സ്ക്രീൻ വിപുലീകരിക്കുന്നു</translation> <translation id="8921624153894383499">Google അസിസ്റ്റന്റ് ഈ ഭാഷ സംസാരിക്കില്ല.</translation> <translation id="8938800817013097409">USB-C ഉപകരണം (പുറകിൽ വലതുവശത്തെ പോർട്ട്)</translation> <translation id="8940956008527784070">ബാറ്ററി കുറവാണ് (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">ക്വിക്ക് ലോഞ്ച്</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> എന്നത് കൈകാര്യം ചെയ്യുന്നു</translation> +<translation id="9029474291399787231">Adobe Flash Player അപ്ഡേറ്റ് ലഭ്യമാണ്</translation> <translation id="9033907480196064950">നിലവിൽ നിങ്ങൾ <ph name="TAB_NAME" /> ആണ് കാസ്റ്റ് ചെയ്യുന്നത്</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">മറ്റൊരു ഉപയോക്താവായി സൈൻ ഇൻ ചെയ്യുക...</translation> <translation id="9201131092683066720">ബാറ്ററി <ph name="PERCENTAGE" />% നിറഞ്ഞു.</translation> <translation id="9210037371811586452">ഏകീകൃത ഡെസ്ക്ടോപ്പ് മോഡിൽ നിന്ന് പുറത്തുകടക്കുന്നു</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">വാൾപേപ്പർ സജ്ജമാക്കുക</translation> <translation id="923686485342484400">സൈൻ ഔട്ട് ചെയ്യുന്നതിന് രണ്ടുതവണ Control Shift Q അമർത്തുക.</translation> <translation id="945522503751344254">ഫീഡ്ബാക്ക് അയയ്ക്കുക</translation>
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb index 4031ca2..13f2def9 100644 --- a/ash/strings/ash_strings_mr.xtb +++ b/ash/strings/ash_strings_mr.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C डिव्हाइस (पुढील बाजूचे पोर्ट)</translation> <translation id="1013923882670373915">"<ph name="DEVICE_NAME" />" Bluetooth डिव्हाइस जोडण्यासाठी परवानगी घेऊ इच्छिते. कृपया त्या डिव्हाइसवर हा पिन एंटर करा: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">स्टायलस बॅटरी कमी आहे</translation> +<translation id="1056775291175587022">कोणतीही नेटवर्क नाहीत</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">शेल्फ स्वयं लपवा</translation> <translation id="1153356358378277386">जोडलेली डीव्हाइस</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">उजवे</translation> <translation id="1383876407941801731">शोधा</translation> <translation id="1467432559032391204">डावे</translation> +<translation id="1479743070547893297">निवडण्यासाठी तुमच्या स्टायलसने काढा</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">लाँचर</translation> <translation id="1525508553941733066">डिसमिस करा</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">तुमची भाषा सेट करा</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854"><ph name="SYSTEM_APP_NAME" /> च्या नवीनतम अपडेटबाबत अधिक जाणून घ्या</translation> <translation id="1995660704900986789">बंद करा</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">मेसेज टाइप करा</translation> <translation id="2049639323467105390"><ph name="DOMAIN" /> याद्वारे हे डिव्हाइस व्यवस्थापित केले जाते.</translation> <translation id="2050339315714019657">पोर्ट्रेट</translation> <translation id="2067602449040652523">कीबोर्डची चमक</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">सुरू ठेवा</translation> <translation id="2365393535144473978">मोबाइल डेटा चालू केल्याने ब्लूटूथ चालू होईल.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">अपडेट उपलब्ध आहे</translation> <translation id="2429753432712299108">"<ph name="DEVICE_NAME" />" Bluetooth डिव्हाइस जोडण्यासाठी परवानगी घेऊ इच्छिते. स्वीकार करण्यापूर्वी, कृपया त्या डिव्हाइसवर ही पासकी दर्शविली असल्याची पुष्टी करा: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">सूचना</translation> <translation id="2484513351006226581">कीबोर्डचा लेआउट स्विच करण्यासाठी <ph name="KEYBOARD_SHORTCUT" /> दाबा.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK सुरु आहे</translation> <translation id="2532589005999780174">उच्च तीव्रता मोड</translation> <translation id="2575685495496069081">एकाहून अधिक साइन-इन बंद केले गेले आहे</translation> +<translation id="2582112259361606227">अपडेट करण्यासाठी रीस्टार्ट करा</translation> <translation id="2597972630681408282">रात्रीचा प्रकाश: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">सिम कार्ड लॉक केले आहे</translation> <translation id="2653659639078652383">सबमिट करा</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">तुम्ही तुमची स्क्रीन शेअर करत आहात</translation> <translation id="2942516765047364088">शेल्फ स्थिती</translation> <translation id="2946119680249604491">कनेक्शन जोडा</translation> +<translation id="2961963223658824723">काहीतरी चूक झाली. काही सेकंदांनी पुन्हा प्रयत्न करा.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> हे <ph name="DOMAIN" /> द्वारे व्यवस्थापित कलेले एक सावर्जनिक सत्र आहे</translation> <translation id="3000461861112256445">मोनो ऑडिओ</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">तळाकडील</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">संक्षिप्त करा</translation> <translation id="3126069444801937830">अद्यतनासाठी पुनर्प्रारंभ करा</translation> <translation id="3147142846278915599">लाँचर (संकालन अॅप्स...)</translation> <translation id="315116470104423982">मोबाइल डेटा</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">लॉक करा</translation> <translation id="3798670284305777884">स्पीकर (अंतर्गत)</translation> +<translation id="380165613292957338">हाय, मी तुम्हाला कशी मदत करू शकतो?</translation> <translation id="3846575436967432996">कोणतीही नेटवर्क माहिती उपलब्ध नाही</translation> <translation id="385051799172605136">मागील</translation> <translation id="3891340733213178823">साइन आउट करण्यासाठी Ctrl+Shift+Q दोनदा दाबा.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C डिव्हाइस (उजव्या बाजूचे मागील पोर्ट)</translation> <translation id="4017989525502048489">लेझर पॉइंट</translation> <translation id="4072264167173457037">मध्यम सिग्नल</translation> +<translation id="4200057768455216496">तुम्ही डॉक मॅग्निफायरसाठीचा शॉर्टकट दाबला. तुम्हाला ते सुरू करायचे आहे का?</translation> <translation id="4217571870635786043">डिक्टेशन</translation> <translation id="4279490309300973883">मिररिंग</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">तुमच्या अॅडमिनिस्ट्रेटरने Google Assistant बंद केलेले आहे.</translation> <translation id="4895488851634969361">बॅटरी भरली आहे.</translation> <translation id="4905614135390995787">उच्च तीव्रता मोड टॉगल करण्यासाठी शॉर्टकट बदलला आहे. कृपया <ph name="OLD_SHORTCUT" /> ऐवजी <ph name="NEW_SHORTCUT" /> वापरा.</translation> +<translation id="4917385247580444890">मजबूत</translation> <translation id="4918086044614829423">स्वीकारा</translation> <translation id="4961318399572185831">स्क्रीन कास्ट करा</translation> <translation id="5136175204352732067">वेगळा कीबोर्ड कनेक्ट केला आहे</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">बोलता अभिप्राय देणे बंद करण्यासाठी Ctrl + Alt + Z दाबा.</translation> <translation id="5648021990716966815">माइक जॅक</translation> +<translation id="5669267381087807207">सक्रिय करीत आहे </translation> <translation id="5673434351075758678">तुमच्या सेटिंग्ज सिंक केल्यानंतर "<ph name="FROM_LOCALE" />" पासून "<ph name="TO_LOCALE" />" पर्यंत.</translation> +<translation id="574392208103952083">मध्यम</translation> <translation id="5744083938413354016">टॅप ड्रॅगिंग</translation> <translation id="5777841717266010279">स्क्रीन सामायिकरण थांबवायचे?</translation> <translation id="57838592816432529">निःशब्द करा</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">नाकारा</translation> <translation id="6453179446719226835">भाषा बदलण्यात आली आहे</translation> <translation id="6459472438155181876"><ph name="DISPLAY_NAME" /> मध्ये स्क्रीन विस्तृत करत आहे</translation> +<translation id="6482559668224714696">पूर्ण-स्क्रीन मॅग्निफायर</translation> <translation id="6490471652906364588">USB-C डिव्हाइस (उजवे पोर्ट)</translation> <translation id="6501401484702599040"><ph name="RECEIVER_NAME" /> वर स्क्रीन कास्ट करीत आहे</translation> <translation id="6521655319214113338">हस्तलेखन इनपुट</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">ब्रेक घ्या!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">सक्रिय करा<ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">या अपडेटसाठी तुमचे डिव्हाइस Powerwash करणे आवश्यक आहे. <ph name="SYSTEM_APP_NAME" /> च्या नवीनतम अपडेटबाबत अधिक जाणून घ्या.</translation> <translation id="6911468394164995108">दुसरीकडे सामील व्हा...</translation> <translation id="6981982820502123353">प्रवेशयोग्यता</translation> <translation id="698231206551913481">एकदा हा वापरकर्ता काढल्यानंतर या वापरकर्त्याशी संबद्ध सर्व फायली आणि स्थानिक डेटा कायमचा हटवला जाईल.</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" /> वाजता परत या.</translation> <translation id="7029814467594812963">सत्र निर्गमन करा</translation> <translation id="7034339000180558234"><ph name="RECEIVER_NAME" /> वर <ph name="TAB_NAME" /> कास्ट करीत आहे</translation> +<translation id="7037152028959403492">तुम्ही उच्च कॉंट्रास्टसाठीचा शॉर्टकट दाबला. तुम्हाला ते सुरू करायचे आहे का?</translation> <translation id="7066646422045619941">हे नेटवर्क आपल्या प्रशासकाने अक्षम केले आहे.</translation> <translation id="7067196344162293536">स्वयं फिरवा</translation> <translation id="7076293881109082629">साइन इन करीत आहे</translation> <translation id="7098389117866926363">USB-C डिव्हाइस (मागील बाजूचे डावे पोर्ट)</translation> <translation id="7131634465328662194">तुम्हाला आपोआप साइन आउट केले जाईल.</translation> +<translation id="7143207342074048698">कनेक्ट करीत आहे</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" /> मध्ये जुन्या रिजोल्यूशनवर परत करत आहे</translation> <translation id="7256634071279256947">मागील मायक्रोफोन</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> शी कनेक्ट केलेले</translation> <translation id="813913629614996137">प्रारंभ करत आहे…</translation> <translation id="8142699993796781067">खाजगी नेटवर्क</translation> +<translation id="8152119955266188852">तुम्ही पूर्ण-स्क्रीन मॅग्निफायर शॉर्टकट दाबला. तुम्हाला ते सुरू करायचे आहे का?</translation> <translation id="8180896103888046100">एका अज्ञात प्राप्तकर्त्यावर कास्ट करणे थांबवा</translation> <translation id="8190698733819146287">भाषा आणि इनपुट सानुकूलित करा...</translation> <translation id="8261506727792406068">हटवा</translation> +<translation id="8297006494302853456">कमकुवत</translation> <translation id="8308637677604853869">मागील मेनू</translation> <translation id="8351131234907093545">टीप तयार करा</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> साठी पर्याय मेनू</translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">मागे जा बटण</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">अॅप विभाजित-स्क्रीनला सपोर्ट करत नाही.</translation> +<translation id="8874184842967597500">कनेक्ट केलेले नाही</translation> <translation id="8878886163241303700">स्क्रीन विस्तृत करत आहे</translation> <translation id="8921624153894383499">Google साहाय्यक ही भाषा बोलत नाही.</translation> <translation id="8938800817013097409">USB-C डिव्हाइस (मागील बाजूचे उजवे पोर्ट)</translation> <translation id="8940956008527784070">बॅटरी कमी झाली (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">त्वरित लाँच</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> द्वारे व्यवस्थापित</translation> +<translation id="9029474291399787231">Adobe Flash Player अपडेट उपलब्ध आहे</translation> <translation id="9033907480196064950">तुम्ही सध्या <ph name="TAB_NAME" /> कास्ट करत आहात</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">वाय-फाय: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">दुसरा वापरकर्ता साइन इन करा...</translation> <translation id="9201131092683066720">बॅटरी <ph name="PERCENTAGE" />% भरली आहे.</translation> <translation id="9210037371811586452">एकीकृत डेस्कटॉप मोड मधून बाहेर पडत आहे</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">वॉलपेपर सेट करा</translation> <translation id="923686485342484400">दोनदा साइन आउट करण्यासाठी Control Shift Q दोनदा दाबा.</translation> <translation id="945522503751344254">अभिप्राय पाठवा</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb index 606d713..fa9eb211 100644 --- a/ash/strings/ash_strings_ms.xtb +++ b/ash/strings/ash_strings_ms.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Peranti USB-C (port depan)</translation> <translation id="1013923882670373915">Peranti Bluetooth "<ph name="DEVICE_NAME" />" ingin kebenaran untuk berpasangan. Sila masukkan kod PIN ini pada peranti tersebut: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Bateri stilus lemah</translation> +<translation id="1056775291175587022">Tiada rangkaian</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Autosembunyi rak</translation> <translation id="1153356358378277386">Peranti digandingkan</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Kanan</translation> <translation id="1383876407941801731">Carian</translation> <translation id="1467432559032391204">Kiri</translation> +<translation id="1479743070547893297">Lukis menggunakan stilus anda untuk memilih</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Pelancar</translation> <translation id="1525508553941733066">KETEPIKAN</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Tetapkan bahasa anda</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Ketahui lebih lanjut tentang kemas kini <ph name="SYSTEM_APP_NAME" /> yang terbaharu</translation> <translation id="1995660704900986789">Matikan kuasa</translation> <translation id="2012624427112548395">Ctrl+Cari+H</translation> +<translation id="2016340657076538683">Taip mesej</translation> <translation id="2049639323467105390">Peranti ini diuruskan oleh <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Potret</translation> <translation id="2067602449040652523">Kecerahan papan kekunci</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Teruskan</translation> <translation id="2365393535144473978">Tindakan mendayakan data mudah alih akan turut mendayakan Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Kemas kini tersedia</translation> <translation id="2429753432712299108">Peranti Bluetooth "<ph name="DEVICE_NAME" />" ingin kebenaran untuk berpasangan. Sebelum menerimanya, sila sahkan bahawa kekunci laluan ini dipaparkan pada peranti tersebut: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Pemberitahuan</translation> <translation id="2484513351006226581">Tekan <ph name="KEYBOARD_SHORTCUT" /> untuk menukar atur letak papan kekunci.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Kekunci CAPS LOCK dihidupkan</translation> <translation id="2532589005999780174">Mod kontras tinggi</translation> <translation id="2575685495496069081">Log masuk berbilang telah dilumpuhkan</translation> +<translation id="2582112259361606227">Mulakan semula untuk mengemas kini</translation> <translation id="2597972630681408282">Lampu Malam: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Kad SIM dikunci</translation> <translation id="2653659639078652383">Serah</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Anda berkongsi skrin anda</translation> <translation id="2942516765047364088">Kedudukan rak</translation> <translation id="2946119680249604491">Tambah sambungan</translation> +<translation id="2961963223658824723">Maaf, kesilapan telah berlaku. Cuba lagi dalam beberapa saat.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> ialah sesi awam yang diurus oleh <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Audio mono</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Bawah</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Runtuhkan</translation> <translation id="3126069444801937830">Mulakan semula untuk mengemas kini</translation> <translation id="3147142846278915599">Pelancar (menyegerakkan apl...)</translation> <translation id="315116470104423982">Data mudah alih</translation> @@ -148,6 +154,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Kunci</translation> <translation id="3798670284305777884">Pembesar suara (dalaman)</translation> +<translation id="380165613292957338">Hai, bagaimanakah saya boleh membantu?</translation> <translation id="3846575436967432996">Tiada maklumat rangkaian tersedia</translation> <translation id="385051799172605136">Kembali</translation> <translation id="3891340733213178823">Tekan Ctrl+Shift+Q dua kali untuk keluar.</translation> @@ -160,6 +167,7 @@ <translation id="3995138139523574647">Peranti USB-C (port belakang sebelah kanan)</translation> <translation id="4017989525502048489">Penuding laser</translation> <translation id="4072264167173457037">Isyarat sederhana</translation> +<translation id="4200057768455216496">Anda menekan pintasan untuk penggadang yang didok. Adakah anda ingin menghidupkannya?</translation> <translation id="4217571870635786043">Pengimlakan</translation> <translation id="4279490309300973883">Pencerminan</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">Google Assistant dilumpuhkan oleh pentadbir anda.</translation> <translation id="4895488851634969361">Bateri penuh.</translation> <translation id="4905614135390995787">Pintasan untuk menogol Mod Kontras Tinggi telah ditukar. Sila gunakan <ph name="NEW_SHORTCUT" /> dan bukannya <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Kuat</translation> <translation id="4918086044614829423">Terima</translation> <translation id="4961318399572185831">Hantar skrin</translation> <translation id="5136175204352732067">Papan kekunci lain disambungkan</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Tekan Ctrl + Alt + Z untuk melumpuhkan maklum balas yang dituturkan.</translation> <translation id="5648021990716966815">Bicu mikrofon</translation> +<translation id="5669267381087807207">Mengaktifkan</translation> <translation id="5673434351075758678">Daripada "<ph name="FROM_LOCALE" />" kepada "<ph name="TO_LOCALE" />" selepas menyegerakkan tetapan anda.</translation> +<translation id="574392208103952083">Sederhana</translation> <translation id="5744083938413354016">Penyeretan ketik</translation> <translation id="5777841717266010279">Hentikan perkongsian skrin?</translation> <translation id="57838592816432529">Redam</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Tolak</translation> <translation id="6453179446719226835">Bahasa telah ditukar</translation> <translation id="6459472438155181876">Melanjutkan skrin ke <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Penggadang skrin penuh</translation> <translation id="6490471652906364588">Peranti USB-C (port kanan)</translation> <translation id="6501401484702599040">Menghantar skrin ke <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Input tulisan tangan</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Berehatlah!</translation> <translation id="683971173229319003">Carian+L</translation> <translation id="6857811139397017780">Aktifkan <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Kemas kini ini memerlukan powerwash dijalankan pada peranti anda. Ketahui lebih lanjut tentang kemas kini <ph name="SYSTEM_APP_NAME" /> yang terbaharu.</translation> <translation id="6911468394164995108">Sertai yang lain...</translation> <translation id="6981982820502123353">Kebolehcapaian</translation> <translation id="698231206551913481">Semua fail dan data yang berkaitan dengan pengguna ini akan dipadamkan secara kekal selepas pengguna ini dialih keluar.</translation> <translation id="7015766095477679451">Datang semula pada <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Keluar dari sesi</translation> <translation id="7034339000180558234">Menghantar <ph name="TAB_NAME" /> ke <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Anda menekan pintasan untuk kontras tinggi. Adakah anda ingin menghidupkannya?</translation> <translation id="7066646422045619941">Rangkaian ini dilumpuhkan oleh pentadbir anda.</translation> <translation id="7067196344162293536">Auto putar</translation> <translation id="7076293881109082629">Melog masuk</translation> <translation id="7098389117866926363">Peranti USB-C (port kiri di belakang)</translation> <translation id="7131634465328662194">Anda akan dilog keluar secara automatik.</translation> +<translation id="7143207342074048698">Menyambung</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Kembali kepada peleraian lama dalam <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Mikrofon belakang</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Disambungkan ke <ph name="NAME" /></translation> <translation id="813913629614996137">Memulakan...</translation> <translation id="8142699993796781067">Rangkaian persendirian</translation> +<translation id="8152119955266188852">Anda menekan pintasan untuk penggadang skrin penuh. Adakah anda ingin menghidupkannya?</translation> <translation id="8180896103888046100">Berhenti menghantar ke penerima yang tidak diketahui</translation> <translation id="8190698733819146287">Sesuaikan bahasa dan input...</translation> <translation id="8261506727792406068">Padam</translation> +<translation id="8297006494302853456">Lemah</translation> <translation id="8308637677604853869">Menu sebelumnya</translation> <translation id="8351131234907093545">Buat nota</translation> <translation id="8392451568018454956">Menu pilihan untuk <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Butang kembali</translation> <translation id="8850991929411075241">Carian+Esc</translation> <translation id="8870509716567206129">Apl tidak menyokong skrin pisah.</translation> +<translation id="8874184842967597500">Tidak bersambung</translation> <translation id="8878886163241303700">Meluaskan skrin</translation> <translation id="8921624153894383499">Google Assistant tidak bertutur dalam bahasa ini.</translation> <translation id="8938800817013097409">Peranti USB-C (port kanan di belakang)</translation> <translation id="8940956008527784070">Bateri lemah (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Lancar pantas</translation> <translation id="8995603266996330174">Diuruskan oleh <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Kemas kini Adobe Flash Player tersedia</translation> <translation id="9033907480196064950">Anda sedang menghantar <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Log masuk pengguna lain...</translation> <translation id="9201131092683066720">Bateri <ph name="PERCENTAGE" />% penuh.</translation> <translation id="9210037371811586452">Keluar daripada mod desktop bersatu</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Tetapkan kertas dinding</translation> <translation id="923686485342484400">Tekan Tekan Shift Q dua kali untuk keluar.</translation> <translation id="945522503751344254">Hantar maklum balas</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb index 2e63ef0..8fbb536d 100644 --- a/ash/strings/ash_strings_nl.xtb +++ b/ash/strings/ash_strings_nl.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C-apparaat (poort aan voorkant)</translation> <translation id="1013923882670373915">Bluetooth-apparaat '<ph name="DEVICE_NAME" />' wil toestemming om te koppelen. Voer de volgende pincode in op dat apparaat: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Batterij van stylus bijna leeg</translation> +<translation id="1056775291175587022">Geen netwerken</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Plank automatisch verbergen</translation> <translation id="1153356358378277386">Gekoppelde apparaten</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Rechts</translation> <translation id="1383876407941801731">Zoeken</translation> <translation id="1467432559032391204">Links</translation> +<translation id="1479743070547893297">Teken met je stylus om te selecteren</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Launcher</translation> <translation id="1525508553941733066">SLUITEN</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Je taal instellen</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Meer informatie over de laatste update van <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Uitschakelen</translation> <translation id="2012624427112548395">Ctrl+Zoeken+H</translation> +<translation id="2016340657076538683">Typ een bericht</translation> <translation id="2049639323467105390">Dit apparaat wordt beheerd door <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Staand</translation> <translation id="2067602449040652523">Toetsenbordhelderheid</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Doorgaan</translation> <translation id="2365393535144473978">Als je mobiele data inschakelt, wordt Bluetooth ingeschakeld.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Update beschikbaar</translation> <translation id="2429753432712299108">Bluetooth-apparaat '<ph name="DEVICE_NAME" />' wil toestemming om te koppelen. Bevestig vóór het accepteren dat de volgende toegangscode op dat apparaat wordt weergegeven: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Meldingen</translation> <translation id="2484513351006226581">Druk op <ph name="KEYBOARD_SHORTCUT" /> om van toetsenbordindeling te wisselen.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK is ingeschakeld</translation> <translation id="2532589005999780174">Modus voor hoog contrast</translation> <translation id="2575685495496069081">Toegang tot meerdere accounts is uitgeschakeld</translation> +<translation id="2582112259361606227">Opnieuw starten om updates uit te voeren</translation> <translation id="2597972630681408282">Nachtverlichting: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Simkaart is vergrendeld</translation> <translation id="2653659639078652383">Verzenden</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Je deelt je scherm</translation> <translation id="2942516765047364088">Positie van plank</translation> <translation id="2946119680249604491">Verbinding toevoegen</translation> +<translation id="2961963223658824723">Er is iets misgegaan. Probeer het over een paar seconden opnieuw.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> is een openbare sessie die wordt beheerd door <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Monogeluid</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Onderaan</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Samenvouwen</translation> <translation id="3126069444801937830">Opnieuw starten om updates uit te voeren</translation> <translation id="3147142846278915599">Launcher (apps synchroniseren...)</translation> <translation id="315116470104423982">Mobiele data</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Vergrendelen</translation> <translation id="3798670284305777884">Luidspreker (intern)</translation> +<translation id="380165613292957338">Hallo, hoe kan ik je helpen?</translation> <translation id="3846575436967432996">Geen netwerkinformatie beschikbaar</translation> <translation id="385051799172605136">Vorige</translation> <translation id="3891340733213178823">Druk twee keer op Ctrl+Shift+Q om uit te loggen.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C-apparaat (poort rechts aan de achterkant)</translation> <translation id="4017989525502048489">Laserpen</translation> <translation id="4072264167173457037">Normaal signaal</translation> +<translation id="4200057768455216496">Je hebt op de sneltoets voor het gedockte vergrootglas gedrukt. Wil je deze functie inschakelen?</translation> <translation id="4217571870635786043">Dicteren</translation> <translation id="4279490309300973883">Mirroring</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">De Google Assistent is uitgeschakeld door je beheerder.</translation> <translation id="4895488851634969361">De batterij is vol.</translation> <translation id="4905614135390995787">De sneltoets om de modus voor hoog contrast in of uit te schakelen, is gewijzigd. Gebruik <ph name="NEW_SHORTCUT" /> in plaats van <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Sterk</translation> <translation id="4918086044614829423">Accepteren</translation> <translation id="4961318399572185831">Scherm casten</translation> <translation id="5136175204352732067">Ander toetsenbord aangesloten</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Druk op Ctrl + Alt + Z om gesproken feedback uit te schakelen.</translation> <translation id="5648021990716966815">Microfoonaansluiting</translation> +<translation id="5669267381087807207">Wordt geactiveerd</translation> <translation id="5673434351075758678">Van '<ph name="FROM_LOCALE" />' naar '<ph name="TO_LOCALE" />' na synchronisatie van je instellingen.</translation> +<translation id="574392208103952083">Gemiddeld</translation> <translation id="5744083938413354016">Tikken en slepen</translation> <translation id="5777841717266010279">Stoppen met scherm delen?</translation> <translation id="57838592816432529">Dempen</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Weigeren</translation> <translation id="6453179446719226835">Taal is gewijzigd</translation> <translation id="6459472438155181876">Scherm uitbreiden naar <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Volledig scherm vergroten</translation> <translation id="6490471652906364588">USB-C-apparaat (poort aan rechterkant)</translation> <translation id="6501401484702599040">Scherm casten naar <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Handschriftinvoer</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Neem een pauze</translation> <translation id="683971173229319003">Zoeken+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> activeren</translation> +<translation id="6910714959251846841">Deze update vereist een powerwash van je apparaat. Meer informatie over de laatste update van <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Verbinding met ander netwerk maken...</translation> <translation id="6981982820502123353">Toegankelijkheid</translation> <translation id="698231206551913481">Alle bestanden en lokale gegevens die zijn gekoppeld aan deze gebruiker, worden definitief verwijderd zodra deze gebruiker is verwijderd.</translation> <translation id="7015766095477679451">Kom terug om <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Sessie sluiten</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> wordt gecast naar <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Je hebt op de sneltoets voor hoog contrast gedrukt. Wil je deze functie inschakelen?</translation> <translation id="7066646422045619941">Dit netwerk is uitgeschakeld door je beheerder.</translation> <translation id="7067196344162293536">Automatisch draaien</translation> <translation id="7076293881109082629">Inloggen</translation> <translation id="7098389117866926363">USB-C-apparaat (poort links aan de achterkant)</translation> <translation id="7131634465328662194">Je wordt automatisch uitgelogd.</translation> +<translation id="7143207342074048698">Verbinding maken</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Terugzetten naar oude resolutie over <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Microfoon aan achterzijde</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Verbonden met <ph name="NAME" /></translation> <translation id="813913629614996137">Starten...</translation> <translation id="8142699993796781067">Privénetwerk</translation> +<translation id="8152119955266188852">Je hebt op de sneltoets voor volledig scherm vergroten gedrukt. Wil je deze functie inschakelen?</translation> <translation id="8180896103888046100">Casten naar een onbekende ontvanger stopzetten</translation> <translation id="8190698733819146287">Talen en invoer aanpassen...</translation> <translation id="8261506727792406068">Verwijderen</translation> +<translation id="8297006494302853456">Zwak</translation> <translation id="8308637677604853869">Vorig menu</translation> <translation id="8351131234907093545">Notitie maken</translation> <translation id="8392451568018454956">Optiemenu voor <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Knop Terug</translation> <translation id="8850991929411075241">Zoeken+Esc</translation> <translation id="8870509716567206129">App biedt geen ondersteuning voor gesplitst scherm.</translation> +<translation id="8874184842967597500">Niet verbonden</translation> <translation id="8878886163241303700">Uitgebreid scherm</translation> <translation id="8921624153894383499">De Google Assistent spreekt deze taal niet.</translation> <translation id="8938800817013097409">USB-C-apparaat (poort rechts aan de achterkant)</translation> <translation id="8940956008527784070">Batterij is bijna leeg (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Snelstarten</translation> <translation id="8995603266996330174">Beheerd door <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Update van Adobe Flash Player beschikbaar</translation> <translation id="9033907480196064950">Je cast momenteel <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wifi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Een andere gebruiker inloggen...</translation> <translation id="9201131092683066720">De batterij is <ph name="PERCENTAGE" />% vol.</translation> <translation id="9210037371811586452">Samengestelde desktopmodus wordt gesloten</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Achtergrond instellen</translation> <translation id="923686485342484400">Druk twee keer op Control+Shift+Q om uit te loggen.</translation> <translation id="945522503751344254">Feedback verzenden</translation>
diff --git a/ash/strings/ash_strings_no.xtb b/ash/strings/ash_strings_no.xtb index 20cee4c..7a3ca98 100644 --- a/ash/strings/ash_strings_no.xtb +++ b/ash/strings/ash_strings_no.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C-enhet (porten foran)</translation> <translation id="1013923882670373915">Bluetooth-enheten «<ph name="DEVICE_NAME" />» ber om tillatelse til å koble til. Skriv inn denne PIN-koden på den aktuelle enheten: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Pekepennen har lite batteri</translation> +<translation id="1056775291175587022">Ingen nettverk</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Skjul hyllen automatisk</translation> <translation id="1153356358378277386">Tilkoblede enheter</translation> @@ -111,7 +112,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Bunn</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Skjul</translation> <translation id="3126069444801937830">Start på nytt for å oppdatere</translation> <translation id="3147142846278915599">Appoversikt (synkroniserer apper ...)</translation> <translation id="315116470104423982">Mobildata</translation> @@ -189,6 +189,7 @@ <translation id="4890187583552566966">Administratoren din har slått av Google-assistenten.</translation> <translation id="4895488851634969361">Batteriet er fullt.</translation> <translation id="4905614135390995787">Hurtigtasten for å slå høykontrastmodus av eller på er endret. Bruk <ph name="NEW_SHORTCUT" /> i stedet for <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Sterk</translation> <translation id="4918086044614829423">Godta</translation> <translation id="4961318399572185831">Cast skjermen</translation> <translation id="5136175204352732067">Et annet tastatur er koblet til</translation> @@ -212,7 +213,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" /> <ph name="DATE" /></translation> <translation id="5600837773213129531">Trykk på Ctrl + Alt + Z for å slå av taletilbakemelding.</translation> <translation id="5648021990716966815">Mikrofonkontakt</translation> +<translation id="5669267381087807207">Aktiverer</translation> <translation id="5673434351075758678">Fra «<ph name="FROM_LOCALE" />» til «<ph name="TO_LOCALE" />» etter at innstillingene dine ble synkronisert.</translation> +<translation id="574392208103952083">Medium</translation> <translation id="5744083938413354016">Trykk-og-dra</translation> <translation id="5777841717266010279">Vil du stoppe skjermdelingen?</translation> <translation id="57838592816432529">Kutt lyden</translation> @@ -292,6 +295,7 @@ <translation id="7076293881109082629">Pålogging</translation> <translation id="7098389117866926363">USB-C-enhet (venstre port på baksiden)</translation> <translation id="7131634465328662194">Du logges av automatisk.</translation> +<translation id="7143207342074048698">Kobler til</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Går tilbake til den gamle oppløsningen om <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Mikrofon bak</translation> @@ -340,6 +344,7 @@ <translation id="8180896103888046100">Slutt å caste til en ukjent mottaker</translation> <translation id="8190698733819146287">Tilpass språk og inndata</translation> <translation id="8261506727792406068">Slett</translation> +<translation id="8297006494302853456">Svak</translation> <translation id="8308637677604853869">Forrige meny</translation> <translation id="8351131234907093545">Opprett et notat</translation> <translation id="8392451568018454956">Alternativmenyen for <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,6 +372,7 @@ <translation id="8841375032071747811">Tilbakeknapp</translation> <translation id="8850991929411075241">Søk+Esc</translation> <translation id="8870509716567206129">Appen støtter ikke delt skjerm.</translation> +<translation id="8874184842967597500">Ikke tilkoblet</translation> <translation id="8878886163241303700">Utvidet skjerm</translation> <translation id="8921624153894383499">Google-assistenten kan ikke dette språket.</translation> <translation id="8938800817013097409">USB-C-enhet (høyre port på baksiden)</translation>
diff --git a/ash/strings/ash_strings_pl.xtb b/ash/strings/ash_strings_pl.xtb index 5a4e6136..89a7446 100644 --- a/ash/strings/ash_strings_pl.xtb +++ b/ash/strings/ash_strings_pl.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Urządzenie USB-C (przedni port)</translation> <translation id="1013923882670373915">Urządzenie Bluetooth „<ph name="DEVICE_NAME" />” chce się sparować. Wpisz na nim ten kod PIN: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Niski poziom baterii rysika</translation> +<translation id="1056775291175587022">Brak sieci</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Autoukrywanie półki</translation> <translation id="1153356358378277386">Sparowane urządzenia</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">W prawo</translation> <translation id="1383876407941801731">Szukaj</translation> <translation id="1467432559032391204">W lewo</translation> +<translation id="1479743070547893297">Zaznacz rysikiem</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Program uruchamiający</translation> <translation id="1525508553941733066">ZAMKNIJ</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Ustaw język</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Więcej informacji o najnowszej aktualizacji <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Wyłącz</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">Wpisz wiadomość</translation> <translation id="2049639323467105390">To urządzenie jest zarządzane przez: <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Pionowo</translation> <translation id="2067602449040652523">Jasność klawiatury</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Dalej</translation> <translation id="2365393535144473978">Wraz z mobilną transmisją danych zostanie włączony Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Dostępna aktualizacja</translation> <translation id="2429753432712299108">Urządzenie Bluetooth „<ph name="DEVICE_NAME" />” chce się sparować. Zanim to zaakceptujesz, sprawdź, czy na tym urządzeniu wyświetla się klucz: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Powiadomienia</translation> <translation id="2484513351006226581">Naciśnij <ph name="KEYBOARD_SHORTCUT" />, by przełączyć układ klawiatury.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK jest włączony.</translation> <translation id="2532589005999780174">Tryb wysokiego kontrastu</translation> <translation id="2575685495496069081">Wielokrotne logowanie jest wyłączone</translation> +<translation id="2582112259361606227">Uruchom ponownie, by zaktualizować</translation> <translation id="2597972630681408282">Podświetlenie nocne: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Karta SIM jest zablokowana</translation> <translation id="2653659639078652383">Prześlij</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Udostępniasz ekran</translation> <translation id="2942516765047364088">Pozycja półki</translation> <translation id="2946119680249604491">Dodaj połączenie</translation> +<translation id="2961963223658824723">Coś poszło nie tak. Spróbuj ponownie za kilka sekund.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> jest publiczną sesją zarządzaną przez <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Dźwięk mono</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Na dół</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Zwiń</translation> <translation id="3126069444801937830">Uruchom ponownie i zaktualizuj</translation> <translation id="3147142846278915599">Menu z aplikacjami (synchronizuję aplikacje...)</translation> <translation id="315116470104423982">Komórkowa transmisja danych</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Zablokuj</translation> <translation id="3798670284305777884">Głośnik (wewnętrzny)</translation> +<translation id="380165613292957338">Cześć, w czym mogę pomóc?</translation> <translation id="3846575436967432996">Brak informacji o sieciach</translation> <translation id="385051799172605136">Wstecz</translation> <translation id="3891340733213178823">Naciśnij dwukrotnie Ctrl+Shift+Q, by się wylogować.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Urządzenie USB-C (tylny port na prawym boku)</translation> <translation id="4017989525502048489">Wskaźnik laserowy</translation> <translation id="4072264167173457037">średni sygnał</translation> +<translation id="4200057768455216496">Naciśnięto skrót lupy zadokowanej. Czy chcesz ją włączyć?</translation> <translation id="4217571870635786043">Dyktowanie</translation> <translation id="4279490309300973883">Odbicie lustrzane</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">Asystenta Google wyłączył administrator.</translation> <translation id="4895488851634969361">Bateria jest pełna.</translation> <translation id="4905614135390995787">Zmieniliśmy skrót, który włącza i wyłącza tryb wysokiego kontrastu. Użyj <ph name="NEW_SHORTCUT" /> zamiast <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Silny</translation> <translation id="4918086044614829423">Akceptuj</translation> <translation id="4961318399572185831">Przesyłanie ekranu</translation> <translation id="5136175204352732067">Podłączono inną klawiaturę</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Naciśnij Ctrl + Alt + Z, by wyłączyć komunikaty głosowe.</translation> <translation id="5648021990716966815">Gniazdo mikrofonu</translation> +<translation id="5669267381087807207">Aktywowanie</translation> <translation id="5673434351075758678">Z języka: „<ph name="FROM_LOCALE" />” na „<ph name="TO_LOCALE" />” po zsynchronizowaniu ustawień.</translation> +<translation id="574392208103952083">Średni</translation> <translation id="5744083938413354016">Przeciąganie dotykiem</translation> <translation id="5777841717266010279">Zakończyć udostępnianie ekranu?</translation> <translation id="57838592816432529">Wycisz</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Odrzuć</translation> <translation id="6453179446719226835">Język został zmieniony</translation> <translation id="6459472438155181876">Rozszerzanie ekranu na <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Lupa pełnoekranowa</translation> <translation id="6490471652906364588">Urządzenie USB-C (prawy port)</translation> <translation id="6501401484702599040">Przesyłam ekran do: <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Pismo odręczne</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Zrób sobie przerwę</translation> <translation id="683971173229319003">Szukaj+L</translation> <translation id="6857811139397017780">Aktywuj sieć <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Ta aktualizacja wymaga usunięcia wszystkich danych z urządzenia za pomocą funkcji Powerwash. Dowiedz się więcej o najnowszej aktualizacji <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Połącz z inną...</translation> <translation id="6981982820502123353">Ułatwienia dostępu</translation> <translation id="698231206551913481">Usunięcie tego użytkownika spowoduje trwałe usunięcie wszystkich związanych z nim plików i danych lokalnych.</translation> <translation id="7015766095477679451">Możesz wrócić o <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Zakończ sesję</translation> <translation id="7034339000180558234">Przesyłam kartę <ph name="TAB_NAME" /> do: <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Naciśnięto skrót wysokiego kontrastu. Czy chcesz go włączyć?</translation> <translation id="7066646422045619941">Ta sieć została wyłączona przez administratora.</translation> <translation id="7067196344162293536">Obracanie automatyczne</translation> <translation id="7076293881109082629">Loguję</translation> <translation id="7098389117866926363">Urządzenie USB-C (lewy port z tyłu)</translation> <translation id="7131634465328662194">Nastąpi automatyczne wylogowanie.</translation> +<translation id="7143207342074048698">Łączenie</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Powrót do wcześniejszej rozdzielczości za <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Tylny mikrofon</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Połączono z <ph name="NAME" /></translation> <translation id="813913629614996137">Inicjuję…</translation> <translation id="8142699993796781067">Sieć prywatna</translation> +<translation id="8152119955266188852">Naciśnięto skrót lupy pełnoekranowej. Czy chcesz ją włączyć?</translation> <translation id="8180896103888046100">Zakończ przesyłanie ekranu do nieznanego odbiornika</translation> <translation id="8190698733819146287">Dostosuj języki i metody wprowadzania...</translation> <translation id="8261506727792406068">Usuń</translation> +<translation id="8297006494302853456">Słaby</translation> <translation id="8308637677604853869">Poprzednie menu</translation> <translation id="8351131234907093545">Utwórz notatkę</translation> <translation id="8392451568018454956">Menu opcji dla <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Przycisk Wstecz</translation> <translation id="8850991929411075241">Szukaj+Esc</translation> <translation id="8870509716567206129">Aplikacja nie obsługuje dzielonego ekranu.</translation> +<translation id="8874184842967597500">Brak połączenia</translation> <translation id="8878886163241303700">Rozszerzony ekran</translation> <translation id="8921624153894383499">Asystent Google nie mówi w tym języku.</translation> <translation id="8938800817013097409">Urządzenie USB-C (prawy port z tyłu)</translation> <translation id="8940956008527784070">Niski stan baterii (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Szybkie uruchamianie</translation> <translation id="8995603266996330174">Zarządzane przez <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Dostępna jest aktualizacja Adobe Flash Playera</translation> <translation id="9033907480196064950">Aktualnie przesyłasz kartę <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Zaloguj innego użytkownika...</translation> <translation id="9201131092683066720">Naładowanie baterii: <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Wyłączam tryb ujednoliconego pulpitu</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Ustaw tapetę</translation> <translation id="923686485342484400">Naciśnij dwukrotnie Control Shift Q, by się wylogować.</translation> <translation id="945522503751344254">Wyślij zgłoszenie</translation>
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb index 06a0ed21..d88e1399 100644 --- a/ash/strings/ash_strings_pt-BR.xtb +++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Dispositivo USB-C (porta frontal)</translation> <translation id="1013923882670373915">O dispositivo Bluetooth "<ph name="DEVICE_NAME" />" deseja permissão para realizar o pareamento. Digite este código PIN no dispositivo: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">A bateria da stylus está fraca</translation> +<translation id="1056775291175587022">Nenhuma rede encontrada</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Ocultar estante automaticamente</translation> <translation id="1153356358378277386">Dispositivos pareados</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Parte inferior</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Recolher</translation> <translation id="3126069444801937830">Reiniciar para atualizar</translation> <translation id="3147142846278915599">Tela de início (sincronizando aplicativos...)</translation> <translation id="315116470104423982">Dados do celular</translation> @@ -198,6 +198,7 @@ <translation id="4890187583552566966">O Google Assistente foi desativado pelo seu administrador.</translation> <translation id="4895488851634969361">A bateria está carregada.</translation> <translation id="4905614135390995787">O atalho para alternar o modo de alto contraste foi alterado. Use <ph name="NEW_SHORTCUT" /> em vez de <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Forte</translation> <translation id="4918086044614829423">Aceitar</translation> <translation id="4961318399572185831">Transmitir tela</translation> <translation id="5136175204352732067">Teclado diferente conectado</translation> @@ -221,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Pressione Ctrl + Alt + Z para desativar o feedback falado.</translation> <translation id="5648021990716966815">Entrada para microfone</translation> +<translation id="5669267381087807207">Ativando</translation> <translation id="5673434351075758678">De "<ph name="FROM_LOCALE" />" para "<ph name="TO_LOCALE" />" após a sincronização das suas configurações.</translation> +<translation id="574392208103952083">Médio</translation> <translation id="5744083938413354016">Arrastar com toque</translation> <translation id="5777841717266010279">Interromper compartilhamento de tela?</translation> <translation id="57838592816432529">Desativar som</translation> @@ -305,6 +308,7 @@ <translation id="7076293881109082629">Como fazer login</translation> <translation id="7098389117866926363">Dispositivo USB-C (porta traseira da esquerda)</translation> <translation id="7131634465328662194">Você será automaticamente desconectado.</translation> +<translation id="7143207342074048698">Conectando</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Revertendo para resolução anterior em <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Microfone traseiro</translation> @@ -354,6 +358,7 @@ <translation id="8180896103888046100">Parar de transmitir para um destinatário desconhecido</translation> <translation id="8190698733819146287">Personalizar idiomas e entrada...</translation> <translation id="8261506727792406068">Excluir</translation> +<translation id="8297006494302853456">Fraco</translation> <translation id="8308637677604853869">Menu anterior</translation> <translation id="8351131234907093545">Criar nota</translation> <translation id="8392451568018454956">Menu de opções para <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -381,6 +386,7 @@ <translation id="8841375032071747811">Botão "Voltar"</translation> <translation id="8850991929411075241">Pesquisa+Esc</translation> <translation id="8870509716567206129">O app não é compatível com a divisão de tela.</translation> +<translation id="8874184842967597500">Não conectado</translation> <translation id="8878886163241303700">Tela ampla</translation> <translation id="8921624153894383499">O Google Assistente não fala esse idioma.</translation> <translation id="8938800817013097409">Dispositivo USB-C (porta traseira da direita)</translation>
diff --git a/ash/strings/ash_strings_pt-PT.xtb b/ash/strings/ash_strings_pt-PT.xtb index fa58e68c..b64c1cbd 100644 --- a/ash/strings/ash_strings_pt-PT.xtb +++ b/ash/strings/ash_strings_pt-PT.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Dispositivo USB-C (porta frontal)</translation> <translation id="1013923882670373915">O dispositivo Bluetooth "<ph name="DEVICE_NAME" />" necessita de autorização para sincronizar. Introduza este código PIN nesse dispositivo: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">A pilha da caneta stylus está fraca</translation> +<translation id="1056775291175587022">Nenhuma rede</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Ocultar prateleira automaticamente</translation> <translation id="1153356358378277386">Dispositivos sincronizados</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Direita</translation> <translation id="1383876407941801731">Pesquisar</translation> <translation id="1467432559032391204">Esquerda</translation> +<translation id="1479743070547893297">Desenhar com a caneta stylus para selecionar</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Iniciador</translation> <translation id="1525508553941733066">IGNORAR</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Definir o idioma</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Saiba mais sobre a mais recente atualização do <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="1995660704900986789">Desligar</translation> <translation id="2012624427112548395">Ctrl + Pesquisa + H</translation> +<translation id="2016340657076538683">Escrever uma mensagem</translation> <translation id="2049639323467105390">Este aparelho é gerido por <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Vertical</translation> <translation id="2067602449040652523">Brilho do teclado</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Continuar</translation> <translation id="2365393535144473978">A ativação dos dados móveis ativa o Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Atualização disponível</translation> <translation id="2429753432712299108">O dispositivo Bluetooth "<ph name="DEVICE_NAME" />" necessita de autorização para sincronizar. Antes de aceitar, confirme que esta chave está indicada nesse dispositivo: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Notificações</translation> <translation id="2484513351006226581">Prima <ph name="KEYBOARD_SHORTCUT" /> para mudar o esquema do teclado.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK está ativado</translation> <translation id="2532589005999780174">Modo de alto contraste</translation> <translation id="2575685495496069081">O início de sessão integrado foi desativado</translation> +<translation id="2582112259361606227">Reiniciar para atualizar</translation> <translation id="2597972630681408282">Luz noturna: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">O cartão SIM está bloqueado</translation> <translation id="2653659639078652383">Submeter</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Está a partilhar o seu ecrã</translation> <translation id="2942516765047364088">Posição da prateleira</translation> <translation id="2946119680249604491">Adicionar ligação</translation> +<translation id="2961963223658824723">Ocorreu um erro. Tente novamente dentro de alguns segundos.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> é uma sessão pública gerida por <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Áudio mono</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Parte inferior</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Reduzir</translation> <translation id="3126069444801937830">Reiniciar para atualizar</translation> <translation id="3147142846278915599">Launcher (a sincronizar aplicações...)</translation> <translation id="315116470104423982">Dados móveis</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Bloquear</translation> <translation id="3798670284305777884">Altifalante (interno)</translation> +<translation id="380165613292957338">Olá, como posso ajudar?</translation> <translation id="3846575436967432996">Não existem informações de rede disponíveis</translation> <translation id="385051799172605136">Anterior</translation> <translation id="3891340733213178823">Prima Ctrl+Shift+Q duas vezes para terminar sessão.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Dispositivo USB-C (porta traseira do lado direito)</translation> <translation id="4017989525502048489">Ponteiro de laser</translation> <translation id="4072264167173457037">Sinal médio</translation> +<translation id="4200057768455216496">Premiu o atalho da lupa ancorada. Pretende ativá-la?</translation> <translation id="4217571870635786043">Ditado</translation> <translation id="4279490309300973883">Espelhamento</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">O Assistente Google foi desativado pelo administrador.</translation> <translation id="4895488851634969361">A bateria está carregada.</translation> <translation id="4905614135390995787">O atalho para ativar/desativar o Modo de alto contraste foi alterado. Utilize <ph name="NEW_SHORTCUT" /> em vez de <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Forte</translation> <translation id="4918086044614829423">Aceitar</translation> <translation id="4961318399572185831">Transmitir ecrã</translation> <translation id="5136175204352732067">Teclado diferente ligado</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Prima Ctrl + Alt + Z para desativar os comentários de voz.</translation> <translation id="5648021990716966815">Entrada para microfone</translation> +<translation id="5669267381087807207">A activar</translation> <translation id="5673434351075758678">De "<ph name="FROM_LOCALE" />" para "<ph name="TO_LOCALE" />" após a sincronização das suas definições.</translation> +<translation id="574392208103952083">Médio</translation> <translation id="5744083938413354016">Arrastamento através do toque</translation> <translation id="5777841717266010279">Parar a partilha do ecrã?</translation> <translation id="57838592816432529">Desativar som</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Rejeitar</translation> <translation id="6453179446719226835">O idioma foi alterado</translation> <translation id="6459472438155181876">A prolongar ecrã para <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Lupa de ecrã inteiro</translation> <translation id="6490471652906364588">Dispositivo USB-C (porta direita)</translation> <translation id="6501401484702599040">A transmitir o ecrã para <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Entrada de escrita manual</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Faça uma pausa!</translation> <translation id="683971173229319003">Pesquisa+L</translation> <translation id="6857811139397017780">Ativar <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Para efetuar esta atualização, é necessário efetuar o Powerwash do dispositivo. Saiba mais sobre a mais recente atualização do <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Ligar-se a outra...</translation> <translation id="6981982820502123353">Acessibilidade</translation> <translation id="698231206551913481">Todos os ficheiros e dados locais associados a este utilizador são permanentemente eliminados assim que este utilizador é removido.</translation> <translation id="7015766095477679451">Volte à(s) <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Sair da sessão</translation> <translation id="7034339000180558234">A transmitir <ph name="TAB_NAME" /> para <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Premiu o atalho de alto contraste. Pretende ativá-lo?</translation> <translation id="7066646422045619941">Esta rede foi desativada pelo gestor.</translation> <translation id="7067196344162293536">Rotação automática</translation> <translation id="7076293881109082629">Iniciar sessão</translation> <translation id="7098389117866926363">Dispositivo USB-C (porta traseira esquerda)</translation> <translation id="7131634465328662194">A sessão será terminada automaticamente.</translation> +<translation id="7143207342074048698">A ligar</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">A reverter para a resolução antiga dentro de <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Microfone posterior</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Ligado a <ph name="NAME" /></translation> <translation id="813913629614996137">A inicializar...</translation> <translation id="8142699993796781067">Rede privada</translation> +<translation id="8152119955266188852">Premiu o atalho da lupa de ecrã inteiro. Pretende ativá-la?</translation> <translation id="8180896103888046100">Parar a transmissão para um recetor desconhecido</translation> <translation id="8190698733819146287">Personalizar idiomas e introdução...</translation> <translation id="8261506727792406068">Eliminar</translation> +<translation id="8297006494302853456">Fraca</translation> <translation id="8308637677604853869">Menu anterior</translation> <translation id="8351131234907093545">Criar nota</translation> <translation id="8392451568018454956">Menu de opções para <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Botão Anterior</translation> <translation id="8850991929411075241">Pesquisa+Esc</translation> <translation id="8870509716567206129">A aplicação não é compatível com o ecrã dividido.</translation> +<translation id="8874184842967597500">Sem ligação</translation> <translation id="8878886163241303700">Ecrã alargado</translation> <translation id="8921624153894383499">O Assistente Google não fala este idioma.</translation> <translation id="8938800817013097409">Dispositivo USB-C (porta traseira direita)</translation> <translation id="8940956008527784070">Bateria fraca (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Início rápido</translation> <translation id="8995603266996330174">Gerido por <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Atualização do Adobe Flash Player disponível</translation> <translation id="9033907480196064950">Está atualmente a transmitir <ph name="TAB_NAME" />.</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Iniciar sessão com outro utilizador...</translation> <translation id="9201131092683066720">A bateria está <ph name="PERCENTAGE" />% cheia.</translation> <translation id="9210037371811586452">A sair do Modo de ambiente de trabalho unificado</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Definir imagem de fundo</translation> <translation id="923686485342484400">Prima Control Shift Q duas vezes para terminar sessão.</translation> <translation id="945522503751344254">Enviar comentários</translation>
diff --git a/ash/strings/ash_strings_ro.xtb b/ash/strings/ash_strings_ro.xtb index 02df6cd..0cfe5de7 100644 --- a/ash/strings/ash_strings_ro.xtb +++ b/ash/strings/ash_strings_ro.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Dispozitiv USB-C (portul din față)</translation> <translation id="1013923882670373915">Dispozitivul Bluetooth „<ph name="DEVICE_NAME" />” solicită permisiunea de a se conecta. Introduceți acest cod PIN pe dispozitivul respectiv: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Bateria creionului este descărcată</translation> +<translation id="1056775291175587022">Nu s-au găsit rețele</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Ascundeți automat raftul</translation> <translation id="1153356358378277386">Dispozitive asociate</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Dreapta</translation> <translation id="1383876407941801731">Caută</translation> <translation id="1467432559032391204">Stânga</translation> +<translation id="1479743070547893297">Desenează cu creionul pentru a selecta</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Lansator</translation> <translation id="1525508553941733066">ÎNCHIDE</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Setează limba</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Află mai multe despre cea mai recentă actualizare <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Oprește alimentarea</translation> <translation id="2012624427112548395">Ctrl + tasta de căutare + H</translation> +<translation id="2016340657076538683">Scrie un mesaj</translation> <translation id="2049639323467105390">Acest dispozitiv este gestionat de <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Portret</translation> <translation id="2067602449040652523">Luminozitatea tastaturii</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Continuă</translation> <translation id="2365393535144473978">Activând datele mobile, se va activa Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Actualizare disponibilă</translation> <translation id="2429753432712299108">Dispozitivul Bluetooth „<ph name="DEVICE_NAME" />” solicită permisiunea de a se conecta. Înainte de a continua, verificați dacă această parolă apare pe dispozitivul respectiv: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Notificări</translation> <translation id="2484513351006226581">Apasă <ph name="KEYBOARD_SHORTCUT" /> pentru a schimba aspectul tastaturii.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Tasta CAPS LOCK este activată</translation> <translation id="2532589005999780174">Mod de contrast ridicat</translation> <translation id="2575685495496069081">Conectarea multiplă a fost dezactivată</translation> +<translation id="2582112259361606227">Repornește pentru a actualiza</translation> <translation id="2597972630681408282">Lumină de noapte: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Cardul SIM este blocat</translation> <translation id="2653659639078652383">Trimite</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Acum permiți accesul la ecran</translation> <translation id="2942516765047364088">Poziție raft</translation> <translation id="2946119680249604491">Adăugați o conexiune</translation> +<translation id="2961963223658824723">A apărut o eroare. Încearcă din nou în câteva secunde.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> este o sesiune publică gestionată de <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Audio mono</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Jos</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Restrânge</translation> <translation id="3126069444801937830">Reporniți pentru a actualiza</translation> <translation id="3147142846278915599">Lansator (se sincronizează aplicațiile...)</translation> <translation id="315116470104423982">Date mobile</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Blocați</translation> <translation id="3798670284305777884">Difuzor (intern)</translation> +<translation id="380165613292957338">Bună ziua, cu ce vă pot ajuta?</translation> <translation id="3846575436967432996">Nu sunt disponibile informații despre rețele</translation> <translation id="385051799172605136">Înapoi</translation> <translation id="3891340733213178823">Apăsați de două ori Ctrl+Shift+Q pentru a vă deconecta.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Dispozitiv USB-C (portul din dreapta spate)</translation> <translation id="4017989525502048489">Indicator laser</translation> <translation id="4072264167173457037">Semnal mediu</translation> +<translation id="4200057768455216496">Ai accesat comanda rapidă pentru lupa andocată. Vrei să o activezi?</translation> <translation id="4217571870635786043">Dictare</translation> <translation id="4279490309300973883">Oglindire</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Asistentul Google este dezactivat de administrator.</translation> <translation id="4895488851634969361">Bateria este încărcată complet.</translation> <translation id="4905614135390995787">Comanda rapidă pentru comutarea modului Contrast ridicat s-a modificat. Folosește <ph name="NEW_SHORTCUT" /> în loc de <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Puternic</translation> <translation id="4918086044614829423">Accept</translation> <translation id="4961318399572185831">Proiectează ecranul</translation> <translation id="5136175204352732067">Altă tastatură conectată</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Apasă Ctrl + Alt + Z ca să dezactivezi feedbackul rostit.</translation> <translation id="5648021990716966815">Mufă pentru microfon</translation> +<translation id="5669267381087807207">Se activează</translation> <translation id="5673434351075758678">Din „<ph name="FROM_LOCALE" />” în „<ph name="TO_LOCALE" />” după sincronizarea setărilor.</translation> +<translation id="574392208103952083">Medie</translation> <translation id="5744083938413354016">Tragere prin atingere</translation> <translation id="5777841717266010279">Oprești permiterea accesului la ecran?</translation> <translation id="57838592816432529">Dezactivează sunetul</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Respingeți</translation> <translation id="6453179446719226835">Limba a fost schimbată</translation> <translation id="6459472438155181876">Se extinde ecranul pe <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Lupă de ecran complet</translation> <translation id="6490471652906364588">Dispozitiv USB-C (portul din dreapta)</translation> <translation id="6501401484702599040">Se proiectează ecranul pe <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Introducerea textului prin scrierea de mână</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Fă o pauză!</translation> <translation id="683971173229319003">Tasta de căutare + L</translation> <translation id="6857811139397017780">Activează <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Această actualizare necesită rularea funcției Powerwash a dispozitivului. Află mai multe despre cea mai recentă actualizare <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Conectați-vă la altă rețea...</translation> <translation id="6981982820502123353">Accesibilitate</translation> <translation id="698231206551913481">Toate fișierele și datele locale asociate acestui utilizator vor fi șterse definitiv după eliminarea utilizatorului.</translation> <translation id="7015766095477679451">Revino la <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Ieșiți din sesiune</translation> <translation id="7034339000180558234">Se proiectează <ph name="TAB_NAME" /> pe <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Ai accesat comanda rapidă pentru contrast ridicat. Vrei să-l activezi?</translation> <translation id="7066646422045619941">Această rețea este dezactivată de administrator.</translation> <translation id="7067196344162293536">Rotire automată</translation> <translation id="7076293881109082629">Conectare</translation> <translation id="7098389117866926363">Dispozitiv USB-C (portul din stânga în spate)</translation> <translation id="7131634465328662194">Vei fi deconectat(ă) automat.</translation> +<translation id="7143207342074048698">Se conectează</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Se revine la rezoluția anterioară în <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Microfonul din spate</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Conectat la <ph name="NAME" /></translation> <translation id="813913629614996137">Se inițializează...</translation> <translation id="8142699993796781067">Rețea privată</translation> +<translation id="8152119955266188852">Ai accesat comanda rapidă pentru lupa de ecran complet. Vrei să o activezi?</translation> <translation id="8180896103888046100">Nu mai proiecta pe un receiver necunoscut</translation> <translation id="8190698733819146287">Personalizează limbile și modul de introducere...</translation> <translation id="8261506727792406068">Șterge</translation> +<translation id="8297006494302853456">Slab</translation> <translation id="8308637677604853869">Meniul anterior</translation> <translation id="8351131234907093545">Creează o notă</translation> <translation id="8392451568018454956">Meniu cu opțiuni pentru <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Butonul Înapoi</translation> <translation id="8850991929411075241">Tasta de căutare + Esc</translation> <translation id="8870509716567206129">Aplicația nu acceptă ecranul împărțit.</translation> +<translation id="8874184842967597500">Neconectat</translation> <translation id="8878886163241303700">Ecran extins</translation> <translation id="8921624153894383499">Asistentul Google nu vorbește în această limbă.</translation> <translation id="8938800817013097409">Dispozitiv USB-C (portul din dreapta în spate)</translation> <translation id="8940956008527784070">Baterie slabă (<ph name="PERCENTAGE" /> %)</translation> <translation id="8984179138335769204">Lansare rapidă</translation> <translation id="8995603266996330174">Gestionat de <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Este disponibilă o actualizare Adobe Flash Player</translation> <translation id="9033907480196064950">În prezent proiectezi <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Conectează-te cu alt nume de utilizator...</translation> <translation id="9201131092683066720">Nivelul bateriei este de <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Se iese din modul desktop unificat</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Setează o imagine de fundal</translation> <translation id="923686485342484400">Apăsați de două ori Control Shift Q pentru a vă deconecta.</translation> <translation id="945522503751344254">Trimite feedback</translation>
diff --git a/ash/strings/ash_strings_ru.xtb b/ash/strings/ash_strings_ru.xtb index 7c784548..a3364a6 100644 --- a/ash/strings/ash_strings_ru.xtb +++ b/ash/strings/ash_strings_ru.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Устройство USB-C (порт спереди)</translation> <translation id="1013923882670373915">Устройству <ph name="DEVICE_NAME" /> требуется разрешение на подключение через Bluetooth. Введите на нем PIN-код: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Батарея стилуса почти разряжена</translation> +<translation id="1056775291175587022">Нет сетей</translation> <translation id="1059194134494239015">Разрешение экрана <ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Автоматически скрывать панель запуска</translation> <translation id="1153356358378277386">Сопряженные устройства</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Снизу</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Свернуть</translation> <translation id="3126069444801937830">Перезагрузите, чтобы обновить</translation> <translation id="3147142846278915599">Панель запуска (синхронизация приложений...)</translation> <translation id="315116470104423982">Мобильное подключение</translation> @@ -197,6 +197,7 @@ <translation id="4890187583552566966">Администратор отключил Google Ассистента</translation> <translation id="4895488851634969361">Батарея полностью заряжена.</translation> <translation id="4905614135390995787">Изменились быстрые клавиши для управления режимом высокой контрастности. Используйте <ph name="NEW_SHORTCUT" /> вместо <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Сильный</translation> <translation id="4918086044614829423">Принять</translation> <translation id="4961318399572185831">Трансляция экрана</translation> <translation id="5136175204352732067">Подключена другая клавиатура</translation> @@ -220,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Чтобы отключить озвучивание текста на экране, нажмите CTRL + ALT + Z.</translation> <translation id="5648021990716966815">Микрофонный разъем</translation> +<translation id="5669267381087807207">Активация</translation> <translation id="5673434351075758678">В результате синхронизации настроек язык изменен. Теперь используется <ph name="TO_LOCALE" />, а не <ph name="FROM_LOCALE" />.</translation> +<translation id="574392208103952083">Средний</translation> <translation id="5744083938413354016">Перетаскивание нажатием</translation> <translation id="5777841717266010279">Закрыть доступ к экрану?</translation> <translation id="57838592816432529">Отключить звук</translation> @@ -303,6 +306,7 @@ <translation id="7076293881109082629">Вход</translation> <translation id="7098389117866926363">Устройство USB-C (порт слева на задней панели)</translation> <translation id="7131634465328662194">После этого вы выйдете из системы.</translation> +<translation id="7143207342074048698">Подключение</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Возврат к предыдущему разрешению через <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Основной микрофон</translation> @@ -352,6 +356,7 @@ <translation id="8180896103888046100">Остановить трансляцию на неизвестное устройство</translation> <translation id="8190698733819146287">Настройки языков и ввода…</translation> <translation id="8261506727792406068">Удалить</translation> +<translation id="8297006494302853456">Слабый</translation> <translation id="8308637677604853869">Предыдущее меню</translation> <translation id="8351131234907093545">Создать заметку</translation> <translation id="8392451568018454956">Меню параметров пользователя "<ph name="USER_EMAIL_ADDRESS" />"</translation> @@ -379,6 +384,7 @@ <translation id="8841375032071747811">Назад</translation> <translation id="8850991929411075241">Клавиша поиска + Esc</translation> <translation id="8870509716567206129">Приложение не поддерживает разделение экрана.j</translation> +<translation id="8874184842967597500">Не подключено</translation> <translation id="8878886163241303700">Раскрытый экран</translation> <translation id="8921624153894383499">Google Ассистент не говорит на этом языке</translation> <translation id="8938800817013097409">Устройство USB-C (порт справа на задней панели)</translation>
diff --git a/ash/strings/ash_strings_sk.xtb b/ash/strings/ash_strings_sk.xtb index 6ac07cb7..5f0e1f4 100644 --- a/ash/strings/ash_strings_sk.xtb +++ b/ash/strings/ash_strings_sk.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Zariadenie USB-C (port vpredu)</translation> <translation id="1013923882670373915">Zariadenie Bluetooth s názvom <ph name="DEVICE_NAME" /> žiada o povolenie párovania. Zadajte na danom zariadení toto číslo PIN: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Batéria dotykového pera je takmer vybitá</translation> +<translation id="1056775291175587022">Žiadne siete</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Automatické skrývanie poličky</translation> <translation id="1153356358378277386">Spárované zariadenia</translation> @@ -117,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Spodok</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Zbaliť</translation> <translation id="3126069444801937830">Reštartovaním vykonáte aktualizáciu</translation> <translation id="3147142846278915599">Spúšťač (synchronizujú sa aplikácie...)</translation> <translation id="315116470104423982">Mobilné dátové prenosy</translation> @@ -197,6 +197,7 @@ <translation id="4890187583552566966">Asistenta Google deaktivoval váš správca.</translation> <translation id="4895488851634969361">Batéria je úplne nabitá.</translation> <translation id="4905614135390995787">Skratka na prepnutie režimu vysokého kontrastu sa zmenila. Namiesto skratky <ph name="OLD_SHORTCUT" /> používajte kombináciu klávesov <ph name="NEW_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Silné</translation> <translation id="4918086044614829423">Prijať</translation> <translation id="4961318399572185831">Prenášanie obrazovky</translation> <translation id="5136175204352732067">Bola pripojená iná klávesnica</translation> @@ -220,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Hovorenú spätnú väzbu zakážete kombináciou klávesov Ctrl+Alt+Z.</translation> <translation id="5648021990716966815">Konektor mikrofónu</translation> +<translation id="5669267381087807207">Prebieha aktivácia</translation> <translation id="5673434351075758678">Po synchronizácii nastavení bol zmenený z možnosti <ph name="FROM_LOCALE" /> na <ph name="TO_LOCALE" />.</translation> +<translation id="574392208103952083">Stredné</translation> <translation id="5744083938413354016">Presunutie klepnutím</translation> <translation id="5777841717266010279">Chcete ukončiť zdieľanie obrazovky?</translation> <translation id="57838592816432529">Vypnúť zvuk</translation> @@ -303,6 +306,7 @@ <translation id="7076293881109082629">Prihlásenie</translation> <translation id="7098389117866926363">Zariadenie USB-C (ľavý port vzadu)</translation> <translation id="7131634465328662194">Odhlásenie prebehne automaticky.</translation> +<translation id="7143207342074048698">Pripája sa</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Vrátenie starého rozlíšenia prebehne o <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Zadný mikrofóm</translation> @@ -352,6 +356,7 @@ <translation id="8180896103888046100">Zastaviť prenos do neznámeho zariadenia</translation> <translation id="8190698733819146287">Prebieha prispôsobenie jazykov a vstupu...</translation> <translation id="8261506727792406068">Odstrániť</translation> +<translation id="8297006494302853456">Slabé</translation> <translation id="8308637677604853869">Predchádzajúca ponuka</translation> <translation id="8351131234907093545">Vytvoriť poznámku</translation> <translation id="8392451568018454956">Ponuka možností pre používateľa <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -379,6 +384,7 @@ <translation id="8841375032071747811">Tlačidlo Späť</translation> <translation id="8850991929411075241">Hľadať+Esc</translation> <translation id="8870509716567206129">Aplikácia nepodporuje rozdelenú obrazovku.</translation> +<translation id="8874184842967597500">Nepripojené</translation> <translation id="8878886163241303700">Rozšírenie obrazovky</translation> <translation id="8921624153894383499">Asistent Google nehovorí týmto jazykom.</translation> <translation id="8938800817013097409">Zariadenie USB-C (pravý port vzadu)</translation>
diff --git a/ash/strings/ash_strings_sl.xtb b/ash/strings/ash_strings_sl.xtb index 96602c4..2985701 100644 --- a/ash/strings/ash_strings_sl.xtb +++ b/ash/strings/ash_strings_sl.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Naprava USB-C (sprednja vrata)</translation> <translation id="1013923882670373915">Naprava Bluetooth »<ph name="DEVICE_NAME" />« želi dovoljenje za seznanjanje. V napravi vnesite ta PIN: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Baterija pisala je skoraj izpraznjena</translation> +<translation id="1056775291175587022">Ni omrežij</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Samodejno skrivanje police</translation> <translation id="1153356358378277386">Seznanjene naprave</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">V desno</translation> <translation id="1383876407941801731">Išči</translation> <translation id="1467432559032391204">V levo</translation> +<translation id="1479743070547893297">Narišite s pisalom, če želite izbirati</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Zaganjalnik</translation> <translation id="1525508553941733066">OPUSTI</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Nastavitev jezika</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Več informacij o najnovejši posodobitvi za <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Izklop</translation> <translation id="2012624427112548395">Ctrl+ tipka za iskanje + H</translation> +<translation id="2016340657076538683">Vnesite sporočilo</translation> <translation id="2049639323467105390">To napravo upravlja <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Pokončno</translation> <translation id="2067602449040652523">Svetlost tipkovnice</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Nadaljuj</translation> <translation id="2365393535144473978">Če omogočite prenos podatkov v mobilnem omrežju, bo omogočen Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Na voljo je posodobitev</translation> <translation id="2429753432712299108">Naprava Bluetooth »<ph name="DEVICE_NAME" />« želi dovoljenje za seznanjanje. Preden sprejmete, se prepričajte, da je na napravi prikazano to geslo: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Obvestila</translation> <translation id="2484513351006226581">Pritisnite <ph name="KEYBOARD_SHORTCUT" />, če želite preklopiti postavitev tipkovnice</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Tipka CAPS LOCK je vklopljena</translation> <translation id="2532589005999780174">Visokokontrastni način</translation> <translation id="2575685495496069081">Prijava z več računi je onemogočena</translation> +<translation id="2582112259361606227">Znova zaženite za posodobitev</translation> <translation id="2597972630681408282">Nočna svetloba: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Kartica SIM je zaklenjena</translation> <translation id="2653659639078652383">Pošlji</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Trenutno imate zaslon v skupni rabi.</translation> <translation id="2942516765047364088">Položaj police</translation> <translation id="2946119680249604491">Dodaj povezavo</translation> +<translation id="2961963223658824723">Prišlo je do napake. Poskusite znova čez nekaj sekund.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> je javna seja, ki jo upravlja <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Mono zvok</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Na dno</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Strni</translation> <translation id="3126069444801937830">Znova zaženite za posodobitev</translation> <translation id="3147142846278915599">Zaganjalnik (sinhronizacija aplikacij ...)</translation> <translation id="315116470104423982">Prenos podatkov v mobilnih omrežjih</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Zakleni</translation> <translation id="3798670284305777884">Zvočnik (vgrajeni)</translation> +<translation id="380165613292957338">Živijo. Kako lahko pomagam?</translation> <translation id="3846575436967432996">Ni podatkov o omrežju</translation> <translation id="385051799172605136">Nazaj</translation> <translation id="3891340733213178823">Dvakrat pritisnite Ctrl + Shift + Q, če se želite odjaviti.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Naprava USB-C (vrata desno zadaj)</translation> <translation id="4017989525502048489">Laserski kazalnik</translation> <translation id="4072264167173457037">Srednje močan signal</translation> +<translation id="4200057768455216496">Pritisnili ste bližnjico za zasidrano lupo. Ali jo želite vklopiti?</translation> <translation id="4217571870635786043">Narek</translation> <translation id="4279490309300973883">Zrcaljenje</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Skrbnik je onemogočil Pomočnika Google.</translation> <translation id="4895488851634969361">Akumulator je poln.</translation> <translation id="4905614135390995787">Bližnjica za preklop na visokokontrastni način se je spremenila. Uporabite <ph name="NEW_SHORTCUT" /> namesto <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Močan</translation> <translation id="4918086044614829423">Sprejmi</translation> <translation id="4961318399572185831">Predvajanje zaslona</translation> <translation id="5136175204352732067">Priklopljena je druga tipkovnica</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Če želite onemogočiti glasovni odziv, pritisnite Ctrl + Alt + Z.</translation> <translation id="5648021990716966815">Vtič za mikrofon</translation> +<translation id="5669267381087807207">Aktiviranje</translation> <translation id="5673434351075758678">Iz jezika »<ph name="FROM_LOCALE" />« v jezik »<ph name="TO_LOCALE" />« po sinhronizaciji nastavitev.</translation> +<translation id="574392208103952083">Srednja</translation> <translation id="5744083938413354016">Vlečenje z dotikom</translation> <translation id="5777841717266010279">Želite ustaviti skupno rabo zaslona?</translation> <translation id="57838592816432529">Izklopi zvok</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Zavrni</translation> <translation id="6453179446719226835">Jezik je spremenjen</translation> <translation id="6459472438155181876">Razširitev zaslon na <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Celozaslonska lupa</translation> <translation id="6490471652906364588">Naprava USB-C (desna vrata)</translation> <translation id="6501401484702599040">Predvajanje zaslona v napravi <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Vnos z rokopisom</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Čas za odmor!</translation> <translation id="683971173229319003">Iskanje + L</translation> <translation id="6857811139397017780">Aktiviraj <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Pred namestitvijo te posodobitve morate uporabiti funkcijo Powerwash. Preberite več o najnovejši posodobitvi za <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Pridružitev drugemu omrežju ...</translation> <translation id="6981982820502123353">Dostopnost</translation> <translation id="698231206551913481">Vse datoteke in lokalni podatki, povezani s tem uporabnikom, bodo trajno izbrisani, ko odstranite uporabnika.</translation> <translation id="7015766095477679451">Vrnite se ob <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Zapusti sejo</translation> <translation id="7034339000180558234">Predvajanje zavihka v <ph name="TAB_NAME" /> sprejemniku <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Pritisnili ste bližnjico za visoki kontrast. Ali ga želite vklopiti?</translation> <translation id="7066646422045619941">To omrežje je onemogočil skrbnik.</translation> <translation id="7067196344162293536">Samodejno sukanje</translation> <translation id="7076293881109082629">Prijava</translation> <translation id="7098389117866926363">Naprava USB-C (vrata levo zadaj)</translation> <translation id="7131634465328662194">Samodejno boste odjavljeni.</translation> +<translation id="7143207342074048698">Vzpostavljanje povezave</translation> <translation id="7165278925115064263">Alt + Shift + K</translation> <translation id="7168224885072002358">Ponastavitev na prejšnjo ločljivost čez <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Zadnji mikrofon</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Povezava z <ph name="NAME" /> je vzpostavljena </translation> <translation id="813913629614996137">Inicializiranje ...</translation> <translation id="8142699993796781067">Zasebno omrežje</translation> +<translation id="8152119955266188852">Pritisnili ste bližnjico za celozaslonsko lupo. Ali jo želite vklopiti?</translation> <translation id="8180896103888046100">Ustvari predvajanje v neznanem sprejemniku</translation> <translation id="8190698733819146287">Prilagajanje jezikov in vnosa ...</translation> <translation id="8261506727792406068">Izbriši</translation> +<translation id="8297006494302853456">Šibek</translation> <translation id="8308637677604853869">Prejšnji meni</translation> <translation id="8351131234907093545">Ustvarjanje zapiska</translation> <translation id="8392451568018454956">Meni z možnostmi za <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Gumb za nazaj</translation> <translation id="8850991929411075241">Iskanje + Esc</translation> <translation id="8870509716567206129">Aplikacija ne podpira načina razdeljenega zaslona.</translation> +<translation id="8874184842967597500">Povezava ni vzpostavljena</translation> <translation id="8878886163241303700">Razširjanje zaslona</translation> <translation id="8921624153894383499">Pomočnik Google ne podpira tega jezika.</translation> <translation id="8938800817013097409">Naprava USB-C (vrata desno zadaj)</translation> <translation id="8940956008527784070">Akumulator je skoraj prazen (<ph name="PERCENTAGE" /> %)</translation> <translation id="8984179138335769204">Hitri zagon</translation> <translation id="8995603266996330174">Upravljavec: <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Na voljo je posodobitev za Adobe Flash Player</translation> <translation id="9033907480196064950">Trenutno predvajate <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Prijava drugega uporabnika ...</translation> <translation id="9201131092683066720">Napolnjenost akumulatorja: <ph name="PERCENTAGE" /> %.</translation> <translation id="9210037371811586452">Izhod iz načina enotnega namizja</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Nastavi sliko za ozadje</translation> <translation id="923686485342484400">Dvakrat pritisnite Control Shift Q, če se želite odjaviti.</translation> <translation id="945522503751344254">Pošlji povratne informacije</translation>
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb index fed3b74..4416c0ee 100644 --- a/ash/strings/ash_strings_sr.xtb +++ b/ash/strings/ash_strings_sr.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Уређај са USB прикључком типа C (предњи порт)</translation> <translation id="1013923882670373915">Bluetooth уређај „<ph name="DEVICE_NAME" />“ жели дозволу за упаривање. Унесите овај PIN кôд на том уређају: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Батерија писаљке је скоро празна</translation> +<translation id="1056775291175587022">Нема мрежа</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Аутоматски сакриј полицу</translation> <translation id="1153356358378277386">Упарени уређаји</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Удесно</translation> <translation id="1383876407941801731">Претражи</translation> <translation id="1467432559032391204">Улево</translation> +<translation id="1479743070547893297">Цртајте писаљком да бисте изабрали</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Покретач</translation> <translation id="1525508553941733066">ОДБАЦИ</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Подесите језик</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Сазнајте више о најновијем ажурирању за: <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Искључи</translation> <translation id="2012624427112548395">Ctrl + тастер за претрагу + H</translation> +<translation id="2016340657076538683">Унесите поруку</translation> <translation id="2049639323467105390">Овим уређајем управља домен <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Вертикално</translation> <translation id="2067602449040652523">Осветљеност тастатуре</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Настави</translation> <translation id="2365393535144473978">Ако омогућите мобилне податке, омогућавате Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Доступно је ажурирање</translation> <translation id="2429753432712299108">Bluetooth уређај „<ph name="DEVICE_NAME" />“ жели дозволу за упаривање. Пре него што му је дате, уверите се да је ова шифра приказана на том уређају: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Обавештења</translation> <translation id="2484513351006226581">Притисните <ph name="KEYBOARD_SHORTCUT" /> да бисте променили распоред тастатуре.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK је укључен</translation> <translation id="2532589005999780174">Режим високог контраста</translation> <translation id="2575685495496069081">Онемогућено је вишеструко пријављивање</translation> +<translation id="2582112259361606227">Рестартујте да бисте ажурирали</translation> <translation id="2597972630681408282">Ноћно светло: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM картица је закључана</translation> <translation id="2653659639078652383">Пошаљи</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Делите екран</translation> <translation id="2942516765047364088">Положај полице</translation> <translation id="2946119680249604491">Додај везу</translation> +<translation id="2961963223658824723">Нешто није у реду. Пробајте поново за пар секунди.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> је јавна сесија којом управља <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Моно звук</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Дно</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Скупите</translation> <translation id="3126069444801937830">Покрените поново да бисте ажурирали</translation> <translation id="3147142846278915599">Покретач (апликације се синхронизују...)</translation> <translation id="315116470104423982">Мобилни подаци</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Закључај</translation> <translation id="3798670284305777884">Звучник (интерни)</translation> +<translation id="380165613292957338">Здраво, како могу да помогнем?</translation> <translation id="3846575436967432996">Нису доступне информације о мрежи</translation> <translation id="385051799172605136">Назад</translation> <translation id="3891340733213178823">Двапут притисните Ctrl+Shift+Q да бисте се одјавили.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Уређај са USB прикључком типа C (десни задњи порт)</translation> <translation id="4017989525502048489">Ласерски показивач</translation> <translation id="4072264167173457037">Сигнал средње јачине</translation> +<translation id="4200057768455216496">Притиснули сте пречицу за монтирану лупу екрана. Желите ли да је укључите?</translation> <translation id="4217571870635786043">Диктирање</translation> <translation id="4279490309300973883">Пресликавање</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Администратор је онемогућио Google помоћник.</translation> <translation id="4895488851634969361">Батерија је пуна.</translation> <translation id="4905614135390995787">Пречица за укључивање и искључивање режима високог контраста је промењена. Користите <ph name="NEW_SHORTCUT" /> уместо <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Јак</translation> <translation id="4918086044614829423">Прихвати</translation> <translation id="4961318399572185831">Пребацивање екрана</translation> <translation id="5136175204352732067">Нека друга тастатура је повезана</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" /> <ph name="DATE" /></translation> <translation id="5600837773213129531">Притисните Ctrl + Alt + Z да бисте онемогућили говорне повратне информације.</translation> <translation id="5648021990716966815">Утикач за микрофон</translation> +<translation id="5669267381087807207">Активирање</translation> <translation id="5673434351075758678">Са језика „<ph name="FROM_LOCALE" />“ на „<ph name="TO_LOCALE" />“ после синхронизације уређаја.</translation> +<translation id="574392208103952083">Средња</translation> <translation id="5744083938413354016">Превлачење додиром</translation> <translation id="5777841717266010279">Желите ли да прекинете дељење екрана?</translation> <translation id="57838592816432529">Искључи звук</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Одбиј</translation> <translation id="6453179446719226835">Језик је промењен</translation> <translation id="6459472438155181876">Проширивање екрана у <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Лупа за цео екран</translation> <translation id="6490471652906364588">Уређај са USB прикључком типа C (десни порт)</translation> <translation id="6501401484702599040">Екран се пребацује на <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Унос рукописа</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Направите паузу!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">Активирај <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Ово ажурирање захтева да обавите powerwash на уређају. Сазнајте више о најновијем ажурирању за: <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Придружи ме другој...</translation> <translation id="6981982820502123353">Приступачност</translation> <translation id="698231206551913481">Све датотеке и локални подаци повезани са овим корисником ће бити трајно избрисани када уклоните овог корисника.</translation> <translation id="7015766095477679451">Вратите се у <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Изађи из сесије</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> се пребацује на <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Притиснули сте пречицу за високи контраст. Желите ли да је укључите?</translation> <translation id="7066646422045619941">Ову мрежу је онемогућио администратор.</translation> <translation id="7067196344162293536">Аутоматски ротирај</translation> <translation id="7076293881109082629">Пријављивање</translation> <translation id="7098389117866926363">Уређај са USB прикључком типа C (леви задњи порт)</translation> <translation id="7131634465328662194">Одјавићемо вас аутоматски.</translation> +<translation id="7143207342074048698">Повезивање</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Враћање на стару резолуцију за <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Задњи микрофон</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Успостављена је веза са <ph name="NAME" /></translation> <translation id="813913629614996137">Покреће се…</translation> <translation id="8142699993796781067">Приватна мрежа</translation> +<translation id="8152119955266188852">Притиснули сте пречицу за лупу за цео екран. Желите ли да је укључите?</translation> <translation id="8180896103888046100">Заустави пребацивање на непознати пријемник</translation> <translation id="8190698733819146287">Прилагоди језике и унос...</translation> <translation id="8261506727792406068">Избриши</translation> +<translation id="8297006494302853456">Слаб</translation> <translation id="8308637677604853869">Претходни мени</translation> <translation id="8351131234907093545">Направите белешку</translation> <translation id="8392451568018454956">Мени са опцијама за <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Дугме Назад</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">Апликација не подржава подељени екран.</translation> +<translation id="8874184842967597500">Није повезано</translation> <translation id="8878886163241303700">Проширени екран</translation> <translation id="8921624153894383499">Google помоћник не говори овај језик.</translation> <translation id="8938800817013097409">Уређај са USB прикључком типа C (задњи десни порт)</translation> <translation id="8940956008527784070">Батерија је скоро празна (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Брзо покретање</translation> <translation id="8995603266996330174">Управља <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Доступно је ажурирање за Adobe Flash Player</translation> <translation id="9033907480196064950">Тренутно пребацујете <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Пријавите још једног корисника...</translation> <translation id="9201131092683066720">Батерија је <ph name="PERCENTAGE" />% пуна.</translation> <translation id="9210037371811586452">Излазак из режима спојених радних површина</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Подеси позадину</translation> <translation id="923686485342484400">Двапут притисните Control Shift Q да бисте се одјавили.</translation> <translation id="945522503751344254">Пошаљи повратне информације</translation>
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb index e6b87b1..3b287be 100644 --- a/ash/strings/ash_strings_sv.xtb +++ b/ash/strings/ash_strings_sv.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C-enhet (främre port)</translation> <translation id="1013923882670373915">Bluetooth-enheten <ph name="DEVICE_NAME" /> har begärt tillstånd för koppling. Ange den här pinkoden på den enheten: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Batteriet håller på att ta slut i e-pennan</translation> +<translation id="1056775291175587022">Inga nätverk</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Dölj hyllan automatiskt</translation> <translation id="1153356358378277386">Kopplade enheter</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Höger</translation> <translation id="1383876407941801731">Sök</translation> <translation id="1467432559032391204">Vänster</translation> +<translation id="1479743070547893297">Välj genom att rita med e-pennan</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Startprogram</translation> <translation id="1525508553941733066">IGNORERA</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Ställ in språk</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Läs mer om den senaste uppdateringen av <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Stäng av</translation> <translation id="2012624427112548395">Ctrl+Sök+H</translation> +<translation id="2016340657076538683">Skriv ett meddelande</translation> <translation id="2049639323467105390">Den här enheten hanteras av <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Stående</translation> <translation id="2067602449040652523">Ljusstyrka för tangentbordet</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Fortsätt</translation> <translation id="2365393535144473978">Om du aktiverar mobildata aktiveras Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Det finns en uppdatering</translation> <translation id="2429753432712299108">Bluetooth-enheten <ph name="DEVICE_NAME" /> har begärt tillstånd för koppling. Innan du godkänner bekräftar du att den här lösenordsnyckeln visas på den enheten: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Aviseringar</translation> <translation id="2484513351006226581">Tryck på <ph name="KEYBOARD_SHORTCUT" /> om du vill byta tangentbordslayout.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK är på</translation> <translation id="2532589005999780174">Högkontrastläge</translation> <translation id="2575685495496069081">Multiinloggning har inaktiverats</translation> +<translation id="2582112259361606227">Starta om för att uppdatera</translation> <translation id="2597972630681408282">Nattljus: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM-kortet är låst</translation> <translation id="2653659639078652383">Skicka</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Du delar skärmen</translation> <translation id="2942516765047364088">Hyllposition</translation> <translation id="2946119680249604491">Lägg till anslutning</translation> +<translation id="2961963223658824723">Ett fel har uppstått. Försök igen om några sekunder.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> är en offentlig session som hanteras av <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Monoljud</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">skift</translation> <translation id="3087734570205094154">Nederst</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Komprimera</translation> <translation id="3126069444801937830">Starta om för att uppdatera</translation> <translation id="3147142846278915599">Översikt (appar synkroniseras …)</translation> <translation id="315116470104423982">Mobildata</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Lås</translation> <translation id="3798670284305777884">Högtalare (inbyggd)</translation> +<translation id="380165613292957338">Hej. Hur kan jag hjälpa dig?</translation> <translation id="3846575436967432996">Det finns ingen nätverksinformation</translation> <translation id="385051799172605136">Bakåt</translation> <translation id="3891340733213178823">Tryck på Ctrl+Skift+Q två gånger om du vill logga ut.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C-enhet (bakre porten på högra sidan)</translation> <translation id="4017989525502048489">Laserpekare</translation> <translation id="4072264167173457037">medelstark signal</translation> +<translation id="4200057768455216496">Du tryckte på kortkommandot för dockad skärmförstoring. Vill du aktivera funktionen?</translation> <translation id="4217571870635786043">Diktering</translation> <translation id="4279490309300973883">Spegling</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Administratören har inaktiverat Google Assistent.</translation> <translation id="4895488851634969361">Batteriet är fullt.</translation> <translation id="4905614135390995787">Kortkommandot för att aktivera och inaktivera högkontrastläget har ändrats. Använd <ph name="NEW_SHORTCUT" /> i stället för <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Stark</translation> <translation id="4918086044614829423">Acceptera</translation> <translation id="4961318399572185831">Casta skärmen</translation> <translation id="5136175204352732067">Ett annat tangentbord har anslutits</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Inaktivera talad feedback genom att trycka på Ctrl + Alt + Z.</translation> <translation id="5648021990716966815">Mikrofonuttag</translation> +<translation id="5669267381087807207">Aktiverar</translation> <translation id="5673434351075758678">Från <ph name="FROM_LOCALE" /> till <ph name="TO_LOCALE" /> efter synkronisering av inställningarna.</translation> +<translation id="574392208103952083">Medium</translation> <translation id="5744083938413354016">Tryck snabbt två gånger och dra</translation> <translation id="5777841717266010279">Vill du avbryta skärmdelningen?</translation> <translation id="57838592816432529">Stäng av ljudet</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Avvisa</translation> <translation id="6453179446719226835">Språket har ändrats</translation> <translation id="6459472438155181876">Utökar skärmen till <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Helskärmsförstoring</translation> <translation id="6490471652906364588">USB-C-enhet (höger port)</translation> <translation id="6501401484702599040">Skärmen castas till <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Inmatning för handskrift</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Ta en paus!</translation> <translation id="683971173229319003">Sök+L</translation> <translation id="6857811139397017780">Aktivera <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Den här uppdateringen kräver att en Powerwash görs av enheten. Läs mer om den senaste uppdateringen av <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Anslut till andra ...</translation> <translation id="6981982820502123353">Tillgänglighet</translation> <translation id="698231206551913481">Alla filer inklusive lokal data som tillhör den här användaren tas bort permanent när användaren tas bort.</translation> <translation id="7015766095477679451">Prova igen klockan <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Avsluta session</translation> <translation id="7034339000180558234">Castar <ph name="TAB_NAME" /> till <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Du tryckte på kortkommandot för högkontrastläge. Vill du aktivera funktionen?</translation> <translation id="7066646422045619941">Det här nätverket har inaktiverats av administratören.</translation> <translation id="7067196344162293536">Rotera automatiskt</translation> <translation id="7076293881109082629">Logga in</translation> <translation id="7098389117866926363">USB-C-enhet (vänstra porten på baksidan)</translation> <translation id="7131634465328662194">Du loggas ut automatiskt.</translation> +<translation id="7143207342074048698">Ansluter</translation> <translation id="7165278925115064263">Alt + Skift + K</translation> <translation id="7168224885072002358">Återgår till den gamla upplösningen om <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Mikrofonen på baksidan</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">Ansluten till <ph name="NAME" /></translation> <translation id="813913629614996137">Initierar …</translation> <translation id="8142699993796781067">Privat nätverk</translation> +<translation id="8152119955266188852">Du tryckte på kortkommandot för helskärmsförstoring. Vill du aktivera funktionen?</translation> <translation id="8180896103888046100">Sluta casta till en okänd mottagare</translation> <translation id="8190698733819146287">Anpassa språk och inmatning...</translation> <translation id="8261506727792406068">Radera</translation> +<translation id="8297006494302853456">Svag</translation> <translation id="8308637677604853869">Föregående meny</translation> <translation id="8351131234907093545">Skapa anteckning</translation> <translation id="8392451568018454956">Alternativmenyn för <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Bakåtknapp</translation> <translation id="8850991929411075241">Sök+Escape</translation> <translation id="8870509716567206129">Appen har inte stöd för delad skärm.</translation> +<translation id="8874184842967597500">Inte ansluten</translation> <translation id="8878886163241303700">Utökad skärm</translation> <translation id="8921624153894383499">Google Assistent talar inte det här språket.</translation> <translation id="8938800817013097409">USB-C-enhet (högra porten på baksidan)</translation> <translation id="8940956008527784070">Låg batterinivå (<ph name="PERCENTAGE" /> %)</translation> <translation id="8984179138335769204">Snabbstart</translation> <translation id="8995603266996330174">Hanteras av <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">En uppdatering av Adobe Flash Player är tillgänglig</translation> <translation id="9033907480196064950"><ph name="TAB_NAME" /> castas</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Logga in med en annan användare ...</translation> <translation id="9201131092683066720">Batteriet är fullt till <ph name="PERCENTAGE" /> %.</translation> <translation id="9210037371811586452">Enhetligt skrivbordsläge avslutas</translation> +<translation id="921331154633982721"><ph name="LABEL" /> – <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Ange bakgrund</translation> <translation id="923686485342484400">Tryck på Control + skift + Q två gånger om du vill logga ut.</translation> <translation id="945522503751344254">Skicka synpunkter</translation>
diff --git a/ash/strings/ash_strings_sw.xtb b/ash/strings/ash_strings_sw.xtb index 9d1c21c..0139bf4b 100644 --- a/ash/strings/ash_strings_sw.xtb +++ b/ash/strings/ash_strings_sw.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Kifaa cha USB-C (mlango wa mbele)</translation> <translation id="1013923882670373915">Kifaa cha Bluetooth cha "<ph name="DEVICE_NAME" />" kinaomba idhini ya kuoanisha. Tafadhali weka nambari hii ya PIN kwenye kifaa hicho: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Chaji ya betri ya Stylus imepungua</translation> +<translation id="1056775291175587022">Hakuna mitandao</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Ficha rafu kiotomatiki</translation> <translation id="1153356358378277386">Vifaa vilivyooanishwa</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Kulia</translation> <translation id="1383876407941801731">Tafuta</translation> <translation id="1467432559032391204">Kushoto</translation> +<translation id="1479743070547893297">Chora ukitumia stylus ili uchague</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Kizindua</translation> <translation id="1525508553941733066">ONDOA</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Weka lugha yako</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Pata maelezo zaidi kuhusu sasisho la hivi karibuni la <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Zima</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">Andika ujumbe</translation> <translation id="2049639323467105390">Kifaa hiki kinadhibitiwa na <ph name="DOMAIN" /> .</translation> <translation id="2050339315714019657">Wima</translation> <translation id="2067602449040652523">Ung'avu wa kibodi</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Endelea</translation> <translation id="2365393535144473978">Kuwasha data ya mtandao wa simu kutawasha Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Sasisho linapatikana</translation> <translation id="2429753432712299108">Kifaa cha Bluetooth cha "<ph name="DEVICE_NAME" />" kinaomba idhini ya kuoanisha. Kabla hujakubali, tafadhali thibitisha kwamba nenosiri hili linaonyeshwa kwenye kifaa hicho: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Arifa</translation> <translation id="2484513351006226581">Gonga <ph name="KEYBOARD_SHORTCUT" /> ili ubadilishe mpangilio wa kibodi.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Caps Lock imewashwa.</translation> <translation id="2532589005999780174">Hali ya juu ya utofautishaji</translation> <translation id="2575685495496069081">Umezima uwezo wa kuingia katika akaunti nyingi kwa wakati mmoja</translation> +<translation id="2582112259361606227">Zima kisha uwashe ili usasishe</translation> <translation id="2597972630681408282">Mwanga wa Usiku: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM kadi imefungwa</translation> <translation id="2653659639078652383">Wasilisha</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Unashiriki skrini yako</translation> <translation id="2942516765047364088">Nafasi ya rafu</translation> <translation id="2946119680249604491">Ongeza muunganisho</translation> +<translation id="2961963223658824723">Hitilafu fulani imetokea. Jaribu tena baada ya sekunde chache.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> ni kipindi cha kila mtu kinachodhibitiwa na <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Kipengele cha sauti moja</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Chini</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Kunja</translation> <translation id="3126069444801937830">Anzisha upya ili kusasisha</translation> <translation id="3147142846278915599">Kifungua programu (inasawazisha programu...)</translation> <translation id="315116470104423982">Data ya mtandao wa simu</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Funga</translation> <translation id="3798670284305777884">Spika (ya ndani)</translation> +<translation id="380165613292957338">Hujambo, ungependa nikusaidie vipi?</translation> <translation id="3846575436967432996">Hakuna maelezo ya mtandao yanayopatikana</translation> <translation id="385051799172605136">Nyuma</translation> <translation id="3891340733213178823">Bonyeza Ctrl+Shift+Q mara mbili ili kuondoka katika akaunti.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Kifaa cha USB-C (mlango wa upande wa kulia nyuma)</translation> <translation id="4017989525502048489">Kielekezi cha leza</translation> <translation id="4072264167173457037">Mtandao ni thabiti kiasi</translation> +<translation id="4200057768455216496">Umebofya njia ya mkato ya kikuzaji kilichoambatishwa. Ungependa kukiwasha?</translation> <translation id="4217571870635786043">Kuandika kwa kutamka</translation> <translation id="4279490309300973883">Kuakisi</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Programu ya Mratibu wa Google imezimwa na msimamizi wako.</translation> <translation id="4895488851634969361">Betri imejaa.</translation> <translation id="4905614135390995787">Njia ya mkato ya kugeuza Hali ya Utofautishaji wa Juu imebadilika. Tafadhali tumia <ph name="NEW_SHORTCUT" /> badala ya <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Thabiti</translation> <translation id="4918086044614829423">Kubali</translation> <translation id="4961318399572185831">Tuma skrini</translation> <translation id="5136175204352732067">Kibodi tofauti imeunganishwa</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Bonyeza Ctrl + Alt + Z ili uzime kipengele cha maelezo yanayotamkwa.</translation> <translation id="5648021990716966815">Pini ya maikrofoni</translation> +<translation id="5669267381087807207">Inaamilisha</translation> <translation id="5673434351075758678">Imebadalisha lugha kutoka "<ph name="FROM_LOCALE" />" kuwa "<ph name="TO_LOCALE" />" baada ya kusawazisha mipangilio yako.</translation> +<translation id="574392208103952083">Wastani</translation> <translation id="5744083938413354016">Uburutaji wa kugonga</translation> <translation id="5777841717266010279">Je,ungependa kuacha kushiriki skrini?</translation> <translation id="57838592816432529">Zima sauti</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Kataa</translation> <translation id="6453179446719226835">Lugha imebadilishwa</translation> <translation id="6459472438155181876">Inapanua skrini kwenye <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Kikuzaji cha skrini nzima</translation> <translation id="6490471652906364588">Kifaa cha USB-C (mlango wa kulia)</translation> <translation id="6501401484702599040">Inatuma skrini kwenye <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Kuingiza data kwa mwandiko wa mkono</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Pumzika kidogo!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">Amilisha <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Sasisho hili linahitaji powerwashing kwenye kifaa chako. Pata maelezo zaidi kuhusu sasisho jipya la <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Jiunge na mwingine...</translation> <translation id="6981982820502123353">Upatikanaji</translation> <translation id="698231206551913481">Faili na data zote zilizo kwenye kifaa zinazohusishwa na mtumiaji zitafutwa kabisa pindi tu mtumiaji huyu atakapoondolewa.</translation> <translation id="7015766095477679451">Rejea saa <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Toka kwenye kipindi</translation> <translation id="7034339000180558234">Inatuma <ph name="TAB_NAME" /> kwenye <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Umebofya njia ya mkato ya utofautishaji wa juu. Ungependa kuuwasha?</translation> <translation id="7066646422045619941">Mtandao huu umezimwa na msimamizi wako.</translation> <translation id="7067196344162293536">Zungusha kiotomatiki</translation> <translation id="7076293881109082629">Unaingia katika akaunti</translation> <translation id="7098389117866926363">Kifaa cha USB-C (mlango wa kushoto nyuma)</translation> <translation id="7131634465328662194">Utaondolewa kwenye akaunti kiotomatiki.</translation> +<translation id="7143207342074048698">Inaunganisha</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Inarejesha katika ubora wa zamani baada ya <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Maikrofoni ya nyuma</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Imeunganishwa kwenye <ph name="NAME" /></translation> <translation id="813913629614996137">Inaanzisha…</translation> <translation id="8142699993796781067">Mtandao binafsi</translation> +<translation id="8152119955266188852">Umebofya njia ya mkato ya kikuzaji cha skrini nzima. Ungependa kukiwasha?</translation> <translation id="8180896103888046100">Acha kutuma kwenye kipokeaji kisichojulikana</translation> <translation id="8190698733819146287">Geuza lugha na uingizaji kukufaa...</translation> <translation id="8261506727792406068">Futa</translation> +<translation id="8297006494302853456">Dhaifu</translation> <translation id="8308637677604853869">Menyu ya awali</translation> <translation id="8351131234907093545">Unda kidokezo</translation> <translation id="8392451568018454956">Menyu ya chaguo za <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Kitufe cha Nyuma</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">Programu haiwezi kutumia skrini iliyogawanywa.</translation> +<translation id="8874184842967597500">Haijaunganishwa</translation> <translation id="8878886163241303700">Kuongeza skrini</translation> <translation id="8921624153894383499">Programu ya Mratibu wa Google haina huduma ya lugha hii.</translation> <translation id="8938800817013097409">Kifaa cha USB-C (mlango wa kulia nyuma)</translation> <translation id="8940956008527784070">Betri inaisha (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Kufungua kwa kasi</translation> <translation id="8995603266996330174">Inadhibitiwa na <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Sasisho la Adobe Flash Player linapatikana</translation> <translation id="9033907480196064950">Kwa sasa unatuma <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Ongeza akaunti nyingine...</translation> <translation id="9201131092683066720">Betri imejaa <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Mfumo unaondoka kwenye hali ya eneo-kazi lililounganishwa</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Weka mandhari</translation> <translation id="923686485342484400">Bonyeza Control Shift Q mara mbili ili kuondoka katika akaunti.</translation> <translation id="945522503751344254">Tuma maoni</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb index 1c73c5d..f470e51 100644 --- a/ash/strings/ash_strings_ta.xtb +++ b/ash/strings/ash_strings_ta.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C சாதனம் (முன்பக்கப் போர்ட்)</translation> <translation id="1013923882670373915">புளூடூத் சாதனம் "<ph name="DEVICE_NAME" />", இணைப்பதற்கான அனுமதியை விரும்புகிறது. அந்தச் சாதனத்தில் இந்த PIN குறியீட்டை உள்ளிடவும்: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">ஸ்டைலஸ் பேட்டரி குறைவாக உள்ளது</translation> +<translation id="1056775291175587022">நெட்வொர்க்குகள் இல்லை</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">அடுக்கைத் தானாக மறை</translation> <translation id="1153356358378277386">இணைத்த சாதனங்கள்</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">வலது</translation> <translation id="1383876407941801731">தேடல்</translation> <translation id="1467432559032391204">இடது</translation> +<translation id="1479743070547893297">தேர்ந்தெடுக்க, உங்கள் ஸ்டைலஸைப் பயன்படுத்தி வரையவும்</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">துவக்கி</translation> <translation id="1525508553941733066">நிராகரி</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">எனது மொழியை அமை</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">சமீபத்திய <ph name="SYSTEM_APP_NAME" /> புதுப்பிப்பைப் பற்றி மேலும் அறிக</translation> <translation id="1995660704900986789">முடக்கு</translation> <translation id="2012624427112548395">கன்ட்ரோல்+தேடல்+H</translation> +<translation id="2016340657076538683">செய்தியை உள்ளிடவும்</translation> <translation id="2049639323467105390"><ph name="DOMAIN" /> ஆல் இந்த சாதனம் நிர்வகிக்கப்படுகிறது.</translation> <translation id="2050339315714019657">செங்குத்து நிலை</translation> <translation id="2067602449040652523">விசைப்பலகை ஒளிர்வு</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">தொடர்க</translation> <translation id="2365393535144473978">மொபைல் டேட்டாவை இயக்கினால், புளூடூத் இயக்கப்படும்.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">புதுப்பிப்பு உள்ளது</translation> <translation id="2429753432712299108">புளூடூத் சாதனம் "<ph name="DEVICE_NAME" />", இணைப்பதற்கான அனுமதியை விரும்புகிறது. ஏற்றுக்கொள்வதற்கு முன்னர், இந்தக் கடவுச்சொல் அந்தச் சாதனத்தில் காண்பிக்கப்பட்டது என்பதை உறுதிப்படுத்தவும்: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">அறிவிப்புகள்</translation> <translation id="2484513351006226581">விசைப்பலகைத் தளவமைப்பை மாற்ற, <ph name="KEYBOARD_SHORTCUT" /> விசையை அழுத்தவும்.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK இயக்கத்தில்</translation> <translation id="2532589005999780174">அதிக ஒளி மாறுபாட்டுப் பயன்முறை</translation> <translation id="2575685495496069081">பல உள்முழைவு முடக்கப்பட்டுள்ளது</translation> +<translation id="2582112259361606227">புதுப்பிக்க, மீண்டும் தொடங்குக</translation> <translation id="2597972630681408282">இரவு ஒளி: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">சிம் கார்டு பூட்டப்பட்டுள்ளது</translation> <translation id="2653659639078652383">சமர்ப்பி</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">உங்கள் திரையைப் பகிர்கிறீர்கள்</translation> <translation id="2942516765047364088">அடுக்கின் நிலை</translation> <translation id="2946119680249604491">இணைப்பைச் சேர்</translation> +<translation id="2961963223658824723">ஏதோ தவறாகிவிட்டது. சில வினாடிகள் கழித்து மீண்டும் முயலவும்.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> ஆனது <ph name="DOMAIN" /> ஆல் நிர்வகிக்கப்படும் பொது அமர்வாகும்</translation> <translation id="3000461861112256445">மோனோ ஆடியோ</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">கீழே</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (புளூடூத்)</translation> -<translation id="3112378005171663295">சுருக்கு</translation> <translation id="3126069444801937830">புதுப்பிக்க மீண்டும் தொடங்குக</translation> <translation id="3147142846278915599">துவக்கி (பயன்பாடுகளை ஒத்திசைக்கிறது...)</translation> <translation id="315116470104423982">மொபைல் டேட்டா</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">பூட்டு</translation> <translation id="3798670284305777884">ஸ்பீக்கர் (அகம்)</translation> +<translation id="380165613292957338">வணக்கம், நான் எவ்வாறு உதவலாம்?</translation> <translation id="3846575436967432996">நெட்வொர்க் தகவல் எதுவும் இல்லை</translation> <translation id="385051799172605136">முந்தைய பக்கம்</translation> <translation id="3891340733213178823">வெளியேற Ctrl+Shift+Q ஐ இருமுறை அழுத்தவும்.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C சாதனம் (வலது பக்கம் பின்னே இருக்கும் போர்ட்)</translation> <translation id="4017989525502048489">லேசர் பாயிண்டர்</translation> <translation id="4072264167173457037">நடுத்தரமான சிக்னல்</translation> +<translation id="4200057768455216496">டாக் செய்யப்பட்ட பெரிதாக்கியின் குறுக்குவழியை அழுத்தியுள்ளீர்கள். அதை இயக்க விரும்புகிறீர்களா?</translation> <translation id="4217571870635786043">சொல்வதை எழுதுவது</translation> <translation id="4279490309300973883">பிரதிபலிக்கிறது</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google அசிஸ்டண்ட்டை உங்கள் நிர்வாகி முடக்கியுள்ளார்.</translation> <translation id="4895488851634969361">பேட்டரி நிரம்பியது.</translation> <translation id="4905614135390995787">அதிக ஒளி மாறுபாட்டுப் பயன்முறையை மாற்றும் குறுக்குவழி மாற்றப்பட்டது. <ph name="OLD_SHORTCUT" />க்குப் பதிலாக, <ph name="NEW_SHORTCUT" />ஐப் பயன்படுத்தவும்.</translation> +<translation id="4917385247580444890">வலிமையானது</translation> <translation id="4918086044614829423">ஏற்கிறேன்</translation> <translation id="4961318399572185831">அனுப்புதல் திரை</translation> <translation id="5136175204352732067">வேறொரு விசைப்பலகை இணைக்கப்பட்டது</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">பேச்சுவடிவக் கருத்தை முடக்க, Ctrl + Alt + Zஐ அழுத்தவும்.</translation> <translation id="5648021990716966815">மைக் ஜாக்</translation> +<translation id="5669267381087807207">செயலாக்குகிறது</translation> <translation id="5673434351075758678">அமைப்புகளை ஒத்திசைத்த பின்னர், "<ph name="FROM_LOCALE" />" இலிருந்து "<ph name="TO_LOCALE" />"க்கு மாற்றப்பட்டது.</translation> +<translation id="574392208103952083">நடுநிலை</translation> <translation id="5744083938413354016">தட்டி நகர்த்துதல்</translation> <translation id="5777841717266010279">திரைப் பகிர்வதை நிறுத்தவா?</translation> <translation id="57838592816432529">ஒலியடக்கு</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">நிராகரி</translation> <translation id="6453179446719226835">மொழி மாற்றப்பட்டது</translation> <translation id="6459472438155181876"><ph name="DISPLAY_NAME" /> க்கு திரை விரிவாக்கப்படுகிறது</translation> +<translation id="6482559668224714696">முழுத்திரைப் பெரிதாக்கி</translation> <translation id="6490471652906364588">USB-C சாதனம் (வலது போர்ட்)</translation> <translation id="6501401484702599040"><ph name="RECEIVER_NAME" />க்குத் திரையை அனுப்புகிறது</translation> <translation id="6521655319214113338">கையெழுத்து உள்ளீடு</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">சிறிது நேரம் இடைவேளை எடுத்துக்கொள்ளவும்!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" /> ஐ செயல்படுத்து</translation> +<translation id="6910714959251846841">இந்தப் புதுப்பிப்பைப் பெற, உங்கள் சாதனத்தைப் பவர்வாஷ் செய்ய வேண்டும். சமீபத்திய <ph name="SYSTEM_APP_NAME" /> புதுப்பிப்பைப் பற்றி மேலும் அறிக.</translation> <translation id="6911468394164995108">மற்றொன்றில் சேர்...</translation> <translation id="6981982820502123353">அணுகல் தன்மை</translation> <translation id="698231206551913481">இந்தப் பயனர் அகற்றப்பட்டதும், பயனருடன் தொடர்புடைய எல்லா கோப்புகளும் அகத் தரவும் நிரந்தரமாக நீக்கப்படும்.</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" />க்கு மீண்டும் சாதனத்தைப் பயன்படுத்தலாம்.</translation> <translation id="7029814467594812963">அமர்விலிருந்து வெளியேறவும்</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" />ஐ <ph name="RECEIVER_NAME" />க்கு அனுப்புகிறது</translation> +<translation id="7037152028959403492">உயர் ஒளி மாறுபாட்டின் குறுக்குவழியை அழுத்தியுள்ளீர்கள். அதை இயக்க விரும்புகிறீர்களா?</translation> <translation id="7066646422045619941">இந்த நெட்வொர்க் உங்கள் நிர்வாகியால் முடக்கப்பட்டுள்ளது.</translation> <translation id="7067196344162293536">தானியங்கு சுழற்றல்</translation> <translation id="7076293881109082629">உள்நுழைகிறீர்கள்</translation> <translation id="7098389117866926363">USB-C சாதனம் (பின்பக்கம் உள்ள இடது போர்ட்)</translation> <translation id="7131634465328662194">நீங்கள் தானாக வெளியேற்றப்படுவீர்கள்.</translation> +<translation id="7143207342074048698">இணைத்தல்</translation> <translation id="7165278925115064263">ஆல்ட்+ஷிஃப்ட்+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" /> வினாடிகளில் பழைய தெளிவுதிறனுக்கு மாற்றியமைக்கப்படும்</translation> <translation id="7256634071279256947">பின்பக்க மைக்ரோஃபோன்</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> உடன் இணைக்கப்பட்டது</translation> <translation id="813913629614996137">துவக்குகிறது...</translation> <translation id="8142699993796781067">தனிப்பட்ட நெட்வொர்க்</translation> +<translation id="8152119955266188852">முழுத்திரைப் பெரிதாக்கியின் குறுக்குவழியை அழுத்தியுள்ளீர்கள். அதை இயக்க விரும்புகிறீர்களா?</translation> <translation id="8180896103888046100">தெரியாத ரிசீவருக்கு அனுப்புவதை நிறுத்து</translation> <translation id="8190698733819146287">மொழிகள் மற்றும் உள்ளீடைத் தனிப்பயனாக்கு...</translation> <translation id="8261506727792406068">நீக்கு</translation> +<translation id="8297006494302853456">வலுவாக இல்லை</translation> <translation id="8308637677604853869">முந்தைய மெனு</translation> <translation id="8351131234907093545">குறிப்பை உருவாக்கு</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> க்கான விருப்பத்தேர்வுகள் மெனு</translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">முந்தையது பொத்தான்</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">திரையைப் பிரிப்பதைப் பயன்பாடு ஆதரிக்கவில்லை.</translation> +<translation id="8874184842967597500">இணைக்கப்படவில்லை</translation> <translation id="8878886163241303700">திரையை விரிவாக்குகிறது</translation> <translation id="8921624153894383499">Google அசிஸ்டண்ட், இந்த மொழியை ஆதரிக்கவில்லை.</translation> <translation id="8938800817013097409">USB-C சாதனம் (பின்பக்கம் உள்ள வலது போர்ட்)</translation> <translation id="8940956008527784070">பேட்டரி குறைவு (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Quick launch</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> ஆல் நிர்வகிக்கப்படுகிறது</translation> +<translation id="9029474291399787231">Adobe Flash Player புதுப்பிப்பு உள்ளது</translation> <translation id="9033907480196064950">தற்போது <ph name="TAB_NAME" />ஐ அலைபரப்புகிறீர்கள்</translation> <translation id="9074739597929991885">புளூடூத்</translation> <translation id="9079731690316798640">வைஃபை: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">வேறொருவராக உள்நுழை...</translation> <translation id="9201131092683066720">பேட்டரி <ph name="PERCENTAGE" />% நிரம்பியது.</translation> <translation id="9210037371811586452">ஒன்றிணைந்த டெஸ்க்டாப் பயன்முறையிலிருந்து வெளியேறுகிறது</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">வால்பேப்பரை அமை</translation> <translation id="923686485342484400">வெளியேற Control Shift Q ஐ இருமுறை அழுத்தவும்.</translation> <translation id="945522503751344254">பின்னூட்டம் அனுப்புக</translation>
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb index 12e6fa2..0ba2a96 100644 --- a/ash/strings/ash_strings_te.xtb +++ b/ash/strings/ash_strings_te.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C పరికరం (ముందువైపు పోర్ట్)</translation> <translation id="1013923882670373915">బ్లూటూత్ పరికరం "<ph name="DEVICE_NAME" />" జత కావడానికి అనుమతి కోరుతోంది. దయచేసి ఆ పరికరంలో ఈ PIN కోడ్ను నమోదు చేయండి: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">స్టైలస్ బ్యాటరీ తక్కువగా ఉంది</translation> +<translation id="1056775291175587022">నెట్వర్క్లు లేవు</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">అరను స్వయంచాలకంగా దాచు</translation> <translation id="1153356358378277386">జత చేసిన పరికరాలు</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">కుడి</translation> <translation id="1383876407941801731">శోధించు</translation> <translation id="1467432559032391204">ఎడమ</translation> +<translation id="1479743070547893297">ఎంచుకోవడానికి మీ స్టైలస్తో గీయండి</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">లాంచర్</translation> <translation id="1525508553941733066">తీసివేయి</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">మీ భాషని సెట్ చేయండి</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">తాజా <ph name="SYSTEM_APP_NAME" /> అప్డేట్ గురించి మరింత తెలుసుకోండి</translation> <translation id="1995660704900986789">పవర్ ఆఫ్ చేయి</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">సందేశాన్ని టైప్ చేయండి</translation> <translation id="2049639323467105390">ఈ పరికరం <ph name="DOMAIN" /> ద్వారా నిర్వహించబడుతుంది.</translation> <translation id="2050339315714019657">నిలువు</translation> <translation id="2067602449040652523">కీబోర్డ్ ప్రకాశం</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">కొనసాగు</translation> <translation id="2365393535144473978">మొబైల్ డేటాను ప్రారంభించడం బ్లూటూత్ని ప్రారంభిస్తుంది.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">అప్డేట్ అందుబాటులో ఉంది</translation> <translation id="2429753432712299108">బ్లూటూత్ పరికరం "<ph name="DEVICE_NAME" />" జత కావడానికి అనుమతి కోరుతోంది. ఆమోదించడానికి ముందు, దయచేసి ఆ పరికరంలో ఈ పాస్కీ చూపబడుతోందని నిర్ధారించుకోండి: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">ప్రకటనలు</translation> <translation id="2484513351006226581">కీబోర్డ్ లేఅవుట్ను మార్చడానికి <ph name="KEYBOARD_SHORTCUT" />ని నొక్కండి.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK ఆన్లో ఉంది</translation> <translation id="2532589005999780174">అధిక కాంట్రాస్ట్ మోడ్</translation> <translation id="2575685495496069081">బహుళ సైన్-ఇన్ నిలిపివేయబడింది</translation> +<translation id="2582112259361606227">అప్డేేట్ చేయడానికి పునఃప్రారంభించండి</translation> <translation id="2597972630681408282">రాత్రి కాంతి: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM కార్డ్ లాక్ అయింది</translation> <translation id="2653659639078652383">సమర్పించు</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">మీరు మీ స్క్రీన్ను షేర్ చేస్తున్నారు</translation> <translation id="2942516765047364088">అర స్థానం</translation> <translation id="2946119680249604491">కనెక్షన్ని జోడించండి</translation> +<translation id="2961963223658824723">ఏదో తప్పు జరిగింది. కొన్ని క్షణాల తర్వాత మళ్లీ ప్రయత్నించండి.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> అనేది <ph name="DOMAIN" /> ద్వారా నిర్వహించబడుతున్న పబ్లిక్ సెషన్</translation> <translation id="3000461861112256445">మోనో ఆడియో</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">దిగువ</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (బ్లూటూత్)</translation> -<translation id="3112378005171663295">కుదించు</translation> <translation id="3126069444801937830">నవీకరించడానికి పునఃప్రారంభించండి</translation> <translation id="3147142846278915599">లాంచర్ (అనువర్తనాలను సమకాలీకరిస్తోంది...)</translation> <translation id="315116470104423982">మొబైల్ డేటా</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">లాక్ చేయి</translation> <translation id="3798670284305777884">స్పీకర్ (అంతర్గతం)</translation> +<translation id="380165613292957338">హాయ్, నేను ఎలా సహాయపడగలను?</translation> <translation id="3846575436967432996">నెట్వర్క్ సమాచారం అందుబాటులో లేదు</translation> <translation id="385051799172605136">వెనుకకు</translation> <translation id="3891340733213178823">సైన్ అవుట్ చేయడానికి Ctrl+Shift+Qని రెండుసార్లు నొక్కండి.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C పరికరం (కుడివైపు వెనుక పోర్ట్)</translation> <translation id="4017989525502048489">లేజర్ పాయింటర్</translation> <translation id="4072264167173457037">సిగ్నల్ ఓ మోస్తరుగా ఉంది</translation> +<translation id="4200057768455216496">డాక్ చేసిన మాగ్నిఫైయర్ కోసం మీరు సత్వరమార్గాన్ని నొక్కారు. మీరు దీనిని ఆన్ చేయాలనుకుంటున్నారా?</translation> <translation id="4217571870635786043">డిక్టేషన్</translation> <translation id="4279490309300973883">ప్రతిబింబిస్తుంది</translation> <translation id="4321179778687042513">ctrl</translation> @@ -188,6 +196,7 @@ <translation id="4890187583552566966">మీ నిర్వాహకునిచే Google సహాయకం నిలిపివేయబడింది.</translation> <translation id="4895488851634969361">బ్యాటరీ నిండింది.</translation> <translation id="4905614135390995787">అధిక కాంట్రాస్ట్ మోడ్ను టోగుల్ చేయడానికి ఉన్న సత్వరమార్గం మార్చబడింది. దయచేసి <ph name="OLD_SHORTCUT" />కు బదులుగా <ph name="NEW_SHORTCUT" /> ఉపయోగించండి.</translation> +<translation id="4917385247580444890">బలమైన</translation> <translation id="4918086044614829423">ఆమోదించు</translation> <translation id="4961318399572185831">స్క్రీన్ ప్రసారం చేయండి</translation> <translation id="5136175204352732067">వేరే కీబోర్డ్ కనెక్ట్ చేయబడింది</translation> @@ -211,7 +220,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">ప్రసంగ రూప అభిప్రాయాన్ని నిలిపివేయడానికి Ctrl + Alt + Z నొక్కండి.</translation> <translation id="5648021990716966815">మైక్ జాక్</translation> +<translation id="5669267381087807207">సక్రియం చేస్తోంది</translation> <translation id="5673434351075758678">మీ సెట్టింగులను సమకాలీకరించిన తర్వాత "<ph name="FROM_LOCALE" />" నుండి "<ph name="TO_LOCALE" />"కి.</translation> +<translation id="574392208103952083">మధ్యస్థం</translation> <translation id="5744083938413354016">నొక్కి లాగండి</translation> <translation id="5777841717266010279">స్క్రీన్ భాగస్వామ్యాన్ని ఆపివేయాలా?</translation> <translation id="57838592816432529">మ్యూట్ చేయి</translation> @@ -254,6 +265,7 @@ <translation id="6452181791372256707">తిరస్కరించు</translation> <translation id="6453179446719226835">భాష మార్చబడింది</translation> <translation id="6459472438155181876"><ph name="DISPLAY_NAME" />కు స్క్రీన్ను విస్తరిస్తోంది</translation> +<translation id="6482559668224714696">పూర్తి స్క్రీన్ మాగ్నిఫైయర్</translation> <translation id="6490471652906364588">USB-C పరికరం (కుడి పోర్ట్)</translation> <translation id="6501401484702599040"><ph name="RECEIVER_NAME" />కి స్క్రీన్ను ప్రసారం చేస్తున్నాము</translation> <translation id="6521655319214113338">చేతివ్రాత ఇన్పుట్</translation> @@ -275,17 +287,20 @@ <translation id="6820676911989879663">విరామం తీసుకోండి!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780"><ph name="NETWORKSERVICE" />ని సక్రియం చెయ్యి</translation> +<translation id="6910714959251846841">ఈ అప్డేట్ కోసం మీ పరికరాన్ని పవర్వాష్ చేయాలి. తాజా <ph name="SYSTEM_APP_NAME" /> అప్డేట్ గురించి మరింత తెలుసుకోండి.</translation> <translation id="6911468394164995108">మరొక దానిలో చేరండి...</translation> <translation id="6981982820502123353">ప్రాప్యత</translation> <translation id="698231206551913481">ఈ వినియోగదారును తీసివేసిన తర్వాత ఈ వినియోగదారుతో అనుబంధించిన అన్ని ఫైల్లు మరియు స్థానిక డేటా శాశ్వతంగా తొలగించబడతాయి.</translation> <translation id="7015766095477679451">తిరిగి <ph name="COME_BACK_TIME" />కి రండి.</translation> <translation id="7029814467594812963">సెషన్ని నిష్క్రమించు</translation> <translation id="7034339000180558234"><ph name="RECEIVER_NAME" />కి <ph name="TAB_NAME" />ని ప్రసారం చేస్తున్నాము</translation> +<translation id="7037152028959403492">అధిక కాంట్రాస్ట్ కోసం మీరు సత్వరమార్గాన్ని నొక్కారు. మీరు దీనిని ఆన్ చేయాలనుకుంటున్నారా?</translation> <translation id="7066646422045619941">ఈ నెట్వర్క్ను మీ నిర్వాహకులు నిలిపివేసారు.</translation> <translation id="7067196344162293536">స్వయంచాలకంగా తిప్పు</translation> <translation id="7076293881109082629">సైన్ ఇన్ చేస్తోంది</translation> <translation id="7098389117866926363">USB-C పరికరం (వెనుక భాగంలో ఎడమ పోర్ట్)</translation> <translation id="7131634465328662194">మీరు ఆటోమేటిక్గా సైన్ అవుట్ చేయబడతారు.</translation> +<translation id="7143207342074048698">కనెక్ట్ అవుతోంది</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" />లో తిరిగి పాత రిజల్యూషన్కి మార్చబడుతోంది</translation> <translation id="7256634071279256947">వెనుకవైపు మైక్రోఫోన్</translation> @@ -331,9 +346,11 @@ <translation id="8132793192354020517"><ph name="NAME" />కు కనెక్ట్ చేయబడింది</translation> <translation id="813913629614996137">ప్రారంభిస్తోంది...</translation> <translation id="8142699993796781067">ప్రైవేట్ నెట్వర్క్</translation> +<translation id="8152119955266188852">పూర్తి స్క్రీన్ మాగ్నిఫైయర్ కోసం మీరు సత్వరమార్గాన్ని నొక్కారు. మీరు దీనిని ఆన్ చేయాలనుకుంటున్నారా?</translation> <translation id="8180896103888046100">తెలియని రిసీవర్కు ప్రసారం చేయడాన్ని ఆపివేయి</translation> <translation id="8190698733819146287">భాషలను అనుకూలీకరించి, ఇన్పుట్ చెయ్యి...</translation> <translation id="8261506727792406068">తొలగించు</translation> +<translation id="8297006494302853456">బలహీనం</translation> <translation id="8308637677604853869">మునుపటి మెను</translation> <translation id="8351131234907093545">గమనికను సృష్టించండి</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> కోసం ఎంపికల మెను</translation> @@ -359,11 +376,13 @@ <translation id="8841375032071747811">వెనుకకు బటన్</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">యాప్లో విభజన స్క్రీన్కి మద్దతు లేదు.</translation> +<translation id="8874184842967597500">కనెక్ట్ చేయబడలేదు</translation> <translation id="8878886163241303700">స్క్రీన్ విస్తరించబడుతోంది</translation> <translation id="8921624153894383499">Google సహాయకం ఈ భాషను మాట్లాడదు.</translation> <translation id="8938800817013097409">USB-C పరికరం (వెనుక భాగంలో కుడి పోర్ట్)</translation> <translation id="8940956008527784070">బ్యాటరీ తక్కువగా ఉంది (<ph name="PERCENTAGE" />%)</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> ద్వారా నిర్వహించబడుతోంది</translation> +<translation id="9029474291399787231">Adobe Flash Player అప్డేట్ అందుబాటులో ఉంది</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> <translation id="9080206825613744995">మైక్రోఫోన్ ఉపయోగంలో ఉంది.</translation> @@ -375,6 +394,7 @@ <translation id="9194617393863864469">మరొక వినియోగదారుగా సైన్ ఇన్ చేయండి...</translation> <translation id="9201131092683066720">బ్యాటరీ <ph name="PERCENTAGE" />% నిండింది.</translation> <translation id="9210037371811586452">ఏకీకృత డెస్క్టాప్ మోడ్ నుండి నిష్క్రమిస్తోంది</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">వాల్పేపర్ను సెట్ చేయండి</translation> <translation id="923686485342484400">సైన్ అవుట్ చేయడానికి Control Shift Qను రెండుసార్లు నొక్కండి.</translation> <translation id="945522503751344254">అభిప్రాయాన్ని పంపండి</translation>
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb index 96989a5..5e9ce6f 100644 --- a/ash/strings/ash_strings_th.xtb +++ b/ash/strings/ash_strings_th.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">อุปกรณ์ USB-C (พอร์ตด้านหน้า)</translation> <translation id="1013923882670373915">อุปกรณ์บลูทูธ "<ph name="DEVICE_NAME" />" ต้องการสิทธิ์ในการจับคู่ โปรดป้อนรหัส PIN นี้บนอุปกรณ์นั้น: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">แบตเตอรี่สไตลัสเหลือน้อย</translation> +<translation id="1056775291175587022">ไม่พบเครือข่าย</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">ซ่อนชั้นวางโดยอัตโนมัติ</translation> <translation id="1153356358378277386">อุปกรณ์ที่จับคู่</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">ขวา</translation> <translation id="1383876407941801731">ค้นหา</translation> <translation id="1467432559032391204">ซ้าย</translation> +<translation id="1479743070547893297">วาดด้วยสไตลัสเพื่อเลือก</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">ตัวเรียกใช้งาน</translation> <translation id="1525508553941733066">ปิด</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">ตั้งค่าภาษา</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">ดูข้อมูลเพิ่มเติมเกี่ยวกับอัปเดตล่าสุดของ <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">ปิดเครื่อง</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">พิมพ์ข้อความ</translation> <translation id="2049639323467105390">อุปกรณ์นี้ได้รับการจัดการโดย <ph name="DOMAIN" /></translation> <translation id="2050339315714019657">แนวตั้ง</translation> <translation id="2067602449040652523">ความสว่างของแป้นพิมพ์</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">ดำเนินการต่อ</translation> <translation id="2365393535144473978">การเปิดใช้เน็ตมือถือจะเปิดใช้บลูทูธ</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">มีเวอร์ชันอัปเดต</translation> <translation id="2429753432712299108">อุปกรณ์บลูทูธ "<ph name="DEVICE_NAME" />" ต้องการสิทธิ์ในการจับคู่ ก่อนที่จะยอมรับ โปรดยืนยันว่ารหัสผ่านนี้ปรากฏบนอุปกรณ์นั้น: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">การแจ้งเตือน</translation> <translation id="2484513351006226581">กด <ph name="KEYBOARD_SHORTCUT" /> เพื่อสลับรูปแบบแป้นพิมพ์</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Caps Lock เปิดอยู่</translation> <translation id="2532589005999780174">โหมดคอนทราสต์สูง</translation> <translation id="2575685495496069081">ปิดใช้การลงชื่อเข้าสู่ระบบพร้อมกันหลายบัญชีอยู่</translation> +<translation id="2582112259361606227">รีสตาร์ทเพื่ออัปเดต</translation> <translation id="2597972630681408282">แสงตอนกลางคืน: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">ซิมการ์ดถูกล็อก</translation> <translation id="2653659639078652383">ส่ง</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">คุณกำลังแชร์หน้าจอของตัวเอง</translation> <translation id="2942516765047364088">ตำแหน่งของชั้นวาง</translation> <translation id="2946119680249604491">เพิ่มการเชื่อมต่อ</translation> +<translation id="2961963223658824723">เกิดข้อผิดพลาด โปรดลองอีกครั้งในอีกสักครู่</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> เป็นเซสชันสาธารณะซึ่งจัดการโดย <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">เสียงแบบโมโน</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">ด้านล่าง</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (บลูทูธ)</translation> -<translation id="3112378005171663295">ยุบ</translation> <translation id="3126069444801937830">รีสตาร์ทเพื่ออัปเดต</translation> <translation id="3147142846278915599">Launcher (กำลังซิงค์แอป...)</translation> <translation id="315116470104423982">เน็ตมือถือ</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">ล็อก</translation> <translation id="3798670284305777884">ลำโพง (ภายใน)</translation> +<translation id="380165613292957338">สวัสดี มีอะไรให้ฉันช่วยไหม</translation> <translation id="3846575436967432996">ไม่มีข้อมูลเครือข่ายที่สามารถใช้งานได้</translation> <translation id="385051799172605136">กลับ</translation> <translation id="3891340733213178823">กด Ctrl+Shift+Q 2 ครั้งเพื่อออกจากระบบ</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">อุปกรณ์ USB-C (พอร์ตด้านหลังขวา)</translation> <translation id="4017989525502048489">ตัวชี้เลเซอร์</translation> <translation id="4072264167173457037">สัญญาณแรงปานกลาง</translation> +<translation id="4200057768455216496">คุณกดแป้นพิมพ์ลัดสำหรับแว่นขยายหน้าจอบางส่วน คุณจะเปิดแว่นขยายไหม</translation> <translation id="4217571870635786043">การพิมพ์ตามคำบอก</translation> <translation id="4279490309300973883">กำลังแสดงผล</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">ผู้ดูแลระบบปิดใช้ Google Assistant</translation> <translation id="4895488851634969361">แบตเตอรี่เต็ม</translation> <translation id="4905614135390995787">มีการเปลี่ยนแปลงแป้นพิมพ์ลัดสำหรับสลับโหมดคอนทราสต์สูง โปรดใช้ <ph name="NEW_SHORTCUT" /> แทน <ph name="OLD_SHORTCUT" /></translation> +<translation id="4917385247580444890">แรง</translation> <translation id="4918086044614829423">ยอมรับ</translation> <translation id="4961318399572185831">แคสต์หน้าจอ</translation> <translation id="5136175204352732067">เชื่อมต่อกับแป้นพิมพ์อื่นแล้ว</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">กด Ctrl + Alt + Z เพื่อปิดใช้อธิบายและอ่านออกเสียง</translation> <translation id="5648021990716966815">ช่องเสียบไมโครโฟน</translation> +<translation id="5669267381087807207">กำลังเปิดการใช้งาน</translation> <translation id="5673434351075758678">เปลี่ยนจาก "<ph name="FROM_LOCALE" />" เป็น "<ph name="TO_LOCALE" />" หลังการซิงก์การตั้งค่า</translation> +<translation id="574392208103952083">ขนาดกลาง</translation> <translation id="5744083938413354016">การแตะลาก</translation> <translation id="5777841717266010279">ต้องการหยุดแชร์หน้าจอไหม</translation> <translation id="57838592816432529">ปิดเสียง</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">ปฏิเสธ</translation> <translation id="6453179446719226835">เปลี่ยนภาษาแล้ว</translation> <translation id="6459472438155181876">ขยายหน้าจอไปยัง <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">แว่นขยายทั้งหน้าจอ</translation> <translation id="6490471652906364588">อุปกรณ์ USB-C (พอร์ตด้านขวา)</translation> <translation id="6501401484702599040">กำลังแคสต์หน้าจอไปยัง <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">ป้อนข้อมูลด้วยลายมือ</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">พักสายตาหน่อย</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">เปิดใช้งาน <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">อัปเดตนี้จะมีการ Powerwash อุปกรณ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับอัปเดตล่าสุดของ <ph name="SYSTEM_APP_NAME" /></translation> <translation id="6911468394164995108">เชื่อมต่อเครือข่ายอื่น...</translation> <translation id="6981982820502123353">การเข้าถึง</translation> <translation id="698231206551913481">ระบบจะลบไฟล์ทั้งหมดและข้อมูลในเครื่องที่เชื่อมโยงกับผู้ใช้รายนี้ออกอย่างถาวรหลังจากนำผู้ใช้รายนี้ออกแล้ว</translation> <translation id="7015766095477679451">กลับมาเมื่อถึงเวลา <ph name="COME_BACK_TIME" /></translation> <translation id="7029814467594812963">ออกจากเซสชัน</translation> <translation id="7034339000180558234">กำลังแคสต์ <ph name="TAB_NAME" /> ไปยัง <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">คุณกดแป้นพิมพ์ลัดสำหรับคอนทราสต์สูง คุณจะเปิดคอนทราสต์สูงไหม</translation> <translation id="7066646422045619941">ผู้ดูแลระบบปิดใช้เครือข่ายนี้</translation> <translation id="7067196344162293536">หมุนอัตโนมัติ</translation> <translation id="7076293881109082629">กำลังลงชื่อเข้าใช้</translation> <translation id="7098389117866926363">อุปกรณ์ USB-C (พอร์ตด้านหลังซ้าย)</translation> <translation id="7131634465328662194">คุณจะออกจากระบบโดยอัตโนมัติ</translation> +<translation id="7143207342074048698">กำลังเชื่อมต่อ</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">เปลี่ยนกลับไปเป็นความละเอียดเดิมภายใน <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">ไมโครโฟนด้านหลัง</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">เชื่อมต่อกับ <ph name="NAME" /></translation> <translation id="813913629614996137">กำลังเริ่มดำเนินการ...</translation> <translation id="8142699993796781067">เครือข่ายส่วนบุคคล</translation> +<translation id="8152119955266188852">คุณกดแป้นพิมพ์ลัดสำหรับแว่นขยายทั้งหน้าจอ คุณจะเปิดแว่นขยายไหม</translation> <translation id="8180896103888046100">หยุดแคสต์ไปยังเครื่องรับที่ไม่รู้จัก</translation> <translation id="8190698733819146287">กำหนดค่าภาษาและการป้อนข้อมูล... </translation> <translation id="8261506727792406068">ลบ</translation> +<translation id="8297006494302853456">อ่อน</translation> <translation id="8308637677604853869">เมนูก่อนหน้า</translation> <translation id="8351131234907093545">สร้างโน้ต</translation> <translation id="8392451568018454956">เมนูตัวเลือกสำหรับ <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">ปุ่มกลับ</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">แอปไม่สนับสนุนการแยกหน้าจอ</translation> +<translation id="8874184842967597500">ไม่ได้เชื่อมต่อ</translation> <translation id="8878886163241303700">กำลังขยายหน้าจอ</translation> <translation id="8921624153894383499">Google Assistant ยังพูดภาษานี้ไม่ได้</translation> <translation id="8938800817013097409">อุปกรณ์ USB-C (พอร์ตด้านหลังขวา)</translation> <translation id="8940956008527784070">แบตเตอรี่ต่ำ (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">การเริ่มใช้งานด่วน</translation> <translation id="8995603266996330174">จัดการโดย <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">มีอัปเดต Adobe Flash Player พร้อมใช้งาน</translation> <translation id="9033907480196064950">คุณกำลังแคสต์ <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">บลูทูธ</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">ลงชื่อเข้าใช้ด้วยชื่อผู้ใช้อื่น...</translation> <translation id="9201131092683066720">มีแบตเตอรี่ <ph name="PERCENTAGE" />%</translation> <translation id="9210037371811586452">กำลังออกจากโหมดเดสก์ท็อปแบบรวมหลายหน้าจอ</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">ตั้งค่าวอลเปเปอร์</translation> <translation id="923686485342484400">กด Control Shift Q 2 ครั้งเพื่อออกจากระบบ</translation> <translation id="945522503751344254">ส่งความคิดเห็น</translation>
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb index c3c69071..f1cd891 100644 --- a/ash/strings/ash_strings_tr.xtb +++ b/ash/strings/ash_strings_tr.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C cihaz (ön bağlantı noktası)</translation> <translation id="1013923882670373915">"<ph name="DEVICE_NAME" />" adlı Bluetooth cihaz eşleme izni istiyor. Lütfen söz konusu cihazda şu PIN kodunu girin: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Ekran kaleminin pili düşük</translation> +<translation id="1056775291175587022">Hücresel ağ yok</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Rafı otomatik gizle</translation> <translation id="1153356358378277386">Eşlenen cihazlar</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Sağa</translation> <translation id="1383876407941801731">Ara</translation> <translation id="1467432559032391204">Sola</translation> +<translation id="1479743070547893297">Seçmek için ekran kaleminizle çizin</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Başlatıcı</translation> <translation id="1525508553941733066">KAPAT</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Dilinizi ayarlayın</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">En yeni <ph name="SYSTEM_APP_NAME" /> güncellemesi ile ilgili daha fazla bilgi edinin</translation> <translation id="1995660704900986789">Kapat</translation> <translation id="2012624427112548395">Ctrl+Arama+H</translation> +<translation id="2016340657076538683">Mesaj yazın</translation> <translation id="2049639323467105390">Bu cihaz <ph name="DOMAIN" /> tarafından yönetiliyor.</translation> <translation id="2050339315714019657">Dikey</translation> <translation id="2067602449040652523">Klavye parlaklığı</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Devam Et</translation> <translation id="2365393535144473978">Mobil veri etkinleştirildiğinde Bluetooth açılır.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Uygulama güncellendi</translation> <translation id="2429753432712299108">"<ph name="DEVICE_NAME" />" adlı Bluetooth cihaz eşleme izni istiyor. Kabul etmeden önce şu cihazda gösterilen bu parolanın gösterildiğini onaylayın: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Bildirimler</translation> <translation id="2484513351006226581">Klavye düzenini değiştirmek için <ph name="KEYBOARD_SHORTCUT" /> tuşlarına basın.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK açık</translation> <translation id="2532589005999780174">Yüksek kontrast modu</translation> <translation id="2575685495496069081">Çoklu oturum açma devre dışı bırakıldı</translation> +<translation id="2582112259361606227">Güncellemek için yeniden başlat</translation> <translation id="2597972630681408282">Gece Işığı: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM kart kilitli</translation> <translation id="2653659639078652383">Gönder</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Ekranınızı paylaşıyorsunuz</translation> <translation id="2942516765047364088">Raf konumu</translation> <translation id="2946119680249604491">Bağlantı ekle</translation> +<translation id="2961963223658824723">Bir sorun oluştu. Birkaç saniye sonra tekrar deneyin.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" />, <ph name="DOMAIN" /> tarafından yönetilen herkese açık bir oturumdur</translation> <translation id="3000461861112256445">Mono ses</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">üstkrktr</translation> <translation id="3087734570205094154">Alt</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Daralt</translation> <translation id="3126069444801937830">Güncellemek için yeniden başlat</translation> <translation id="3147142846278915599">Launcher (uygulamalar senkronize ediliyor...)</translation> <translation id="315116470104423982">Mobil veriler</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Kilitle</translation> <translation id="3798670284305777884">Hoparlör (dahili)</translation> +<translation id="380165613292957338">Merhaba, nasıl yardımcı olabilirim?</translation> <translation id="3846575436967432996">Hiçbir ağ bilgisi yok</translation> <translation id="385051799172605136">Geri</translation> <translation id="3891340733213178823">Oturumu kapatmak için Ctrl+ÜstKrktr+Q tuşlarına iki defa basın.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C cihaz (sağ arka bağlantı noktası)</translation> <translation id="4017989525502048489">Lazer işaretçi</translation> <translation id="4072264167173457037">Orta düzeyde sinyal</translation> +<translation id="4200057768455216496">Yerleştirilmiş büyüteç kısayoluna bastınız. Bu özelliği açmak istiyor musunuz?</translation> <translation id="4217571870635786043">Dikte</translation> <translation id="4279490309300973883">Yansıtılıyor</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Google Asistan, yöneticiniz tarafından devre dışı bırakıldı.</translation> <translation id="4895488851634969361">Pil dolu.</translation> <translation id="4905614135390995787">Yüksek Kontrast Modunu açma/kapatma kısayolu değişti. Lütfen <ph name="OLD_SHORTCUT" /> yerine <ph name="NEW_SHORTCUT" /> tuşlarını kullanın.</translation> +<translation id="4917385247580444890">Güçlü</translation> <translation id="4918086044614829423">Kabul et</translation> <translation id="4961318399572185831">Ekranı yayınla</translation> <translation id="5136175204352732067">Farklı klavye bağlandı</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Sesli geri bildirimi devre dışı bırakmak için Ctrl + Alt + Z tuşlarına basın.</translation> <translation id="5648021990716966815">Mikrofon jakı</translation> +<translation id="5669267381087807207">Etkinleştiriliyor</translation> <translation id="5673434351075758678">Ayarlarınız senkronize edildikten sonra "<ph name="FROM_LOCALE" />" olan dil "<ph name="TO_LOCALE" />" olarak değiştirildi.</translation> +<translation id="574392208103952083">Orta</translation> <translation id="5744083938413354016">Dokunarak sürükleme</translation> <translation id="5777841717266010279">Ekran paylaşma durdurulsun mu?</translation> <translation id="57838592816432529">Sesi kapat</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Reddet</translation> <translation id="6453179446719226835">Dil değiştirildi</translation> <translation id="6459472438155181876">Ekran şuraya genişletiliyor: <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Tam ekran büyüteci</translation> <translation id="6490471652906364588">USB-C cihaz (sağ bağlantı noktası)</translation> <translation id="6501401484702599040">Ekran, <ph name="RECEIVER_NAME" /> üzerinde yayınlanıyor</translation> <translation id="6521655319214113338">El yazısı girişi</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Mola verin!</translation> <translation id="683971173229319003">Ara+L</translation> <translation id="6857811139397017780">Şunu etkinleştir: <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Bu güncelleme, cihazınızda powerwash işlemi yapılmasını gerektiriyor. En yeni <ph name="SYSTEM_APP_NAME" /> güncellemesi ile ilgili daha fazla bilgi edinin.</translation> <translation id="6911468394164995108">Başka ağa katıl...</translation> <translation id="6981982820502123353">Erişilebilirlik</translation> <translation id="698231206551913481">Bu kullanıcıyla ilişkilendirilen tüm dosyalar ve yerel veriler, bu kullanıcı kaldırıldıktan sonra kalıcı olarak silinir.</translation> <translation id="7015766095477679451">Saat <ph name="COME_BACK_TIME" /> olduğunda geri gelin.</translation> <translation id="7029814467594812963">Oturumdan çık</translation> <translation id="7034339000180558234"><ph name="TAB_NAME" /> sekmesi <ph name="RECEIVER_NAME" /> üzerinde yayınlanıyor</translation> +<translation id="7037152028959403492">Yüksek kontrast kısayoluna bastınız. Bu özelliği açmak istiyor musunuz?</translation> <translation id="7066646422045619941">Bu ağ, yöneticiniz tarafından devre dışı bırakıldı.</translation> <translation id="7067196344162293536">Otomatik döndür</translation> <translation id="7076293881109082629">Oturum açılıyor</translation> <translation id="7098389117866926363">USB-C cihaz (arkadaki sol bağlantı noktası)</translation> <translation id="7131634465328662194">Oturumunuz otomatik olarak kapatılacak.</translation> +<translation id="7143207342074048698">Bağlanıyor</translation> <translation id="7165278925115064263">Alt+Üst Karakter+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" /> saniye içinde eski çözünürlüğe dönülüyor</translation> <translation id="7256634071279256947">Arka mikrofon</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517"><ph name="NAME" /> ağına bağlanıldı</translation> <translation id="813913629614996137">İlk kullanıma hazırlanıyor...</translation> <translation id="8142699993796781067">Özel ağ</translation> +<translation id="8152119955266188852">Tam ekran büyüteç kısayoluna bastınız. Bu özelliği açmak istiyor musunuz?</translation> <translation id="8180896103888046100">Bilinmeyen bir alıcıya yayını durdur</translation> <translation id="8190698733819146287">Dilleri ve girişi özelleştir...</translation> <translation id="8261506727792406068">Sil</translation> +<translation id="8297006494302853456">Zayıf</translation> <translation id="8308637677604853869">Önceki menü</translation> <translation id="8351131234907093545">Not oluştur</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> seçenekler menüsü</translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Geri düğmesi</translation> <translation id="8850991929411075241">Ara+Esc</translation> <translation id="8870509716567206129">Uygulama bölünmüş ekranı desteklemiyor.</translation> +<translation id="8874184842967597500">Bağlı değil</translation> <translation id="8878886163241303700">Genişletilmiş ekran</translation> <translation id="8921624153894383499">Google Asistan bu dili konuşmuyor.</translation> <translation id="8938800817013097409">USB-C cihaz (arkadaki sağ bağlantı noktası)</translation> <translation id="8940956008527784070">Pil gücü az (%<ph name="PERCENTAGE" />)</translation> <translation id="8984179138335769204">Hızlı başlat</translation> <translation id="8995603266996330174">Yöneten: <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Adobe Flash Player güncellemesi mevcut</translation> <translation id="9033907480196064950">Şu anda <ph name="TAB_NAME" /> sekmesini yayınlıyorsunuz</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Kablosuz: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Başka bir kullanıcı olarak oturum aç...</translation> <translation id="9201131092683066720">Pil %<ph name="PERCENTAGE" /> dolu.</translation> <translation id="9210037371811586452">Birleşik masaüstü modundan çıkılıyor</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Duvar kağıdını ayarla</translation> <translation id="923686485342484400">Oturumu kapatmak için Control ÜstKrktr Q tuşlarına iki defa basın.</translation> <translation id="945522503751344254">Geri bildirim gönder</translation>
diff --git a/ash/strings/ash_strings_uk.xtb b/ash/strings/ash_strings_uk.xtb index 8b4c0c9..f27c3bf 100644 --- a/ash/strings/ash_strings_uk.xtb +++ b/ash/strings/ash_strings_uk.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Пристрій із портом USB типу C (на передній панелі)</translation> <translation id="1013923882670373915">Пристрою Bluetooth "<ph name="DEVICE_NAME" />" потрібен дозвіл на підключення. Введіть на пристрої цей PIN-код: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Низький заряд акумулятора стилуса</translation> +<translation id="1056775291175587022">Немає мереж</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Автоматично ховати полицю</translation> <translation id="1153356358378277386">Підключені пристрої</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Праворуч</translation> <translation id="1383876407941801731">Пошук</translation> <translation id="1467432559032391204">Ліворуч</translation> +<translation id="1479743070547893297">Малюйте стилусом, щоб вибрати</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Панель запуску</translation> <translation id="1525508553941733066">ЗАКРИТИ</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Вибрати мову</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Докладніше про останнє оновлення додатка <ph name="SYSTEM_APP_NAME" /></translation> <translation id="1995660704900986789">Вимкнути</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">Введіть повідомлення</translation> <translation id="2049639323467105390">Цим пристроєм керує домен <ph name="DOMAIN" />.</translation> <translation id="2050339315714019657">Портретна</translation> <translation id="2067602449040652523">Яскравість клавіатури</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Продовжити</translation> <translation id="2365393535144473978">Якщо ввімкнути мобільне передавання даних, увімкнеться Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Доступне оновлення</translation> <translation id="2429753432712299108">Пристрою Bluetooth "<ph name="DEVICE_NAME" />" потрібен дозвіл на підключення. Перш ніж надати його, підтвердьте, що на пристрої відображається цей ключ доступу: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Сповіщення</translation> <translation id="2484513351006226581">Натисніть комбінацію клавіш <ph name="KEYBOARD_SHORTCUT" />, щоб змінити розкладку клавіатури.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Режим CAPS LOCK увімкнено</translation> <translation id="2532589005999780174">Режим високого контрасту</translation> <translation id="2575685495496069081">Паралельний вхід вимкнено</translation> +<translation id="2582112259361606227">Перезапустіть, щоб оновити</translation> <translation id="2597972630681408282">Нічний режим: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM-карту заблоковано</translation> <translation id="2653659639078652383">Надіслати</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Ви показуєте свій екран</translation> <translation id="2942516765047364088">Розташування полиці</translation> <translation id="2946119680249604491">Додати з’єднання</translation> +<translation id="2961963223658824723">Сталася помилка. Повторіть спробу за кілька секунд.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> – загальнодоступний сеанс, керований доменом <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Монофонічне аудіо</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Низ</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Згорнути</translation> <translation id="3126069444801937830">Перезапустіть, щоб оновити</translation> <translation id="3147142846278915599">Панель запуску (синхронізація додатків…)</translation> <translation id="315116470104423982">Мобільне передавання даних</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Заблокувати</translation> <translation id="3798670284305777884">Динамік (внутрішній)</translation> +<translation id="380165613292957338">Вітаю! Чим я можу допомогти?</translation> <translation id="3846575436967432996">Інформація про мережу не доступна</translation> <translation id="385051799172605136">Назад</translation> <translation id="3891340733213178823">Щоб вийти, двічі натисніть Ctrl+Shift+Q.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">пристрій, під’єднаний до порту USB-C (праворуч на задній панелі)</translation> <translation id="4017989525502048489">Лазерний вказівник</translation> <translation id="4072264167173457037">середній сигнал</translation> +<translation id="4200057768455216496">Ви натиснули комбінацію клавіш для закріпленої лупи. Увімкнути?</translation> <translation id="4217571870635786043">Диктування</translation> <translation id="4279490309300973883">Дзеркальне відображення</translation> <translation id="4321179778687042513">ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">Ваш адміністратор вимкнув Google Асистент.</translation> <translation id="4895488851634969361">Акумулятор заряджений.</translation> <translation id="4905614135390995787">Комбінація клавіш для керування режимом високого контрасту змінилася. Тепер це <ph name="NEW_SHORTCUT" />, а не <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Потужний</translation> <translation id="4918086044614829423">Прийняти</translation> <translation id="4961318399572185831">Трансляція екрана</translation> <translation id="5136175204352732067">Під’єднано іншу клавіатуру</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Натисніть Ctrl + Alt + Z, щоб вимкнути голосові підказки.</translation> <translation id="5648021990716966815">Гніздо для мікрофона</translation> +<translation id="5669267381087807207">Активація</translation> <translation id="5673434351075758678">Після синхронізації налаштувань мову змінено. Попередня мова: <ph name="FROM_LOCALE" />, нова: <ph name="TO_LOCALE" />.</translation> +<translation id="574392208103952083">Середній</translation> <translation id="5744083938413354016">Перетягування дотиком</translation> <translation id="5777841717266010279">Скасувати спільний доступ до екрана?</translation> <translation id="57838592816432529">Вимкнути звук</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">Відхилити</translation> <translation id="6453179446719226835">Мову змінено</translation> <translation id="6459472438155181876">Розширення екрана на <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Лупа для всього екрана</translation> <translation id="6490471652906364588">Пристрій із портом USB типу C (праворуч)</translation> <translation id="6501401484702599040">Вміст екрана транслюється на пристрій "<ph name="RECEIVER_NAME" />"</translation> <translation id="6521655319214113338">Рукописний ввід</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">Зробіть перерву!</translation> <translation id="683971173229319003">Search (Пошук)+L</translation> <translation id="6857811139397017780">Активувати <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Для цього оновлення потрібно виконати Powerwash на пристрої. Докладніше про останнє оновлення додатка <ph name="SYSTEM_APP_NAME" />.</translation> <translation id="6911468394164995108">Під’єднатися до іншої...</translation> <translation id="6981982820502123353">Доступність</translation> <translation id="698231206551913481">Якщо видалити цього користувача, усі файли та локальні дані, зв’язані з ним, буде видалено назавжди.</translation> <translation id="7015766095477679451">Поверніться о <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Завершити сеанс</translation> <translation id="7034339000180558234">Вкладка "<ph name="TAB_NAME" />" транслюється на пристрій "<ph name="RECEIVER_NAME" />"</translation> +<translation id="7037152028959403492">Ви натиснули комбінацію клавіш для високого контрасту. Увімкнути?</translation> <translation id="7066646422045619941">Ваш адміністратор вимкнув цю мережу.</translation> <translation id="7067196344162293536">Автоматичне обертання</translation> <translation id="7076293881109082629">Вхід</translation> <translation id="7098389117866926363">Пристрій, під’єднаний до порту USB-C (ліворуч на задній панелі)</translation> <translation id="7131634465328662194">Ви вийдете автоматично.</translation> +<translation id="7143207342074048698">Під’єднання</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Попередня роздільна здатність повернеться через <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Мікрофон на задній панелі</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">З'єднано з <ph name="NAME" /></translation> <translation id="813913629614996137">Ініціалізація...</translation> <translation id="8142699993796781067">Приватна мережа</translation> +<translation id="8152119955266188852">Ви натиснули комбінацію клавіш для лупи на весь екран. Увімкнути?</translation> <translation id="8180896103888046100">Зупинити трансляцію на невідомий пристрій</translation> <translation id="8190698733819146287">Налаштувати мови та введення тексту...</translation> <translation id="8261506727792406068">Видалити</translation> +<translation id="8297006494302853456">Слабкий</translation> <translation id="8308637677604853869">Попереднє меню</translation> <translation id="8351131234907093545">Створити нотатку</translation> <translation id="8392451568018454956">Меню параметрів для <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">Кнопка "Назад"</translation> <translation id="8850991929411075241">Search (Пошук)+Esc</translation> <translation id="8870509716567206129">Додаток не підтримує розділення екрана.</translation> +<translation id="8874184842967597500">Не під’єднано</translation> <translation id="8878886163241303700">Розширення екрана</translation> <translation id="8921624153894383499">Google Асистент не підтримує цю мову.</translation> <translation id="8938800817013097409">Пристрій, під’єднаний до порту USB-C (праворуч на задній панелі)</translation> <translation id="8940956008527784070">Низький заряд акумулятора (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Швидкий запуск</translation> <translation id="8995603266996330174">Керується доменом <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Доступне оновлення Adobe Flash Player</translation> <translation id="9033907480196064950">Зараз ви транслюєте вкладку "<ph name="TAB_NAME" />"</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">Увійти як інший користувач…</translation> <translation id="9201131092683066720">Акумулятор заряджений на <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Вихід з уніфікованого режиму робочого стола</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Вибрати фоновий малюнок</translation> <translation id="923686485342484400">Щоб вийти, двічі натисніть Control Shift Q.</translation> <translation id="945522503751344254">Надіслати відгук</translation>
diff --git a/ash/strings/ash_strings_vi.xtb b/ash/strings/ash_strings_vi.xtb index 1aa608e..1920b90 100644 --- a/ash/strings/ash_strings_vi.xtb +++ b/ash/strings/ash_strings_vi.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">Thiết bị USB-C (cổng phía trước)</translation> <translation id="1013923882670373915">Thiết bị Bluetooth "<ph name="DEVICE_NAME" />" muốn được phép ghép nối. Vui lòng nhập mã PIN này trên thiết bị đó: <ph name="PINCODE" /></translation> <translation id="1032891413405719768">Pin của bút cảm ứng ở mức thấp</translation> +<translation id="1056775291175587022">Không có mạng</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />: <ph name="RESOLUTION" /></translation> <translation id="112308213915226829">Tự động ẩn giá</translation> <translation id="1153356358378277386">Thiết bị được ghép nối</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">Phải</translation> <translation id="1383876407941801731">Tìm kiếm</translation> <translation id="1467432559032391204">Trái</translation> +<translation id="1479743070547893297">Chọn vẽ bằng bút cảm ứng</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">Trình chạy</translation> <translation id="1525508553941733066">LOẠI BỎ</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">Đặt ngôn ngữ</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">Tìm hiểu thêm về bản cập nhật <ph name="SYSTEM_APP_NAME" /> mới nhất</translation> <translation id="1995660704900986789">Tắt nguồn</translation> <translation id="2012624427112548395">Ctrl+Search+H</translation> +<translation id="2016340657076538683">Nhập tin nhắn</translation> <translation id="2049639323467105390">Thiết bị này được <ph name="DOMAIN" /> quản lý.</translation> <translation id="2050339315714019657">Khổ dọc</translation> <translation id="2067602449040652523">Độ sáng bàn phím</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">Tiếp tục</translation> <translation id="2365393535144473978">Bật dữ liệu di động sẽ bật Bluetooth.</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">Đã có bản cập nhật</translation> <translation id="2429753432712299108">Thiết bị Bluetooth "<ph name="DEVICE_NAME" />" muốn được phép ghép nối. Trước khi chấp nhận, vui lòng xác nhận rằng mã xác nhận này đã hiển thị trên thiết bị đó: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Thông báo</translation> <translation id="2484513351006226581">Hãy nhấn <ph name="KEYBOARD_SHORTCUT" /> để chuyển bố cục bàn phím.</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">Đang bật CAPS LOCK</translation> <translation id="2532589005999780174">Chế độ tương phản cao</translation> <translation id="2575685495496069081">Đã tắt tính năng đăng nhập nhiều tài khoản</translation> +<translation id="2582112259361606227">Khởi động lại để cập nhật</translation> <translation id="2597972630681408282">Chế độ ánh sáng ban đêm: <ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">Thẻ SIM bị khóa</translation> <translation id="2653659639078652383">Gửi</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">Bạn đang chia sẻ màn hình của mình</translation> <translation id="2942516765047364088">Vị trí giá</translation> <translation id="2946119680249604491">Thêm kết nối</translation> +<translation id="2961963223658824723">Đã xảy ra sự cố. Hãy thử lại sau vài giây.</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> là phiên công khai được quản lý bởi <ph name="DOMAIN" /></translation> <translation id="3000461861112256445">Đơn âm</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">Bên dưới</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (Bluetooth)</translation> -<translation id="3112378005171663295">Thu gọn</translation> <translation id="3126069444801937830">Khởi động lại để cập nhật</translation> <translation id="3147142846278915599">Trình khởi chạy (đang đồng bộ hóa ứng dụng...)</translation> <translation id="315116470104423982">Dữ liệu di động</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">Khóa</translation> <translation id="3798670284305777884">Loa (bên trong)</translation> +<translation id="380165613292957338">Xin chào, tôi có thể trợ giúp gì?</translation> <translation id="3846575436967432996">Không có thông tin mạng</translation> <translation id="385051799172605136">Quay lại</translation> <translation id="3891340733213178823">Nhấn Ctrl+Shift+Q hai lần để đăng xuất.</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">Thiết bị USB-C (cổng phía sau, bên phải)</translation> <translation id="4017989525502048489">Con trỏ laser</translation> <translation id="4072264167173457037">Tín hiệu trung bình</translation> +<translation id="4200057768455216496">Bạn đã nhấn phím tắt của tính năng phóng to ở vị trí cố định. Bạn có muốn bật tính năng này không?</translation> <translation id="4217571870635786043">Nhập bằng giọng nói</translation> <translation id="4279490309300973883">Đang phản chiếu</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">Quản trị viên của bạn đã tắt Trợ lý Google.</translation> <translation id="4895488851634969361">Pin đầy.</translation> <translation id="4905614135390995787">Phím tắt để chuyển đổi Chế độ tương phản cao đã thay đổi. Vui lòng sử dụng <ph name="NEW_SHORTCUT" /> thay vì <ph name="OLD_SHORTCUT" />.</translation> +<translation id="4917385247580444890">Mạnh</translation> <translation id="4918086044614829423">Chấp nhận</translation> <translation id="4961318399572185831">Truyền màn hình</translation> <translation id="5136175204352732067">Đã kết nối bàn phím khác</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Nhấn Ctrl + Alt + Z để tắt phản hồi bằng giọng nói.</translation> <translation id="5648021990716966815">Giắc cắm micrô</translation> +<translation id="5669267381087807207">Đang kích hoạt</translation> <translation id="5673434351075758678">Từ "<ph name="FROM_LOCALE" />" sang "<ph name="TO_LOCALE" />" sau khi đồng bộ hóa cài đặt của bạn.</translation> +<translation id="574392208103952083">Trung bình</translation> <translation id="5744083938413354016">Kéo nhấn</translation> <translation id="5777841717266010279">Bạn muốn dừng chia sẻ màn hình?</translation> <translation id="57838592816432529">Tắt tiếng</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">Từ chối</translation> <translation id="6453179446719226835">Đã thay đổi ngôn ngữ</translation> <translation id="6459472438155181876">Đang mở rộng màn hình tới <ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">Phóng to toàn bộ màn hình</translation> <translation id="6490471652906364588">Thiết bị USB-C (cổng bên phải)</translation> <translation id="6501401484702599040">Đang truyền màn hình tới <ph name="RECEIVER_NAME" /></translation> <translation id="6521655319214113338">Nhập bằng chữ viết tay</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">Hãy nghỉ giải lao!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">Kích hoạt <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">Bản cập nhật này yêu cầu phải dọn sạch thiết bị của bạn. Hãy tìm hiểu thêm về bản cập nhật <ph name="SYSTEM_APP_NAME" /> mới nhất.</translation> <translation id="6911468394164995108">Tham gia mạng khác...</translation> <translation id="6981982820502123353">Truy cập</translation> <translation id="698231206551913481">Tất cả các tệp và dữ liệu cục bộ liên quan tới người dùng này sẽ bị xóa vĩnh viễn sau khi người dùng này bị xóa.</translation> <translation id="7015766095477679451">Quay lại lúc <ph name="COME_BACK_TIME" />.</translation> <translation id="7029814467594812963">Thoát khỏi phiên</translation> <translation id="7034339000180558234">Đang truyền <ph name="TAB_NAME" /> tới <ph name="RECEIVER_NAME" /></translation> +<translation id="7037152028959403492">Bạn đã nhấn phím tắt để có độ tương phản cao. Bạn có muốn bật chế độ này không?</translation> <translation id="7066646422045619941">Mạng này bị quản trị viên của bạn tắt.</translation> <translation id="7067196344162293536">Tự động xoay</translation> <translation id="7076293881109082629">Đăng nhập</translation> <translation id="7098389117866926363">Thiết bị USB-C (cổng bên trái ở phía sau)</translation> <translation id="7131634465328662194">Bạn sẽ tự động bị đăng xuất.</translation> +<translation id="7143207342074048698">Đang kết nối</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358">Sẽ hoàn nguyên về độ phân giải cũ sau <ph name="TIMEOUT_SECONDS" /></translation> <translation id="7256634071279256947">Micrô mặt sau</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">Đã kết nối với <ph name="NAME" /></translation> <translation id="813913629614996137">Đang khởi chạy...</translation> <translation id="8142699993796781067">Mạng riêng</translation> +<translation id="8152119955266188852">Bạn đã nhấn phím tắt để phóng to toàn bộ màn hình. Bạn có muốn bật chế độ này không?</translation> <translation id="8180896103888046100">Dừng truyền tới người nhận không xác định</translation> <translation id="8190698733819146287">Tùy chỉnh ngôn ngữ và dữ liệu nhập...</translation> <translation id="8261506727792406068">Xóa</translation> +<translation id="8297006494302853456">Yếu</translation> <translation id="8308637677604853869">Menu trước</translation> <translation id="8351131234907093545">Tạo ghi chú</translation> <translation id="8392451568018454956">Menu tùy chọn dành cho <ph name="USER_EMAIL_ADDRESS" /></translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">Nút quay lại</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">Ứng dụng không hỗ trợ chế độ chia đôi màn hình.</translation> +<translation id="8874184842967597500">Chưa kết nối</translation> <translation id="8878886163241303700">Mở rộng màn hình</translation> <translation id="8921624153894383499">Trợ lý Google không hỗ trợ ngôn ngữ này.</translation> <translation id="8938800817013097409">Thiết bị USB-C (cổng bên phải ở phía sau)</translation> <translation id="8940956008527784070">Pin yếu (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">Khởi động nhanh</translation> <translation id="8995603266996330174">Được quản lý bởi <ph name="DOMAIN" /></translation> +<translation id="9029474291399787231">Đã có bản cập nhật Adobe Flash Player</translation> <translation id="9033907480196064950">Bạn hiện đang truyền <ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">Đăng nhập người dùng khác...</translation> <translation id="9201131092683066720">Pin đầy <ph name="PERCENTAGE" />%.</translation> <translation id="9210037371811586452">Đang thoát chế độ màn hình hợp nhất</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">Đặt hình nền</translation> <translation id="923686485342484400">Nhấn Control Shift Q hai lần để đăng xuất.</translation> <translation id="945522503751344254">Gửi phản hồi</translation>
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb index 8964998..da7204c 100644 --- a/ash/strings/ash_strings_zh-CN.xtb +++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C 设备(前方端口)</translation> <translation id="1013923882670373915">蓝牙设备“<ph name="DEVICE_NAME" />”需要配对许可。请在该设备上输入以下PIN码:<ph name="PINCODE" /></translation> <translation id="1032891413405719768">触控笔电池电量较低</translation> +<translation id="1056775291175587022">找不到任何网络</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />:<ph name="RESOLUTION" /></translation> <translation id="112308213915226829">自动隐藏任务栏</translation> <translation id="1153356358378277386">已配对的设备</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">向右</translation> <translation id="1383876407941801731">搜索</translation> <translation id="1467432559032391204">向左</translation> +<translation id="1479743070547893297">使用触控笔绘图即可进行选择</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">启动器</translation> <translation id="1525508553941733066">关闭</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">设置语言</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">详细了解最新的 <ph name="SYSTEM_APP_NAME" />更新</translation> <translation id="1995660704900986789">关机</translation> <translation id="2012624427112548395">Ctrl+搜索键+H</translation> +<translation id="2016340657076538683">请输入消息</translation> <translation id="2049639323467105390">此设备由 <ph name="DOMAIN" /> 管理。</translation> <translation id="2050339315714019657">纵向</translation> <translation id="2067602449040652523">键盘亮度</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">继续</translation> <translation id="2365393535144473978">如果您启用移动数据网络,蓝牙亦会随之开启。</translation> <translation id="2391579633712104609">180°</translation> +<translation id="2412593942846481727">有可用的更新</translation> <translation id="2429753432712299108">蓝牙设备“<ph name="DEVICE_NAME" />”需要配对许可。在接受之前,请确保该设备上显示以下配对密钥:<ph name="PASSKEY" /></translation> <translation id="2482878487686419369">通知</translation> <translation id="2484513351006226581">按 <ph name="KEYBOARD_SHORTCUT" />键可切换键盘布局。</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">CAPS LOCK 已打开</translation> <translation id="2532589005999780174">高反差模式</translation> <translation id="2575685495496069081">多帐号登录已被停用</translation> +<translation id="2582112259361606227">重启即可更新</translation> <translation id="2597972630681408282">夜间模式:<ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM 卡已被锁定</translation> <translation id="2653659639078652383">提交</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">您正在共享自己的屏幕</translation> <translation id="2942516765047364088">任务栏位置</translation> <translation id="2946119680249604491">添加连接</translation> +<translation id="2961963223658824723">出了点问题。请过几秒钟后重试。</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416">“<ph name="DISPLAY_NAME" />”是由 <ph name="DOMAIN" /> 管理的公用自助终端</translation> <translation id="3000461861112256445">单声道音频</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">shift</translation> <translation id="3087734570205094154">底部</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" />(蓝牙)</translation> -<translation id="3112378005171663295">收起</translation> <translation id="3126069444801937830">重新启动以进行更新</translation> <translation id="3147142846278915599">启动器(正在同步应用…)</translation> <translation id="315116470104423982">移动数据</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">alt</translation> <translation id="3784455785234192852">锁定</translation> <translation id="3798670284305777884">扬声器(内部)</translation> +<translation id="380165613292957338">嗨,有什么我可以帮您的吗?</translation> <translation id="3846575436967432996">没有可用的网络信息</translation> <translation id="385051799172605136">后退</translation> <translation id="3891340733213178823">连按两次Ctrl+Shift+Q即可退出。</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C 设备(右侧后端端口)</translation> <translation id="4017989525502048489">激光笔</translation> <translation id="4072264167173457037">信号中等</translation> +<translation id="4200057768455216496">您按下了停靠放大镜的快捷键。要开启这项功能吗?</translation> <translation id="4217571870635786043">语音输入</translation> <translation id="4279490309300973883">正在镜像</translation> <translation id="4321179778687042513">ctrl</translation> @@ -190,6 +198,7 @@ <translation id="4890187583552566966">Google 智能助理已被您的管理员停用。</translation> <translation id="4895488851634969361">电池电量已满。</translation> <translation id="4905614135390995787">用于切换高反差模式的快捷键已更改。请使用 <ph name="NEW_SHORTCUT" />,而不是 <ph name="OLD_SHORTCUT" />。</translation> +<translation id="4917385247580444890">强</translation> <translation id="4918086044614829423">接受</translation> <translation id="4961318399572185831">投射屏幕</translation> <translation id="5136175204352732067">所连接的键盘已不是原来的那个</translation> @@ -213,7 +222,9 @@ <translation id="5597451508971090205"><ph name="DATE" /><ph name="SHORT_WEEKDAY" /></translation> <translation id="5600837773213129531">按 Ctrl + Alt + Z 即可停用语音反馈。</translation> <translation id="5648021990716966815">麦克风耳机插孔</translation> +<translation id="5669267381087807207">正在激活</translation> <translation id="5673434351075758678">当系统同步完您的设置后,“<ph name="FROM_LOCALE" />”即会改为“<ph name="TO_LOCALE" />”。</translation> +<translation id="574392208103952083">中</translation> <translation id="5744083938413354016">点按拖动</translation> <translation id="5777841717266010279">要停止屏幕共享吗?</translation> <translation id="57838592816432529">静音</translation> @@ -258,6 +269,7 @@ <translation id="6452181791372256707">拒绝</translation> <translation id="6453179446719226835">语言已更改</translation> <translation id="6459472438155181876">正在将屏幕扩展到<ph name="DISPLAY_NAME" /></translation> +<translation id="6482559668224714696">全屏放大镜</translation> <translation id="6490471652906364588">USB-C 设备(右侧端口)</translation> <translation id="6501401484702599040">正在将屏幕投射到“<ph name="RECEIVER_NAME" />”</translation> <translation id="6521655319214113338">手写输入</translation> @@ -282,17 +294,20 @@ <translation id="6820676911989879663">休息一下!</translation> <translation id="683971173229319003">Search+L</translation> <translation id="6857811139397017780">激活 <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">必须对您的设备执行 Powerwash 才能安装这项更新。详细了解最新的 <ph name="SYSTEM_APP_NAME" />更新。</translation> <translation id="6911468394164995108">连接其他网络...</translation> <translation id="6981982820502123353">无障碍</translation> <translation id="698231206551913481">移除该用户后,与其关联的所有文件和本地数据都会被永久删除。</translation> <translation id="7015766095477679451">您需要等到<ph name="COME_BACK_TIME" /> 才能再次使用此设备。</translation> <translation id="7029814467594812963">退出会话</translation> <translation id="7034339000180558234">正在将“<ph name="TAB_NAME" />”投射到“<ph name="RECEIVER_NAME" />”</translation> +<translation id="7037152028959403492">您按下了高对比度的快捷键。要开启这项功能吗?</translation> <translation id="7066646422045619941">您的管理员已禁用此网络。</translation> <translation id="7067196344162293536">自动旋转</translation> <translation id="7076293881109082629">正在登录</translation> <translation id="7098389117866926363">USB-C 设备(背面左侧端口)</translation> <translation id="7131634465328662194">您将会自动退出会话。</translation> +<translation id="7143207342074048698">正在连接</translation> <translation id="7165278925115064263">Alt+Shift+K</translation> <translation id="7168224885072002358"><ph name="TIMEOUT_SECONDS" />秒后恢复到原分辨率</translation> <translation id="7256634071279256947">后置麦克风</translation> @@ -338,9 +353,11 @@ <translation id="8132793192354020517">已连接到 <ph name="NAME" /></translation> <translation id="813913629614996137">正在初始化…</translation> <translation id="8142699993796781067">专用网络</translation> +<translation id="8152119955266188852">您按下了全屏放大镜的快捷键。要开启这项功能吗?</translation> <translation id="8180896103888046100">停止投射到未知接收器</translation> <translation id="8190698733819146287">自定义语言和输入法...</translation> <translation id="8261506727792406068">删除</translation> +<translation id="8297006494302853456">弱</translation> <translation id="8308637677604853869">上一菜单</translation> <translation id="8351131234907093545">创建记事</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> 的“选项”菜单</translation> @@ -368,12 +385,14 @@ <translation id="8841375032071747811">“返回”按钮</translation> <translation id="8850991929411075241">Search+Esc</translation> <translation id="8870509716567206129">应用不支持分屏。</translation> +<translation id="8874184842967597500">未连接</translation> <translation id="8878886163241303700">正在扩展屏幕</translation> <translation id="8921624153894383499">Google 智能助理不支持此语言。</translation> <translation id="8938800817013097409">USB-C 设备(背面右侧端口)</translation> <translation id="8940956008527784070">电池电量不足 (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">快速启动</translation> <translation id="8995603266996330174">由 <ph name="DOMAIN" /> 管理</translation> +<translation id="9029474291399787231">有可用的 Adobe Flash Player 更新</translation> <translation id="9033907480196064950">您目前正在投射<ph name="TAB_NAME" /></translation> <translation id="9074739597929991885">蓝牙</translation> <translation id="9079731690316798640">Wi-Fi:<ph name="ADDRESS" /></translation> @@ -386,6 +405,7 @@ <translation id="9194617393863864469">登录其他用户帐号…</translation> <translation id="9201131092683066720">电池电量为<ph name="PERCENTAGE" />%。</translation> <translation id="9210037371811586452">正在退出统一桌面模式</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">设置壁纸</translation> <translation id="923686485342484400">连按两次Ctrl+Shift+Q即可退出。</translation> <translation id="945522503751344254">发送反馈</translation>
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb index eb9c6a2..e9343ae0 100644 --- a/ash/strings/ash_strings_zh-TW.xtb +++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -4,6 +4,7 @@ <translation id="1012876632442809908">USB-C 裝置 (前方連接埠)</translation> <translation id="1013923882670373915">藍牙裝置「<ph name="DEVICE_NAME" />」要求配對權限,請在裝置上輸入以下 PIN 碼:<ph name="PINCODE" /></translation> <translation id="1032891413405719768">觸控筆電量偏低</translation> +<translation id="1056775291175587022">沒有網路</translation> <translation id="1059194134494239015"><ph name="DISPLAY_NAME" />:<ph name="RESOLUTION" /></translation> <translation id="112308213915226829">自動隱藏檔案櫃</translation> <translation id="1153356358378277386">配對裝置</translation> @@ -20,6 +21,7 @@ <translation id="1346748346194534595">向右</translation> <translation id="1383876407941801731">搜尋</translation> <translation id="1467432559032391204">向左</translation> +<translation id="1479743070547893297">使用觸控筆畫出選取範圍</translation> <translation id="1484102317210609525"><ph name="DEVICE_NAME" /> (HDMI/DP)</translation> <translation id="1510238584712386396">啟動器</translation> <translation id="1525508553941733066">關閉</translation> @@ -50,8 +52,10 @@ <translation id="1957803754585243749">0°</translation> <translation id="1957958912175573503">設定語言</translation> <translation id="1969011864782743497"><ph name="DEVICE_NAME" /> (USB)</translation> +<translation id="1993072747612765854">進一步瞭解最新的 <ph name="SYSTEM_APP_NAME" />更新內容</translation> <translation id="1995660704900986789">關閉</translation> <translation id="2012624427112548395">Ctrl 鍵 + 搜尋鍵 + H 鍵</translation> +<translation id="2016340657076538683">輸入訊息</translation> <translation id="2049639323467105390">這個裝置由 <ph name="DOMAIN" /> 管理。</translation> <translation id="2050339315714019657">縱向</translation> <translation id="2067602449040652523">鍵盤亮度</translation> @@ -75,6 +79,7 @@ <translation id="2359808026110333948">繼續</translation> <translation id="2365393535144473978">如果啟用行動數據,藍牙功能也會一併開啟。</translation> <translation id="2391579633712104609">180 度</translation> +<translation id="2412593942846481727">有可用的更新</translation> <translation id="2429753432712299108">藍牙裝置「<ph name="DEVICE_NAME" />」要求配對權限。接受要求前,請確認裝置顯示以下密碼金鑰:<ph name="PASSKEY" /></translation> <translation id="2482878487686419369">通知</translation> <translation id="2484513351006226581">按下 <ph name="KEYBOARD_SHORTCUT" />可切換鍵盤配置。</translation> @@ -82,6 +87,7 @@ <translation id="2509468283778169019">大寫鍵已啟用</translation> <translation id="2532589005999780174">高反差模式</translation> <translation id="2575685495496069081">多重登入功能已停用</translation> +<translation id="2582112259361606227">重新啟動即可更新</translation> <translation id="2597972630681408282">夜燈功能:<ph name="NIGHT_LIGHT_STATUS" /></translation> <translation id="2617342710774726426">SIM 卡已鎖定</translation> <translation id="2653659639078652383">提交</translation> @@ -103,6 +109,7 @@ <translation id="2911940648265863620">你正在分享螢幕畫面</translation> <translation id="2942516765047364088">檔案櫃位置</translation> <translation id="2946119680249604491">新增連線</translation> +<translation id="2961963223658824723">發生錯誤,請於幾秒後再試一次。</translation> <translation id="2963773877003373896">mod3</translation> <translation id="2999742336789313416"><ph name="DISPLAY_NAME" /> 是受 <ph name="DOMAIN" /> 管理的公開工作階段</translation> <translation id="3000461861112256445">單聲道音訊</translation> @@ -111,7 +118,6 @@ <translation id="3077734595579995578">Shift</translation> <translation id="3087734570205094154">置底</translation> <translation id="3105990244222795498"><ph name="DEVICE_NAME" /> (藍牙)</translation> -<translation id="3112378005171663295">收合</translation> <translation id="3126069444801937830">重新啟動即可更新</translation> <translation id="3147142846278915599">啟動器 (正在同步處理應用程式...)</translation> <translation id="315116470104423982">行動數據</translation> @@ -147,6 +153,7 @@ <translation id="3783640748446814672">Alt</translation> <translation id="3784455785234192852">鎖定</translation> <translation id="3798670284305777884">喇叭 (內部)</translation> +<translation id="380165613292957338">你好,需要什麼協助嗎?</translation> <translation id="3846575436967432996">沒有可用的網路資訊</translation> <translation id="385051799172605136">返回</translation> <translation id="3891340733213178823">按兩下 Ctrl+Shift+Q 鍵即可登出。</translation> @@ -159,6 +166,7 @@ <translation id="3995138139523574647">USB-C 裝置 (右後方連接埠)</translation> <translation id="4017989525502048489">雷射筆</translation> <translation id="4072264167173457037">訊號中等</translation> +<translation id="4200057768455216496">你按下了停駐放大鏡的快速鍵。確定要啟用這項功能嗎?</translation> <translation id="4217571870635786043">語音輸入</translation> <translation id="4279490309300973883">鏡像</translation> <translation id="4321179778687042513">Ctrl</translation> @@ -189,6 +197,7 @@ <translation id="4890187583552566966">你的管理員停用了 Google 助理。</translation> <translation id="4895488851634969361">電池電量已滿。</translation> <translation id="4905614135390995787">切換高對比模式的快速鍵已變更,請改用 <ph name="NEW_SHORTCUT" /> (停用 <ph name="OLD_SHORTCUT" />)。</translation> +<translation id="4917385247580444890">強</translation> <translation id="4918086044614829423">接受</translation> <translation id="4961318399572185831">投放螢幕</translation> <translation id="5136175204352732067">已連接其他鍵盤</translation> @@ -212,7 +221,9 @@ <translation id="5597451508971090205"><ph name="DATE" /><ph name="SHORT_WEEKDAY" /></translation> <translation id="5600837773213129531">按下 Ctrl + Alt + Z 鍵即可停用互動朗讀功能。</translation> <translation id="5648021990716966815">麥克風插孔</translation> +<translation id="5669267381087807207">啟用中</translation> <translation id="5673434351075758678">同步處理設定後,「<ph name="FROM_LOCALE" />」已變更為「<ph name="TO_LOCALE" />」。</translation> +<translation id="574392208103952083">中</translation> <translation id="5744083938413354016">輕觸拖曳</translation> <translation id="5777841717266010279">停止共用螢幕?</translation> <translation id="57838592816432529">靜音</translation> @@ -257,6 +268,7 @@ <translation id="6452181791372256707">拒絕</translation> <translation id="6453179446719226835">語言已變更</translation> <translation id="6459472438155181876">正在擴充 <ph name="DISPLAY_NAME" /> 畫面</translation> +<translation id="6482559668224714696">全螢幕放大鏡</translation> <translation id="6490471652906364588">USB-C 裝置 (右側連接埠)</translation> <translation id="6501401484702599040">正在將畫面投放到「<ph name="RECEIVER_NAME" />」</translation> <translation id="6521655319214113338">手寫輸入</translation> @@ -281,17 +293,20 @@ <translation id="6820676911989879663">目前禁止使用裝置!</translation> <translation id="683971173229319003">搜尋鍵 + L 鍵</translation> <translation id="6857811139397017780">啟用 <ph name="NETWORKSERVICE" /></translation> +<translation id="6910714959251846841">必須對你的裝置執行 Powerwash 才能安裝這項更新。進一步瞭解最新的 <ph name="SYSTEM_APP_NAME" />更新內容。</translation> <translation id="6911468394164995108">加入其他網路...</translation> <translation id="6981982820502123353">協助工具</translation> <translation id="698231206551913481">將這位使用者移除後,與這位使用者相關聯的所有檔案和本機資料都會遭到永久刪除。</translation> <translation id="7015766095477679451"><ph name="COME_BACK_TIME" /> 裝置就會解除鎖定。</translation> <translation id="7029814467594812963">結束工作階段</translation> <translation id="7034339000180558234">正在將「<ph name="TAB_NAME" />」畫面投放到「<ph name="RECEIVER_NAME" />」</translation> +<translation id="7037152028959403492">你按下了高對比的快速鍵。確定要啟用這項功能嗎?</translation> <translation id="7066646422045619941">您的管理員已停用這個網路。</translation> <translation id="7067196344162293536">自動旋轉</translation> <translation id="7076293881109082629">登入中</translation> <translation id="7098389117866926363">USB-C 裝置 (背面左側連接埠)</translation> <translation id="7131634465328662194">系統會自動將你登出。</translation> +<translation id="7143207342074048698">連線中</translation> <translation id="7165278925115064263">Alt + Shift + K 鍵</translation> <translation id="7168224885072002358">系統將在 <ph name="TIMEOUT_SECONDS" /> 秒後還原成原來的解析度</translation> <translation id="7256634071279256947">後置麥克風</translation> @@ -337,9 +352,11 @@ <translation id="8132793192354020517">已連線至 <ph name="NAME" /></translation> <translation id="813913629614996137">正在初始化...</translation> <translation id="8142699993796781067">私人網路</translation> +<translation id="8152119955266188852">你按下了全螢幕放大鏡的快速鍵。確定要啟用這項功能嗎?</translation> <translation id="8180896103888046100">停止投放至不明接收端</translation> <translation id="8190698733819146287">自訂語言與輸入法...</translation> <translation id="8261506727792406068">刪除</translation> +<translation id="8297006494302853456">弱</translation> <translation id="8308637677604853869">前一個選單</translation> <translation id="8351131234907093545">寫筆記</translation> <translation id="8392451568018454956"><ph name="USER_EMAIL_ADDRESS" /> 的選項選單</translation> @@ -367,12 +384,14 @@ <translation id="8841375032071747811">返回按鈕</translation> <translation id="8850991929411075241">搜尋鍵 + Esc 鍵</translation> <translation id="8870509716567206129">這個應用程式不支援分割畫面。</translation> +<translation id="8874184842967597500">未連線</translation> <translation id="8878886163241303700">延伸螢幕</translation> <translation id="8921624153894383499">Google 助理不支援這個語言。</translation> <translation id="8938800817013097409">USB-C 裝置 (背面右側連接埠)</translation> <translation id="8940956008527784070">電池電量不足 (<ph name="PERCENTAGE" />%)</translation> <translation id="8984179138335769204">快速啓動</translation> <translation id="8995603266996330174">由 <ph name="DOMAIN" /> 管理</translation> +<translation id="9029474291399787231">有可用的 Adobe Flash Player 更新</translation> <translation id="9033907480196064950">你目前正在投放「<ph name="TAB_NAME" />」</translation> <translation id="9074739597929991885">藍牙</translation> <translation id="9079731690316798640">Wi-Fi:<ph name="ADDRESS" /></translation> @@ -385,6 +404,7 @@ <translation id="9194617393863864469">登入其他使用者帳戶...</translation> <translation id="9201131092683066720">電池電量為 <ph name="PERCENTAGE" />%。</translation> <translation id="9210037371811586452">退出整合桌面模式</translation> +<translation id="921331154633982721"><ph name="LABEL" /> <ph name="SUBLABEL" /></translation> <translation id="9215934040295798075">設定桌布</translation> <translation id="923686485342484400">按兩下 Ctrl+Shift+Q 鍵即可登出。</translation> <translation id="945522503751344254">提供意見</translation>
diff --git a/ash/system/night_light/night_light_feature_pod_controller.cc b/ash/system/night_light/night_light_feature_pod_controller.cc index d9166f3..04f9acd 100644 --- a/ash/system/night_light/night_light_feature_pod_controller.cc +++ b/ash/system/night_light/night_light_feature_pod_controller.cc
@@ -6,6 +6,7 @@ #include "ash/public/cpp/ash_features.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/night_light/night_light_controller.h" @@ -21,7 +22,9 @@ FeaturePodButton* NightLightFeaturePodController::CreateButton() { DCHECK(!button_); button_ = new FeaturePodButton(this); - button_->SetVisible(features::IsNightLightEnabled()); + button_->SetVisible( + features::IsNightLightEnabled() && + Shell::Get()->session_controller()->ShouldEnableSettings()); button_->SetLabel( l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_BUTTON_LABEL)); UpdateButton();
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc index 3be802e..13ecbd2 100644 --- a/ash/system/status_area_widget.cc +++ b/ash/system/status_area_widget.cc
@@ -77,13 +77,8 @@ select_to_speak_tray_ = std::make_unique<SelectToSpeakTray>(shelf_); status_area_widget_delegate_->AddChildView(select_to_speak_tray_.get()); - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableExperimentalAccessibilityFeatures)) { - // Dictation is currently only available behind the experimental - // accessibility features flag. - dictation_button_tray_ = std::make_unique<DictationButtonTray>(shelf_); - status_area_widget_delegate_->AddChildView(dictation_button_tray_.get()); - } + dictation_button_tray_ = std::make_unique<DictationButtonTray>(shelf_); + status_area_widget_delegate_->AddChildView(dictation_button_tray_.get()); logout_button_tray_ = std::make_unique<LogoutButtonTray>(shelf_); status_area_widget_delegate_->AddChildView(logout_button_tray_.get());
diff --git a/ash/system/tray_accessibility.cc b/ash/system/tray_accessibility.cc index a278934..e832477 100644 --- a/ash/system/tray_accessibility.cc +++ b/ash/system/tray_accessibility.cc
@@ -230,14 +230,11 @@ IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SELECT_TO_SPEAK), select_to_speak_enabled_); - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableExperimentalAccessibilityFeatures)) { - dictation_enabled_ = controller->IsDictationEnabled(); - dictation_view_ = AddScrollListCheckableItem( - kDictationOffIcon, // Need to get Chrome UI Review to comment on this - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_DICTATION), - dictation_enabled_); - } + dictation_enabled_ = controller->IsDictationEnabled(); + dictation_view_ = AddScrollListCheckableItem( + kDictationOffIcon, + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_DICTATION), + dictation_enabled_); high_contrast_enabled_ = controller->IsHighContrastEnabled(); high_contrast_view_ = AddScrollListCheckableItem(
diff --git a/ash/test/content/test_shell_content_state.cc b/ash/test/content/test_shell_content_state.cc index be29529..1b04af0 100644 --- a/ash/test/content/test_shell_content_state.cc +++ b/ash/test/content/test_shell_content_state.cc
@@ -16,20 +16,4 @@ return active_browser_context_.get(); } -content::BrowserContext* TestShellContentState::GetBrowserContextByIndex( - UserIndex index) { - return nullptr; -} - -content::BrowserContext* TestShellContentState::GetBrowserContextForWindow( - aura::Window* window) { - return nullptr; -} - -content::BrowserContext* -TestShellContentState::GetUserPresentingBrowserContextForWindow( - aura::Window* window) { - return nullptr; -} - } // namespace ash
diff --git a/ash/test/content/test_shell_content_state.h b/ash/test/content/test_shell_content_state.h index 5a6cc4c..6d8e30b1 100644 --- a/ash/test/content/test_shell_content_state.h +++ b/ash/test/content/test_shell_content_state.h
@@ -20,20 +20,11 @@ public: TestShellContentState(); - content::ScreenOrientationDelegate* screen_orientation_delegate() { - return &orientation_delegate_; - } - private: ~TestShellContentState() override; // Overridden from ShellContentState: content::BrowserContext* GetActiveBrowserContext() override; - content::BrowserContext* GetBrowserContextByIndex(UserIndex index) override; - content::BrowserContext* GetBrowserContextForWindow( - aura::Window* window) override; - content::BrowserContext* GetUserPresentingBrowserContextForWindow( - aura::Window* window) override; std::unique_ptr<content::BrowserContext> active_browser_context_;
diff --git a/ash/window_manager_service.cc b/ash/window_manager_service.cc index 473fe71..6b081fc9b 100644 --- a/ash/window_manager_service.cc +++ b/ash/window_manager_service.cc
@@ -179,11 +179,14 @@ registry_.AddInterface(base::BindRepeating( &WindowManagerService::BindServiceFactory, base::Unretained(this))); - const bool register_path_provider = running_standalone_; - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), - "ash_service_resources.pak", "ash_service_resources_200.pak", nullptr, - views::AuraInit::Mode::AURA_MUS_WINDOW_MANAGER, register_path_provider); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.resource_file = "ash_service_resources.pak"; + params.resource_file_200 = "ash_service_resources_200.pak"; + params.mode = views::AuraInit::Mode::AURA_MUS_WINDOW_MANAGER; + params.register_path_provider = running_standalone_; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) { context()->QuitNow(); return;
diff --git a/ash/wm/always_on_top_controller_unittest.cc b/ash/wm/always_on_top_controller_unittest.cc index b43b2c2..69899db 100644 --- a/ash/wm/always_on_top_controller_unittest.cc +++ b/ash/wm/always_on_top_controller_unittest.cc
@@ -72,9 +72,6 @@ controller->ActivateKeyboard(keyboard_controller); // Mock a keyboard appearing. - aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); - ASSERT_TRUE(keyboard_container); - keyboard_container->Show(); aura::Window* contents_window = keyboard_controller->ui()->GetContentsWindow(); const int kKeyboardHeight = 200;
diff --git a/ash/wm/overview/scoped_transform_overview_window.cc b/ash/wm/overview/scoped_transform_overview_window.cc index c4953d2..ded37ac 100644 --- a/ash/wm/overview/scoped_transform_overview_window.cc +++ b/ash/wm/overview/scoped_transform_overview_window.cc
@@ -569,6 +569,24 @@ StopObservingImplicitAnimations(); } +void ScopedTransformOverviewWindow::ResizeMinimizedWidgetIfNeeded() { + if (!minimized_widget_) + return; + + gfx::Rect bounds(window_->GetBoundsInScreen()); + if (bounds.size() == window_->GetBoundsInScreen().size()) + return; + + wm::WindowMirrorView* mirror_view = + static_cast<wm::WindowMirrorView*>(minimized_widget_->GetContentsView()); + if (mirror_view) { + mirror_view->RecreateMirrorLayers(); + bounds.Inset(0, 0, 0, + bounds.height() - mirror_view->GetPreferredSize().height()); + minimized_widget_->SetBounds(bounds); + } +} + void ScopedTransformOverviewWindow::OnImplicitAnimationsCompleted() { CreateAndApplyMaskAndShadow(); selector_item_->OnDragAnimationCompleted();
diff --git a/ash/wm/overview/scoped_transform_overview_window.h b/ash/wm/overview/scoped_transform_overview_window.h index c27d30a..3fdb6f3 100644 --- a/ash/wm/overview/scoped_transform_overview_window.h +++ b/ash/wm/overview/scoped_transform_overview_window.h
@@ -182,6 +182,10 @@ // Stop listening to any animations to finish. void CancelAnimationsListener(); + // If the original window is minimized, resize |minimized_widget_| to match + // the bounds of the |window_|. + void ResizeMinimizedWidgetIfNeeded(); + views::Widget* minimized_widget() { return minimized_widget_.get(); } // ui::ImplicitAnimationObserver:
diff --git a/ash/wm/overview/window_grid.h b/ash/wm/overview/window_grid.h index 15e71b4a..f06ade9 100644 --- a/ash/wm/overview/window_grid.h +++ b/ash/wm/overview/window_grid.h
@@ -178,6 +178,8 @@ return window_animation_observer_; } + const gfx::Rect bounds() const { return bounds_; } + views::Widget* new_selector_item_widget_for_testing() { return new_selector_item_widget_.get(); }
diff --git a/ash/wm/overview/window_selector_item.cc b/ash/wm/overview/window_selector_item.cc index e868db9e..d8a7323 100644 --- a/ash/wm/overview/window_selector_item.cc +++ b/ash/wm/overview/window_selector_item.cc
@@ -971,6 +971,15 @@ window_selector_->SelectWindow(this); } +void WindowSelectorItem::OnWindowBoundsChanged( + aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) { + if (reason == ui::PropertyChangeReason::NOT_FROM_ANIMATION) + transform_window_.ResizeMinimizedWidgetIfNeeded(); +} + void WindowSelectorItem::OnWindowDestroying(aura::Window* window) { window->RemoveObserver(this); transform_window_.OnWindowDestroyed();
diff --git a/ash/wm/overview/window_selector_item.h b/ash/wm/overview/window_selector_item.h index a8a79ba1..d7ccc6d 100644 --- a/ash/wm/overview/window_selector_item.h +++ b/ash/wm/overview/window_selector_item.h
@@ -182,6 +182,10 @@ void ButtonPressed(views::Button* sender, const ui::Event& event) override; // aura::WindowObserver: + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds, + ui::PropertyChangeReason reason) override; void OnWindowDestroying(aura::Window* window) override; void OnWindowTitleChanged(aura::Window* window) override;
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index 919b56d..ccf0640 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -1867,8 +1867,8 @@ ASSERT_TRUE(resizer.get()); EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting()); DragWindowTo(resizer.get(), gfx::Point(600, 300)); - EXPECT_EQ(GetIndicatorState(resizer.get()), - IndicatorState::kPreviewAreaRight); + // No preview window shows up on overview side of the screen. + EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kNone); CompleteDrag(std::move(resizer)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::RIGHT_SNAPPED); @@ -1953,7 +1953,8 @@ EXPECT_EQ(split_view_controller()->right_window(), window1.get()); EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting()); DragWindowTo(resizer.get(), gfx::Point(0, 300)); - EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kPreviewAreaLeft); + // No preview window shows up on overview side of the screen. + EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kNone); CompleteDrag(std::move(resizer)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::BOTH_SNAPPED); @@ -2052,7 +2053,8 @@ // 2.a. The dragged window can replace the only snapped window in the split // screen. After that, the old snapped window will be put back in overview. DragWindowTo(resizer.get(), gfx::Point(0, 500)); - EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kPreviewAreaLeft); + // No preview window shows up on overview side of the screen. + EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kNone); CompleteDrag(std::move(resizer)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::LEFT_SNAPPED); @@ -2071,8 +2073,8 @@ resizer = StartDrag(window1.get(), window2.get()); ASSERT_TRUE(resizer.get()); DragWindowTo(resizer.get(), gfx::Point(600, 500)); - EXPECT_EQ(GetIndicatorState(resizer.get()), - IndicatorState::kPreviewAreaRight); + // No preview window shows up on overview side of the screen. + EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kNone); CompleteDrag(std::move(resizer)); EXPECT_EQ(split_view_controller()->state(), SplitViewController::BOTH_SNAPPED);
diff --git a/ash/wm/tablet_mode/tablet_mode_window_resizer.cc b/ash/wm/tablet_mode/tablet_mode_window_resizer.cc index 867e633..85ec92fb 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_resizer.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_resizer.cc
@@ -46,6 +46,7 @@ constexpr float kScrimOpacity = 0.8; constexpr float kScrimBlur = 5.f; constexpr int kScrimTransitionInMs = 250; +constexpr int kScrimRoundRectRadiusDp = 4; // Returns the window selector if overview mode is active, otherwise returns // nullptr. @@ -76,23 +77,36 @@ } // Creates a transparent scrim which is placed below |dragged_window|. -std::unique_ptr<views::Widget> CreateScrim(aura::Window* dragged_window) { +std::unique_ptr<views::Widget> CreateScrim(aura::Window* dragged_window, + const gfx::Rect& bounds) { std::unique_ptr<views::Widget> widget = CreateBackgroundWidget( /*root_window=*/dragged_window->GetRootWindow(), /*layer_type=*/ui::LAYER_TEXTURED, /*background_color=*/kScrimBackgroundColor, /*border_thickness=*/0, - /*border_radius=*/0, + /*border_radius=*/kScrimRoundRectRadiusDp, /*border_color=*/SK_ColorTRANSPARENT, /*initial_opacity=*/0.f, /*parent=*/dragged_window->parent(), /*stack_on_top=*/false); - widget->SetBounds(display::Screen::GetScreen() - ->GetDisplayNearestWindow(dragged_window) - .work_area()); + widget->SetBounds(bounds); return widget; } +// When the dragged window is dragged past this value, the drag indicators will +// show up. +int GetIndicatorsVerticalThreshold(const gfx::Rect& work_area_bounds) { + return work_area_bounds.y() + + work_area_bounds.height() * kIndicatorsThresholdRatio; +} + +// When the dragged window is dragged past this value, a scrim will show up, +// indicating the dragged window will be maximized after releasing. +int GetMaximizeVerticalThreshold(const gfx::Rect& work_area_bounds) { + return work_area_bounds.y() + + work_area_bounds.height() * kMaximizeThresholdRatio; +} + } // namespace TabletModeWindowResizer::TabletModeWindowResizer(wm::WindowState* window_state) @@ -144,8 +158,11 @@ // Update the drag indicators and snap preview window if necessary. UpdateIndicatorsAndPreviewWindow(location_in_screen); - // Update the scrim and do scale transform of the source window if necessary. - UpdateScrimAndSourceWindow(location_in_screen); + // Update the source window if necessary. + UpdateSourceWindow(location_in_screen); + + // Update the scrim that beneath the dragged window if necessary. + UpdateScrim(location_in_screen); // Update dragged window's bounds. gfx::Rect bounds = CalculateBoundsForDrag(location_in_parent); @@ -210,9 +227,8 @@ void TabletModeWindowResizer::UpdateIndicatorsAndPreviewWindow( const gfx::Point& location_in_screen) { - SplitViewController::SnapPosition snap_position = - GetSnapPosition(location_in_screen); - if (snap_position != SplitViewController::NONE) { + if (GetSnapPosition(location_in_screen) != SplitViewController::NONE && + !split_view_controller_->IsSplitViewModeActive()) { // Show the preview window if |location_in_screen| is not contained by an // eligible target window item to merge the dragged window. WindowSelectorItem* item = @@ -234,7 +250,7 @@ location_in_screen); } -void TabletModeWindowResizer::UpdateScrimAndSourceWindow( +void TabletModeWindowResizer::UpdateSourceWindow( const gfx::Point& location_in_screen) { // Only do the scale if the source window is not the dragged window && the // source window is not in splitscreen && the source window is not in @@ -252,15 +268,9 @@ const gfx::Rect work_area_bounds = display::Screen::GetScreen() ->GetDisplayNearestWindow(GetTarget()) .work_area(); - const int indicators_vertical_threshold = - work_area_bounds.y() + - work_area_bounds.height() * kIndicatorsThresholdRatio; - const int maximize_vertical_threshold = - work_area_bounds.y() + - work_area_bounds.height() * kMaximizeThresholdRatio; - gfx::Rect expected_bounds(work_area_bounds); - if (location_in_screen.y() >= indicators_vertical_threshold) { + if (location_in_screen.y() >= + GetIndicatorsVerticalThreshold(work_area_bounds)) { SplitViewController::SnapPosition snap_position = GetSnapPosition(location_in_screen); @@ -277,21 +287,6 @@ ? SplitViewController::RIGHT : SplitViewController::LEFT); } - - const bool should_show_blurred_scrim = - (location_in_screen.y() > maximize_vertical_threshold) && - (snap_position == SplitViewController::NONE); - // When the event is between |indicators_vertical_threshold| and - // |maximize_vertical_threshold|, the scrim is still shown but is invisible - // to the user (transparent). It's needed to prevent the dragged window to - // merge into the scaled down source window. - ShowScrim(should_show_blurred_scrim ? kScrimOpacity : 0.f, - should_show_blurred_scrim ? kScrimBlur : 0.f); - } else { - // Remove |scrim_| entirely so that the dragged window can be merged back - // to the source window when the dragged window is dragged back toward the - // top area of the screen. - scrim_.reset(); } source_window->SetBoundsInScreen( @@ -299,6 +294,58 @@ display::Screen::GetScreen()->GetDisplayNearestWindow(source_window)); } +void TabletModeWindowResizer::UpdateScrim( + const gfx::Point& location_in_screen) { + const gfx::Rect work_area_bounds = display::Screen::GetScreen() + ->GetDisplayNearestWindow(GetTarget()) + .work_area(); + if (location_in_screen.y() < + GetIndicatorsVerticalThreshold(work_area_bounds)) { + // Remove |scrim_| entirely so that the dragged window can be merged back + // to the source window when the dragged window is dragged back toward the + // top area of the screen. + scrim_.reset(); + return; + } + + // If overview mode is active, do not show the scrim on the overview side of + // the screen. + if (Shell::Get()->window_selector_controller()->IsSelecting()) { + WindowGrid* window_grid = GetWindowSelector()->GetGridWithRootWindow( + GetTarget()->GetRootWindow()); + if (window_grid && window_grid->bounds().Contains(location_in_screen)) { + scrim_.reset(); + return; + } + } + + SplitViewController::SnapPosition snap_position = + GetSnapPosition(location_in_screen); + gfx::Rect expected_bounds(work_area_bounds); + if (split_view_controller_->IsSplitViewModeActive()) { + expected_bounds = split_view_controller_->GetSnappedWindowBoundsInScreen( + GetTarget(), snap_position); + } else { + expected_bounds.Inset(kHighlightScreenEdgePaddingDp, + kHighlightScreenEdgePaddingDp); + } + + bool should_show_blurred_scrim = false; + if (location_in_screen.y() >= + GetMaximizeVerticalThreshold(work_area_bounds)) { + if (split_view_controller_->IsSplitViewModeActive() != + (snap_position == SplitViewController::NONE)) { + should_show_blurred_scrim = true; + } + } + // When the event is between |indicators_vertical_threshold| and + // |maximize_vertical_threshold|, the scrim is still shown but is invisible + // to the user (transparent). It's needed to prevent the dragged window to + // merge into the scaled down source window. + ShowScrim(should_show_blurred_scrim ? kScrimOpacity : 0.f, + should_show_blurred_scrim ? kScrimBlur : 0.f, expected_bounds); +} + SplitViewController::SnapPosition TabletModeWindowResizer::GetSnapPosition( const gfx::Point& location_in_screen) const { gfx::Rect work_area_bounds = display::Screen::GetScreen() @@ -307,26 +354,44 @@ // The user has to drag pass the indicator vertical threshold to snap the // window. - const int indicators_vertical_threshold = - work_area_bounds.y() + - work_area_bounds.height() * kIndicatorsThresholdRatio; - if (location_in_screen.y() < indicators_vertical_threshold) + if (location_in_screen.y() < GetIndicatorsVerticalThreshold(work_area_bounds)) return SplitViewController::NONE; - if (split_view_controller_->IsCurrentScreenOrientationLandscape()) { + const bool is_landscape = + split_view_controller_->IsCurrentScreenOrientationLandscape(); + const bool is_primary = + split_view_controller_->IsCurrentScreenOrientationPrimary(); + + // If split view mode is active during dragging, the dragged window will be + // either snapped left or right (if it's not merged into overview window), + // depending on the relative position of |location_in_screen| and the current + // divider position. + if (split_view_controller_->IsSplitViewModeActive()) { + const int position = + is_landscape ? location_in_screen.x() : location_in_screen.y(); + if (position < split_view_controller_->divider_position()) { + return is_primary ? SplitViewController::LEFT + : SplitViewController::RIGHT; + } else { + return is_primary ? SplitViewController::RIGHT + : SplitViewController::LEFT; + } + } + + // Otherwise, check to see if the current event location |location_in_screen| + // is within the drag indicators bounds. + if (is_landscape) { const int screen_edge_inset = work_area_bounds.width() * kHighlightScreenPrimaryAxisRatio + kHighlightScreenEdgePaddingDp; work_area_bounds.Inset(screen_edge_inset, 0); if (location_in_screen.x() < work_area_bounds.x()) { - return split_view_controller_->IsCurrentScreenOrientationPrimary() - ? SplitViewController::LEFT - : SplitViewController::RIGHT; + return is_primary ? SplitViewController::LEFT + : SplitViewController::RIGHT; } - if (location_in_screen.x() > work_area_bounds.right()) { - return split_view_controller_->IsCurrentScreenOrientationPrimary() - ? SplitViewController::RIGHT - : SplitViewController::LEFT; + if (location_in_screen.x() >= work_area_bounds.right()) { + return is_primary ? SplitViewController::RIGHT + : SplitViewController::LEFT; } return SplitViewController::NONE; } else { @@ -337,28 +402,41 @@ work_area_bounds.height() * kHighlightScreenPrimaryAxisRatio + kHighlightScreenEdgePaddingDp; work_area_bounds.Inset(0, screen_edge_inset); - if (location_in_screen.y() > work_area_bounds.bottom()) { - return split_view_controller_->IsCurrentScreenOrientationPrimary() - ? SplitViewController::RIGHT - : SplitViewController::LEFT; + if (location_in_screen.y() >= work_area_bounds.bottom()) { + return is_primary ? SplitViewController::RIGHT + : SplitViewController::LEFT; } return SplitViewController::NONE; } } -void TabletModeWindowResizer::ShowScrim(float opacity, float blur) { - if (scrim_ && scrim_->GetLayer()->GetTargetOpacity() == opacity) +void TabletModeWindowResizer::ShowScrim(float opacity, + float blur, + const gfx::Rect& bounds_in_screen) { + gfx::Rect bounds(bounds_in_screen); + ::wm::ConvertRectFromScreen(GetTarget()->parent(), &bounds); + + if (scrim_ && scrim_->GetLayer()->GetTargetOpacity() == opacity && + scrim_->GetNativeWindow()->bounds() == bounds) { return; + } if (!scrim_) - scrim_ = CreateScrim(GetTarget()); + scrim_ = CreateScrim(GetTarget(), bounds); GetTarget()->parent()->StackChildBelow(scrim_->GetNativeWindow(), GetTarget()); scrim_->GetLayer()->SetBackgroundBlur(blur); + + if (scrim_->GetNativeWindow()->bounds() != bounds) { + scrim_->SetOpacity(0.f); + scrim_->SetBounds(bounds); + } ui::ScopedLayerAnimationSettings animation(scrim_->GetLayer()->GetAnimator()); animation.SetTweenType(gfx::Tween::EASE_IN_OUT); animation.SetTransitionDuration( base::TimeDelta::FromMilliseconds(kScrimTransitionInMs)); + animation.SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); scrim_->SetOpacity(opacity); } @@ -373,19 +451,14 @@ gfx::Rect work_area_bounds = display::Screen::GetScreen() ->GetDisplayNearestWindow(GetTarget()) .work_area(); - const int indicators_vertical_threshold = - work_area_bounds.y() + - work_area_bounds.height() * kIndicatorsThresholdRatio; - if (location_in_screen.y() < indicators_vertical_threshold) + if (location_in_screen.y() < GetIndicatorsVerticalThreshold(work_area_bounds)) return false; // If the event location has passed the maximize vertical threshold, and the // event location is not in snap indicator area, and overview mode is not // active at the moment, do not show the drag indicators. - const int maximize_vertical_threshold = - work_area_bounds.y() + - work_area_bounds.height() * kMaximizeThresholdRatio; - if (location_in_screen.y() > maximize_vertical_threshold && + if (location_in_screen.y() >= + GetMaximizeVerticalThreshold(work_area_bounds) && GetSnapPosition(location_in_screen) == SplitViewController::NONE && !Shell::Get()->window_selector_controller()->IsSelecting()) { return false;
diff --git a/ash/wm/tablet_mode/tablet_mode_window_resizer.h b/ash/wm/tablet_mode/tablet_mode_window_resizer.h index 3ac41fe..d98371e 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_resizer.h +++ b/ash/wm/tablet_mode/tablet_mode_window_resizer.h
@@ -57,14 +57,18 @@ // |kIndicatorThresholdRatio| threshold and restores it if the dragged window // is dragged back toward the top of the screen. |location_in_screen| is the // current drag location for the dragged window. - void UpdateScrimAndSourceWindow(const gfx::Point& location_in_screen); + void UpdateSourceWindow(const gfx::Point& location_in_screen); + + // Shows/Hides/Destroies the scrim widget |scrim_| based on the current + // location |location_in_screen|. + void UpdateScrim(const gfx::Point& location_in_screen); // Gets the desired snap position for |location_in_screen|. SplitViewController::SnapPosition GetSnapPosition( const gfx::Point& location_in_screen) const; - // Shows the scrim with the specified opacity and blur. - void ShowScrim(float opacity, float blur); + // Shows the scrim with the specified opacity, blur and expected bounds. + void ShowScrim(float opacity, float blur, const gfx::Rect& bounds_in_screen); // Returns true if the drag indicators should show. bool ShouldShowDragIndicators(const gfx::Point& location_in_screen) const;
diff --git a/ash/wm/window_mirror_view.cc b/ash/wm/window_mirror_view.cc index c2e5c00..af0c13f 100644 --- a/ash/wm/window_mirror_view.cc +++ b/ash/wm/window_mirror_view.cc
@@ -44,6 +44,13 @@ target_->ClearProperty(aura::client::kMirroringEnabledKey); } +void WindowMirrorView::RecreateMirrorLayers() { + if (layer_owner_) + layer_owner_.reset(); + + InitLayerOwner(); +} + gfx::Size WindowMirrorView::CalculatePreferredSize() const { return GetClientAreaBounds().size(); }
diff --git a/ash/wm/window_mirror_view.h b/ash/wm/window_mirror_view.h index 7b96deb9..4d3edaf 100644 --- a/ash/wm/window_mirror_view.h +++ b/ash/wm/window_mirror_view.h
@@ -29,6 +29,9 @@ WindowMirrorView(aura::Window* window, bool trilinear_filtering_on_init); ~WindowMirrorView() override; + // Recreates |layer_owner_|. + void RecreateMirrorLayers(); + // views::View: gfx::Size CalculatePreferredSize() const override; void Layout() override;
diff --git a/ash/wm/window_positioner.cc b/ash/wm/window_positioner.cc index f6b5d946..5b9a59d2 100644 --- a/ash/wm/window_positioner.cc +++ b/ash/wm/window_positioner.cc
@@ -273,23 +273,12 @@ void WindowPositioner::RearrangeVisibleWindowOnShow( aura::Window* added_window) { wm::WindowState* added_window_state = wm::GetWindowState(added_window); - if (!added_window->TargetVisibility()) - return; - - if (!UseAutoWindowManager(added_window) || + if (!added_window->TargetVisibility() || + !UseAutoWindowManager(added_window) || added_window_state->bounds_changed_by_user()) { - if (added_window_state->minimum_visibility()) { - // Guarantee minimum visibility within the work area. - gfx::Rect work_area = - screen_util::GetDisplayWorkAreaBoundsInParent(added_window); - gfx::Rect bounds = added_window->bounds(); - gfx::Rect new_bounds = bounds; - wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &new_bounds); - if (new_bounds != bounds) - added_window->SetBounds(new_bounds); - } return; } + // Find a single open managed window. bool single_window; aura::Window* other_shown_window = GetReferenceWindow(
diff --git a/ash/wm/window_positioner_unittest.cc b/ash/wm/window_positioner_unittest.cc index 6f6fed39..9c3151a 100644 --- a/ash/wm/window_positioner_unittest.cc +++ b/ash/wm/window_positioner_unittest.cc
@@ -16,7 +16,6 @@ #include "base/strings/string_number_conversions.h" #include "ui/display/screen.h" #include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_delegate.h" namespace ash { @@ -81,48 +80,6 @@ EXPECT_EQ("300x300", bounds.size().ToString()); } -namespace { - -// A WidgetDelegate that returns the out of display saved bounds. -class OutOfDisplayDelegate : public views::WidgetDelegate { - public: - explicit OutOfDisplayDelegate(views::Widget* widget) : widget_(widget) {} - ~OutOfDisplayDelegate() override = default; - - // Overridden from WidgetDelegate: - void DeleteDelegate() override { delete this; } - views::Widget* GetWidget() override { return widget_; } - const views::Widget* GetWidget() const override { return widget_; } - bool GetSavedWindowPlacement(const views::Widget* widget, - gfx::Rect* bounds, - ui::WindowShowState* show_state) const override { - bounds->SetRect(450, 10, 100, 100); - *show_state = ui::SHOW_STATE_NORMAL; - return true; - } - - private: - views::Widget* widget_; - - DISALLOW_COPY_AND_ASSIGN(OutOfDisplayDelegate); -}; - -} // namespace - -TEST_F(WindowPositionerTest, EnsureMinimumVisibility) { - UpdateDisplay("400x400"); - views::Widget* widget = new views::Widget(); - views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); - params.delegate = new OutOfDisplayDelegate(widget); - widget->Init(params); - widget->SetBounds(gfx::Rect(450, 10, 100, 100)); - wm::GetWindowState(widget->GetNativeView())->set_minimum_visibility(true); - widget->Show(); - // Make sure the bounds is adjusted to be inside the work area. - EXPECT_EQ("375,10 100x100", widget->GetWindowBoundsInScreen().ToString()); - widget->CloseNow(); -} - TEST_F(WindowPositionerTest, IgnoreFullscreenInAutoRearrange) { // Set bigger than 1366 so that the new window is opened in normal state. UpdateDisplay("1400x800");
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 4f81a2b..869a057 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -505,7 +505,6 @@ unminimize_to_restore_bounds_(false), hide_shelf_when_fullscreen_(true), autohide_shelf_when_maximized_or_fullscreen_(false), - minimum_visibility_(false), cached_always_on_top_(false), ignore_property_change_(false), current_state_(new DefaultState(ToWindowStateType(GetShowState()))) {
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index ec9e9d03..1170c2d 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -231,16 +231,6 @@ autohide_shelf_when_maximized_or_fullscreen_ = value; } - // If the minimum visibility is true, ash will try to keep a - // minimum amount of the window is always visible on the work area - // when shown. - // TODO(oshima): Consolidate this and GetWindowPositionManaged - // into single parameter to control the window placement. - bool minimum_visibility() const { return minimum_visibility_; } - void set_minimum_visibility(bool minimum_visibility) { - minimum_visibility_ = minimum_visibility; - } - // Gets/Sets the bounds of the window before it was moved by the auto window // management. As long as it was not auto-managed, it will return NULL. const base::Optional<gfx::Rect> pre_auto_manage_window_bounds() { @@ -426,7 +416,6 @@ bool ignore_keyboard_bounds_change_ = false; bool hide_shelf_when_fullscreen_; bool autohide_shelf_when_maximized_or_fullscreen_; - bool minimum_visibility_; bool cached_always_on_top_; bool allow_set_bounds_direct_ = false;
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index baa8a52..369da4c 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -1820,7 +1820,7 @@ kb_controller->NotifyContentsLoaded(); int shift = - work_area.height() - kb_controller->GetContainerWindow()->bounds().y(); + work_area.height() - kb_controller->GetContentsWindow()->bounds().y(); gfx::Rect changed_window_bounds(orig_window_bounds); changed_window_bounds.Offset(0, -shift); // Window should be shifted up.
diff --git a/base/BUILD.gn b/base/BUILD.gn index f0f92302..b643a92e 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -816,6 +816,7 @@ "task/sequence_manager/lazily_deallocated_deque.h", "task/sequence_manager/lazy_now.cc", "task/sequence_manager/lazy_now.h", + "task/sequence_manager/sequence_manager.h", "task/sequence_manager/sequenced_task_source.h", "task/sequence_manager/task_queue.h", "task/sequence_manager/task_time_observer.h", @@ -1051,6 +1052,7 @@ "win/patch_util.h", "win/process_startup_helper.cc", "win/process_startup_helper.h", + "win/reference.h", "win/registry.cc", "win/registry.h", "win/resource_util.cc", @@ -2442,6 +2444,7 @@ "win/message_window_unittest.cc", "win/object_watcher_unittest.cc", "win/pe_image_unittest.cc", + "win/reference_unittest.cc", "win/registry_unittest.cc", "win/scoped_bstr_unittest.cc", "win/scoped_handle_unittest.cc",
diff --git a/base/process/process_fuchsia.cc b/base/process/process_fuchsia.cc index 94bce34..e6acd56 100644 --- a/base/process/process_fuchsia.cc +++ b/base/process/process_fuchsia.cc
@@ -9,6 +9,7 @@ #include "base/debug/activity_tracker.h" #include "base/fuchsia/default_job.h" +#include "base/fuchsia/fuchsia_logging.h" #include "base/strings/stringprintf.h" namespace base { @@ -53,7 +54,7 @@ zx_status_t status = zx_object_get_child( GetDefaultJob(), pid, ZX_RIGHT_SAME_RIGHTS, handle.receive()); if (status != ZX_OK) { - DLOG(ERROR) << "zx_object_get_child failed: " << status; + ZX_DLOG(ERROR, status) << "zx_object_get_child"; return Process(); } return Process(handle.release()); @@ -69,9 +70,10 @@ Process Process::DeprecatedGetProcessFromHandle(ProcessHandle handle) { DCHECK_NE(handle, GetCurrentProcessHandle()); ScopedZxHandle out; - if (zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, out.receive()) != - ZX_OK) { - DLOG(ERROR) << "zx_handle_duplicate failed: " << handle; + zx_status_t result = + zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, out.receive()); + if (result != ZX_OK) { + ZX_DLOG(ERROR, result) << "zx_handle_duplicate(from_handle)"; return Process(); } @@ -104,9 +106,10 @@ return Process(); ScopedZxHandle out; - if (zx_handle_duplicate(process_.get(), ZX_RIGHT_SAME_RIGHTS, - out.receive()) != ZX_OK) { - DLOG(ERROR) << "zx_handle_duplicate failed: " << process_.get(); + zx_status_t result = + zx_handle_duplicate(process_.get(), ZX_RIGHT_SAME_RIGHTS, out.receive()); + if (result != ZX_OK) { + ZX_DLOG(ERROR, result) << "zx_handle_duplicate"; return Process(); } @@ -130,19 +133,17 @@ bool Process::Terminate(int exit_code, bool wait) const { // exit_code isn't supportable. https://crbug.com/753490. zx_status_t status = zx_task_kill(Handle()); - // TODO(scottmg): Put these LOG/CHECK back to DLOG/DCHECK after - // https://crbug.com/750756 is diagnosed. if (status == ZX_OK && wait) { zx_signals_t signals; status = zx_object_wait_one(Handle(), ZX_TASK_TERMINATED, zx_deadline_after(ZX_SEC(60)), &signals); if (status != ZX_OK) { - LOG(ERROR) << "Error waiting for process exit: " << status; + ZX_DLOG(ERROR, status) << "zx_object_wait_one(terminate)"; } else { CHECK(signals & ZX_TASK_TERMINATED); } } else if (status != ZX_OK) { - LOG(ERROR) << "Unable to terminate process: " << status; + ZX_DLOG(ERROR, status) << "zx_task_kill"; } return status >= 0; @@ -172,18 +173,8 @@ zx_signals_t signals_observed = 0; zx_status_t status = zx_object_wait_one(process_.get(), ZX_TASK_TERMINATED, deadline, &signals_observed); - - // TODO(scottmg): Make these LOGs into DLOGs after https://crbug.com/750756 is - // fixed. - if (status != ZX_OK && status != ZX_ERR_TIMED_OUT) { - LOG(ERROR) << "zx_object_wait_one failed, status=" << status; - return false; - } - if (status == ZX_ERR_TIMED_OUT) { - zx_time_t now = TimeTicks::Now().ToZxTime(); - LOG(ERROR) << "zx_object_wait_one timed out, signals=" << signals_observed - << ", deadline=" << deadline << ", now=" << now - << ", delta=" << (now - deadline); + if (status != ZX_OK) { + ZX_DLOG(ERROR, status) << "zx_object_wait_one"; return false; } @@ -191,7 +182,7 @@ status = zx_object_get_info(process_.get(), ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), nullptr, nullptr); if (status != ZX_OK) { - LOG(ERROR) << "zx_object_get_info failed, status=" << status; + ZX_DLOG(ERROR, status) << "zx_object_get_info"; if (exit_code) *exit_code = -1; return false;
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc index 075a800..9a30941 100644 --- a/base/profiler/native_stack_sampler_win.cc +++ b/base/profiler/native_stack_sampler_win.cc
@@ -4,8 +4,9 @@ #include "base/profiler/native_stack_sampler.h" -#include <objbase.h> #include <windows.h> + +#include <objbase.h> #include <stddef.h> #include <winternl.h>
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager.h b/base/task/sequence_manager/sequence_manager.h similarity index 70% rename from third_party/blink/renderer/platform/scheduler/base/sequence_manager.h rename to base/task/sequence_manager/sequence_manager.h index 0318c81..47f20cd3b 100644 --- a/third_party/blink/renderer/platform/scheduler/base/sequence_manager.h +++ b/base/task/sequence_manager/sequence_manager.h
@@ -2,28 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_H_ +#ifndef BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_H_ +#define BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_H_ #include <memory> #include <utility> #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" +#include "base/task/sequence_manager/task_queue_impl.h" #include "base/task/sequence_manager/task_time_observer.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" -#include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" namespace base { namespace sequence_manager { +class TimeDomain; + // SequenceManager manages TaskQueues which have different properties // (e.g. priority, common task type) multiplexing all posted tasks into // a single backing sequence (currently bound to a single thread, which is // refererred as *main thread* in the comments below). SequenceManager // implementation can be used in a various ways to apply scheduling logic. -class PLATFORM_EXPORT SequenceManager { +class SequenceManager { public: class Observer { public: @@ -35,11 +35,13 @@ virtual ~SequenceManager() = default; - // Create SequenceManager using MessageLoop on the current thread. - static std::unique_ptr<SequenceManager> CreateOnCurrentThread(); + // TODO(kraynov): Bring back CreateOnCurrentThread static method here + // when the move is done. It's not here yet to reduce PLATFORM_EXPORT + // macros hacking during the move. - // Must be called once, on the main thread. - // Observer is expected to outlive the SequenceManager. + // Must be called on the main thread. + // Can be called only once, before creating TaskQueues. + // Observer must outlive the SequenceManager. virtual void SetObserver(Observer* observer) = 0; // Must be called on the main thread. @@ -48,7 +50,10 @@ virtual void AddTaskTimeObserver(TaskTimeObserver* task_time_observer) = 0; virtual void RemoveTaskTimeObserver(TaskTimeObserver* task_time_observer) = 0; - // TaskQueues have their TimeDomain which must be registered in advance. + // Registers a TimeDomain with SequenceManager. + // TaskQueues must only be created with a registered TimeDomain. + // Conversely, any TimeDomain must remain registered until no + // TaskQueues (using that TimeDomain) remain. virtual void RegisterTimeDomain(TimeDomain* time_domain) = 0; virtual void UnregisterTimeDomain(TimeDomain* time_domain) = 0; @@ -64,8 +69,8 @@ // Removes all canceled delayed tasks. virtual void SweepCanceledDelayedTasks() = 0; - // Some TaskQueues do monitor a quiescent state, so this method returns - // true if any such queue has ran a task since the last call. + // Returns true if no tasks were executed in TaskQueues that monitor + // quiescence since the last call to this method. virtual bool GetAndClearSystemIsQuiescentBit() = 0; // Set the number of tasks executed in a single SequenceManager invocation. @@ -73,6 +78,9 @@ // logic at the cost of a potentially worse latency. 1 by default. virtual void SetWorkBatchSize(int work_batch_size) = 0; + // Enables crash keys that can be set in the scope of a task which help + // to identify the culprit if upcoming work results in a crash. + // Key names must be thread-specific to avoid races and corrupted crash dumps. virtual void EnableCrashKeys(const char* file_name_crash_key, const char* function_name_crash_key) = 0; @@ -86,9 +94,8 @@ template <typename TaskQueueType, typename... Args> scoped_refptr<TaskQueueType> CreateTaskQueue(const TaskQueue::Spec& spec, Args&&... args) { - scoped_refptr<TaskQueueType> task_queue(new TaskQueueType( - CreateTaskQueueImpl(spec), spec, std::forward<Args>(args)...)); - return task_queue; + return WrapRefCounted(new TaskQueueType(CreateTaskQueueImpl(spec), spec, + std::forward<Args>(args)...)); } protected: @@ -99,4 +106,4 @@ } // namespace sequence_manager } // namespace base -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_H_ +#endif // BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_H_
diff --git a/base/win/reference.h b/base/win/reference.h new file mode 100644 index 0000000..7fadfb2 --- /dev/null +++ b/base/win/reference.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 BASE_WIN_REFERENCE_H_ +#define BASE_WIN_REFERENCE_H_ + +#include <windows.foundation.collections.h> +#include <wrl/implements.h> + +#include <type_traits> +#include <utility> + +#include "base/macros.h" + +namespace base { +namespace win { + +// Implementation of the UWP's IReference interface. +template <typename T> +class Reference + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>, + ABI::Windows::Foundation::IReference<T>> { + public: + using AbiT = typename ABI::Windows::Foundation::Internal::GetAbiType< + typename ABI::Windows::Foundation::IReference<T>::T_complex>::type; + + explicit Reference(const AbiT& value) : value_(value) {} + explicit Reference(AbiT&& value) : value_(std::move(value)) {} + + // ABI::Windows::Foundation::IReference: + IFACEMETHODIMP get_Value(AbiT* value) override { + *value = value_; + return S_OK; + } + + private: + ~Reference() = default; + AbiT value_; + + DISALLOW_COPY_AND_ASSIGN(Reference); +}; + +} // namespace win +} // namespace base + +#endif // BASE_WIN_REFERENCE_H_
diff --git a/base/win/reference_unittest.cc b/base/win/reference_unittest.cc new file mode 100644 index 0000000..4116872 --- /dev/null +++ b/base/win/reference_unittest.cc
@@ -0,0 +1,38 @@ +// 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/win/reference.h" + +#include <windows.foundation.h> +#include <wrl/client.h> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace win { + +namespace { + +using Microsoft::WRL::Make; + +} // namespace + +TEST(ReferenceTest, Value) { + auto ref = Make<Reference<int>>(123); + int value = 0; + HRESULT hr = ref->get_Value(&value); + EXPECT_TRUE(SUCCEEDED(hr)); + EXPECT_EQ(123, value); +} + +TEST(ReferenceTest, ValueAggregate) { + auto ref = Make<Reference<bool>>(true); + boolean value = false; + HRESULT hr = ref->get_Value(&value); + EXPECT_TRUE(SUCCEEDED(hr)); + EXPECT_TRUE(value); +} + +} // namespace win +} // namespace base
diff --git a/build/fuchsia/sdk.sha1 b/build/fuchsia/sdk.sha1 index 1a40548..58dd34d 100644 --- a/build/fuchsia/sdk.sha1 +++ b/build/fuchsia/sdk.sha1
@@ -1 +1 @@ -195b24ffb560cbbbba41dadbe3a6710dd58d02af \ No newline at end of file +0fe5efe7d114ff39c1f2f2606e8dad87bb62cdc4 \ No newline at end of file
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 4d9d1f4..6f47ea9 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -133,6 +133,18 @@ sys_include_flags = "" } + if (use_lld) { + # Invoke ninja as wrapper instead of tool wrapper, because python + # invocation requires higher cpu usage compared to ninja invocation, and + # the python wrapper is only needed to work around link.exe problems. + # TODO(thakis): Remove wrapper once lld-link can merge manifests without + # relying on mt.exe being in %PATH% on Windows. + linker_wrapper = "ninja -t msvc -e $env -- " # Note trailing space. + } else { + linker_wrapper = + "$python_path $tool_wrapper_path link-wrapper $env False " # Note trailing space. + } + clflags = "" # Pass /FC flag to the compiler if needed. @@ -196,7 +208,8 @@ tool("alink") { rspfile = "{{output}}.rsp" - command = "$python_path $tool_wrapper_path link-wrapper $env False $lib /nologo {{arflags}} /OUT:{{output}} @$rspfile" + command = + "$linker_wrapper$lib /nologo {{arflags}} /OUT:{{output}} @$rspfile" description = "LIB {{output}}" outputs = [ # Ignore {{output_extension}} and always use .lib, there's no reason to @@ -218,7 +231,7 @@ rspfile = "${dllname}.rsp" pool = "//build/toolchain:link_pool($default_toolchain)" - command = "$python_path $tool_wrapper_path link-wrapper $env False $link /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" + command = "$linker_wrapper$link /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" default_output_extension = ".dll" default_output_dir = "{{root_out_dir}}" @@ -251,7 +264,7 @@ rspfile = "${dllname}.rsp" pool = "//build/toolchain:link_pool($default_toolchain)" - command = "$python_path $tool_wrapper_path link-wrapper $env False $link /nologo /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" + command = "$linker_wrapper$link /nologo /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" default_output_extension = ".dll" default_output_dir = "{{root_out_dir}}" @@ -275,7 +288,8 @@ rspfile = "$exename.rsp" pool = "//build/toolchain:link_pool($default_toolchain)" - command = "$python_path $tool_wrapper_path link-wrapper $env False $link /nologo /OUT:$exename /PDB:$pdbname @$rspfile" + command = + "$linker_wrapper$link /nologo /OUT:$exename /PDB:$pdbname @$rspfile" if (host_os == "win") { shellprefix = "cmd /c"
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 99acdd1e..87ac7fc 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -537,8 +537,10 @@ "//gpu/command_buffer/client:raster", "//gpu/command_buffer/common", "//gpu/ipc:gl_in_process_context", + "//gpu/ipc/service", "//gpu/skia_bindings", "//media", + "//services/viz/privileged/interfaces", "//skia", "//testing/gtest", "//ui/gfx",
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc index 805520f..932e449 100644 --- a/cc/paint/paint_image.cc +++ b/cc/paint/paint_image.cc
@@ -137,10 +137,8 @@ // TODO(vmpstr): If this image is using subset_rect, then we don't support // decoding to any scale other than the original. See the comment in Decode() // explaining this in more detail. - // TODO(vmpstr): For now, always decode to the original size. This can be - // enabled with the following code, and should be done as a follow-up. - // if (paint_image_generator_ && subset_rect_.IsEmpty()) - // return paint_image_generator_->GetSupportedDecodeSize(requested_size); + if (paint_image_generator_ && subset_rect_.IsEmpty()) + return paint_image_generator_->GetSupportedDecodeSize(requested_size); return SkISize::Make(width(), height()); }
diff --git a/cc/paint/paint_image_unittest.cc b/cc/paint/paint_image_unittest.cc index 78a2240bd..d8c59fc 100644 --- a/cc/paint/paint_image_unittest.cc +++ b/cc/paint/paint_image_unittest.cc
@@ -82,4 +82,27 @@ generator->reset_frames_decoded(); } +TEST(PaintImageTest, SupportedDecodeSize) { + SkISize full_size = SkISize::Make(10, 10); + std::vector<SkISize> supported_sizes = {SkISize::Make(5, 5)}; + std::vector<FrameMetadata> frames = {FrameMetadata()}; + sk_sp<FakePaintImageGenerator> generator = + sk_make_sp<FakePaintImageGenerator>( + SkImageInfo::MakeN32Premul(full_size.width(), full_size.height()), + frames, true, supported_sizes); + PaintImage image = PaintImageBuilder::WithDefault() + .set_id(PaintImage::GetNextId()) + .set_paint_image_generator(generator) + .set_frame_index(0u) + .TakePaintImage(); + EXPECT_EQ(image.GetSupportedDecodeSize(supported_sizes[0]), + supported_sizes[0]); + + PaintImage subset = PaintImageBuilder::WithCopy(image) + .make_subset(gfx::Rect(8, 8)) + .TakePaintImage(); + EXPECT_EQ(subset.GetSupportedDecodeSize(supported_sizes[0]), + SkISize::Make(8, 8)); +} + } // namespace cc
diff --git a/cc/paint/paint_typeface.cc b/cc/paint/paint_typeface.cc index 2595d84..d6ee8c0 100644 --- a/cc/paint/paint_typeface.cc +++ b/cc/paint/paint_typeface.cc
@@ -4,8 +4,8 @@ #include "cc/paint/paint_typeface.h" #include "build/build_config.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontConfigInterface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" namespace cc {
diff --git a/cc/test/DEPS b/cc/test/DEPS index dc2e876..b542323 100644 --- a/cc/test/DEPS +++ b/cc/test/DEPS
@@ -8,8 +8,11 @@ "+gpu/command_buffer/common/context_creation_attribs.h", "+gpu/command_buffer/common/skia_utils.h", "+gpu/command_buffer/service/image_factory.h", + "+gpu/config/gpu_info.h", "+gpu/ipc", "+gpu/skia_bindings/grcontext_for_gles2_interface.h", + "+mojo/public/cpp/bindings/strong_binding.h", + "+services/viz/privileged/interfaces/gl/gpu_host.mojom.h", ] specific_include_rules = {
diff --git a/cc/test/fake_paint_image_generator.cc b/cc/test/fake_paint_image_generator.cc index b620a59..ce2be35 100644 --- a/cc/test/fake_paint_image_generator.cc +++ b/cc/test/fake_paint_image_generator.cc
@@ -9,12 +9,14 @@ FakePaintImageGenerator::FakePaintImageGenerator( const SkImageInfo& info, std::vector<FrameMetadata> frames, - bool allocate_discardable_memory) + bool allocate_discardable_memory, + std::vector<SkISize> supported_sizes) : PaintImageGenerator(info, std::move(frames)), image_backing_memory_( allocate_discardable_memory ? info.computeMinByteSize() : 0, 0), - image_pixmap_(info, image_backing_memory_.data(), info.minRowBytes()) {} + image_pixmap_(info, image_backing_memory_.data(), info.minRowBytes()), + supported_sizes_(std::move(supported_sizes)) {} FakePaintImageGenerator::~FakePaintImageGenerator() = default; @@ -50,4 +52,15 @@ return false; } +SkISize FakePaintImageGenerator::GetSupportedDecodeSize( + const SkISize& requested_size) const { + for (auto& size : supported_sizes_) { + if (size.width() >= requested_size.width() && + size.height() >= requested_size.height()) { + return size; + } + } + return PaintImageGenerator::GetSupportedDecodeSize(requested_size); +} + } // namespace cc
diff --git a/cc/test/fake_paint_image_generator.h b/cc/test/fake_paint_image_generator.h index 55a82165..fe8a1d3 100644 --- a/cc/test/fake_paint_image_generator.h +++ b/cc/test/fake_paint_image_generator.h
@@ -15,7 +15,8 @@ explicit FakePaintImageGenerator( const SkImageInfo& info, std::vector<FrameMetadata> frames = {FrameMetadata()}, - bool allocate_discardable_memory = true); + bool allocate_discardable_memory = true, + std::vector<SkISize> supported_sizes = {}); ~FakePaintImageGenerator() override; sk_sp<SkData> GetEncodedData() const override; @@ -30,6 +31,7 @@ void* planes[3], size_t frame_index, uint32_t lazy_pixel_ref) override; + SkISize GetSupportedDecodeSize(const SkISize& requested_size) const override; const base::flat_map<size_t, int>& frames_decoded() const { return frames_decoded_count_; @@ -40,6 +42,7 @@ std::vector<uint8_t> image_backing_memory_; SkPixmap image_pixmap_; base::flat_map<size_t, int> frames_decoded_count_; + std::vector<SkISize> supported_sizes_; }; } // namespace cc
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index d39c68f2..3213530 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc
@@ -29,9 +29,20 @@ #include "components/viz/service/display/output_surface_client.h" #include "components/viz/service/display/software_output_device.h" #include "components/viz/service/display/software_renderer.h" +#include "components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h" +#include "components/viz/service/display_embedder/skia_output_surface_impl.h" +#include "components/viz/service/display_embedder/viz_process_context_provider.h" +#include "components/viz/service/gl/gpu_service_impl.h" #include "components/viz/test/paths.h" #include "components/viz/test/test_shared_bitmap_manager.h" #include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/command_buffer/client/shared_memory_limits.h" +#include "gpu/config/gpu_info.h" +#include "gpu/ipc/gpu_in_process_thread_service.h" +#include "gpu/ipc/service/gpu_memory_buffer_factory.h" +#include "gpu/ipc/service/gpu_watchdog_thread.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "services/viz/privileged/interfaces/gl/gpu_host.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -45,9 +56,7 @@ renderer_settings_.dont_round_texture_sizes_for_pixel_tests = true; } -PixelTest::~PixelTest() { - child_resource_provider_->ShutdownAndReleaseAllResources(); -} +PixelTest::~PixelTest() = default; bool PixelTest::RunPixelTest(viz::RenderPassList* pass_list, const base::FilePath& ref_file, @@ -225,11 +234,115 @@ void PixelTest::SetUpSkiaRenderer() { SetUpGLWithoutRenderer(false); renderer_ = std::make_unique<viz::SkiaRenderer>( - &renderer_settings_, output_surface_.get(), resource_provider_.get()); + &renderer_settings_, output_surface_.get(), resource_provider_.get(), + nullptr /* skia_output_surface */); renderer_->Initialize(); renderer_->SetVisible(true); } +void PixelTest::SetUpGpuServiceOnGpuThread(base::WaitableEvent* event) { + ASSERT_TRUE(gpu_thread_->task_runner()->BelongsToCurrentThread()); + gpu_service_ = std::make_unique<viz::GpuServiceImpl>( + gpu::GPUInfo(), nullptr /* watchdog_thread */, io_thread_->task_runner(), + gpu::GpuFeatureInfo(), gpu::GpuPreferences(), gpu::GPUInfo(), + gpu::GpuFeatureInfo(), base::DoNothing() /* exit_callback */); + + // Uses a null gpu_host here, because we don't want to receive any message. + std::unique_ptr<viz::mojom::GpuHost> gpu_host; + viz::mojom::GpuHostPtr gpu_host_proxy; + mojo::MakeStrongBinding(std::move(gpu_host), + mojo::MakeRequest(&gpu_host_proxy)); + gpu_service_->InitializeWithHost( + std::move(gpu_host_proxy), gpu::GpuProcessActivityFlags(), + nullptr /* sync_point_manager */, nullptr /* shutdown_event */); + gpu_command_service_ = base::MakeRefCounted<gpu::GpuInProcessThreadService>( + gpu_thread_->task_runner(), gpu_service_->sync_point_manager(), + gpu_service_->mailbox_manager(), gpu_service_->share_group(), + gpu_service_->gpu_feature_info(), + gpu_service_->gpu_channel_manager()->gpu_preferences()); + event->Signal(); +} + +void PixelTest::SetUpSkiaRendererDDL() { + // Set up the GPU service. + gpu_thread_ = std::make_unique<base::Thread>("GPUMainThread"); + ASSERT_TRUE(gpu_thread_->Start()); + io_thread_ = std::make_unique<base::Thread>("GPUIOThread"); + ASSERT_TRUE(io_thread_->Start()); + base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + gpu_thread_->task_runner()->PostTask( + FROM_HERE, base::BindOnce(&PixelTest::SetUpGpuServiceOnGpuThread, + base::Unretained(this), &event)); + event.Wait(); + + // Set up the skia renderer. + output_surface_ = std::make_unique<viz::SkiaOutputSurfaceImpl>( + gpu_service_.get(), gpu::kNullSurfaceHandle, + nullptr /* synthetic_begin_frame_source */); + output_surface_->BindToClient(output_surface_client_.get()); + resource_provider_ = std::make_unique<viz::DisplayResourceProvider>( + viz::DisplayResourceProvider::kGpu, + nullptr /* compositor_context_provider */, + nullptr /* shared_bitmap_manager */); + renderer_ = std::make_unique<viz::SkiaRenderer>( + &renderer_settings_, output_surface_.get(), resource_provider_.get(), + static_cast<viz::SkiaOutputSurfaceImpl*>(output_surface_.get())); + renderer_->Initialize(); + renderer_->SetVisible(true); + + // Set up the client side context provider, etc + auto* gpu_channel_manager = gpu_service_->gpu_channel_manager(); + gpu_memory_buffer_manager_ = + std::make_unique<viz::InProcessGpuMemoryBufferManager>( + gpu_channel_manager); + gpu::ImageFactory* image_factory = nullptr; + if (gpu_channel_manager->gpu_memory_buffer_factory()) { + image_factory = + gpu_channel_manager->gpu_memory_buffer_factory()->AsImageFactory(); + } + auto* gpu_channel_manager_delegate = gpu_channel_manager->delegate(); + child_context_provider_ = + base::MakeRefCounted<viz::VizProcessContextProvider>( + gpu_command_service_, gpu::kNullSurfaceHandle, + gpu_memory_buffer_manager_.get(), image_factory, + gpu_channel_manager_delegate, gpu::SharedMemoryLimits()); + child_context_provider_->BindToCurrentThread(); + child_resource_provider_ = + std::make_unique<viz::ClientResourceProvider>(true); +} + +void PixelTest::TearDownGpuServiceOnGpuThread(base::WaitableEvent* event) { + gpu_command_service_ = nullptr; + gpu_service_ = nullptr; + event->Signal(); +} + +void PixelTest::TearDown() { + // Tear down the client side context provider, etc. + child_resource_provider_->ShutdownAndReleaseAllResources(); + child_resource_provider_ = nullptr; + child_context_provider_ = nullptr; + gpu_memory_buffer_manager_ = nullptr; + + // Tear down the skia renderer. + renderer_ = nullptr; + resource_provider_ = nullptr; + output_surface_ = nullptr; + + if (gpu_command_service_) { + // Tear down the GPU service. + base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + gpu_thread_->task_runner()->PostTask( + FROM_HERE, base::BindOnce(&PixelTest::TearDownGpuServiceOnGpuThread, + base::Unretained(this), &event)); + event.Wait(); + } + io_thread_ = nullptr; + gpu_thread_ = nullptr; +} + void PixelTest::EnableExternalStencilTest() { static_cast<PixelTestOutputSurface*>(output_surface_.get()) ->set_has_external_stencil_test(true);
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h index a7c1a901..e7ba16fc 100644 --- a/cc/test/pixel_test.h +++ b/cc/test/pixel_test.h
@@ -16,21 +16,28 @@ #include "components/viz/service/display/output_surface.h" #include "components/viz/service/display/skia_renderer.h" #include "components/viz/service/display/software_renderer.h" +#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" +#include "gpu/ipc/in_process_command_buffer.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_implementation.h" +namespace base { +class Thread; +} + namespace viz { class CopyOutputResult; class DirectRenderer; class DisplayResourceProvider; +class GLRenderer; +class GpuServiceImpl; class TestSharedBitmapManager; } namespace cc { class FakeOutputSurfaceClient; class OutputSurface; -class TestInProcessContextProvider; class PixelTest : public testing::Test { protected: @@ -71,6 +78,13 @@ viz::ResourceId AllocateAndFillSoftwareResource(const gfx::Size& size, const SkBitmap& source); + // For SkiaRendererDDL. + std::unique_ptr<base::Thread> gpu_thread_; + std::unique_ptr<base::Thread> io_thread_; + std::unique_ptr<viz::GpuServiceImpl> gpu_service_; + std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_; + scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_command_service_; + viz::RendererSettings renderer_settings_; gfx::Size device_viewport_size_; bool disable_picture_quad_image_filtering_; @@ -78,7 +92,7 @@ std::unique_ptr<viz::OutputSurface> output_surface_; std::unique_ptr<viz::TestSharedBitmapManager> shared_bitmap_manager_; std::unique_ptr<viz::DisplayResourceProvider> resource_provider_; - scoped_refptr<TestInProcessContextProvider> child_context_provider_; + scoped_refptr<viz::ContextProvider> child_context_provider_; std::unique_ptr<viz::ClientResourceProvider> child_resource_provider_; std::unique_ptr<viz::DirectRenderer> renderer_; viz::SoftwareRenderer* software_renderer_ = nullptr; @@ -87,8 +101,11 @@ void SetUpGLWithoutRenderer(bool flipped_output_surface); void SetUpGLRenderer(bool flipped_output_surface); void SetUpSkiaRenderer(); + void SetUpSkiaRendererDDL(); void SetUpSoftwareRenderer(); + void TearDown() override; + void EnableExternalStencilTest(); private: @@ -97,6 +114,8 @@ bool PixelsMatchReference(const base::FilePath& ref_file, const PixelComparator& comparator); + void SetUpGpuServiceOnGpuThread(base::WaitableEvent* event); + void TearDownGpuServiceOnGpuThread(base::WaitableEvent* event); std::unique_ptr<gl::DisableNullDrawGLBindings> enable_pixel_output_; }; @@ -151,6 +170,18 @@ std::move(current_task_runner)) {} }; +class SkiaRendererDDL : public viz::SkiaRenderer { + public: + SkiaRendererDDL(const viz::RendererSettings* settings, + viz::OutputSurface* output_surface, + viz::DisplayResourceProvider* resource_provider, + viz::SkiaOutputSurface* skia_output_surface) + : viz::SkiaRenderer(settings, + output_surface, + resource_provider, + skia_output_surface) {} +}; + template <> inline void RendererPixelTest<viz::GLRenderer>::SetUp() { SetUpGLRenderer(false); @@ -181,6 +212,11 @@ SetUpSkiaRenderer(); } +template <> +inline void RendererPixelTest<SkiaRendererDDL>::SetUp() { + SetUpSkiaRendererDDL(); +} + typedef RendererPixelTest<viz::GLRenderer> GLRendererPixelTest; typedef RendererPixelTest<viz::SoftwareRenderer> SoftwareRendererPixelTest; typedef RendererPixelTest<viz::SkiaRenderer> SkiaRendererPixelTest;
diff --git a/chrome/VERSION b/chrome/VERSION index 8eaccb08..560c86f 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=69 MINOR=0 -BUILD=3467 +BUILD=3468 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index c1e556b..a18fb599 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -211,6 +211,7 @@ "$google_play_services_package:google_play_services_auth_base_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_cast_framework_java", "$google_play_services_package:google_play_services_cast_java", "$google_play_services_package:google_play_services_fido_java", "$google_play_services_package:google_play_services_gcm_java", @@ -457,6 +458,7 @@ ":partner_location_descriptor_proto_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_cast_framework_java", "$google_play_services_package:google_play_services_cast_java", "$google_play_services_package:google_play_services_fido_java", "//base:base_java", @@ -534,6 +536,7 @@ ":partner_location_descriptor_proto_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_cast_framework_java", "$google_play_services_package:google_play_services_cast_java", "$google_play_services_package:google_play_services_fido_java", "$google_play_services_package:google_play_services_gcm_java",
diff --git a/chrome/android/OWNERS b/chrome/android/OWNERS index 23c3197..6f0880c 100644 --- a/chrome/android/OWNERS +++ b/chrome/android/OWNERS
@@ -1,6 +1,5 @@ bauerb@chromium.org dtrainor@chromium.org -mariakhomenko@chromium.org nyquist@chromium.org tedchoc@chromium.org yfriedman@chromium.org
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java index 72548c6..1f01dafe 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java
@@ -4,9 +4,14 @@ package org.chromium.chrome.browser.feed; +import android.content.Context; import android.content.res.Resources; +import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Point; +import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; @@ -19,24 +24,32 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.BasicNativePage; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.NativePageHost; -import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.feed.action.FeedActionHandler; +import org.chromium.chrome.browser.ntp.ContextMenuManager; +import org.chromium.chrome.browser.ntp.ContextMenuManager.TouchEnabledDelegate; +import org.chromium.chrome.browser.ntp.NewTabPage; +import org.chromium.chrome.browser.ntp.NewTabPage.FakeboxDelegate; +import org.chromium.chrome.browser.ntp.NewTabPageLayout; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegateImpl; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.util.ViewUtils; +import org.chromium.chrome.browser.widget.displaystyle.UiConfig; + +import java.util.Arrays; /** * Provides a new tab page that displays an interest feed rendered list of content suggestions. */ -public class FeedNewTabPage extends BasicNativePage { +public class FeedNewTabPage + extends NewTabPage implements TouchEnabledDelegate, NewTabPageLayout.ScrollDelegate { private final StreamLifecycleManager mStreamLifecycleManager; private FrameLayout mRootView; - private String mTitle; private FeedImageLoader mImageLoader; private static class DummySnackbarApi implements SnackbarApi { @@ -114,7 +127,7 @@ */ public FeedNewTabPage(ChromeActivity activity, NativePageHost nativePageHost, TabModelSelector tabModelSelector) { - super(activity, nativePageHost); + super(activity, nativePageHost, tabModelSelector); FeedProcessScope feedProcessScope = FeedProcessScopeFactory.getFeedProcessScope(); Tab tab = nativePageHost.getActiveTab(); @@ -138,16 +151,33 @@ stream.getView().setBackgroundColor(Color.WHITE); mRootView.addView(stream.getView()); + stream.setHeaderViews(Arrays.asList(mNewTabPageLayout)); + // TODO(skym): This is a work around for outstanding Feed bug. stream.triggerRefresh(); } @Override - protected void initialize(ChromeActivity activity, NativePageHost host) { - mRootView = new FrameLayout(activity); + protected void initializeMainView(Context context) { + mRootView = new FrameLayout(context); mRootView.setLayoutParams(new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); - mTitle = activity.getResources().getString(org.chromium.chrome.R.string.button_new_tab); + + // Don't store a direct reference to the activity, because it might change later if the tab + // is reparented. + // TODO(twellington): Move this somewhere it can be shared with NewTabPageView? + Runnable closeContextMenuCallback = () -> mTab.getActivity().closeContextMenu(); + ContextMenuManager contextMenuManager = + new ContextMenuManager(mNewTabPageManager.getNavigationDelegate(), + this::setTouchEnabled, closeContextMenuCallback); + mTab.getWindowAndroid().addContextMenuCloseListener(contextMenuManager); + + LayoutInflater inflater = LayoutInflater.from(context); + mNewTabPageLayout = (NewTabPageLayout) inflater.inflate(R.layout.new_tab_page_layout, null); + mNewTabPageLayout.initialize(mNewTabPageManager, mTab, mTileGroupDelegate, + mSearchProviderHasLogo, + TemplateUrlService.getInstance().isDefaultSearchEngineGoogle(), this, + contextMenuManager, new UiConfig(mRootView)); } @Override @@ -163,12 +193,72 @@ } @Override - public String getTitle() { - return mTitle; + protected void restoreLastScrollPosition() { + // This behavior is handled by the Feed library. } @Override - public String getHost() { - return UrlConstants.NTP_HOST; + protected void setSearchProviderInfoOnView(boolean hasLogo, boolean isGoogle) { + mNewTabPageLayout.setSearchProviderInfo(hasLogo, isGoogle); + } + + @Override + protected void scrollToSuggestions() { + // TODO(twellington): implement this method. + } + + @Override + public void getSearchBoxBounds(Rect bounds, Point translation) { + // TODO(twellington): implement this method. + } + + @Override + public void setFakeboxDelegate(FakeboxDelegate fakeboxDelegate) { + // TODO(twellington): implement this method. + } + + @Override + public boolean shouldCaptureThumbnail() { + // TODO(twellington): add more logic to this method that also takes into account other + // UI changes that should trigger a thumbnail capture. + return mNewTabPageLayout.shouldCaptureThumbnail(); + } + + @Override + public void captureThumbnail(Canvas canvas) { + mNewTabPageLayout.onPreCaptureThumbnail(); + ViewUtils.captureBitmap(mRootView, canvas); + } + + // TouchEnabledDelegate interface. + + @Override + public void setTouchEnabled(boolean enabled) { + // TODO(twellington): implement this method. + } + + // ScrollDelegate interface. + + @Override + public boolean isScrollViewInitialized() { + // TODO(twellington): implement this method. + return false; + } + + @Override + public int getVerticalScrollOffset() { + // TODO(twellington): implement this method. + return 0; + } + + @Override + public boolean isChildVisibleAtPosition(int position) { + // TODO(twellington): implement this method. + return false; + } + + @Override + public void snapScroll() { + // TODO(twellington): implement this method. } }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 0eebd71..8a6635f 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -172,6 +172,12 @@ android:value="180226000"/> {% endif %} + <!-- Cast support --> + <meta-data + android:name= + "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" + android:value="org.chromium.chrome.browser.media.router.caf.CastOptionsProvider"/> + <!-- Note: All activities directly or indirectly derived from ChromeActivity must specify android:hardwareAccelerated="false". @@ -276,6 +282,21 @@ android:resource="@xml/searchable" /> </activity-alias> + <activity android:name="org.chromium.chrome.browser.media.MediaLauncherActivity" + android:theme="@android:style/Theme.NoDisplay" + android:excludeFromRecents="true" + android:exported="true" + android:enabled="false"><!-- This will be selectively enabled at runtime. --> + <intent-filter tools:ignore="AppLinkUrlError"> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.DEFAULT" /> + <!-- TODO(https://crbug.com/800875): Limit these to supported MIME types. --> + <data android:mimeType="audio/*" /> + <data android:mimeType="image/*" /> + <data android:mimeType="video/*" /> + </intent-filter> + </activity> + <activity android:name="org.chromium.chrome.browser.LauncherShortcutActivity" android:theme="@android:style/Theme.NoDisplay" android:taskAffinity=""
diff --git a/chrome/android/java/res/drawable-v21/transition_expand_less_expand_more_black_24dp.xml b/chrome/android/java/res/drawable-v21/transition_expand_less_expand_more_black_24dp.xml new file mode 100644 index 0000000..2b34214 --- /dev/null +++ b/chrome/android/java/res/drawable-v21/transition_expand_less_expand_more_black_24dp.xml
@@ -0,0 +1,34 @@ +<?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. --> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + xmlns:aapt="http://schemas.android.com/aapt" + tools:targetApi="21"> + + <aapt:attr name="android:drawable"> + <vector + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + + <path + android:name="arrow" + android:fillColor="#000000" + android:pathData="M12,8L6,14L7.41,15.41L12,10.83L16.59,15.41L18,14z"/> + </vector> + </aapt:attr> + + <target android:name="arrow"> + <aapt:attr name="android:animation"> + <objectAnimator + android:duration="250" + android:propertyName="pathData" + android:valueFrom="M12,8L6,14L7.41,15.41L12,10.83L16.59,15.41L18,14z" + android:valueTo="M12,13.17L7.41,8.59L6,10L12,16L18,10L16.59,8.59z" + android:valueType="pathType"/> + </aapt:attr> + </target> +</animated-vector>
diff --git a/chrome/android/java/res/drawable-v21/transition_expand_more_expand_less_black_24dp.xml b/chrome/android/java/res/drawable-v21/transition_expand_more_expand_less_black_24dp.xml new file mode 100644 index 0000000..0451908 --- /dev/null +++ b/chrome/android/java/res/drawable-v21/transition_expand_more_expand_less_black_24dp.xml
@@ -0,0 +1,34 @@ +<?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. --> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + xmlns:aapt="http://schemas.android.com/aapt" + tools:targetApi="21"> + + <aapt:attr name="android:drawable"> + <vector + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + + <path + android:name="arrow" + android:fillColor="#000000" + android:pathData="M12,8L6,14L7.41,15.41L12,10.83L16.59,15.41L18,14z"/> + </vector> + </aapt:attr> + + <target android:name="arrow"> + <aapt:attr name="android:animation"> + <objectAnimator + android:duration="250" + android:propertyName="pathData" + android:valueFrom="M12,13.17L7.41,8.59L6,10L12,16L18,10L16.59,8.59z" + android:valueTo="M12,8L6,14L7.41,15.41L12,10.83L16.59,15.41L18,14z" + android:valueType="pathType"/> + </aapt:attr> + </target> +</animated-vector>
diff --git a/chrome/android/java/res/drawable/infobar_download_complete.xml b/chrome/android/java/res/drawable/infobar_download_complete.xml new file mode 100644 index 0000000..9e516c4 --- /dev/null +++ b/chrome/android/java/res/drawable/infobar_download_complete.xml
@@ -0,0 +1,25 @@ +<?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. --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + tools:targetApi="21" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + + <path + android:name="circle" + android:fillColor="@color/google_blue_50" + android:fillAlpha="0" + android:pathData="M 0,12 C 0,6 6,0 12,0 C 18,0 24,6 24,12 C 24,18 18,24 12,24 C 6,24 0,18 0,12"/> + + <path + android:name="check_mark" + android:pathData="M5 18h14v2H5v-2zm4.6-2.7L5 10.7l2-1.9 2.6 2.6L17 4l2 2-9.4 9.3z" + android:fillColor="@color/google_blue_500"/> + +</vector> \ No newline at end of file
diff --git a/chrome/android/java/res/drawable/infobar_download_complete_animation.xml b/chrome/android/java/res/drawable/infobar_download_complete_animation.xml index bfd9f28..8590b01 100644 --- a/chrome/android/java/res/drawable/infobar_download_complete_animation.xml +++ b/chrome/android/java/res/drawable/infobar_download_complete_animation.xml
@@ -6,27 +6,8 @@ <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:aapt="http://schemas.android.com/aapt" - tools:targetApi="21"> - - <aapt:attr name="android:drawable"> - <vector - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:name="circle" - android:fillColor="@color/google_blue_50" - android:pathData="M 0,12 C 0,6 6,0 12,0 C 18,0 24,6 24,12 C 24,18 18,24 12,24 C 6,24 0,18 0,12"/> - - <path - android:name="check_mark" - android:pathData="M5 18h14v2H5v-2zm4.6-2.7L5 10.7l2-1.9 2.6 2.6L17 4l2 2-9.4 9.3z" - android:fillColor="@color/google_blue_500"/> - - </vector> - </aapt:attr> + tools:targetApi="21" + android:drawable="@drawable/infobar_download_complete"> <target android:name="circle"> <aapt:attr name="android:animation">
diff --git a/chrome/android/java/res/layout/checkable_image_view_widget.xml b/chrome/android/java/res/layout/checkable_image_view_widget.xml new file mode 100644 index 0000000..f783408 --- /dev/null +++ b/chrome/android/java/res/layout/checkable_image_view_widget.xml
@@ -0,0 +1,9 @@ +<?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. --> +<org.chromium.ui.widget.CheckableImageView + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/checkable_image_view" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/>
diff --git a/chrome/android/java/res/layout/content_suggestions_card_modern.xml b/chrome/android/java/res/layout/content_suggestions_card_modern.xml index a8875d0..c3ceb49 100644 --- a/chrome/android/java/res/layout/content_suggestions_card_modern.xml +++ b/chrome/android/java/res/layout/content_suggestions_card_modern.xml
@@ -114,6 +114,20 @@ android:textColor="@color/snippets_publisher_name_color" android:textDirection="locale" tools:text=" - 3 hours ago" /> + + <!-- We can't add this ImageView as a CompoundDrawable to the TextView because we + want to have different paddings between the favicon (which is a compound + drawable on the TextView) and the offline icon. --> + <!-- TODO(twellington): Remove this if the simplified NTP ships --> + <ImageView + android:id="@+id/offline_icon_publisher_row" + android:layout_width="@dimen/snippets_offline_icon_size" + android:layout_height="@dimen/snippets_offline_icon_size" + android:layout_marginStart="6dp" + android:src="@drawable/offline_pin_round" + android:contentDescription="@string/accessibility_ntp_offline_badge" + android:visibility="gone" + tools:tint="@color/black_alpha_54" /> </LinearLayout> </LinearLayout> </RelativeLayout>
diff --git a/chrome/android/java/res/layout/explore_sites_category_tile_view.xml b/chrome/android/java/res/layout/explore_sites_category_tile_view.xml index e42a33c..f262f0e 100644 --- a/chrome/android/java/res/layout/explore_sites_category_tile_view.xml +++ b/chrome/android/java/res/layout/explore_sites_category_tile_view.xml
@@ -7,15 +7,16 @@ <org.chromium.chrome.browser.explore_sites.ExploreSitesCategoryTileView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - android:padding="10dp" android:layout_width="wrap_content" - android:layout_height="wrap_content" > + android:layout_height="wrap_content" + android:orientation="vertical" + android:layout_weight="0.33" > <!-- Main icon/image --> <ImageView android:id="@+id/explore_sites_category_tile_icon" android:layout_gravity="center_horizontal" - android:layout_marginTop="@dimen/tile_view_icon_margin_top_modern" + android:layout_marginTop="@dimen/explore_sites_padding" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@null" /> @@ -26,5 +27,5 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" - android:textAppearance="@style/BlackCaption" /> + android:textAppearance="@style/BlackCaptionDefault" /> </org.chromium.chrome.browser.explore_sites.ExploreSitesCategoryTileView>
diff --git a/chrome/android/java/res/layout/explore_sites_section.xml b/chrome/android/java/res/layout/explore_sites_section.xml index f1e908a..5ef294f 100644 --- a/chrome/android/java/res/layout/explore_sites_section.xml +++ b/chrome/android/java/res/layout/explore_sites_section.xml
@@ -7,14 +7,16 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" > + android:layout_marginTop="@dimen/explore_sites_margin" + android:orientation="vertical" + android:gravity="center" > <TextView - style="@style/BlackCaptionDefault" + style="@style/BlackCaption" android:id="@+id/explore_sites_title" android:layout_width="match_parent" android:layout_height="wrap_content" - android:gravity="center_vertical" + android:gravity="center" android:text="@string/ntp_explore_sites_title" /> <LinearLayout @@ -24,10 +26,12 @@ android:orientation="horizontal" /> <Button + style="@style/SuggestionCardAction" android:id="@+id/explore_sites_more_button" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="12dp" + android:gravity="center" + android:layout_margin="@dimen/explore_sites_margin" android:text="@string/ntp_explore_sites_more" /> </LinearLayout>
diff --git a/chrome/android/java/res/layout/site_list_expandable_header.xml b/chrome/android/java/res/layout/site_list_expandable_header.xml deleted file mode 100644 index 6169cf0d..0000000 --- a/chrome/android/java/res/layout/site_list_expandable_header.xml +++ /dev/null
@@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2015 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<ImageView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/expando" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:contentDescription="@null" /> \ No newline at end of file
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 87ef3d1..f96befb 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -346,6 +346,9 @@ <dimen name="ntp_search_box_transition_length">16dp</dimen> <dimen name="ntp_search_box_logo_padding">8dp</dimen> <dimen name="ntp_search_box_voice_search_margin_end_modern">6dp</dimen> + <dimen name="explore_sites_radius">8dp</dimen> + <dimen name="explore_sites_padding">6dp</dimen> + <dimen name="explore_sites_margin">12dp</dimen> <!-- Negative vertical inset added to the search box bounds when modern is enabled. 4dp is added to both the top and bottom bounds to bring the 48dp modern_toolbar_background_size to 56dp (matches toolbar_height_no_shadow). -->
diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml index da0edd8..6f886fb7 100644 --- a/chrome/android/java/res/xml/main_preferences.xml +++ b/chrome/android/java/res/xml/main_preferences.xml
@@ -6,84 +6,93 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:orderingFromXml="false"> + <PreferenceCategory + android:key="account_section" + android:order="0" + android:title="@string/prefs_section_account"/> <org.chromium.chrome.browser.preferences.SignInPreference android:key="sign_in" - android:order="0" + android:order="1" android:title="@string/sign_in_to_chrome"/> + <Preference + android:fragment="org.chromium.chrome.browser.preferences.SyncAndServicesPreferences" + android:key="sync_and_services" + android:order="2" + android:title="@string/prefs_sync_and_services"/> <PreferenceCategory android:key="basics_section" - android:order="1" + android:order="3" android:title="@string/prefs_section_basics"/> <org.chromium.chrome.browser.preferences.ChromeBasePreference android:fragment="org.chromium.chrome.browser.preferences.SearchEnginePreference" android:key="search_engine" - android:order="2" + android:order="4" android:title="@string/prefs_search_engine"/> <org.chromium.chrome.browser.preferences.ChromeBasePreference android:fragment="org.chromium.chrome.browser.preferences.autofill.AutofillAndPaymentsPreferences" android:key="autofill_settings" - android:order="3" + android:order="5" android:title="@string/prefs_autofill_and_payments"/> <org.chromium.chrome.browser.preferences.ChromeBasePreference android:fragment="org.chromium.chrome.browser.preferences.password.SavePasswordsPreferences" android:key="saved_passwords" - android:order="4" + android:order="6" android:title="@string/prefs_saved_passwords_title"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.NotificationsPreferences" android:key="notifications" - android:order="5" + android:order="7" android:title="@string/prefs_notifications"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.ContextualSuggestionsPreference" android:key="contextual_suggestions" - android:order="6" + android:order="8" android:title="@string/prefs_contextual_suggestions"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.HomepagePreferences" android:key="homepage" - android:order="7" + android:order="9" android:title="@string/options_homepage_title"/> <PreferenceCategory android:key="advanced_section" - android:order="8" + android:order="10" android:title="@string/prefs_section_advanced"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.privacy.PrivacyPreferences" android:key="privacy" - android:order="9" + android:order="11" android:title="@string/prefs_privacy"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.AccessibilityPreferences" android:key="accessibility" - android:order="10" + android:order="12" android:title="@string/prefs_accessibility"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.website.SiteSettingsPreferences" android:key="content_settings" - android:order="11" + android:order="13" android:title="@string/prefs_site_settings"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.languages.LanguagesPreferences" android:key="languages" - android:order="12" + android:order="14" android:title="@string/prefs_languages"/> <org.chromium.chrome.browser.preferences.ChromeBasePreference android:fragment="org.chromium.chrome.browser.preferences.datareduction.DataReductionPreferences" android:key="data_reduction" - android:order="13" + android:order="15" android:title="@string/data_reduction_title"/> <org.chromium.chrome.browser.preferences.ChromeBasePreference android:fragment="org.chromium.chrome.browser.preferences.download.DownloadPreferences" android:key="downloads" - android:order="14" + android:order="16" android:title="@string/menu_downloads"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.AboutChromePreferences" android:key="about_chrome" - android:order="15" + android:order="17" android:title="@string/prefs_about_chrome"/> </PreferenceScreen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index d3a9dc7..eeb0a08 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -24,7 +24,6 @@ import android.support.annotation.CallSuper; import android.util.DisplayMetrics; import android.util.Pair; -import android.view.Display; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -323,21 +322,6 @@ public void preInflationStartup() { super.preInflationStartup(); - if (VrShellDelegate.bootsToVr()) { - // TODO(mthiesse): Remove this once b/78108624 is fixed. This is a workaround for a - // platform bug where Chrome crashes on launch for standalone devices if not launched - // onto the primary display (There's a virtual display 2D apps are default launched onto - // with different display properties). Re-launch with the same intent but to the primary - // display. - if (DisplayAndroid.getNonMultiDisplay(this).getDisplayId() != Display.DEFAULT_DISPLAY) { - finish(); - startActivity(getIntent(), - ApiCompatibilityUtils.createLaunchDisplayIdActivityOptions( - Display.DEFAULT_DISPLAY)); - return; - } - } - // We need to explicitly enable VR mode here so that the system doesn't kick us out of VR, // or drop us into the 2D-in-VR rendering mode, while we prepare for VR rendering. if (VrIntentUtils.isLaunchingIntoVr(this, getIntent())) { @@ -1838,9 +1822,9 @@ getTabContentManager(), contentContainer, mContextualSearchManager); if (controlContainer != null && DeviceClassManager.enableToolbarSwipe() - && getCompositorViewHolder().getLayoutManager().getTopSwipeHandler() != null) { + && getCompositorViewHolder().getLayoutManager().getToolbarSwipeHandler() != null) { controlContainer.setSwipeHandler( - getCompositorViewHolder().getLayoutManager().getTopSwipeHandler()); + getCompositorViewHolder().getLayoutManager().getToolbarSwipeHandler()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index ed8b3d4..3eb74fe2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -582,11 +582,12 @@ boolean isLegacyMultiWindow = MultiWindowUtils.getInstance().isLegacyMultiWindow(this); if (!isShowingPromo && !mIntentWithEffect && FirstRunStatus.getFirstRunFlowComplete() && preferenceManager.getPromosSkippedOnFirstStart() - // VrShellDelegate.isInVr may not return true at this point even Chrome is about - // to enter VR. So we use VrIntentUtils.isVrIntent to check if we are in VR or - // about to enter VR. Although a VR intent doesn't ensure Chrome enters VR, it - // is fine to delay the promo until the next time Chrome launches. - && !VrIntentUtils.isVrIntent(getIntent()) && !isLegacyMultiWindow) { + && !VrShellDelegate.isInVr() + // VrShellDelegate.isInVr may not return true at this point even though Chrome + // is about to enter VR, so we need to also check whether we're launching into + // VR. + && !VrIntentUtils.isLaunchingIntoVr(this, getIntent()) + && !isLegacyMultiWindow) { // Data reduction promo should be temporarily suppressed if the sign in promo is // shown to avoid nagging users too much. isShowingPromo = SigninPromoUtil.launchSigninPromoIfNeeded(this)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java index 69e5ca8..f68775d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -406,14 +406,6 @@ */ @SuppressLint("InlinedApi") private @Action int dispatchToTabbedActivity() { - // Avoid Daydream's 2D-in-VR rendering mode by launching 2D intents in VR if we're in - // VR mode and the intent is supported in VR. - // TODO(mthiesse): If we ever support VR browsing in more than just Tabbed Activity, - // (ie CCT), we'll need to figure out how to handle this at a higher level. - if (VrIntentUtils.maybeForwardToVrLauncher(mIntent, mActivity)) { - return Action.FINISH_ACTIVITY; - } - maybePrefetchDnsInBackground(); Intent newIntent = new Intent(mIntent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java index 9fdbad7..dbb48f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java
@@ -16,10 +16,12 @@ import android.widget.LinearLayout; import android.widget.ListView; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import java.util.ArrayList; +import java.util.concurrent.TimeUnit; /** * Handles the drag touch events on AppMenu that start from the menu button. @@ -158,7 +160,8 @@ mAppMenu.dismiss(); return true; } else if (eventActionMasked == MotionEvent.ACTION_UP) { - nativeRecordAppMenuTouchDuration(timeSinceDown); + RecordHistogram.recordTimesHistogram( + "WrenchMenu.TouchDuration", timeSinceDown, TimeUnit.MILLISECONDS); } mIsSingleTapCanceled |= timeSinceDown > mTapTimeout; @@ -295,6 +298,4 @@ mScreenVisibleRect.offset(mScreenVisiblePoint[0], mScreenVisiblePoint[1]); return mScreenVisibleRect; } - - private static native void nativeRecordAppMenuTouchDuration(long timeMs); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessoryPagerAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessoryPagerAdapter.java index 090e860..895ffbd4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessoryPagerAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessoryPagerAdapter.java
@@ -34,7 +34,7 @@ */ public AccessoryPagerAdapter(SimpleListObservable<Tab> tabList) { mTabList = tabList; - mViews = new HashMap<>(mTabList.getItemCount()); + mViews = new HashMap<>(mTabList.size()); } @NonNull @@ -69,7 +69,7 @@ @Override public int getCount() { - return mTabList.getItemCount(); + return mTabList.size(); } @Override @@ -80,7 +80,7 @@ @Override public int getItemPosition(@NonNull Object object) { ViewGroup viewToBeFound = (ViewGroup) object; - for (int i = 0; i < mTabList.getItemCount(); i++) { + for (int i = 0; i < mTabList.size(); i++) { if (mViews.get(mTabList.get(i)).equals(viewToBeFound)) { return i; // The tab the view is connected to still exists and its position is i. }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetMediator.java index cf309fc..563ffb9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetMediator.java
@@ -47,7 +47,7 @@ void addTab(KeyboardAccessoryData.Tab tab) { mModel.getTabList().add(tab); if (mModel.getActiveTabIndex() == NO_ACTIVE_TAB) { - mModel.setActiveTabIndex(mModel.getTabList().getItemCount() - 1); + mModel.setActiveTabIndex(mModel.getTabList().size() - 1); } } @@ -59,7 +59,7 @@ } void setActiveTab(int position) { - assert position < mModel.getTabList().getItemCount() + assert position < mModel.getTabList().size() || position >= 0 : position + " is not a valid tab index!"; mModel.setActiveTabIndex(position); } @@ -83,7 +83,7 @@ } if (activeTab >= 0) return activeTab; // The new active tab is valid. // If there are items left, take the first one. - int itemCountAfterDeletion = mModel.getTabList().getItemCount() - 1; + int itemCountAfterDeletion = mModel.getTabList().size() - 1; return itemCountAfterDeletion > 0 ? 0 : NO_ACTIVE_TAB; } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetModel.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetModel.java index 37feaf9..dca23b75 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetModel.java
@@ -45,7 +45,7 @@ void setActiveTabIndex(int activeTabPosition) { if (mActiveTabIndex == activeTabPosition) return; - assert((activeTabPosition >= 0 && activeTabPosition < mTabList.getItemCount()) + assert((activeTabPosition >= 0 && activeTabPosition < mTabList.size()) || activeTabPosition == NO_ACTIVE_TAB) : "Tried to set invalid index '" + activeTabPosition + "' as active tab!"; mActiveTabIndex = activeTabPosition;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java index 51eb8a30..bc0047f4c9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java
@@ -10,14 +10,13 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.autofill.AutofillKeyboardSuggestions; import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Action; -import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryViewBinder.ActionViewBinder; +import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryViewBinder.ActionViewHolder; import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryViewBinder.TabViewBinder; import org.chromium.chrome.browser.modelutil.LazyViewBinderAdapter; import org.chromium.chrome.browser.modelutil.ListModelChangeProcessor; import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; -import org.chromium.chrome.browser.modelutil.RecyclerViewModelChangeProcessor; -import org.chromium.chrome.browser.modelutil.SimpleListObservable; +import org.chromium.chrome.browser.modelutil.SimpleRecyclerViewMcp; import org.chromium.ui.base.WindowAndroid; /** @@ -77,17 +76,19 @@ } /** - * Creates an adapter to an {@link ActionViewBinder} that is wired + * Creates an adapter to an {@link ActionViewHolder} that is wired * up to the model change processor which listens to the given {@link KeyboardAccessoryModel}. * @param model the {@link KeyboardAccessoryModel} the adapter gets its data from. - * @return Returns a fully initialized and wired adapter to an ActionViewBinder. + * @return Returns a fully initialized and wired adapter to an ActionViewHolder. */ - static RecyclerViewAdapter<SimpleListObservable<Action>, ActionViewBinder.ViewHolder> - createActionsAdapter(KeyboardAccessoryModel model) { - RecyclerViewAdapter<SimpleListObservable<Action>, ActionViewBinder.ViewHolder> - actionsAdapter = - new RecyclerViewAdapter<>(model.getActionList(), new ActionViewBinder()); - model.addActionListObserver(new RecyclerViewModelChangeProcessor<>(actionsAdapter)); + static RecyclerViewAdapter<ActionViewHolder, Void> createActionsAdapter( + KeyboardAccessoryModel model) { + SimpleRecyclerViewMcp<Action, ActionViewHolder, Void> processor = + new SimpleRecyclerViewMcp<>(model.getActionList(), null, ActionViewHolder::bind); + RecyclerViewAdapter<ActionViewHolder, Void> actionsAdapter = + new RecyclerViewAdapter<>(processor, ActionViewHolder::create); + processor.addObserver(actionsAdapter); + model.addActionListObserver(processor); return actionsAdapter; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java index 057e738..e5ff3ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java
@@ -156,8 +156,8 @@ private boolean shouldShowAccessory() { if (!mIsKeyboardVisible && mModel.activeTab() == null) return false; - return mModel.getAutofillSuggestions() != null || mModel.getActionList().getItemCount() > 0 - || mModel.getTabList().getItemCount() > 0; + return mModel.getAutofillSuggestions() != null || mModel.getActionList().size() > 0 + || mModel.getTabList().size() > 0; } private void updateVisibility() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewBinder.java index ebde2c9..7e82c24 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryViewBinder.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.autofill.keyboard_accessory; +import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.ViewGroup; @@ -14,7 +15,6 @@ import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryModel.PropertyKey; import org.chromium.chrome.browser.modelutil.LazyViewBinderAdapter; import org.chromium.chrome.browser.modelutil.ListModelChangeProcessor; -import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; import org.chromium.chrome.browser.modelutil.SimpleListObservable; import org.chromium.ui.widget.ButtonCompat; @@ -25,33 +25,25 @@ class KeyboardAccessoryViewBinder implements LazyViewBinderAdapter.SimpleViewBinder<KeyboardAccessoryModel, KeyboardAccessoryView, PropertyKey> { - static class ActionViewBinder - implements RecyclerViewAdapter.ViewBinder<SimpleListObservable<Action>, - ActionViewBinder.ViewHolder> { - static class ViewHolder extends RecyclerView.ViewHolder { - public ViewHolder(ButtonCompat actionView) { - super(actionView); - } - - ButtonCompat getActionView() { - return (ButtonCompat) super.itemView; - } + static class ActionViewHolder extends RecyclerView.ViewHolder { + public ActionViewHolder(ButtonCompat actionView) { + super(actionView); } - @Override - public ActionViewBinder.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - return new ViewHolder( + public static ActionViewHolder create(ViewGroup parent, int viewType) { + assert viewType == 0; + return new ActionViewHolder( (ButtonCompat) LayoutInflater.from(parent.getContext()) .inflate(R.layout.keyboard_accessory_action, parent, false)); } - @Override - public void onBindViewHolder( - SimpleListObservable<Action> actions, ViewHolder holder, int position) { - final Action action = actions.get(position); - holder.getActionView().setText(action.getCaption()); - holder.getActionView().setOnClickListener( - view -> action.getCallback().onResult(action)); + public void bind(Action action, @Nullable Void payload) { + getActionView().setText(action.getCaption()); + getActionView().setOnClickListener(view -> action.getCallback().onResult(action)); + } + + private ButtonCompat getActionView() { + return (ButtonCompat) super.itemView; } } @@ -87,7 +79,7 @@ void updateAllTabs(KeyboardAccessoryView view, SimpleListObservable<Tab> model) { view.clearTabs(); - for (int i = 0; i < model.getItemCount(); ++i) { + for (int i = 0; i < model.size(); ++i) { Tab tab = model.get(i); // Mutate tab icons so we can apply color filters. view.addTabAt(i, tab.getIcon().mutate(), tab.getContentDescription());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetCoordinator.java index 4e56f63..ed23315 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetCoordinator.java
@@ -15,8 +15,8 @@ import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Item; import org.chromium.chrome.browser.autofill.keyboard_accessory.PasswordAccessorySheetViewBinder.TextViewHolder; import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; -import org.chromium.chrome.browser.modelutil.RecyclerViewModelChangeProcessor; import org.chromium.chrome.browser.modelutil.SimpleListObservable; +import org.chromium.chrome.browser.modelutil.SimpleRecyclerViewMcp; /** * This component is a tab that can be added to the {@link ManualFillingCoordinator} which shows it @@ -26,7 +26,6 @@ private final Context mContext; private final SimpleListObservable<Item> mModel = new SimpleListObservable<>(); private final KeyboardAccessoryData.Observer<Item> mMediator = mModel::set; - private final PasswordAccessorySheetViewBinder mBinder = new PasswordAccessorySheetViewBinder(); private final KeyboardAccessoryData.Tab mTab; @@ -70,8 +69,7 @@ } private void onTabCreated(View view) { - mBinder.initializeView((RecyclerView) view, - PasswordAccessorySheetCoordinator.createAdapter(mModel, mBinder)); + PasswordAccessorySheetViewBinder.initializeView((RecyclerView) view, createAdapter(mModel)); } /** @@ -80,11 +78,14 @@ * @param model the {@link SimpleListObservable<Item>} the adapter gets its data from. * @return Returns a fully initialized and wired adapter to a PasswordAccessorySheetViewBinder. */ - static RecyclerViewAdapter<SimpleListObservable<Item>, TextViewHolder> createAdapter( - SimpleListObservable<Item> model, PasswordAccessorySheetViewBinder viewBinder) { - RecyclerViewAdapter<SimpleListObservable<Item>, TextViewHolder> adapter = - new PasswordAccessorySheetViewAdapter<>(model, viewBinder); - model.addObserver(new RecyclerViewModelChangeProcessor<>(adapter)); + static RecyclerViewAdapter<TextViewHolder, Void> createAdapter( + SimpleListObservable<Item> model) { + SimpleRecyclerViewMcp<Item, TextViewHolder, Void> processor = + new SimpleRecyclerViewMcp<>(model, Item::getType, TextViewHolder::bind); + RecyclerViewAdapter<TextViewHolder, Void> adapter = + new RecyclerViewAdapter<>(processor, TextViewHolder::create); + model.addObserver(processor); + processor.addObserver(adapter); return adapter; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewAdapter.java deleted file mode 100644 index 39d327f..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewAdapter.java +++ /dev/null
@@ -1,30 +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. - -package org.chromium.chrome.browser.autofill.keyboard_accessory; - -import android.support.v7.widget.RecyclerView; - -import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; -import org.chromium.chrome.browser.modelutil.SimpleListObservable; - -class PasswordAccessorySheetViewAdapter<VH extends RecyclerView.ViewHolder> - extends RecyclerViewAdapter<SimpleListObservable<KeyboardAccessoryData.Item>, VH> { - /** - * Construct a new {@link RecyclerViewAdapter}. - * - * @param model The {@link SimpleListObservable<KeyboardAccessoryData.Item>} model used to - * retrieve items to display in the {@link RecyclerView}. - * @param viewBinder The {@link ViewBinder} binding this adapter to the view holder. - */ - public PasswordAccessorySheetViewAdapter(SimpleListObservable<KeyboardAccessoryData.Item> model, - ViewBinder<SimpleListObservable<KeyboardAccessoryData.Item>, VH> viewBinder) { - super(model, viewBinder); - } - - @Override - public int getItemViewType(int position) { - return mModel.get(position).getType(); - } -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewBinder.java index 58b1274..e7b7178 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewBinder.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.autofill.keyboard_accessory; +import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.method.PasswordTransformationMethod; @@ -21,9 +22,7 @@ * This stateless class provides methods to bind the items in a {@link SimpleListObservable<Item>} * to the {@link RecyclerView} used as view of the Password accessory sheet component. */ -class PasswordAccessorySheetViewBinder - implements RecyclerViewAdapter.ViewBinder<SimpleListObservable<Item>, - PasswordAccessorySheetViewBinder.TextViewHolder> { +class PasswordAccessorySheetViewBinder { /** * Holds a TextView that represents a list entry. */ @@ -32,45 +31,44 @@ super(itemView); } - TextView getView() { + static TextViewHolder create(ViewGroup parent, @Item.Type int viewType) { + switch (viewType) { + case Item.TYPE_LABEL: { + return new TextViewHolder( + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.password_accessory_sheet_label, parent, + false)); + } + case Item.TYPE_SUGGESTIONS: { + return new TextViewHolder( + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.password_accessory_sheet_suggestion, parent, + false)); + } + } + assert false : viewType; + return null; + } + + void bind(Item item, @Nullable Void payload) { + if (item.isPassword()) { + getView().setTransformationMethod(new PasswordTransformationMethod()); + } + getView().setText(item.getCaption()); + if (item.getItemSelectedCallback() != null) { + getView().setOnClickListener(src -> item.getItemSelectedCallback().onResult(item)); + } + } + + private TextView getView() { return (TextView) itemView; } } - @Override - public TextViewHolder onCreateViewHolder(ViewGroup parent, @Item.Type int viewType) { - if (viewType == Item.TYPE_LABEL) { - return new TextViewHolder( - LayoutInflater.from(parent.getContext()) - .inflate(R.layout.password_accessory_sheet_label, parent, false)); - } - if (viewType == Item.TYPE_SUGGESTIONS) { - return new TextViewHolder( - LayoutInflater.from(parent.getContext()) - .inflate(R.layout.password_accessory_sheet_suggestion, parent, false)); - } - assert false : "Every Item.Type needs to be assigned a view!"; - return null; - } - - @Override - public void onBindViewHolder( - SimpleListObservable<Item> model, TextViewHolder holder, int position) { - Item item = model.get(position); - if (item.isPassword()) { - holder.getView().setTransformationMethod(new PasswordTransformationMethod()); - } - holder.getView().setText(item.getCaption()); - if (item.getItemSelectedCallback() != null) { - holder.getView().setOnClickListener( - src -> item.getItemSelectedCallback().onResult(item)); - } - } - - void initializeView(RecyclerView view, RecyclerViewAdapter adapter) { + static void initializeView(RecyclerView view, RecyclerViewAdapter adapter) { view.setLayoutManager( new LinearLayoutManager(view.getContext(), LinearLayoutManager.VERTICAL, false)); view.setItemAnimator(null); view.setAdapter(adapter); } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java index 520a5db..6db72eb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java
@@ -15,7 +15,6 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeVersionInfo; import org.chromium.chrome.browser.WebContentsFactory; -import org.chromium.chrome.browser.content.ContentUtils; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler; import org.chromium.chrome.browser.tab.Tab; @@ -319,7 +318,6 @@ OverlayViewDelegate delegate = new OverlayViewDelegate(cv); mContentViewCore = ContentViewCore.create(mActivity, ChromeVersionInfo.getProductVersion(), mWebContents, delegate, cv, mActivity.getWindowAndroid()); - ContentUtils.setUserAgentOverride(mWebContents); // Transfers the ownership of the WebContents to the native OverlayPanelContent. nativeSetWebContents(mNativeOverlayPanelContentPtr, mWebContents, mWebContentsDelegate);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index 5f6f796..97595ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -883,7 +883,7 @@ * @return The {@link EdgeSwipeHandler} responsible for processing swipe events for the toolbar. * By default this returns null. */ - public EdgeSwipeHandler getTopSwipeHandler() { + public EdgeSwipeHandler getToolbarSwipeHandler() { return null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java index 0c8702f..451a8d2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -94,7 +94,7 @@ * @return The {@link EdgeSwipeHandler} responsible for processing swipe events for the toolbar. */ @Override - public EdgeSwipeHandler getTopSwipeHandler() { + public EdgeSwipeHandler getToolbarSwipeHandler() { return mToolbarSwipeHandler; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java index 4bec637..3c016c3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/content/ContentUtils.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.content; -import org.chromium.content_public.browser.WebContents; - /** * A utility class to expose content functionality. */ @@ -17,16 +15,5 @@ return nativeGetBrowserUserAgent(); } - /** - * Set the user agent used for override. Currently, the only use case we have - * for overriding a user agent involves spoofing a desktop Linux user agent - * for "Request desktop site". Set it for WebContents so that it is available - * when a NavigationEntry requires the user agent to be overridden. - */ - public static void setUserAgentOverride(WebContents webContents) { - nativeSetUserAgentOverride(webContents); - } - private static native String nativeGetBrowserUserAgent(); - private static native void nativeSetUserAgentOverride(WebContents webContents); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContentCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContentCoordinator.java index 92f8fd2d..fdddd81 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContentCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContentCoordinator.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.contextual_suggestions; import android.content.Context; +import android.support.annotation.Nullable; import android.support.v4.view.ViewCompat; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.OnScrollListener; @@ -13,10 +14,14 @@ import android.view.ViewGroup; import org.chromium.chrome.R; -import org.chromium.chrome.browser.modelutil.RecyclerViewModelChangeProcessor; +import org.chromium.chrome.browser.modelutil.ForwardingListObservable; +import org.chromium.chrome.browser.modelutil.ListObservable; +import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; import org.chromium.chrome.browser.ntp.ContextMenuManager; +import org.chromium.chrome.browser.ntp.cards.ChildNode; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCallback; +import org.chromium.chrome.browser.ntp.cards.TreeNode; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; @@ -33,8 +38,43 @@ private ContextualSuggestionsModel mModel; private WindowAndroid mWindowAndroid; private ContextMenuManager mContextMenuManager; - private RecyclerViewModelChangeProcessor<ClusterList, NewTabPageViewHolder, PartialBindCallback> - mModelChangeProcessor; + private ModelChangeProcessor mModelChangeProcessor; + + /** + * This class acts as an adapter between RecyclerView contents represented by a + * {@link TreeNode} and the new {@link RecyclerViewAdapter.Delegate} interface. + * TODO(bauerb): Merge {@link TreeNode} into {@link RecyclerViewAdapter.Delegate}. + */ + private static class ModelChangeProcessor extends ForwardingListObservable<PartialBindCallback> + implements RecyclerViewAdapter.Delegate<NewTabPageViewHolder, PartialBindCallback>, + ListObservable.ListObserver<PartialBindCallback> { + private final TreeNode mTreeNode; + + private ModelChangeProcessor(ChildNode treeNode) { + mTreeNode = treeNode; + } + + @Override + public int getItemCount() { + return mTreeNode.getItemCount(); + } + + @Override + public int getItemViewType(int position) { + return mTreeNode.getItemViewType(position); + } + + @Override + public void onBindViewHolder(NewTabPageViewHolder viewHolder, int position, + @Nullable PartialBindCallback payload) { + if (payload == null) { + mTreeNode.onBindViewHolder(viewHolder, position); + return; + } + + payload.onResult(viewHolder); + } + } /** * Construct a new {@link ContentCoordinator}. @@ -77,13 +117,15 @@ mRecyclerView::setTouchEnabled, closeContextMenuCallback); mWindowAndroid.addContextMenuCloseListener(mContextMenuManager); + final ClusterList clusterList = mModel.getClusterList(); + mModelChangeProcessor = new ModelChangeProcessor(clusterList); ContextualSuggestionsAdapter adapter = new ContextualSuggestionsAdapter(profile, new UiConfig(mRecyclerView), uiDelegate, - mModel.getClusterList(), mContextMenuManager); + mContextMenuManager, mModelChangeProcessor); mRecyclerView.setAdapter(adapter); - mModelChangeProcessor = new RecyclerViewModelChangeProcessor<>(adapter); - mModel.getClusterList().addObserver(mModelChangeProcessor); + mModelChangeProcessor.addObserver(adapter); + clusterList.addObserver(mModelChangeProcessor); // TODO(twellington): Should this be a proper model property, set by the mediator and bound // to the RecyclerView?
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java index da48f79..550b234a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsAdapter.java
@@ -4,13 +4,13 @@ package org.chromium.chrome.browser.contextual_suggestions; -import android.support.v7.widget.RecyclerView; import android.view.ViewGroup; import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; import org.chromium.chrome.browser.ntp.ContextMenuManager; import org.chromium.chrome.browser.ntp.cards.ItemViewType; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; +import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCallback; import org.chromium.chrome.browser.ntp.snippets.SectionHeaderViewHolder; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.profiles.Profile; @@ -18,22 +18,34 @@ import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import java.util.List; - /** * An adapter that contains the view binder for the content component. */ -class ContextualSuggestionsAdapter extends RecyclerViewAdapter<ClusterList, NewTabPageViewHolder> { - private class ContextualSuggestionsViewBinder - implements ViewBinder<ClusterList, NewTabPageViewHolder> { +class ContextualSuggestionsAdapter + extends RecyclerViewAdapter<NewTabPageViewHolder, PartialBindCallback> { + private static class ContextualSuggestionsViewHolderFactory + implements ViewHolderFactory<NewTabPageViewHolder> { + private final Profile mProfile; + private final UiConfig mUiConfig; + private final SuggestionsUiDelegate mUiDelegate; + private final ContextMenuManager mContextMenuManager; + + public ContextualSuggestionsViewHolderFactory(Profile profile, UiConfig uiConfig, + SuggestionsUiDelegate uiDelegate, ContextMenuManager contextMenuManager) { + mProfile = profile; + mUiConfig = uiConfig; + mUiDelegate = uiDelegate; + mContextMenuManager = contextMenuManager; + } + @Override - public NewTabPageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public NewTabPageViewHolder createViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case ItemViewType.HEADER: - return new SectionHeaderViewHolder(mRecyclerView, mUiConfig); + return new SectionHeaderViewHolder((SuggestionsRecyclerView) parent, mUiConfig); case ItemViewType.SNIPPET: - return new ContextualSuggestionCardViewHolder(mRecyclerView, + return new ContextualSuggestionCardViewHolder((SuggestionsRecyclerView) parent, mContextMenuManager, mUiDelegate, mUiConfig, OfflinePageBridge.getForProfile(mProfile)); @@ -42,74 +54,27 @@ return null; } } - - @Override - public void onBindViewHolder(ClusterList model, NewTabPageViewHolder holder, int position) { - model.onBindViewHolder(holder, position); - } } - private final Profile mProfile; - private final UiConfig mUiConfig; - private final SuggestionsUiDelegate mUiDelegate; - private final ClusterList mClusterList; - private final ContextMenuManager mContextMenuManager; - - private SuggestionsRecyclerView mRecyclerView; - /** * Construct a new {@link ContextualSuggestionsAdapter}. * @param profile The regular {@link Profile}. * @param uiConfig The {@link UiConfig} used to adjust view display. * @param uiDelegate The {@link SuggestionsUiDelegate} used to help construct items in the * content view. - * @param clusterList The {@link ClusterList} for the component. * @param contextMenuManager The {@link ContextMenuManager} used to display a context menu. + * @param delegate The {@link Delegate} implementing the core logic. */ ContextualSuggestionsAdapter(Profile profile, UiConfig uiConfig, - SuggestionsUiDelegate uiDelegate, ClusterList clusterList, - ContextMenuManager contextMenuManager) { - super(clusterList, null); - - setViewBinder(new ContextualSuggestionsViewBinder()); - - mProfile = profile; - mUiConfig = uiConfig; - mUiDelegate = uiDelegate; - mClusterList = clusterList; - mContextMenuManager = contextMenuManager; - } - - @Override - @ItemViewType - public int getItemViewType(int position) { - return mClusterList.getItemViewType(position); - } - - @Override - public void onAttachedToRecyclerView(RecyclerView recyclerView) { - mRecyclerView = (SuggestionsRecyclerView) recyclerView; - } - - @Override - public void onDetachedFromRecyclerView(RecyclerView recyclerView) { - mRecyclerView = null; + SuggestionsUiDelegate uiDelegate, ContextMenuManager contextMenuManager, + RecyclerViewAdapter.Delegate<NewTabPageViewHolder, PartialBindCallback> delegate) { + super(delegate, + new ContextualSuggestionsViewHolderFactory( + profile, uiConfig, uiDelegate, contextMenuManager)); } @Override public void onViewRecycled(NewTabPageViewHolder holder) { holder.recycle(); } - - @Override - public void onBindViewHolder(NewTabPageViewHolder holder, int position, List<Object> payloads) { - if (payloads.isEmpty()) { - onBindViewHolder(holder, position); - return; - } - - for (Object payload : payloads) { - ((NewTabPageViewHolder.PartialBindCallback) payload).onResult(holder); - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS index 2b5bfcd..94b86d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/OWNERS
@@ -1,2 +1 @@ -mariakhomenko@chromium.org yusufo@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DirectoryOption.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DirectoryOption.java index ddc446e6..ae086da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DirectoryOption.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DirectoryOption.java
@@ -4,12 +4,18 @@ package org.chromium.chrome.browser.download; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Environment; import android.support.annotation.IntDef; +import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordHistogram; +import java.io.File; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; /** * Denotes a given option for directory selection; includes name, location, and space. @@ -27,9 +33,62 @@ public static final int OPTION_COUNT = 3; /** + * Asynchronous task to retrieve all download directories on a background thread. + */ + public static class AllDirectoriesTask + extends AsyncTask<Void, Void, ArrayList<DirectoryOption>> { + @Override + protected ArrayList<DirectoryOption> doInBackground(Void... params) { + ArrayList<DirectoryOption> dirs = new ArrayList<>(); + + // Retrieve default directory. + File defaultDirectory = + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + + // If no default directory, return an error option. + if (defaultDirectory == null) { + dirs.add(new DirectoryOption(null, 0, 0, DirectoryOption.ERROR_OPTION)); + return dirs; + } + + DirectoryOption defaultOption = + toDirectoryOption(defaultDirectory, DirectoryOption.DEFAULT_OPTION); + dirs.add(defaultOption); + + // Retrieve additional directories, i.e. the external SD card directory. + String primaryStorageDir = Environment.getExternalStorageDirectory().getAbsolutePath(); + File[] files; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + files = ContextUtils.getApplicationContext().getExternalFilesDirs( + Environment.DIRECTORY_DOWNLOADS); + } else { + files = new File[] {Environment.getExternalStorageDirectory()}; + } + + if (files.length <= 1) return dirs; + + for (int i = 0; i < files.length; ++i) { + if (files[i] == null) continue; + // Skip primary storage directory. + if (files[i].getAbsolutePath().contains(primaryStorageDir)) continue; + dirs.add(toDirectoryOption(files[i], DirectoryOption.ADDITIONAL_OPTION)); + } + return dirs; + } + + private DirectoryOption toDirectoryOption( + File dir, @DownloadLocationDirectoryType int type) { + if (dir == null) return null; + return new DirectoryOption( + dir.getAbsolutePath(), dir.getUsableSpace(), dir.getTotalSpace(), type); + } + } + + /** * Name of the current download directory. */ - public final String name; + public String name; /** * The absolute path of the download location. @@ -49,11 +108,16 @@ /** * The type of the directory option. */ - public final int type; + public final @DownloadLocationDirectoryType int type; public DirectoryOption(String name, String location, long availableSpace, long totalSpace, @DownloadLocationDirectoryType int type) { + this(location, availableSpace, totalSpace, type); this.name = name; + } + + public DirectoryOption(String location, long availableSpace, long totalSpace, + @DownloadLocationDirectoryType int type) { this.location = location; this.availableSpace = availableSpace; this.totalSpace = totalSpace;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadInfoBarController.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadInfoBarController.java index 99c02a9..3ef8c27b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadInfoBarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadInfoBarController.java
@@ -114,6 +114,9 @@ public String link; public int icon; + // Whether the icon corresponds to a vector drawable. + public boolean hasVectorDrawable; + // Whether the icon should have animation. public boolean hasAnimation; @@ -531,9 +534,11 @@ if (infoBarState == DownloadInfoBarState.DOWNLOADING) { info.icon = showAccelerating ? R.drawable.infobar_downloading_sweep_animation : R.drawable.infobar_downloading_fill_animation; + info.hasVectorDrawable = true; } else if (offlineItemState == OfflineItemState.COMPLETE) { stringRes = R.plurals.multiple_download_complete; - info.icon = R.drawable.infobar_download_complete_animation; + info.icon = R.drawable.infobar_download_complete; + info.hasVectorDrawable = true; } else if (offlineItemState == OfflineItemState.FAILED) { stringRes = R.plurals.multiple_download_failed; info.icon = R.drawable.ic_error_outline_googblue_24dp; @@ -587,6 +592,7 @@ R.string.download_infobar_filename, itemToShow.title); info.id = itemToShow.id; info.link = getContext().getString(R.string.open_downloaded_label); + info.icon = R.drawable.infobar_download_complete_animation; info.hasAnimation = true; info.dontRepeat = true; } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialog.java index 9406d0d6..c2f2cb36 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialog.java
@@ -28,12 +28,14 @@ /** * Dialog that is displayed to ask user where they want to download the file. */ -public class DownloadLocationDialog extends ModalDialogView implements OnCheckedChangeListener { +public class DownloadLocationDialog extends ModalDialogView + implements OnCheckedChangeListener, DownloadDirectoryAdapter.Delegate { private DownloadDirectoryAdapter mDirectoryAdapter; private AlertDialogEditText mFileName; private Spinner mFileLocation; private CheckBox mDontShowAgain; + private @DownloadLocationDialogType int mDialogType; /** * Create a {@link DownloadLocationDialog} with the given properties. @@ -96,21 +98,12 @@ @DownloadLocationDialogType int dialogType, File suggestedPath, Params params) { super(controller, params); - mDirectoryAdapter = new DownloadDirectoryAdapter(context); + mDirectoryAdapter = new DownloadDirectoryAdapter(context, this); mFileName = (AlertDialogEditText) params.customView.findViewById(R.id.file_name); mFileName.setText(suggestedPath.getName()); mFileLocation = (Spinner) params.customView.findViewById(R.id.file_location); - mFileLocation.setAdapter(mDirectoryAdapter); - - int selectedItemId = mDirectoryAdapter.getSelectedItemId(); - if (selectedItemId == NO_SELECTED_ITEM_ID - || dialogType == DownloadLocationDialogType.LOCATION_FULL - || dialogType == DownloadLocationDialogType.LOCATION_NOT_FOUND) { - selectedItemId = mDirectoryAdapter.useFirstValidSelectableItemId(); - } - mFileLocation.setSelection(selectedItemId); // Automatically check "don't show again" the first time the user is seeing the dialog. mDontShowAgain = (CheckBox) params.customView.findViewById(R.id.show_again_checkbox); @@ -118,6 +111,8 @@ == DownloadPromptStatus.SHOW_INITIAL; mDontShowAgain.setChecked(isInitial); mDontShowAgain.setOnCheckedChangeListener(this); + + mDialogType = dialogType; } // CompoundButton.OnCheckedChangeListener implementation. @@ -155,4 +150,22 @@ boolean getDontShowAgain() { return mDontShowAgain != null && mDontShowAgain.isChecked(); } + + // DownloadDirectoryAdapter.Delegate implementation. + + @Override + public void onDirectoryOptionsReady() { + int selectedItemId = mDirectoryAdapter.getSelectedItemId(); + if (selectedItemId == NO_SELECTED_ITEM_ID + || mDialogType == DownloadLocationDialogType.LOCATION_FULL + || mDialogType == DownloadLocationDialogType.LOCATION_NOT_FOUND) { + selectedItemId = mDirectoryAdapter.useFirstValidSelectableItemId(); + } + + mFileLocation.setAdapter(mDirectoryAdapter); + mFileLocation.setSelection(selectedItemId); + } + + @Override + public void onDirectorySelectionChanged() {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 5540c27..757c406 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -25,7 +25,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ObserverList; -import org.chromium.base.StrictModeContext; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; @@ -33,6 +32,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.download.DirectoryOption.AllDirectoriesTask; import org.chromium.chrome.browser.download.DownloadMetrics.DownloadOpenSource; import org.chromium.chrome.browser.download.ui.BackendProvider; import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; @@ -1541,26 +1541,29 @@ // Only show the missing directory snackbar once. if (!prefServiceBridge.getBoolean(Pref.SHOW_MISSING_SD_CARD_ERROR_ANDROID)) return; - String[] downloadDirs = DownloadUtils.getAllDownloadDirectories(); - if (downloadDirs.length > 1) return; + AllDirectoriesTask task = new AllDirectoriesTask() { + @Override + protected void onPostExecute(ArrayList<DirectoryOption> dirs) { + if (dirs.size() > 1) return; + String externalStorageDir = + Environment.getExternalStorageDirectory().getAbsolutePath(); - String externalStorageDir = null; - try (StrictModeContext unused = StrictModeContext.allowDiskWrites()) { - externalStorageDir = Environment.getExternalStorageDirectory().getAbsolutePath(); - } - - for (DownloadItem item : list) { - boolean missingOnSDCard = isFilePathOnMissingExternalDrive( - item.getDownloadInfo().getFilePath(), externalStorageDir, downloadDirs); - if (!isUnresumableOrCancelled(item) && missingOnSDCard) { - mHandler.post(() -> { - // TODO(shaktisahu): Show it on infobar in the right way. - mDownloadSnackbarController.onDownloadDirectoryNotFound(); - }); - prefServiceBridge.setBoolean(Pref.SHOW_MISSING_SD_CARD_ERROR_ANDROID, false); - break; + for (DownloadItem item : list) { + boolean missingOnSDCard = isFilePathOnMissingExternalDrive( + item.getDownloadInfo().getFilePath(), externalStorageDir, dirs); + if (!isUnresumableOrCancelled(item) && missingOnSDCard) { + mHandler.post(() -> { + // TODO(shaktisahu): Show it on infobar in the right way. + mDownloadSnackbarController.onDownloadDirectoryNotFound(); + }); + prefServiceBridge.setBoolean( + Pref.SHOW_MISSING_SD_CARD_ERROR_ANDROID, false); + break; + } + } } - } + }; + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } /** @@ -1583,20 +1586,20 @@ * @param filePath The file path to check. * @param externalStorageDir The absolute path of external storage directory for primary * storage. - * @param downloadDirs All available download directories including primary storage and + * @param directoryOptions All available download directories including primary storage and * secondary storage. * * @return Whether this file path is in a directory that is no longer available. */ - private boolean isFilePathOnMissingExternalDrive( - String filePath, String externalStorageDir, String[] downloadDirs) { + private boolean isFilePathOnMissingExternalDrive(String filePath, String externalStorageDir, + ArrayList<DirectoryOption> directoryOptions) { if (filePath.contains(externalStorageDir)) { return false; } - for (String dir : downloadDirs) { - if (TextUtils.isEmpty(dir)) continue; - if (filePath.contains(dir)) return false; + for (DirectoryOption directory : directoryOptions) { + if (TextUtils.isEmpty(directory.location)) continue; + if (filePath.contains(directory.location)) return false; } return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java index ecd037d3..3f306f9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -23,7 +23,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.FileUtils; import org.chromium.base.Log; -import org.chromium.base.PathUtils; import org.chromium.base.StrictModeContext; import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.LibraryProcessType; @@ -1150,18 +1149,6 @@ } /** - * Gets all of the directories available for downloads, including internal & external storage. - * - * If the external directories are not available for querying (on older versions of Android), - * return an array with just the internal directory. - * - * @return The absolute paths of download directories. - */ - public static String[] getAllDownloadDirectories() { - return PathUtils.getAllPrivateDownloadsDirectories(); - } - - /** * Returns if the path is in the download directory on primary storage. * @param path The directory to check. * @return If the path is in the download directory on primary storage.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java index 5e002c2..d5f0750 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
@@ -8,8 +8,10 @@ import android.view.View; import org.chromium.chrome.browser.download.home.list.DateOrderedListCoordinator; +import org.chromium.chrome.browser.download.home.snackbars.DeleteUndoCoordinator; import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.snackbar.SnackbarManager; /** * The top level coordinator for the download home UI. This is currently an in progress class and @@ -17,15 +19,20 @@ */ public class DownloadManagerCoordinatorImpl { private final DateOrderedListCoordinator mListCoordinator; + private final DeleteUndoCoordinator mDeleteCoordinator; /** Builds a {@link DownloadManagerCoordinatorImpl} instance. */ - public DownloadManagerCoordinatorImpl(Profile profile, Context context, boolean offTheRecord) { - mListCoordinator = new DateOrderedListCoordinator( - context, offTheRecord, OfflineContentAggregatorFactory.forProfile(profile)); + public DownloadManagerCoordinatorImpl(Profile profile, Context context, boolean offTheRecord, + SnackbarManager snackbarManager) { + mDeleteCoordinator = new DeleteUndoCoordinator(snackbarManager); + mListCoordinator = new DateOrderedListCoordinator(context, offTheRecord, + OfflineContentAggregatorFactory.forProfile(profile), + (items, callback) -> mDeleteCoordinator.showSnackbar(items, callback)); } /** Tears down this coordinator. */ public void destroy() { + mDeleteCoordinator.destroy(); mListCoordinator.destroy(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsCoordinator.java index cac17672..efc6e84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsCoordinator.java
@@ -14,8 +14,8 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; -import org.chromium.chrome.browser.modelutil.RecyclerViewModelChangeProcessor; import org.chromium.chrome.browser.modelutil.SimpleListObservable; +import org.chromium.chrome.browser.modelutil.SimpleRecyclerViewMcp; /** * The coordinator responsible for managing a list of chips. To get the {@link View} that @@ -23,7 +23,7 @@ */ public class ChipsCoordinator implements ChipsProvider.Observer { private final ChipsProvider mProvider; - private final SimpleListObservable<Chip> mModel; + private final SimpleListObservable<Chip> mModel = new SimpleListObservable<>(); private final RecyclerView mView; /** @@ -38,13 +38,15 @@ mProvider = provider; // Build the underlying components. - mModel = new SimpleListObservable<>(); mView = createView(context); - RecyclerViewAdapter<SimpleListObservable<Chip>, ChipsViewBinder.ChipsViewHolder> adapter = - new RecyclerViewAdapter<>(mModel, new ChipsViewBinder()); + SimpleRecyclerViewMcp<Chip, ChipsViewHolder, Void> processor = + new SimpleRecyclerViewMcp<>(mModel, null, ChipsViewHolder::bind); + RecyclerViewAdapter<ChipsViewHolder, Void> adapter = + new RecyclerViewAdapter<>(processor, ChipsViewHolder::create); mView.setAdapter(adapter); - mModel.addObserver(new RecyclerViewModelChangeProcessor<>(adapter)); + processor.addObserver(adapter); + mModel.addObserver(processor); mProvider.addObserver(this); mModel.set(mProvider.getChips());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewBinder.java deleted file mode 100644 index 23e8ded2..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewBinder.java +++ /dev/null
@@ -1,88 +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. - -package org.chromium.chrome.browser.download.home.filter.chips; - -import android.content.res.ColorStateList; -import android.support.v4.view.ViewCompat; -import android.support.v7.widget.RecyclerView.ViewHolder; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter.ViewBinder; -import org.chromium.chrome.browser.modelutil.SimpleListObservable; -import org.chromium.chrome.browser.widget.TintedImageView; - -/** Responsible for binding the {@link ChipsModel} to {@link ViewHolder}s in the RecyclerView. */ -class ChipsViewBinder - implements ViewBinder<SimpleListObservable<Chip>, ChipsViewBinder.ChipsViewHolder> { - /** The {@link ViewHolder} responsible for reflecting a {@link Chip} to a {@link View}. */ - public static class ChipsViewHolder extends ViewHolder { - private final int mTextStartPaddingWithIconPx; - private final int mTextStartPaddingWithNoIconPx; - - private final TextView mText; - private final TintedImageView mImage; - - /** Builds a ChipsViewHolder around a specific {@link View}. */ - public ChipsViewHolder(View itemView) { - super(itemView); - - mText = (TextView) itemView.findViewById(R.id.text); - mImage = (TintedImageView) itemView.findViewById(R.id.icon); - - ColorStateList textColors = mText.getTextColors(); - if (textColors != null) mImage.setTint(textColors); - - mTextStartPaddingWithIconPx = - mText.getResources().getDimensionPixelSize(R.dimen.chip_icon_padding); - mTextStartPaddingWithNoIconPx = - mText.getResources().getDimensionPixelSize(R.dimen.chip_no_icon_padding); - } - - /** - * Pushes the properties of {@code chip} to {@code itemView}. - * @param chip The {@link Chip} to visually reflect in the stored {@link View}. - */ - public void bind(Chip chip) { - itemView.setEnabled(chip.enabled); - mText.setEnabled(chip.enabled); - mImage.setEnabled(chip.enabled); - - itemView.setSelected(chip.selected); - itemView.setOnClickListener(v -> chip.chipSelectedListener.run()); - mText.setContentDescription(mText.getContext().getText(chip.contentDescription)); - mText.setText(chip.text); - - int textStartPadding = mTextStartPaddingWithIconPx; - if (chip.icon == Chip.INVALID_ICON_ID) { - mImage.setVisibility(ViewGroup.GONE); - textStartPadding = mTextStartPaddingWithNoIconPx; - } else { - textStartPadding = mTextStartPaddingWithIconPx; - mImage.setVisibility(ViewGroup.VISIBLE); - mImage.setImageResource(chip.icon); - } - - ViewCompat.setPaddingRelative(mText, textStartPadding, mText.getPaddingTop(), - ViewCompat.getPaddingEnd(mText), mText.getPaddingBottom()); - } - } - - // ViewBinder implementation. - @Override - public ChipsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - return new ChipsViewHolder( - LayoutInflater.from(parent.getContext()).inflate(R.layout.chip, null)); - } - - @Override - public void onBindViewHolder( - SimpleListObservable<Chip> model, ChipsViewHolder holder, int position) { - holder.bind(model.get(position)); - } -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java new file mode 100644 index 0000000..610010c --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java
@@ -0,0 +1,84 @@ +// 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.download.home.filter.chips; + +import android.content.res.ColorStateList; +import android.support.annotation.Nullable; +import android.support.v4.view.ViewCompat; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.chromium.chrome.browser.modelutil.SimpleRecyclerViewMcp; +import org.chromium.chrome.browser.widget.TintedImageView; + +/** The {@link ViewHolder} responsible for reflecting a {@link Chip} to a {@link View}. */ +public class ChipsViewHolder extends ViewHolder { + private final int mTextStartPaddingWithIconPx; + private final int mTextStartPaddingWithNoIconPx; + + private final TextView mText; + private final TintedImageView mImage; + + /** Builds a ChipsViewHolder around a specific {@link View}. */ + private ChipsViewHolder(View itemView) { + super(itemView); + + mText = itemView.findViewById(org.chromium.chrome.R.id.text); + mImage = (TintedImageView) itemView.findViewById(org.chromium.chrome.R.id.icon); + + ColorStateList textColors = mText.getTextColors(); + if (textColors != null) mImage.setTint(textColors); + + mTextStartPaddingWithIconPx = mText.getResources().getDimensionPixelSize( + org.chromium.chrome.R.dimen.chip_icon_padding); + mTextStartPaddingWithNoIconPx = mText.getResources().getDimensionPixelSize( + org.chromium.chrome.R.dimen.chip_no_icon_padding); + } + + /** + * Used as a method reference for ViewHolderFactory. + * @see org.chromium.chrome.browser.modelutil.RecyclerViewAdapter + * .ViewHolderFactory#createViewHolder + */ + public static ChipsViewHolder create(ViewGroup parent, int viewType) { + assert viewType == 0; + return new ChipsViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(org.chromium.chrome.R.layout.chip, null)); + } + + /** + * Used as a method reference for ViewBinder, to push the properties of {@code chip} to + * {@link #itemView}. + * @param chip The {@link Chip} to visually reflect in the stored {@link View}. + * @param payload Unused payload; must be null. + * @see SimpleRecyclerViewMcp + * .ViewBinder#onBindViewHolder + */ + public void bind(Chip chip, @Nullable Void payload) { + itemView.setEnabled(chip.enabled); + mText.setEnabled(chip.enabled); + mImage.setEnabled(chip.enabled); + + itemView.setSelected(chip.selected); + itemView.setOnClickListener(v -> chip.chipSelectedListener.run()); + mText.setContentDescription(mText.getContext().getText(chip.contentDescription)); + mText.setText(chip.text); + + final int textStartPadding; + if (chip.icon == Chip.INVALID_ICON_ID) { + mImage.setVisibility(ViewGroup.GONE); + textStartPadding = mTextStartPaddingWithNoIconPx; + } else { + textStartPadding = mTextStartPaddingWithIconPx; + mImage.setVisibility(ViewGroup.VISIBLE); + mImage.setImageResource(chip.icon); + } + + ViewCompat.setPaddingRelative(mText, textStartPadding, mText.getPaddingTop(), + ViewCompat.getPaddingEnd(mText), mText.getPaddingBottom()); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java index 0902b84..4e1c801 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java
@@ -19,6 +19,7 @@ import org.chromium.components.offline_items_collection.OfflineItem; import org.chromium.components.offline_items_collection.VisualsCallback; +import java.io.File; import java.util.ArrayList; import java.util.List; @@ -100,7 +101,9 @@ /** @see OfflineContentProvider#removeItem(ContentId) */ public void removeItem(OfflineItem item) { - // TODO(dtrainor): Implement deletion. + DownloadManagerService.getDownloadManagerService().removeDownload( + item.id.id, item.isOffTheRecord, item.externallyRemoved); + FileDeletionQueue.get().delete(new File(item.filePath)); } /** @see OfflineContentProvider#cancelDownload(ContentId) */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java new file mode 100644 index 0000000..0f429e8 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java
@@ -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. + +package org.chromium.chrome.browser.download.home.glue; + +import android.os.AsyncTask; +import android.support.annotation.VisibleForTesting; + +import org.chromium.base.Callback; +import org.chromium.base.FileUtils; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Helper queue that will erase {@link File}s passed into {@link FileDeletionQueue#delete(File)} or + * {@link FileDeletionQueue#delete(List)} one at a time on an {@link AsyncTask#THREAD_POOL_EXECUTOR} + * thread. The deletions happen serially in order to prevent overloading the background thread + * pool. + */ +class FileDeletionQueue { + private final Queue<File> mFiles = new LinkedList<File>(); + + /** The outstanding {@link AsyncTask} if any is currently running. */ + private FileDeletionTask mTask; + + /** {@link Callback} meant to be called on the background thread to perform the deletion. */ + private final Callback<File> mDeleter; + + /** @return A singleton instance of {@link FileDeletionQueue}. */ + public static FileDeletionQueue get() { + return LazyHolder.INSTANCE; + } + + /** Deletes {@code file} on a background thread at some point in the near future. */ + public void delete(File file) { + mFiles.add(file); + deleteNextFile(); + } + + /** + * Deletes the {@link File}s in {@code files} on a background thread at some point in the near + * future. + */ + public void delete(List<File> files) { + mFiles.addAll(files); + deleteNextFile(); + } + + /** + * @param deleter A {@link Callback} that will be triggered on the background thread to do the + * actual deleting of the file. + */ + @VisibleForTesting + FileDeletionQueue(Callback<File> deleter) { + mDeleter = deleter; + } + + private void deleteNextFile() { + if (mTask != null) return; + + File file = mFiles.poll(); + if (file == null) return; + + System.out.println("dtrainor: Starting " + file.getName()); + + mTask = new FileDeletionTask(); + mTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, file); + } + + private class FileDeletionTask extends AsyncTask<File, Void, Void> { + // AsyncTask implementation. + @Override + protected Void doInBackground(File... params) { + System.out.println("dtrainor: Deleting " + params[0].getName()); + mDeleter.onResult(params[0]); + return null; + } + + @Override + protected void onPostExecute(Void result) { + System.out.println("dtrainor: Post"); + super.onPostExecute(result); + mTask = null; + deleteNextFile(); + } + } + + private static class LazyHolder { + private static final FileDeletionQueue INSTANCE = + new FileDeletionQueue(file -> FileUtils.recursivelyDeleteFile(file)); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/OfflineContentProviderGlue.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/OfflineContentProviderGlue.java index fb2428d..66e3172 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/OfflineContentProviderGlue.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/OfflineContentProviderGlue.java
@@ -5,11 +5,8 @@ package org.chromium.chrome.browser.download.home.glue; import org.chromium.base.Callback; -import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; -import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.widget.ThumbnailProvider; -import org.chromium.chrome.browser.widget.ThumbnailProviderImpl; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LegacyHelpers; import org.chromium.components.offline_items_collection.OfflineContentProvider; @@ -31,7 +28,6 @@ private final boolean mIncludeOffTheRecord; private final DownloadGlue mDownloadProvider; - private final ThumbnailProvider mThumbnailProvider; private Query mOutstandingQuery; @@ -41,8 +37,6 @@ mProvider = provider; mIncludeOffTheRecord = includeOffTheRecord; mDownloadProvider = new DownloadGlue(this); - mThumbnailProvider = new ThumbnailProviderImpl( - ((ChromeApplication) ContextUtils.getApplicationContext()).getReferencePool()); mProvider.addObserver(this); } @@ -129,6 +123,16 @@ return true; } + /** + * Helper method to remove {@link OfflineItemVisuals} for a {@code id}. Note that this might + * not be necessary if everything is using an {@link OfflineContentProvider}. However the glue + * layer needs to determine what to do with downloads that have externally managed thumbnails. + */ + public void removeVisualsForItem(ThumbnailProvider provider, ContentId id) { + if (!LegacyHelpers.isLegacyDownload(id)) return; + provider.removeThumbnailsFromDisk(id.id); + } + /** @see OfflineContentProvider#addObserver(OfflineContentProvider.Observer) */ public void addObserver(OfflineContentProvider.Observer observer) { mObservers.addObserver(observer);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java index 4c97e2f2..84a1de6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListCoordinator.java
@@ -7,39 +7,62 @@ import android.content.Context; import android.view.View; +import org.chromium.base.Callback; import org.chromium.chrome.browser.download.home.filter.FilterCoordinator; import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem; import org.chromium.components.offline_items_collection.OfflineContentProvider; +import org.chromium.components.offline_items_collection.OfflineItem; + +import java.util.List; /** * The top level coordinator for the download home UI. This is currently an in progress class and * is not fully fleshed out yet. */ public class DateOrderedListCoordinator { + /** + * A helper interface for exposing the decision for whether or not to delete + * {@link OfflineItem}s to an external layer. + */ + @FunctionalInterface + public interface DeleteController { + /** + * Will be called whenever {@link OfflineItem}s are in the process of being removed from the + * UI. This method will be called to determine if that removal should actually happen. + * Based on the result passed to {@code callback}, the removal might be reverted instead of + * being committed. It is expected that {@code callback} will always be triggered no matter + * what happens to the controller itself. + * + * @param items The list of {@link OfflineItem}s that were explicitly slated for removal. + * @param callback The {@link Callback} to notify when the deletion decision is finalized. + * The callback value represents whether or not the deletion should occur. + */ + void canDelete(List<OfflineItem> items, Callback<Boolean> callback); + } + private final FilterCoordinator mFilterCoordinator; - private final ListItemModel mModel; - private final DecoratedListItemModel mDecoratedModel; private final DateOrderedListMediator mMediator; private final DateOrderedListView mView; /** Creates an instance of a DateOrderedListCoordinator, which will visually represent * {@code provider} as a list of items. - * @param context The {@link Context} to use to build the views. - * @param offTheRecord Whether or not to include off the record items. - * @param provider The {@link OfflineContentProvider} to visually represent. + * @param context The {@link Context} to use to build the views. + * @param offTheRecord Whether or not to include off the record items. + * @param provider The {@link OfflineContentProvider} to visually represent. + * @param deleteController A class to manage whether or not items can be deleted. */ - public DateOrderedListCoordinator( - Context context, Boolean offTheRecord, OfflineContentProvider provider) { - mModel = new ListItemModel(); - mDecoratedModel = new DecoratedListItemModel(mModel); - mView = new DateOrderedListView(context, mDecoratedModel); - mMediator = new DateOrderedListMediator(offTheRecord, provider, mModel); + public DateOrderedListCoordinator(Context context, Boolean offTheRecord, + OfflineContentProvider provider, DeleteController deleteController) { + ListItemModel model = new ListItemModel(); + DecoratedListItemModel decoratedModel = new DecoratedListItemModel(model); + mView = new DateOrderedListView(context, decoratedModel); + mMediator = new DateOrderedListMediator(offTheRecord, provider, deleteController, model); // Hook up the FilterCoordinator with our mediator. mFilterCoordinator = new FilterCoordinator(context, mMediator.getFilterSource()); - mFilterCoordinator.addObserver(filter -> mMediator.onFilterTypeSelected(filter)); - mDecoratedModel.setHeader(new ViewListItem(Long.MAX_VALUE, mFilterCoordinator.getView())); + mFilterCoordinator.addObserver(mMediator::onFilterTypeSelected); + decoratedModel.setHeader(new ViewListItem(Long.MAX_VALUE, mFilterCoordinator.getView())); } /** Tears down this coordinator. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java index ba3fd7921..dfcacefb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
@@ -6,6 +6,7 @@ import android.os.Handler; +import org.chromium.base.CollectionUtil; import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.download.home.OfflineItemSource; @@ -17,6 +18,7 @@ import org.chromium.chrome.browser.download.home.filter.TypeOfflineItemFilter; import org.chromium.chrome.browser.download.home.glue.OfflineContentProviderGlue; import org.chromium.chrome.browser.download.home.glue.ThumbnailRequestGlue; +import org.chromium.chrome.browser.download.home.list.DateOrderedListCoordinator.DeleteController; import org.chromium.chrome.browser.widget.ThumbnailProvider; import org.chromium.chrome.browser.widget.ThumbnailProvider.ThumbnailRequest; import org.chromium.chrome.browser.widget.ThumbnailProviderImpl; @@ -25,6 +27,8 @@ import org.chromium.components.offline_items_collection.VisualsCallback; import java.io.Closeable; +import java.util.Collection; +import java.util.List; /** * A Mediator responsible for converting an OfflineContentProvider to a list of items in downloads @@ -35,6 +39,7 @@ private final OfflineContentProviderGlue mProvider; private final ListItemModel mModel; + private final DeleteController mDeleteController; private final OfflineItemSource mSource; private final DateOrderedListMutator mListMutator; @@ -48,12 +53,13 @@ /** * Creates an instance of a DateOrderedListMediator that will push {@code provider} into * {@code model}. - * @param offTheRecord Whether or not to include off the record items. - * @param provider The {@link OfflineContentProvider} to visually represent. - * @param model The {@link ListItemModel} to push {@code provider} into. + * @param offTheRecord Whether or not to include off the record items. + * @param provider The {@link OfflineContentProvider} to visually represent. + * @param deleteController A class to manage whether or not items can be deleted. + * @param model The {@link ListItemModel} to push {@code provider} into. */ - public DateOrderedListMediator( - boolean offTheRecord, OfflineContentProvider provider, ListItemModel model) { + public DateOrderedListMediator(boolean offTheRecord, OfflineContentProvider provider, + DeleteController deleteController, ListItemModel model) { // Build a chain from the data source to the model. The chain will look like: // [OfflineContentProvider] -> // [OfflineItemSource] -> @@ -66,6 +72,7 @@ mProvider = new OfflineContentProviderGlue(provider, offTheRecord); mModel = model; + mDeleteController = deleteController; mSource = new OfflineItemSource(mProvider); mOffTheRecordFilter = new OffTheRecordOfflineItemFilter(offTheRecord, mSource); @@ -84,7 +91,8 @@ mModel.getProperties().setCancelCallback(item -> mProvider.cancelDownload(item)); mModel.getProperties().setShareCallback(item -> {}); // TODO(dtrainor): Pipe into the undo snackbar and the DeleteUndoOfflineItemFilter. - mModel.getProperties().setRemoveCallback(item -> mProvider.removeItem(item)); + mModel.getProperties().setRemoveCallback( + item -> onDeleteItems(CollectionUtil.newArrayList(item))); mModel.getProperties().setVisualsProvider( (item, w, h, callback) -> { return getVisuals(item, w, h, callback); }); } @@ -124,6 +132,27 @@ return mDeleteUndoFilter; } + private void onDeleteItems(List<OfflineItem> items) { + // Calculate the real offline items we are going to remove here. + final Collection<OfflineItem> itemsToDelete = + ItemUtils.findItemsWithSameFilePath(items, mSource.getItems()); + + mDeleteUndoFilter.addPendingDeletions(itemsToDelete); + mDeleteController.canDelete(items, delete -> { + if (delete) { + for (OfflineItem item : itemsToDelete) { + mProvider.removeItem(item); + + // Remove and have a single decision path for cleaning up thumbnails when the + // glue layer is no longer needed. + mProvider.removeVisualsForItem(mThumbnailProvider, item.id); + } + } else { + mDeleteUndoFilter.removePendingDeletions(itemsToDelete); + } + }); + } + private Runnable getVisuals( OfflineItem item, int iconWidthPx, int iconHeightPx, VisualsCallback callback) { if (!UiUtils.canHaveThumbnails(item)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutator.java index 7369745..d647f4c5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutator.java
@@ -76,10 +76,10 @@ @Override public void onItemsRemoved(Collection<OfflineItem> items) { - for (int i = mModel.getItemCount() - 1; i >= 0; i--) { + for (int i = mModel.size() - 1; i >= 0; i--) { ListItem.DateListItem item = getItemAt(i); boolean isHeader = isHeader(item); - boolean isLast = i == mModel.getItemCount() - 1; + boolean isLast = i == mModel.size() - 1; boolean isNextHeader = isLast ? false : isHeader(getItemAt(i + 1)); boolean removeHeader = isHeader && (isLast || isNextHeader); boolean removeItem = !isHeader && items.contains(getOfflineItemFrom(item)); @@ -109,7 +109,7 @@ } private int indexOfItem(ContentId id) { - for (int i = 0; i < mModel.getItemCount(); i++) { + for (int i = 0; i < mModel.size(); i++) { ListItem.DateListItem listItem = getItemAt(i); if (isHeader(listItem)) continue; if (getOfflineItemFrom(listItem).id.equals(id)) return i; @@ -119,7 +119,7 @@ } private int getBestIndexFor(OfflineItem item) { - for (int i = 0; i < mModel.getItemCount(); i++) { + for (int i = 0; i < mModel.size(); i++) { ListItem.DateListItem listItem = getItemAt(i); // We need to compare different things depending on whether or not the ListItem is a @@ -132,11 +132,11 @@ if (itemTimestamp > listItem.date.getTime()) return i; } - return mModel.getItemCount(); + return mModel.size(); } private ListItem.DateListItem getItemAt(int index) { - return (ListItem.DateListItem) mModel.getItemAt(index); + return (ListItem.DateListItem) mModel.get(index); } private boolean isHeader(ListItem.DateListItem item) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java index 351ba390..c30a319 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java
@@ -6,8 +6,8 @@ import android.content.Context; import android.graphics.Rect; +import android.support.annotation.Nullable; import android.support.v7.widget.GridLayoutManager; -import android.support.v7.widget.GridLayoutManager.SpanSizeLookup; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ItemDecoration; import android.support.v7.widget.RecyclerView.Recycler; @@ -15,8 +15,9 @@ import android.view.View; import org.chromium.chrome.R; +import org.chromium.chrome.browser.modelutil.ForwardingListObservable; import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; -import org.chromium.chrome.browser.modelutil.RecyclerViewModelChangeProcessor; +import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; /** * The View component of a DateOrderedList. This takes the DateOrderedListModel and creates the @@ -32,6 +33,31 @@ private final RecyclerView mView; + private static class ModelChangeProcessor extends ForwardingListObservable<Void> + implements RecyclerViewAdapter.Delegate<ListItemViewHolder, Void> { + private final DecoratedListItemModel mModel; + + public ModelChangeProcessor(DecoratedListItemModel model) { + mModel = model; + } + + @Override + public int getItemCount() { + return mModel.size(); + } + + @Override + public int getItemViewType(int position) { + return ListUtils.getViewTypeForItem(mModel.get(position)); + } + + @Override + public void onBindViewHolder( + ListItemViewHolder viewHolder, int position, @Nullable Void payload) { + viewHolder.bind(mModel.getProperties(), mModel.get(position)); + } + } + /** Creates an instance of a {@link DateOrderedListView} representing {@code model}. */ public DateOrderedListView(Context context, DecoratedListItemModel model) { mModel = model; @@ -45,11 +71,11 @@ mPrefetchVerticalPaddingPx = context.getResources().getDimensionPixelSize( R.dimen.download_manager_prefetch_vertical_margin); - DateOrderedListViewBinder listViewBinder = new DateOrderedListViewBinder(); - DateOrderedListViewAdapter adapter = new DateOrderedListViewAdapter(mModel, listViewBinder); - RecyclerViewModelChangeProcessor<DecoratedListItemModel, ListItemViewHolder, Void> - modelChangeProcessor = new RecyclerViewModelChangeProcessor<>(adapter); - mModel.addObserver(modelChangeProcessor); + ModelChangeProcessor processor = new ModelChangeProcessor(mModel); + RecyclerViewAdapter<ListItemViewHolder, Void> adapter = + new DateOrderedListViewAdapter(mModel, processor, ListItemViewHolder::create); + processor.addObserver(adapter); + mModel.addObserver(processor); mView = new RecyclerView(context); mView.setHasFixedSize(true); @@ -94,7 +120,7 @@ // SpanSizeLookup implementation. @Override public int getSpanSize(int position) { - return ListUtils.getSpanSize(mModel.getItemAt(position), getSpanCount()); + return ListUtils.getSpanSize(mModel.get(position), getSpanCount()); } } } @@ -104,9 +130,9 @@ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { int position = parent.getChildAdapterPosition(view); - if (position < 0 || position >= mModel.getItemCount()) return; + if (position < 0 || position >= mModel.size()) return; - switch (ListUtils.getViewTypeForItem(mModel.getItemAt(position))) { + switch (ListUtils.getViewTypeForItem(mModel.get(position))) { case ListUtils.IMAGE: outRect.left = mImagePaddingPx; outRect.right = mImagePaddingPx;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java index 69343364..94ab0280 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java
@@ -6,31 +6,28 @@ import android.support.v7.widget.RecyclerView; -import org.chromium.chrome.browser.download.home.list.ListUtils.ViewType; import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; /** * A helper {@link RecyclerView.Adapter} implementation meant to glue a {@link ListItemModel} * to the right {@link ViewHolder} and {@link ViewBinder}. + * TODO(bauerb): Remove this class together with reliance on stable IDs */ -class DateOrderedListViewAdapter - extends RecyclerViewAdapter<DecoratedListItemModel, ListItemViewHolder> { +class DateOrderedListViewAdapter extends RecyclerViewAdapter<ListItemViewHolder, Void> { + private final DecoratedListItemModel mModel; + /** Creates an instance of a {@link DateOrderedListViewAdapter}. */ public DateOrderedListViewAdapter(DecoratedListItemModel model, - ViewBinder<DecoratedListItemModel, ListItemViewHolder> viewBinder) { - super(model, viewBinder); + Delegate<ListItemViewHolder, Void> delegate, + ViewHolderFactory<ListItemViewHolder> factory) { + super(delegate, factory); + mModel = model; setHasStableIds(true); } @Override public long getItemId(int position) { if (!hasStableIds()) return RecyclerView.NO_ID; - return mModel.getItemAt(position).stableId; + return mModel.get(position).stableId; } - - @Override - public @ViewType int getItemViewType(int position) { - ListItem item = mModel.getItemAt(position); - return ListUtils.getViewTypeForItem(item); - } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java deleted file mode 100644 index 92579cc7f..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java +++ /dev/null
@@ -1,46 +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. - -package org.chromium.chrome.browser.download.home.list; - -import android.view.ViewGroup; - -import org.chromium.chrome.browser.download.home.list.ListUtils.ViewType; -import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter.ViewBinder; - -/** - * A {@link ViewBinder} responsible for connecting a {@link DateOrderedListModel} with a underlying - * {@link ViewHolder}. - */ -class DateOrderedListViewBinder implements ViewBinder<DecoratedListItemModel, ListItemViewHolder> { - // ViewBinder implementation. - @Override - public ListItemViewHolder onCreateViewHolder(ViewGroup parent, @ViewType int viewType) { - switch (viewType) { - case ListUtils.DATE: - return ListItemViewHolder.DateViewHolder.create(parent); - case ListUtils.IN_PROGRESS: - return new ListItemViewHolder.InProgressViewHolder(parent); - case ListUtils.GENERIC: - return ListItemViewHolder.GenericViewHolder.create(parent); - case ListUtils.VIDEO: - return new ListItemViewHolder.VideoViewHolder(parent); - case ListUtils.IMAGE: - return new ListItemViewHolder.ImageViewHolder(parent); - case ListUtils.CUSTOM_VIEW: - return new ListItemViewHolder.CustomViewHolder(parent); - case ListUtils.PREFETCH: - return ListItemViewHolder.PrefetchViewHolder.create(parent); - } - - assert false; - return null; - } - - @Override - public void onBindViewHolder( - DecoratedListItemModel model, ListItemViewHolder holder, int position) { - holder.bind(model.getProperties(), model.getItemAt(position)); - } -} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DecoratedListItemModel.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DecoratedListItemModel.java index a8977a4..db41157 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DecoratedListItemModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DecoratedListItemModel.java
@@ -9,9 +9,14 @@ import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem; import org.chromium.chrome.browser.modelutil.ListObservable; import org.chromium.chrome.browser.modelutil.ListObservable.ListObserver; +import org.chromium.chrome.browser.modelutil.SimpleList; -/** A wrapper class that adds decoration {@link ListItem}s to a {@link ListItemModel}. */ -class DecoratedListItemModel extends ListObservable<Void> implements ListObserver<Void> { +/** + * A wrapper class that adds decoration {@link ListItem}s to a {@link ListItemModel}. + * TODO(bauerb): Replace this with InnerNode (once it has been migrated to the UI architecture) + */ +class DecoratedListItemModel + extends ListObservable<Void> implements ListObserver<Void>, SimpleList<ListItem> { private final ListItemModel mModel; private ViewListItem mHeaderItem; @@ -43,10 +48,16 @@ } } - /** @see ListItemModel#getItemAt(int) */ - public ListItem getItemAt(int index) { + // SimpleList implementation. + @Override + public int size() { + return mModel.size() + (mHeaderItem == null ? 0 : 1); + } + + @Override + public ListItem get(int index) { if (index == 0 && mHeaderItem != null) return mHeaderItem; - return mModel.getItemAt(convertIndexForSource(index)); + return mModel.get(convertIndexForSource(index)); } // ListObserver implementation. @@ -67,12 +78,6 @@ notifyItemRangeChanged(convertIndexFromSource(index), count, payload); } - // ListObservable implementation. - @Override - public int getItemCount() { - return mModel.getItemCount() + (mHeaderItem == null ? 0 : 1); - } - private int convertIndexForSource(int index) { return mHeaderItem == null ? index : index - 1; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ItemUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ItemUtils.java new file mode 100644 index 0000000..1128d180 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ItemUtils.java
@@ -0,0 +1,47 @@ +// 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.download.home.list; + +import android.text.TextUtils; + +import org.chromium.components.offline_items_collection.OfflineItem; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** Helper methods to make performing actions on {@link OfflineItem}s easier. */ +class ItemUtils { + private ItemUtils() {} + + /** + * Finds all {@link OfflineItem}s in {@code allItems} that have the same file path as an + * {@link OfflineItem} in {@code items}. Note that {@link OfflineItem}s in {@code items} with + * empty or {@code null} file paths are ignored in the search, but that {@link OfflineItem} is + * still included in the returned {@link Collection}. + * + * @param items A {@link Collection} of {@link OfflineItem}s to use as the source for file + * paths. + * @param allItems A {@link Collection} of {@link OfflineItem}s to search for matching file + * paths in. + * @return All {@link OfflineItem}s in {@code allItems} that have file paths that match + * an {@link OfflineItem} in {@code items}. The values in {@code items} are + * automatically included. + */ + public static Collection<OfflineItem> findItemsWithSameFilePath( + Collection<OfflineItem> items, Collection<OfflineItem> allItems) { + Set<String> uniqueFilePaths = new HashSet<>(); + for (OfflineItem item : items) { + if (!TextUtils.isEmpty(item.filePath)) uniqueFilePaths.add(item.filePath); + } + + Set<OfflineItem> matchedItems = new HashSet<>(items); + for (OfflineItem item : allItems) { + if (uniqueFilePaths.contains(item.filePath)) matchedItems.add(item); + } + + return matchedItems; + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.java index 30daf06..243e603b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.download.home.list; import org.chromium.chrome.browser.modelutil.ListObservable; +import org.chromium.chrome.browser.modelutil.SimpleList; import java.util.ArrayList; import java.util.List; @@ -14,7 +15,7 @@ * This includes (1) a {@link ListObservable} implementation and (2) exposing a * {@link ListPropertyModel} for shared item properties and general list information. */ -class ListItemModel extends BatchListObservable { +class ListItemModel extends BatchListObservable implements SimpleList<ListItem> { private final List<ListItem> mItems = new ArrayList<>(); private final ListPropertyModel mListProperties = new ListPropertyModel(); @@ -44,14 +45,14 @@ notifyItemChanged(index); } - /** @return The {@link ListItem} at {@code index}. */ - public ListItem getItemAt(int index) { + // SimpleList implementation. + @Override + public ListItem get(int index) { return mItems.get(index); } - // ListObservable implementation. @Override - public int getItemCount() { + public int size() { return mItems.size(); } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java index 7d3bccf..6c5159b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java
@@ -40,11 +40,38 @@ private static final int INVALID_ID = -1; /** Creates an instance of a {@link ListItemViewHolder}. */ - public ListItemViewHolder(View itemView) { + protected ListItemViewHolder(View itemView) { super(itemView); } /** + * Used as a method reference for ViewHolderFactory. + * @see + * org.chromium.chrome.browser.modelutil.RecyclerViewAdapter.ViewHolderFactory#createViewHolder + */ + public static ListItemViewHolder create(ViewGroup parent, @ListUtils.ViewType int viewType) { + switch (viewType) { + case ListUtils.DATE: + return DateViewHolder.create(parent); + case ListUtils.IN_PROGRESS: + return new InProgressViewHolder(parent); + case ListUtils.GENERIC: + return GenericViewHolder.create(parent); + case ListUtils.VIDEO: + return new VideoViewHolder(parent); + case ListUtils.IMAGE: + return new ImageViewHolder(parent); + case ListUtils.CUSTOM_VIEW: + return new CustomViewHolder(parent); + case ListUtils.PREFETCH: + return PrefetchViewHolder.create(parent); + } + + assert false; + return null; + } + + /** * Binds the currently held {@link View} to {@code item}. * @param properties The shared {@link ListPropertyModel} all items can access. * @param item The {@link ListItem} to visually represent in this {@link ViewHolder}.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/snackbars/DeleteUndoCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/snackbars/DeleteUndoCoordinator.java new file mode 100644 index 0000000..8f1c800 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/snackbars/DeleteUndoCoordinator.java
@@ -0,0 +1,69 @@ +// 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.download.home.snackbars; + +import org.chromium.base.Callback; +import org.chromium.base.ContextUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.snackbar.Snackbar; +import org.chromium.chrome.browser.snackbar.SnackbarManager; +import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; +import org.chromium.components.offline_items_collection.OfflineItem; + +import java.util.Collection; + +/** + * A coordinator that is responsible for processing {@link OfflineItem} deletion requests and - + * based on a user decision or inaction - approve or reject the request. + */ +public class DeleteUndoCoordinator { + private final SnackbarManager mView; + private final SnackbarController mController; + + /** Creates a {@link DeleteUndoCoordinator} instance. */ + public DeleteUndoCoordinator(SnackbarManager snackbarManager) { + mView = snackbarManager; + mController = new SnackbarControllerImpl(); + } + + /** Destroys this coordinator. This will dismiss all outstanding snackbars with no action. */ + public void destroy() { + mView.dismissSnackbars(mController); + } + + /** + * Shows a snackbar for an undoable delete action on {@link OfflineItem}s. + * + * @param itemsSelected The {@link OfflineItem}s the user explicitly selected to delete. + * @param callback The {@link Callback} to notify when the snackbar is finished showing. + */ + public void showSnackbar(Collection<OfflineItem> itemsSelected, Callback<Boolean> callback) { + assert !itemsSelected.isEmpty(); + + Snackbar snackbar = Snackbar.make(UndoUiUtils.getTitleFor(itemsSelected), mController, + Snackbar.TYPE_ACTION, Snackbar.UMA_DOWNLOAD_DELETE_UNDO); + snackbar.setAction(ContextUtils.getApplicationContext().getString(R.string.undo), callback); + snackbar.setTemplateText(UndoUiUtils.getTemplateTextFor(itemsSelected)); + mView.showSnackbar(snackbar); + } + + private static class SnackbarControllerImpl implements SnackbarController { + // SnackbarController implementation. + @Override + public void onAction(Object actionData) { + notifyCallback(actionData, false); + } + + @Override + public void onDismissNoAction(Object actionData) { + notifyCallback(actionData, true); + } + + @SuppressWarnings("unchecked") + private static void notifyCallback(Object actionData, boolean delete) { + ((Callback<Boolean>) actionData).onResult(delete); + } + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/snackbars/UndoUiUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/snackbars/UndoUiUtils.java new file mode 100644 index 0000000..a15789d2 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/snackbars/UndoUiUtils.java
@@ -0,0 +1,38 @@ +// 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.download.home.snackbars; + +import android.content.Context; + +import org.chromium.base.ContextUtils; +import org.chromium.chrome.R; +import org.chromium.components.offline_items_collection.OfflineItem; + +import java.util.Collection; +import java.util.Locale; + +/** Helpers for building components or strings of the download deletion undo UI. */ +final class UndoUiUtils { + private UndoUiUtils() {} + + /** @return A {@link String} representing the title text for an undo snackbar. */ + public static String getTitleFor(Collection<OfflineItem> items) { + if (items.size() == 1) { + return items.iterator().next().title; + } else { + return String.format(Locale.getDefault(), "%d", items.size()); + } + } + + /** @return A {@link String} representing the template text for an undo snackbar. */ + public static String getTemplateTextFor(Collection<OfflineItem> items) { + Context context = ContextUtils.getApplicationContext(); + if (items.size() == 1) { + return context.getString(R.string.undo_bar_delete_message); + } else { + return context.getString(R.string.undo_bar_multiple_downloads_delete_message); + } + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java index 9f32aed..5034ebe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
@@ -33,6 +33,8 @@ import org.chromium.chrome.browser.BasicNativePage; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.download.DirectoryOption; +import org.chromium.chrome.browser.download.DirectoryOption.AllDirectoriesTask; import org.chromium.chrome.browser.download.DownloadManagerService; import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory; @@ -561,29 +563,35 @@ private void maybeShowDownloadSettingsTextBubble(final Tracker tracker) { // If the user doesn't have an SD card don't show the IPH. - String[] externalDirs = DownloadUtils.getAllDownloadDirectories(); - if (externalDirs.length < 2) return; + AllDirectoriesTask task = new AllDirectoriesTask() { + @Override + protected void onPostExecute(ArrayList<DirectoryOption> dirs) { + if (dirs.size() < 2) return; - // Check to see if the help UI should be triggered. - if (!tracker.shouldTriggerHelpUI(FeatureConstants.DOWNLOAD_SETTINGS_FEATURE)) return; + // Check to see if the help UI should be triggered. + if (!tracker.shouldTriggerHelpUI(FeatureConstants.DOWNLOAD_SETTINGS_FEATURE)) + return; - // Build and show text bubble. - View anchorView = mToolbar.findViewById(R.id.settings_menu_id); + // Build and show text bubble. + View anchorView = mToolbar.findViewById(R.id.settings_menu_id); - // Show the setting text bubble after the root view is attached to window. - if (mToolbar.isAttachedToWindow()) { - showDownloadSettingsInProductHelp(tracker, anchorView); - } else { - mToolbar.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { - @Override - public void onViewAttachedToWindow(View v) { + // Show the setting text bubble after the root view is attached to window. + if (mToolbar.isAttachedToWindow()) { showDownloadSettingsInProductHelp(tracker, anchorView); - mToolbar.removeOnAttachStateChangeListener(this); + } else { + mToolbar.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View v) { + showDownloadSettingsInProductHelp(tracker, anchorView); + mToolbar.removeOnAttachStateChangeListener(this); + } + @Override + public void onViewDetachedFromWindow(View v) {} + }); } - @Override - public void onViewDetachedFromWindow(View v) {} - }); - } + } + }; + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private void showDownloadSettingsInProductHelp(final Tracker tracker, View anchorView) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java index cfc6431..fe2532f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java
@@ -31,7 +31,7 @@ public ExploreSitesCategoryTile(String categoryName, String iconUrl, String navigationUrl) { mCategoryName = categoryName; mIconUrl = iconUrl; - mNavigationUrl = navigationUrl; + mNavigationUrl = ExploreSitesBridge.nativeGetCatalogUrl() + navigationUrl; } public String getNavigationUrl() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTileView.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTileView.java index ee2e5764..01b82520 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTileView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTileView.java
@@ -5,28 +5,41 @@ package org.chromium.chrome.browser.explore_sites; import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; +import org.chromium.chrome.browser.util.ViewUtils; +import org.chromium.chrome.browser.widget.RoundedIconGenerator; /** * The View representing a single explore sites category. * Consists of a large image icon over descriptive text. */ -public class ExploreSitesCategoryTileView extends FrameLayout { +public class ExploreSitesCategoryTileView extends LinearLayout { /** The data represented by this tile. */ private ExploreSitesCategoryTile mCategoryData; + private Resources mResources; + private RoundedIconGenerator mIconGenerator; + private TextView mTitleView; private ImageView mIconView; + private int mIconWidthPx; + private int mIconHeightPx; + /** Constructor for inflating from XML. */ public ExploreSitesCategoryTileView(Context context, AttributeSet attrs) { super(context, attrs); + mResources = context.getResources(); } @Override @@ -36,12 +49,29 @@ mIconView = findViewById(R.id.explore_sites_category_tile_icon); } - public void initialize(ExploreSitesCategoryTile category) { + public void initialize(ExploreSitesCategoryTile category, int widthPx, int heightPx) { mCategoryData = category; + mIconWidthPx = widthPx; + mIconHeightPx = heightPx; + mIconGenerator = new RoundedIconGenerator(widthPx, heightPx, + mResources.getDimensionPixelSize(R.dimen.explore_sites_radius), + ApiCompatibilityUtils.getColor( + mResources, R.color.default_favicon_background_color), + mResources.getDimensionPixelSize(R.dimen.headline_size_medium)); + updateIcon(null); mTitleView.setText(mCategoryData.getCategoryName()); } - public void updateIcon(Drawable drawable) { + public void updateIcon(Bitmap bitmap) { + Drawable drawable; + if (bitmap == null) { + drawable = new BitmapDrawable(mResources, + mIconGenerator.generateIconForText(mCategoryData.getCategoryName())); + } else { + drawable = ViewUtils.createRoundedBitmapDrawable( + Bitmap.createScaledBitmap(bitmap, mIconWidthPx, mIconHeightPx, false), + mResources.getDimensionPixelSize(R.dimen.explore_sites_radius)); + } mCategoryData.setIconDrawable(drawable); mIconView.setImageDrawable(drawable); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSection.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSection.java index f9a2b762..3b711c7c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSection.java
@@ -12,25 +12,22 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate; -import org.chromium.chrome.browser.util.ViewUtils; import org.chromium.ui.mojom.WindowOpenDisposition; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; /** * Describes a portion of UI responsible for rendering a group of categories. * It abstracts general tasks related to initializing and fetching data for the UI. */ public class ExploreSitesSection { - private static final int ICON_CORNER_RADIUS = 5; + private static final int MAX_TILES = 3; private Profile mProfile; private SuggestionsNavigationDelegate mNavigationDelegate; private View mExploreSection; private LinearLayout mCategorySection; - private AtomicInteger mCategoryIconFetchesInFlight; public ExploreSitesSection( View view, Profile profile, SuggestionsNavigationDelegate navigationDelegate) { mProfile = profile; @@ -42,19 +39,37 @@ private void initialize() { mCategorySection = mExploreSection.findViewById(R.id.explore_sites_tiles); ExploreSitesBridge.getNtpCategories(mProfile, this::initializeTiles); + + View moreCategoriesButton = mExploreSection.findViewById(R.id.explore_sites_more_button); + moreCategoriesButton.setOnClickListener( + (View v) + -> mNavigationDelegate.navigateToSuggestionUrl( + WindowOpenDisposition.CURRENT_TAB, + ExploreSitesBridge.nativeGetCatalogUrl())); } private void initializeTiles(List<ExploreSitesCategoryTile> tileList) { - if (tileList.isEmpty()) { - return; - } - mCategoryIconFetchesInFlight = new AtomicInteger(tileList.size()); + if (tileList == null) return; + + int parentWidth = mExploreSection.getWidth(); + int tileWidth = (parentWidth + - (mExploreSection.getResources().getDimensionPixelSize( + R.dimen.explore_sites_padding) + * 2)) + / MAX_TILES; + int tileHeight = tileWidth / 3 * 2; + + int tileCount = 0; for (final ExploreSitesCategoryTile tile : tileList) { + // Ensures only 3 tiles are shown. + tileCount++; + if (tileCount > MAX_TILES) break; + final ExploreSitesCategoryTileView tileView = (ExploreSitesCategoryTileView) LayoutInflater.from(mExploreSection.getContext()) .inflate(R.layout.explore_sites_category_tile_view, mCategorySection, false); - tileView.initialize(tile); + tileView.initialize(tile, tileWidth, tileHeight); mCategorySection.addView(tileView); tileView.setOnClickListener( (View v) @@ -66,7 +81,6 @@ } private void onIconRetrieved(ExploreSitesCategoryTileView tileView, Bitmap icon) { - tileView.updateIcon(ViewUtils.createRoundedBitmapDrawable(icon, ICON_CORNER_RADIUS)); - mCategoryIconFetchesInFlight.decrementAndGet(); + tileView.updateIcon(icon); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/SimplifiedNtpFeedbackSource.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/SimplifiedNtpFeedbackSource.java index 1ba45c8..ad702c882 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/SimplifiedNtpFeedbackSource.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/SimplifiedNtpFeedbackSource.java
@@ -5,7 +5,7 @@ package org.chromium.chrome.browser.feedback; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ntp.NewTabPageView; +import org.chromium.chrome.browser.ntp.NewTabPageLayout; import java.util.HashMap; import java.util.Map; @@ -28,7 +28,7 @@ if (!isEnabled) { mMap.put(SIMPLIFIED_NTP_KEY, DISABLED_VALUE); } else { - boolean isAblationEnabled = NewTabPageView.isSimplifiedNtpAblationEnabled(); + boolean isAblationEnabled = NewTabPageLayout.isSimplifiedNtpAblationEnabled(); mMap.put( SIMPLIFIED_NTP_KEY, isAblationEnabled ? ENABLED_ABLATION_VALUE : ENABLED_VALUE); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java index fbd4a3ba..a33c11c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
@@ -26,6 +26,7 @@ import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; import org.chromium.chrome.browser.widget.ControlContainer; import org.chromium.content_public.browser.ContentVideoView; import org.chromium.content_public.common.BrowserControlsState; @@ -314,7 +315,11 @@ @Override public boolean shouldShowNotificationToast() { - return !isOverlayVideoMode(); + // The toast tells user how to leave fullscreen by touching the screen. Since, + // there is no touchscreen when browsing in VR, the toast doesn't have any useful + // information. + return !isOverlayVideoMode() && !VrShellDelegate.isInVr() + && !VrShellDelegate.bootsToVr(); } }; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java index 9355ad5..a1712add 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java
@@ -8,6 +8,7 @@ import android.support.annotation.Nullable; import android.support.graphics.drawable.Animatable2Compat; import android.support.graphics.drawable.AnimatedVectorDrawableCompat; +import android.support.graphics.drawable.VectorDrawableCompat; import android.support.v4.view.ViewCompat; import android.view.View; import android.widget.TextView; @@ -121,7 +122,12 @@ ViewCompat.setAccessibilityLiveRegion(messageView, View.ACCESSIBILITY_LIVE_REGION_POLITE); if (!mInfo.hasAnimation) { - layout.getIcon().setImageResource(mInfo.icon); + if (mInfo.hasVectorDrawable) { + layout.getIcon().setImageDrawable(VectorDrawableCompat.create( + layout.getResources(), mInfo.icon, layout.getContext().getTheme())); + } else { + layout.getIcon().setImageResource(mInfo.icon); + } return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java b/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java index 200ca44..afe4dcdf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java
@@ -307,7 +307,8 @@ return; } - if (VrIntentUtils.isLaunchingIntoVr(activity, activity.getIntent())) { + if (VrIntentUtils.isLaunchingIntoVr(activity, activity.getIntent()) + || VrShellDelegate.isInVr()) { showPromoDialogForVr(dialogCreator, activity); } else { showPromoDialog(dialogCreator);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java new file mode 100644 index 0000000..4aa82382 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java
@@ -0,0 +1,43 @@ +// 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.media; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; + +import org.chromium.chrome.browser.util.IntentUtils; + +/** + * The MediaLauncherActivity handles media-viewing Intents from other apps. It takes the given + * content:// URI from the Intent and properly routes it to a media-viewing CustomTabActivity. + */ +public class MediaLauncherActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent input = IntentUtils.sanitizeIntent(getIntent()); + Uri contentUri = input.getData(); + String mimeType = getContentResolver().getType(contentUri); + + if (!MediaViewerUtils.isMediaMIMEType(mimeType)) { + // With our intent-filter, we should only receive implicit intents with media MIME + // types. If we receive a non-media MIME type, it is likely a malicious explicit intent, + // so we should not proceed. + finish(); + return; + } + + // TODO(https://crbug.com/800880): Determine file:// URI when possible. + Intent intent = MediaViewerUtils.getMediaViewerIntent( + contentUri, contentUri, mimeType, false /* allowExternalAppHandlers */); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(intent); + + finish(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java index 1f3292d..ab4e2a63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java
@@ -30,7 +30,9 @@ */ public class MediaViewerUtils { private static final String DEFAULT_MIME_TYPE = "*/*"; + private static final String MIMETYPE_AUDIO = "audio"; private static final String MIMETYPE_IMAGE = "image"; + private static final String MIMETYPE_VIDEO = "video"; /** * Creates an Intent that allows viewing the given file in an internal media viewer. @@ -139,6 +141,21 @@ if (referrer != null) intent.putExtra(Intent.EXTRA_REFERRER, referrer); } + /** + * Checks whether a given MIME type is a valid media MIME type. + * @param mimeType The MIME type to check. + * @return Whether the MIME type is a valid media MIME type. + */ + public static boolean isMediaMIMEType(String mimeType) { + if (TextUtils.isEmpty(mimeType)) return false; + + String[] pieces = mimeType.toLowerCase(Locale.getDefault()).split("/"); + if (pieces.length != 2) return false; + + return (MIMETYPE_AUDIO.equals(pieces[0]) || MIMETYPE_IMAGE.equals(pieces[0]) + || MIMETYPE_VIDEO.equals(pieces[0])); + } + private static Intent createShareIntent(Uri fileUri, String mimeType) { if (TextUtils.isEmpty(mimeType)) mimeType = DEFAULT_MIME_TYPE;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/ClientRecord.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/ClientRecord.java similarity index 82% rename from chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/ClientRecord.java rename to chrome/android/java/src/org/chromium/chrome/browser/media/router/ClientRecord.java index b3d43cf..11cb8911 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/ClientRecord.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/ClientRecord.java
@@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.media.router.cast; - -import org.chromium.chrome.browser.media.router.MediaRoute; +package org.chromium.chrome.browser.media.router; import java.util.ArrayList; import java.util.List; @@ -53,13 +51,8 @@ */ public List<String> pendingMessages = new ArrayList<String>(); - ClientRecord( - String routeId, - String clientId, - String appId, - String autoJoinPolicy, - String origin, - int tabId) { + public ClientRecord(String routeId, String clientId, String appId, String autoJoinPolicy, + String origin, int tabId) { this.routeId = routeId; this.clientId = clientId; this.appId = appId;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java index d8d26d9..5671823 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java
@@ -11,11 +11,16 @@ import android.support.v7.media.MediaRouter; import android.support.v7.media.MediaRouter.RouteInfo; +import com.google.android.gms.cast.framework.CastSession; +import com.google.android.gms.cast.framework.SessionManagerListener; + import org.chromium.base.Log; import org.chromium.chrome.browser.media.router.ChromeMediaRouter; +import org.chromium.chrome.browser.media.router.ClientRecord; import org.chromium.chrome.browser.media.router.DiscoveryCallback; import org.chromium.chrome.browser.media.router.DiscoveryDelegate; import org.chromium.chrome.browser.media.router.MediaController; +import org.chromium.chrome.browser.media.router.MediaRoute; import org.chromium.chrome.browser.media.router.MediaRouteManager; import org.chromium.chrome.browser.media.router.MediaRouteProvider; import org.chromium.chrome.browser.media.router.MediaSink; @@ -27,13 +32,18 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; /** * A {@link MediaRouteProvider} implementation for Cast devices and applications, using Cast v3 API. */ -public class CafMediaRouteProvider implements MediaRouteProvider, DiscoveryDelegate { +public class CafMediaRouteProvider + implements MediaRouteProvider, DiscoveryDelegate, SessionManagerListener<CastSession> { private static final String TAG = "cr_CafMRP"; + private static final String AUTO_JOIN_PRESENTATION_ID = "auto-join"; + private static final String PRESENTATION_ID_SESSION_ID_PREFIX = "cast-session_"; + protected static final List<MediaSink> NO_SINKS = Collections.emptyList(); protected final MediaRouter mAndroidMediaRouter; @@ -41,6 +51,12 @@ protected final Map<String, DiscoveryCallback> mDiscoveryCallbacks = new HashMap<String, DiscoveryCallback>(); protected Handler mHandler = new Handler(); + protected final Map<String, MediaRoute> mRoutes = new HashMap<String, MediaRoute>(); + private CreateRouteRequestInfo mPendingCreateRouteRequestInfo; + private CastSessionController mSessionController; + + private ClientRecord mLastRemovedRouteRecord; + private final Map<String, ClientRecord> mClientRecords = new HashMap<String, ClientRecord>(); private CafMediaRouteProvider(MediaRouter androidMediaRouter, MediaRouteManager manager) { mAndroidMediaRouter = androidMediaRouter; @@ -51,6 +67,14 @@ return new CafMediaRouteProvider(ChromeMediaRouter.getAndroidMediaRouter(), manager); } + public Map<String, ClientRecord> getClientRecords() { + return mClientRecords; + } + + public Set<String> getClientIds() { + return mClientRecords.keySet(); + } + @Override public boolean supportsSource(String sourceId) { return getSourceFromId(sourceId) != null; @@ -170,23 +194,95 @@ @Override public void createRoute(String sourceId, String sinkId, String presentationId, String origin, int tabId, boolean isIncognito, int nativeRequestId) { - // Not implemented. + Log.d(TAG, "createRoute"); + if (mPendingCreateRouteRequestInfo != null) { + // TODO(zqzhang): do something. + } + if (mAndroidMediaRouter == null) { + mManager.onRouteRequestError("Not supported", nativeRequestId); + return; + } + + MediaSink sink = MediaSink.fromSinkId(sinkId, mAndroidMediaRouter); + if (sink == null) { + mManager.onRouteRequestError("No sink", nativeRequestId); + return; + } + + MediaSource source = CastMediaSource.from(sourceId); + if (source == null) { + mManager.onRouteRequestError("Unsupported presentation URL", nativeRequestId); + return; + } + + mPendingCreateRouteRequestInfo = new CreateRouteRequestInfo( + source, sink, presentationId, origin, tabId, isIncognito, nativeRequestId); + + CastUtils.getCastContext().setReceiverApplicationId(source.getApplicationId()); + + for (MediaRouter.RouteInfo routeInfo : mAndroidMediaRouter.getRoutes()) { + if (routeInfo.getId().equals(sink.getId())) { + // Unselect and then select so that CAF will get notified of the selection. + mAndroidMediaRouter.unselect(0); + routeInfo.select(); + break; + } + } } @Override public void joinRoute( String sourceId, String presentationId, String origin, int tabId, int nativeRequestId) { - // Not implemented. + CastMediaSource source = CastMediaSource.from(sourceId); + if (source == null || source.getClientId() == null) { + mManager.onRouteRequestError("Unsupported presentation URL", nativeRequestId); + return; + } + + if (!hasSession()) { + mManager.onRouteRequestError("No presentation", nativeRequestId); + return; + } + + if (!canJoinExistingSession(presentationId, origin, tabId, source)) { + mManager.onRouteRequestError("No matching route", nativeRequestId); + return; + } + + MediaRoute route = + new MediaRoute(mSessionController.getSink().getId(), sourceId, presentationId); + addRoute(route, origin, tabId); + mManager.onRouteCreated(route.id, route.sinkId, nativeRequestId, this, false); } @Override public void closeRoute(String routeId) { - // Not implemented. + MediaRoute route = mRoutes.get(routeId); + if (route == null) return; + + if (!hasSession()) { + mRoutes.remove(routeId); + mManager.onRouteClosed(routeId); + return; + } + + ClientRecord client = getClientRecordByRouteId(routeId); + if (client != null && mAndroidMediaRouter != null) { + MediaSink sink = + MediaSink.fromSinkId(mSessionController.getSink().getId(), mAndroidMediaRouter); + if (sink != null) { + mSessionController.notifyReceiverAction(routeId, sink, client.clientId, "stop"); + } + } + + mSessionController.endSession(); } @Override public void detachRoute(String routeId) { - // Not implemented. + mRoutes.remove(routeId); + + removeClient(getClientRecordByRouteId(routeId)); } @Override @@ -204,4 +300,200 @@ private MediaSource getSourceFromId(String sourceId) { return CastMediaSource.from(sourceId); } + + /////////////////////////////////////////////// + // SessionManagerListener implementation + /////////////////////////////////////////////// + + @Override + public void onSessionStarting(CastSession session) { + Log.d(TAG, "onSessionStarting"); + mSessionController = new CastSessionController(session, this, + mPendingCreateRouteRequestInfo.sink, mPendingCreateRouteRequestInfo.source); + MediaRoute route = new MediaRoute(mPendingCreateRouteRequestInfo.sink.getId(), + mPendingCreateRouteRequestInfo.source.getSourceId(), + mPendingCreateRouteRequestInfo.presentationId); + addRoute( + route, mPendingCreateRouteRequestInfo.origin, mPendingCreateRouteRequestInfo.tabId); + mManager.onRouteCreated( + route.id, route.sinkId, mPendingCreateRouteRequestInfo.nativeRequestId, this, true); + + String clientId = ((CastMediaSource) mPendingCreateRouteRequestInfo.source).getClientId(); + + if (clientId != null) { + ClientRecord clientRecord = mClientRecords.get(clientId); + if (clientRecord != null) { + mSessionController.notifyReceiverAction(clientRecord.routeId, + mPendingCreateRouteRequestInfo.sink, clientId, "cast"); + } + } + } + + @Override + public void onSessionStarted(CastSession session, String sessionId) { + Log.d(TAG, "onSessionStarted"); + mPendingCreateRouteRequestInfo = null; + mSessionController.onSessionStarted(); + } + + @Override + public void onSessionStartFailed(CastSession session, int error) { + for (String routeId : mRoutes.keySet()) { + mManager.onRouteClosedWithError(routeId, "Launch error"); + } + mRoutes.clear(); + mClientRecords.clear(); + } + + @Override + public void onSessionEnding(CastSession session) { + // Not implemented. + } + + @Override + public void onSessionEnded(CastSession session, int error) { + if (!hasSession()) return; + + if (mClientRecords.isEmpty()) { + for (String routeId : mRoutes.keySet()) mManager.onRouteClosed(routeId); + mRoutes.clear(); + } else { + mLastRemovedRouteRecord = mClientRecords.values().iterator().next(); + for (ClientRecord client : mClientRecords.values()) { + mManager.onRouteClosed(client.routeId); + + mRoutes.remove(client.routeId); + } + mClientRecords.clear(); + } + + detachFromSession(); + if (mAndroidMediaRouter != null) { + mAndroidMediaRouter.selectRoute(mAndroidMediaRouter.getDefaultRoute()); + } + } + + @Override + public void onSessionResuming(CastSession session, String sessionId) {} + + @Override + public void onSessionResumed(CastSession session, boolean wasSuspended) {} + + @Override + public void onSessionResumeFailed(CastSession session, int error) {} + + @Override + public void onSessionSuspended(CastSession session, int reason) {} + + public boolean hasSession() { + return mSessionController != null; + } + + private void detachFromSession() { + mSessionController.onSessionEnded(); + mSessionController = null; + } + + private void addRoute(MediaRoute route, String origin, int tabId) { + mRoutes.put(route.id, route); + + CastMediaSource source = CastMediaSource.from(route.sourceId); + final String clientId = source.getClientId(); + + if (clientId == null || mClientRecords.containsKey(clientId)) return; + + mClientRecords.put(clientId, + new ClientRecord(route.id, clientId, source.getApplicationId(), + source.getAutoJoinPolicy(), origin, tabId)); + } + + private void removeClient(@Nullable ClientRecord client) { + if (client == null) return; + + mLastRemovedRouteRecord = client; + mClientRecords.remove(client.clientId); + } + + @Nullable + private ClientRecord getClientRecordByRouteId(String routeId) { + for (ClientRecord record : mClientRecords.values()) { + if (record.routeId.equals(routeId)) return record; + } + return null; + } + + private static class CreateRouteRequestInfo { + public final MediaSource source; + public final MediaSink sink; + public final String presentationId; + public final String origin; + public final int tabId; + public final boolean isIncognito; + public final int nativeRequestId; + + public CreateRouteRequestInfo(MediaSource source, MediaSink sink, String presentationId, + String origin, int tabId, boolean isIncognito, int nativeRequestId) { + this.source = source; + this.sink = sink; + this.presentationId = presentationId; + this.origin = origin; + this.tabId = tabId; + this.isIncognito = isIncognito; + this.nativeRequestId = nativeRequestId; + } + } + + private boolean canJoinExistingSession( + String presentationId, String origin, int tabId, CastMediaSource source) { + if (AUTO_JOIN_PRESENTATION_ID.equals(presentationId)) { + return canAutoJoin(source, origin, tabId); + } + if (presentationId.startsWith(PRESENTATION_ID_SESSION_ID_PREFIX)) { + String sessionId = presentationId.substring(PRESENTATION_ID_SESSION_ID_PREFIX.length()); + return mSessionController.getSession().getSessionId().equals(sessionId); + } + for (MediaRoute route : mRoutes.values()) { + if (route.presentationId.equals(presentationId)) return true; + } + return false; + } + + private boolean canAutoJoin(CastMediaSource source, String origin, int tabId) { + if (source.getAutoJoinPolicy().equals(CastMediaSource.AUTOJOIN_PAGE_SCOPED)) return false; + + CastMediaSource currentSource = (CastMediaSource) mSessionController.getSource(); + if (!currentSource.getApplicationId().equals(source.getApplicationId())) return false; + + if (mClientRecords.isEmpty() && mLastRemovedRouteRecord != null) { + return isSameOrigin(origin, mLastRemovedRouteRecord.origin) + && tabId == mLastRemovedRouteRecord.tabId; + } + + if (mClientRecords.isEmpty()) return false; + + ClientRecord client = mClientRecords.values().iterator().next(); + + if (source.getAutoJoinPolicy().equals(CastMediaSource.AUTOJOIN_ORIGIN_SCOPED)) { + return isSameOrigin(origin, client.origin); + } + if (source.getAutoJoinPolicy().equals(CastMediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED)) { + return isSameOrigin(origin, client.origin) && tabId == client.tabId; + } + + return false; + } + + /** + * Compares two origins. Empty origin strings correspond to unique origins in + * url::Origin. + * + * @param originA A URL origin. + * @param originB A URL origin. + * @return True if originA and originB represent the same origin, false otherwise. + */ + private static final boolean isSameOrigin(String originA, String originB) { + if (originA == null || originA.isEmpty() || originB == null || originB.isEmpty()) + return false; + return originA.equals(originB); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastMessageHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastMessageHandler.java new file mode 100644 index 0000000..e0e9959 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastMessageHandler.java
@@ -0,0 +1,15 @@ +// 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.media.router.caf; + +/** + * The handler for cast messages. It receives events between the Cast SDK and the page, process and + * dispatch the messages accordingly. The handler talks to the Cast SDK via CastSession, and + * talks to the pages via the media router. + */ +public class CastMessageHandler { + // Sequence number used when no sequence number is required or was initially passed. + static final int INVALID_SEQUENCE_NUMBER = -1; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastOptionsProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastOptionsProvider.java new file mode 100644 index 0000000..b805cc6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastOptionsProvider.java
@@ -0,0 +1,26 @@ +// 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.media.router.caf; + +import android.content.Context; + +import com.google.android.gms.cast.framework.CastOptions; +import com.google.android.gms.cast.framework.OptionsProvider; +import com.google.android.gms.cast.framework.SessionProvider; + +import java.util.List; + +/** {@link OptionsProvider} implementation for Chrome MR. */ +public class CastOptionsProvider implements OptionsProvider { + @Override + public CastOptions getCastOptions(Context context) { + return new CastOptions.Builder().setCastMediaOptions(null).build(); + } + + @Override + public List<SessionProvider> getAdditionalSessionProviders(Context context) { + return null; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastSessionController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastSessionController.java new file mode 100644 index 0000000..feab413 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastSessionController.java
@@ -0,0 +1,75 @@ +// 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.media.router.caf; + +import com.google.android.gms.cast.framework.CastSession; + +import org.chromium.chrome.browser.media.router.ClientRecord; +import org.chromium.chrome.browser.media.router.MediaSink; +import org.chromium.chrome.browser.media.router.MediaSource; + +/** + * A wrapper for {@link CastSession}, extending its functionality for Chrome MediaRouter. + * + * Has the same lifecycle with CastSession. + */ +public class CastSessionController { + private static final String TAG = "CastSessionController"; + + private final CastSession mCastSession; + private final CafMediaRouteProvider mProvider; + private final MediaSink mSink; + private final MediaSource mSource; + + public CastSessionController(CastSession castSession, CafMediaRouteProvider provider, + MediaSink sink, MediaSource source) { + mCastSession = castSession; + mProvider = provider; + mSink = sink; + mSource = source; + } + + public MediaSource getSource() { + return mSource; + } + + public MediaSink getSink() { + return mSink; + } + + public CastSession getSession() { + return mCastSession; + } + + public void onSessionStarted() { + for (ClientRecord client : mProvider.getClientRecords().values()) { + if (!client.isConnected) continue; + + onClientConnected(client.clientId); + } + // TODO(zqzhang): register necessary listeners and attach to RemoteMediaClient. + } + + public void onSessionEnded() { + // Not implemented. + } + + public void endSession() { + CastSession currentCastSession = + CastUtils.getCastContext().getSessionManager().getCurrentCastSession(); + if (currentCastSession == mCastSession) { + CastUtils.getCastContext().getSessionManager().endCurrentSession(true); + } + } + + public void notifyReceiverAction( + String routeId, MediaSink sink, String clientId, String action) { + // Not implemented. + } + + private void onClientConnected(String clientId) { + // Not implemented. + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastUtils.java new file mode 100644 index 0000000..2469741 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CastUtils.java
@@ -0,0 +1,16 @@ +// 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.media.router.caf; + +import com.google.android.gms.cast.framework.CastContext; + +import org.chromium.base.ContextUtils; + +/** Utility methods for Cast. */ +public class CastUtils { + public static CastContext getCastContext() { + return CastContext.getSharedInstance(ContextUtils.getApplicationContext()); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java index ce7871fb..a38be7c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java
@@ -164,6 +164,7 @@ } } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Override public void createRoute(String sourceId, String sinkId, String presentationId, String origin, int tabId, boolean isIncognito, int nativeRequestId) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProvider.java index 64b1bff..ad23c44 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProvider.java
@@ -12,6 +12,7 @@ import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.media.router.ChromeMediaRouter; +import org.chromium.chrome.browser.media.router.ClientRecord; import org.chromium.chrome.browser.media.router.MediaRoute; import org.chromium.chrome.browser.media.router.MediaRouteManager; import org.chromium.chrome.browser.media.router.MediaRouteProvider; @@ -44,18 +45,21 @@ return new CastMediaRouteProvider(ChromeMediaRouter.getAndroidMediaRouter(), manager); } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Override public void onSessionStartFailed() { super.onSessionStartFailed(); mClientRecords.clear(); } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Override public void onSessionStarted(CastSession session) { super.onSessionStarted(session); mMessageHandler.onSessionCreated(mSession); } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Override public void onSessionEnded() { if (mSession == null) return; @@ -102,10 +106,12 @@ return mMessageHandler; } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. public Set<String> getClients() { return mClientRecords.keySet(); } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. public Map<String, ClientRecord> getClientRecords() { return mClientRecords; } @@ -124,6 +130,7 @@ mMessageHandler); } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Override public void onSessionStarting( ChromeCastSessionManager.CastSessionLaunchRequest sessionLaunchRequest) { @@ -146,6 +153,7 @@ } } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Override public void joinRoute(String sourceId, String presentationId, String origin, int tabId, int nativeRequestId) { @@ -170,6 +178,7 @@ mManager.onRouteCreated(route.id, route.sinkId, nativeRequestId, this, false); } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Override public void closeRoute(String routeId) { MediaRoute route = mRoutes.get(routeId); @@ -312,6 +321,7 @@ mMessageHandler = new CastMessageHandler(this); } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. private boolean canAutoJoin(CastMediaSource source, String origin, int tabId) { if (source.getAutoJoinPolicy().equals(CastMediaSource.AUTOJOIN_PAGE_SCOPED)) return false; @@ -338,6 +348,7 @@ return false; } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. private boolean canJoinExistingSession( String presentationId, String origin, int tabId, CastMediaSource source) { if (AUTO_JOIN_PRESENTATION_ID.equals(presentationId)) { @@ -353,6 +364,7 @@ return false; } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @Nullable private ClientRecord getClientRecordByRouteId(String routeId) { for (ClientRecord record : mClientRecords.values()) { @@ -361,6 +373,7 @@ return null; } + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. @VisibleForTesting void addRoute(MediaRoute route, String origin, int tabId) { mRoutes.put(route.id, route); @@ -425,6 +438,7 @@ * @param originB A URL origin. * @return True if originA and originB represent the same origin, false otherwise. */ + // Migrated to CafMediaRouteProvider. See https://crbug.com/711860. private static final boolean isSameOrigin(String originA, String originB) { if (originA == null || originA.isEmpty() || originB == null || originB.isEmpty()) return false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandler.java index c485f6c..77c76fe4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandler.java
@@ -14,6 +14,7 @@ import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.media.router.ClientRecord; import java.util.ArrayDeque; import java.util.Arrays;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CreateRouteRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CreateRouteRequest.java index 9e485967..c391f46 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CreateRouteRequest.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CreateRouteRequest.java
@@ -31,6 +31,7 @@ * Since there're numerous asynchronous calls involved in getting the application to launch * the class is implemented as a state machine. */ +// Migrated to CafMediaRouteProvider. See https://crbug.com/711860. public class CreateRouteRequest implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Cast.ApplicationConnectionResult>,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ForwardingListObservable.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ForwardingListObservable.java new file mode 100644 index 0000000..fdb11f7d0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ForwardingListObservable.java
@@ -0,0 +1,32 @@ +// 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.modelutil; + +import android.support.annotation.Nullable; + +import org.chromium.chrome.browser.modelutil.ListObservable.ListObserver; + +/** + * Helper class for implementing a {@link ListObserver} that just forwards to its own observers. + * @param <P> The payload type for partial updates, or {@link Void} if the class doesn't support + * partial updates. + * TODO(bauerb): Remove this class if it turns out we can shortcut notifications + */ +public class ForwardingListObservable<P> extends ListObservable<P> implements ListObserver<P> { + @Override + public void onItemRangeInserted(ListObservable source, int index, int count) { + notifyItemRangeInserted(index, count); + } + + @Override + public void onItemRangeRemoved(ListObservable source, int index, int count) { + notifyItemRangeRemoved(index, count); + } + + @Override + public void onItemRangeChanged( + ListObservable<P> source, int index, int count, @Nullable P payload) { + notifyItemRangeChanged(index, count, payload); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListModelChangeProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListModelChangeProcessor.java index 2453081..a8d5c200 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListModelChangeProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListModelChangeProcessor.java
@@ -13,7 +13,7 @@ * Internally uses a view binder to bind model properties to a view like a TabLayout. * * Do not use this class to fill {@link RecyclerView}s - consider using the - * {@link RecyclerViewModelChangeProcessor} which was specifically designed for that use case! + * {@link SimpleRecyclerViewMcp} which was specifically designed for that use case! * * @param <M> The {@link ListObservable} model. * @param <V> The view object that is changing.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListObservable.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListObservable.java index 0938df6e9..7cff9f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListObservable.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/ListObservable.java
@@ -11,6 +11,11 @@ /** * A base class for models maintaining a list of items. Note that ListObservable models do not need * to be implemented as a list. Internally they may use any structure to organize their items. + * Note also that this class on purpose does not expose an item type (it only exposes a + * <i>payload</i> type for partial change notifications), nor does it give access to the list + * contents. This is because the list might not be homogeneous -- it could represent items of vastly + * different types that don't share a common base class. Use the {@link SimpleListObservable} + * subclass for homogeneous lists. * @param <P> The parameter type for the payload for partial updates. Use {@link Void} for * implementations that don't support partial updates. */ @@ -59,9 +64,6 @@ private final ObserverList<ListObserver<P>> mObservers = new ObserverList<>(); - /** @return The total number of items held by the model. */ - public abstract int getItemCount(); - /** * @param observer An observer to be notified of changes to the model. */ @@ -104,6 +106,7 @@ * @param count The number of added items. */ protected void notifyItemRangeInserted(int index, int count) { + assert count > 0; // No spurious notifications for (ListObserver observer : mObservers) { observer.onItemRangeInserted(this, index, count); } @@ -117,6 +120,7 @@ * @param count The number of removed items. */ protected void notifyItemRangeRemoved(int index, int count) { + assert count > 0; // No spurious notifications for (ListObserver observer : mObservers) { observer.onItemRangeRemoved(this, index, count); } @@ -131,6 +135,7 @@ * @param payload Optional parameter, use {@code null} to identify a "full" update. */ protected void notifyItemRangeChanged(int index, int count, @Nullable P payload) { + assert count > 0; // No spurious notifications for (ListObserver<P> observer : mObservers) { observer.onItemRangeChanged(this, index, count, payload); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/RecyclerViewAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/RecyclerViewAdapter.java index 134e55c..e0462fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/RecyclerViewAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/RecyclerViewAdapter.java
@@ -4,86 +4,135 @@ package org.chromium.chrome.browser.modelutil; +import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.ViewGroup; +import org.chromium.chrome.browser.modelutil.ListObservable.ListObserver; + +import java.util.List; + /** - * An adapter that uses a {@link ViewBinder} to bind items in a {@link ListObservable} model to - * {@link ViewHolder}s. + * A base {@link RecyclerView} adapter that delegates most of its logic. This allows compositing + * different delegates together to support different UI features living in the same + * {@link RecyclerView}. * - * @param <E> The type of the {@link ListObservable} model. * @param <VH> The {@link ViewHolder} type for the {@link RecyclerView}. + * @param <P> The payload type for partial updates, or {@link Void} if the adapter does not support + * partial updates. */ -public class RecyclerViewAdapter<E extends ListObservable, VH extends ViewHolder> - extends RecyclerView.Adapter<VH> { +public class RecyclerViewAdapter<VH extends ViewHolder, P> + extends RecyclerView.Adapter<VH> implements ListObserver<P> { /** - * A view binder used to bind items in the {@link ListObservable} model to {@link ViewHolder}s. - * - * @param <E> The type of the {@link ListObservable} model. + * Delegate interface for the adapter. + * @param <VH> The {@link ViewHolder} type for the {@link RecyclerView}. + * @param <P> The payload type for partial updates, or {@link Void} if the adapter does not + * support partial updates. + */ + public interface Delegate<VH, P> { + /** + * @return The number of items represented by the adapter. + * @see RecyclerView.Adapter#getItemCount + */ + int getItemCount(); + + /** + * @param position The adapter position for which to return the view type. + * @return The view type for the item at the given {@code position} in the adapter. + * @see RecyclerView.Adapter#getItemViewType + */ + int getItemViewType(int position); + + /** + * Bind a given {@code viewHolder} to the data represented by the item at the given + * {@code position} in the adapter. If {@code payload} is non-null, performs a "partial" + * update of only the property represented by {@code payload}. + * @param viewHolder A view holder to bind. + * @param position The adapter position of the item to bind to the {@code viewHolder}. + * @param payload The payload for partial updates, or null to perform a full bind. + * @see RecyclerView.Adapter#onBindViewHolder + */ + void onBindViewHolder(VH viewHolder, int position, @Nullable P payload); + } + + /** + * Factory for creating new {@link ViewHolder}s. * @param <VH> The {@link ViewHolder} type for the {@link RecyclerView}. */ - public interface ViewBinder<E, VH> { + public interface ViewHolderFactory<VH> { /** * Called when the {@link RecyclerView} needs a new {@link ViewHolder} of the given * {@code viewType} to represent an item. * - * @param parent The {@link ViewGroup} into which the new {@link View} will be added after + * @param parent The {@link ViewGroup} into which the new view will be added after * it's bound to an adapter position. - * @param viewType The view type of the new {@link View}. - * @return A new {@link ViewHolder} that holds a {@link View} of the given view type. + * @param viewType The view type of the new view. + * @return A new {@link ViewHolder} that holds a view of the given view type. + * @see RecyclerView.Adapter#createViewHolder */ - VH onCreateViewHolder(ViewGroup parent, int viewType); - - /** - * Called to display the item at the specified {@code position} in the provided - * {@code holder}. - * - * @param model The {@link ListObservable} model used to retrieve the item at - * {@code position}. - * @param holder The {@link ViewHolder} which should be updated to represent {@code item}. - * @param position The position of the item to be bound. - */ - void onBindViewHolder(E model, VH holder, int position); - } - - protected final E mModel; - - private ViewBinder<E, VH> mViewBinder; - - /** - * Construct a new {@link RecyclerViewAdapter}. - * @param model The {@link ListObservable} model used to retrieve items to display in the - * {@link RecyclerView}. - * @param viewBinder The {@link ViewBinder} binding this adapter to the view holder. - */ - public RecyclerViewAdapter(E model, RecyclerViewAdapter.ViewBinder<E, VH> viewBinder) { - mModel = model; - mViewBinder = viewBinder; + VH createViewHolder(ViewGroup parent, int viewType); } /** - * Set the {@link ViewBinder} to use with this adapter. - * - * @param viewBinder The {@link ViewBinder} used to bind items in the {@link ListObservable} - * model to {@link ViewHolder}s. + * Creates a new adapter for the given {@code delegate} and {@link ViewHolder} {@code factory}. + * @param delegate The delegate for this adapter. + * @param factory The {@link ViewHolder} factory for this adapter. */ - public void setViewBinder(ViewBinder<E, VH> viewBinder) { - mViewBinder = viewBinder; + public RecyclerViewAdapter(Delegate<VH, P> delegate, ViewHolderFactory<VH> factory) { + mDelegate = delegate; + mFactory = factory; } + private final Delegate<VH, P> mDelegate; + private final ViewHolderFactory<VH> mFactory; + @Override public int getItemCount() { - return mModel.getItemCount(); + return mDelegate.getItemCount(); + } + + @Override + public int getItemViewType(int position) { + return mDelegate.getItemViewType(position); } @Override public VH onCreateViewHolder(ViewGroup parent, int viewType) { - return mViewBinder.onCreateViewHolder(parent, viewType); + return mFactory.createViewHolder(parent, viewType); } @Override - public void onBindViewHolder(VH holder, int position) { - mViewBinder.onBindViewHolder(mModel, holder, position); + public void onBindViewHolder(VH vh, int position) { + mDelegate.onBindViewHolder(vh, position, null); + } + + @SuppressWarnings("unchecked") + @Override + public void onBindViewHolder(VH holder, int position, List<Object> payloads) { + if (payloads.isEmpty()) { + onBindViewHolder(holder, position); + return; + } + + for (Object p : payloads) { + mDelegate.onBindViewHolder(holder, position, (P) p); + } + } + + @Override + public void onItemRangeInserted(ListObservable source, int index, int count) { + notifyItemRangeInserted(index, count); + } + + @Override + public void onItemRangeRemoved(ListObservable source, int index, int count) { + notifyItemRangeRemoved(index, count); + } + + @Override + public void onItemRangeChanged( + ListObservable<P> source, int index, int count, @Nullable P payload) { + notifyItemRangeChanged(index, count, payload); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/RecyclerViewModelChangeProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/RecyclerViewModelChangeProcessor.java deleted file mode 100644 index 05f168af..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/RecyclerViewModelChangeProcessor.java +++ /dev/null
@@ -1,52 +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. - -package org.chromium.chrome.browser.modelutil; - -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.RecyclerView.ViewHolder; - -import org.chromium.chrome.browser.modelutil.ListObservable.ListObserver; - -/** - * A model change processor for use with a {@link RecyclerView}. The - * {@link RecyclerViewModelChangeProcessor} should be registered as an observer of a - * {@link ListObservable} model. Notifies the associated {@link RecyclerViewAdapter<VH>} of - * changes to the model. - * - * @param <E> The type of the {@link ListObservable} model. - * @param <VH> The {@link ViewHolder} type for the RecyclerView. - * @param <P> The payload type for partial updates. Use {@link Void} for models that don't support - * partial updates. - */ -public class RecyclerViewModelChangeProcessor<E extends ListObservable, VH extends ViewHolder, P> - implements ListObserver<P> { - private RecyclerViewAdapter<E, VH> mAdapter; - - /** - * Constructs a new {@link RecyclerViewModelChangeProcessor}. - * @param adapter The {@link RecyclerViewAdapter} to be notified of changes to a - * {@link ListObservable} model. - */ - public RecyclerViewModelChangeProcessor(RecyclerViewAdapter<E, VH> adapter) { - mAdapter = adapter; - } - - @Override - public void onItemRangeInserted(ListObservable source, int index, int count) { - mAdapter.notifyItemRangeInserted(index, count); - } - - @Override - public void onItemRangeRemoved(ListObservable source, int index, int count) { - mAdapter.notifyItemRangeRemoved(index, count); - } - - @Override - public void onItemRangeChanged( - ListObservable<P> source, int index, int count, @Nullable P payload) { - mAdapter.notifyItemRangeChanged(index, count, payload); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleList.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleList.java new file mode 100644 index 0000000..090c6f0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleList.java
@@ -0,0 +1,53 @@ +// 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.modelutil; + +import android.support.annotation.NonNull; + +import java.util.AbstractList; +import java.util.Iterator; +import java.util.List; + +/** + * A minimal subset of the functionality of {@link List}, to allow easier implementation in + * classes that already extend another class and therefore can't inherit from {@link AbstractList}. + * @param <T> The type of list item. + */ +public interface SimpleList<T> extends Iterable<T> { + /** + * @return The size of the list. + * @see List#size + */ + int size(); + + /** + * Returns the item at the given position. + * @param index The position to get the item from. + * @return Returns the found item. + * @see List#get + */ + T get(int index); + + /** + * @return An iterator over elements in the list. The iterator is not safe for concurrent + * modifications and does not check whether the underlying list is being modified. + */ + @Override + @NonNull + default Iterator<T> iterator() { + return new Iterator<T>() { + private int mI = 0; + + @Override + public boolean hasNext() { + return mI < size(); + } + + @Override + public T next() { + return get(mI++); + } + }; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleListObservable.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleListObservable.java index b573015..c65f2ae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleListObservable.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleListObservable.java
@@ -13,7 +13,7 @@ * It allows models to compose different ListObservables. * @param <T> The object type that this class manages in a list. */ -public class SimpleListObservable<T> extends ListObservable<Void> { +public class SimpleListObservable<T> extends ListObservable<Void> implements SimpleList<T> { private final List<T> mItems = new ArrayList<>(); /** @@ -21,12 +21,13 @@ * @param index The position to get the item from. * @return Returns the found item. */ + @Override public T get(int index) { return mItems.get(index); } @Override - public int getItemCount() { + public int size() { return mItems.size(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleRecyclerViewMcp.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleRecyclerViewMcp.java new file mode 100644 index 0000000..9972912 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/SimpleRecyclerViewMcp.java
@@ -0,0 +1,85 @@ +// 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.modelutil; + +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; + +/** + * A model change processor (MCP), i.e. an implementation of {@link RecyclerViewAdapter.Delegate}, + * which represents a homogeneous {@link SimpleList} of items that are independent of each other. + * It is intended primarily (but not exclusively) for use in a {@link RecyclerView}. + * @param <T> The type of items in the list. + * @param <VH> The view holder type that shows items. + * @param <P> The payload type for partial updates, or {@link Void} if the object doesn't + * support partial updates. + */ +public class SimpleRecyclerViewMcp<T, VH, P> + extends ForwardingListObservable<P> implements RecyclerViewAdapter.Delegate<VH, P> { + /** + * A view binder used to bind items in the {@link ListObservable} model to view holders. + * + * @param <T> The item type in the {@link SimpleList} model. + * @param <VH> The view holder type that shows items. + * @param <P> The payload type for partial updates, or {@link Void} if the object doesn't + * support partial updates. + */ + public interface ViewBinder<T, VH, P> { + /** + * Called to display the specified {@code item} in the provided {@code holder}. + * @param holder The view holder which should be updated to represent the {@code item}. + * @param item The item in the list. + * @param payload The payload for partial updates. + */ + void onBindViewHolder(VH holder, T item, @Nullable P payload); + } + + /** + * A functional interface to return the view type for an item. + * @param <T> The item type. + */ + public interface ItemViewTypeCallback<T> { + /** + * @param item The item for which to return the view type. + * @return The view type for the given {@code item}. + * @see RecyclerView.Adapter#getItemViewType + */ + int getItemViewType(T item); + } + + private final SimpleList<T> mModel; + private final ItemViewTypeCallback<T> mItemViewTypeCallback; + private final ViewBinder<T, VH, P> mViewBinder; + + /** + * @param model The {@link SimpleList} model used to retrieve items to display. + * @param itemViewTypeCallback The callback to return the view type for an item, or null to use + * the default view type. + * @param viewBinder The {@link ViewBinder} binding this adapter to the view holder. + */ + public SimpleRecyclerViewMcp(SimpleList<T> model, + @Nullable ItemViewTypeCallback<T> itemViewTypeCallback, + ViewBinder<T, VH, P> viewBinder) { + mModel = model; + mItemViewTypeCallback = itemViewTypeCallback; + mViewBinder = viewBinder; + } + + @Override + public int getItemCount() { + return mModel.size(); + } + + @Override + public int getItemViewType(int position) { + if (mItemViewTypeCallback == null) return 0; + + return mItemViewTypeCallback.getItemViewType(mModel.get(position)); + } + + @Override + public void onBindViewHolder(VH holder, int position, @Nullable P payload) { + mViewBinder.onBindViewHolder(holder, mModel.get(position), payload); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index 35948bc..8c53993 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -4,10 +4,12 @@ package org.chromium.chrome.browser.ntp; +import android.content.Context; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.support.annotation.Nullable; import android.support.v4.view.ViewCompat; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; @@ -73,18 +75,22 @@ // Key for the scroll position data that may be stored in a navigation entry. private static final String NAVIGATION_ENTRY_SCROLL_POSITION_KEY = "NewTabPageScrollPosition"; - private final Tab mTab; + protected final Tab mTab; private final String mTitle; private final int mBackgroundColor; private final int mThemeColor; - private final NewTabPageView mNewTabPageView; - private final NewTabPageManagerImpl mNewTabPageManager; - private final TileGroup.Delegate mTileGroupDelegate; + protected final NewTabPageManagerImpl mNewTabPageManager; + protected final TileGroup.Delegate mTileGroupDelegate; private final boolean mIsTablet; + /** + * The {@link NewTabPageView} shown in this NewTabPageLayout. This may be null in sub-classes. + */ + private @Nullable NewTabPageView mNewTabPageView; + protected NewTabPageLayout mNewTabPageLayout; private TabObserver mTabObserver; - private boolean mSearchProviderHasLogo; + protected boolean mSearchProviderHasLogo; private FakeboxDelegate mFakeboxDelegate; private LocationBarVoiceRecognitionHandler mVoiceRecognitionHandler; @@ -166,7 +172,7 @@ } } - private class NewTabPageManagerImpl + protected class NewTabPageManagerImpl extends SuggestionsUiDelegateImpl implements NewTabPageManager { public NewTabPageManagerImpl(SuggestionsSource suggestionsSource, SuggestionsEventReporter eventReporter, @@ -180,7 +186,7 @@ @Override public boolean isLocationBarShownInNTP() { if (mIsDestroyed) return false; - return isInSingleUrlBarMode() && !mNewTabPageView.urlFocusAnimationsDisabled(); + return isInSingleUrlBarMode() && !mNewTabPageLayout.urlFocusAnimationsDisabled(); } @Override @@ -220,7 +226,7 @@ // If not visible when loading completes, wait until onShown is received. if (!mTab.isHidden()) recordNTPShown(); if (mTab.getUrl().contains(UrlConstants.CONTENT_SUGGESTIONS_SUFFIX)) { - mNewTabPageView.scrollToSuggestions(); + scrollToSuggestions(); } } } @@ -240,7 +246,7 @@ if (mIsDestroyed) return; super.onLoadingComplete(tiles); - mNewTabPageView.onTilesLoaded(); + mNewTabPageLayout.onTilesLoaded(); } @Override @@ -298,7 +304,7 @@ // Showing the NTP is only meaningful when the page has been loaded already. if (mIsLoaded) recordNTPShown(); - mNewTabPageView.getTileGroup().onSwitchToForeground(/* trackLoadTask = */ false); + mNewTabPageLayout.getTileGroup().onSwitchToForeground(/* trackLoadTask = */ false); } @Override @@ -308,36 +314,13 @@ @Override public void onPageLoadStarted(Tab tab, String url) { - int scrollPosition = mNewTabPageView.getScrollPosition(); - if (scrollPosition == RecyclerView.NO_POSITION) return; - - if (mTab.getWebContents() == null) return; - - NavigationController controller = mTab.getWebContents().getNavigationController(); - int index = controller.getLastCommittedEntryIndex(); - NavigationEntry entry = controller.getEntryAtIndex(index); - if (entry == null) return; - - // At least under test conditions this method may be called initially for the load - // of the NTP itself, at which point the last committed entry is not for the NTP - // yet. This method will then be called a second time when the user navigates away, - // at which point the last committed entry is for the NTP. The extra data must only - // be set in the latter case. - if (!isNTPUrl(entry.getUrl())) return; - - controller.setEntryExtraData(index, NAVIGATION_ENTRY_SCROLL_POSITION_KEY, - Integer.toString(scrollPosition)); + restoreLastScrollPosition(); } }; mTab.addObserver(mTabObserver); updateSearchProviderHasLogo(); - LayoutInflater inflater = LayoutInflater.from(activity); - mNewTabPageView = (NewTabPageView) inflater.inflate(R.layout.new_tab_page_view, null); - mNewTabPageView.initialize(mNewTabPageManager, mTab, mTileGroupDelegate, - mSearchProviderHasLogo, - TemplateUrlService.getInstance().isDefaultSearchEngineGoogle(), - getScrollPositionFromNavigationEntry()); + initializeMainView(activity); eventReporter.onSurfaceOpened(); @@ -350,18 +333,70 @@ TraceEvent.end(TAG); } + /** + * Create and initialize the main view contained in this NewTabPage. + * @param context The context used to inflate the view. + */ + protected void initializeMainView(Context context) { + LayoutInflater inflater = LayoutInflater.from(context); + mNewTabPageView = (NewTabPageView) inflater.inflate(R.layout.new_tab_page_view, null); + mNewTabPageLayout = mNewTabPageView.getNewTabPageLayout(); + + mNewTabPageView.initialize(mNewTabPageManager, mTab, mTileGroupDelegate, + mSearchProviderHasLogo, + TemplateUrlService.getInstance().isDefaultSearchEngineGoogle(), + getScrollPositionFromNavigationEntry()); + } + + /** + * Restore the last scroll position stored in the navigation entry (if set). + */ + protected void restoreLastScrollPosition() { + int scrollPosition = mNewTabPageView.getScrollPosition(); + if (scrollPosition == RecyclerView.NO_POSITION) return; + + if (mTab.getWebContents() == null) return; + + NavigationController controller = mTab.getWebContents().getNavigationController(); + int index = controller.getLastCommittedEntryIndex(); + NavigationEntry entry = controller.getEntryAtIndex(index); + if (entry == null) return; + + // At least under test conditions this method may be called initially for the load of the + // NTP itself, at which point the last committed entry is not for the NTP yet. This method + // will then be called a second time when the user navigates away, at which point the last + // committed entry is for the NTP. The extra data must only be set in the latter case. + if (!isNTPUrl(entry.getUrl())) return; + + controller.setEntryExtraData( + index, NAVIGATION_ENTRY_SCROLL_POSITION_KEY, Integer.toString(scrollPosition)); + } + + /** + * Scroll to the list of suggested articles. + */ + protected void scrollToSuggestions() { + mNewTabPageView.scrollToSuggestions(); + } + /** @return The view container for the new tab page. */ @VisibleForTesting public NewTabPageView getNewTabPageView() { return mNewTabPageView; } + /** @return The view container for the new tab layout. */ + @VisibleForTesting + public NewTabPageLayout getNewTabPageLayout() { + return mNewTabPageLayout; + } + /** * Updates whether the NewTabPage should animate on URL focus changes. * @param disable Whether to disable the animations. */ public void setUrlFocusAnimationsDisabled(boolean disable) { - mNewTabPageView.setUrlFocusAnimationsDisabled(disable); + mNewTabPageLayout.setUrlFocusAnimationsDisabled(disable); } private boolean isInSingleUrlBarMode() { @@ -374,9 +409,19 @@ private void onSearchEngineUpdated() { updateSearchProviderHasLogo(); - mNewTabPageView.setSearchProviderInfo(mSearchProviderHasLogo, + setSearchProviderInfoOnView(mSearchProviderHasLogo, TemplateUrlService.getInstance().isDefaultSearchEngineGoogle()); - mNewTabPageView.loadSearchProviderLogo(); + mNewTabPageLayout.loadSearchProviderLogo(); + } + + /** + * Set the search provider info on the main child view, so that it can change layouts if + * needed. + * @param hasLogo Whether the search provider has a logo. + * @param isGoogle Whether the search provider is Google. + */ + protected void setSearchProviderInfoOnView(boolean hasLogo, boolean isGoogle) { + mNewTabPageView.setSearchProviderInfo(hasLogo, isGoogle); } /** @@ -387,7 +432,7 @@ * @param percent The percentage of the URL bar focus animation. */ public void setUrlFocusChangeAnimationPercent(float percent) { - mNewTabPageView.setUrlFocusChangeAnimationPercent(percent); + mNewTabPageLayout.setUrlFocusChangeAnimationPercent(percent); } /** @@ -407,7 +452,7 @@ * @param alpha opacity (alpha) value to use. */ public void setSearchBoxAlpha(float alpha) { - mNewTabPageView.setSearchBoxAlpha(alpha); + mNewTabPageLayout.setSearchBoxAlpha(alpha); } /** @@ -416,7 +461,7 @@ * @param alpha opacity (alpha) value to use. */ public void setSearchProviderLogoAlpha(float alpha) { - mNewTabPageView.setSearchProviderLogoAlpha(alpha); + mNewTabPageLayout.setSearchProviderLogoAlpha(alpha); } /** @@ -425,7 +470,7 @@ * @param drawable The search box background. */ public void setSearchBoxBackground(Drawable drawable) { - mNewTabPageView.setSearchBoxBackground(drawable); + mNewTabPageLayout.setSearchBoxBackground(drawable); } /** @@ -440,7 +485,7 @@ * @param listener The listener to be notified on changes. */ public void setSearchBoxScrollListener(OnSearchBoxScrollListener listener) { - mNewTabPageView.setSearchBoxScrollListener(listener); + mNewTabPageLayout.setSearchBoxScrollListener(listener); } /** @@ -453,7 +498,7 @@ // The toolbar can't get the reference to the native page until its initialization is // finished, so we can't cache it here and transfer it to the view later. We pull that // state from the location bar when we get a reference to it as a workaround. - mNewTabPageView.setUrlFocusChangeAnimationPercent( + mNewTabPageLayout.setUrlFocusChangeAnimationPercent( fakeboxDelegate.isUrlBarFocused() ? 1f : 0f); } } @@ -465,7 +510,7 @@ LocationBarVoiceRecognitionHandler voiceRecognitionHandler) { mVoiceRecognitionHandler = voiceRecognitionHandler; if (mVoiceRecognitionHandler != null) { - mNewTabPageView.updateVoiceSearchButtonVisibility(); + mNewTabPageLayout.updateVoiceSearchButtonVisibility(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java index 7fa20b52f..b30b4e9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -6,26 +6,67 @@ import android.content.Context; import android.content.res.Resources; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.graphics.drawable.RippleDrawable; import android.os.Build; import android.support.annotation.Nullable; +import android.support.v4.view.MarginLayoutParamsCompat; +import android.text.Editable; +import android.text.TextWatcher; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewStub; +import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.TextView; +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.TraceEvent; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider; +import org.chromium.chrome.browser.explore_sites.ExploreSitesSection; +import org.chromium.chrome.browser.locale.LocaleManager; +import org.chromium.chrome.browser.ntp.NewTabPage.OnSearchBoxScrollListener; +import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; +import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.SiteSection; +import org.chromium.chrome.browser.suggestions.SiteSectionViewHolder; +import org.chromium.chrome.browser.suggestions.SuggestionsConfig; +import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory; +import org.chromium.chrome.browser.suggestions.Tile; import org.chromium.chrome.browser.suggestions.TileGridLayout; +import org.chromium.chrome.browser.suggestions.TileGroup; +import org.chromium.chrome.browser.suggestions.TileRenderer; +import org.chromium.chrome.browser.suggestions.TileView; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.util.MathUtils; +import org.chromium.chrome.browser.util.ViewUtils; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; +import org.chromium.chrome.browser.widget.displaystyle.UiConfig; +import org.chromium.ui.base.DeviceFormFactor; /** * Layout for the new tab page. This positions the page elements in the correct vertical positions. * There are no separate phone and tablet UIs; this layout adapts based on the available space. */ -public class NewTabPageLayout extends LinearLayout { +public class NewTabPageLayout + extends LinearLayout implements TileGroup.Observer, VrShellDelegate.VrModeObserver { + private static final String TAG = "NewTabPageLayout"; + + /** + * Parameter for the simplified NTP ablation experiment arm which removes the additional + * suggestions sections without replacing them with shortcut buttons. + */ + private static final String PARAM_SIMPLIFIED_NTP_ABLATION = "simplified_ntp_ablation"; + private final int mTileGridLayoutBleed; private final int mSearchboxShadowWidth; @@ -34,8 +75,97 @@ private LogoView mSearchProviderLogoView; private View mSearchBoxView; private ViewGroup mSiteSectionView; + private SiteSectionViewHolder mSiteSectionViewHolder; + private ImageView mVoiceSearchButton; + private View mTileGridPlaceholder; + private View mNoSearchLogoSpacer; + private ViewGroup mShortcutsView; + @Nullable private View mExploreSectionView; // View is null if explore flag is disabled. + @Nullable + private ExploreSitesSection mExploreSection; // Null when explore sites disabled. + + private OnSearchBoxScrollListener mSearchBoxScrollListener; + + private NewTabPageManager mManager; + private Tab mTab; + private LogoDelegateImpl mLogoDelegate; + private TileGroup mTileGroup; + private UiConfig mUiConfig; + + /** + * Whether the tiles shown in the layout have finished loading. + * With {@link #mHasShownView}, it's one of the 2 flags used to track initialisation progress. + */ + private boolean mTilesLoaded; + + /** + * Whether the view has been shown at least once. + * With {@link #mTilesLoaded}, it's one of the 2 flags used to track initialization progress. + */ + private boolean mHasShownView; + + private boolean mSearchProviderHasLogo = true; + private boolean mSearchProviderIsGoogle; + + private boolean mInitialized; + + private float mUrlFocusChangePercent; + private boolean mDisableUrlFocusChangeAnimations; + private boolean mIsViewMoving; + + /** Flag used to request some layout changes after the next layout pass is completed. */ + private boolean mTileCountChanged; + private boolean mSnapshotTileGridChanged; + + /** + * Vertical inset to add to the top and bottom of the search box bounds. May be 0 if no inset + * should be applied. See {@link Rect#inset(int, int)}. + */ + private int mSearchBoxBoundsVerticalInset; + + private ScrollDelegate mScrollDelegate; + + /** + * @return Whether the simplified NTP ablation experiment arm which removes the additional + * suggestions sections without replacing them with shortcut buttons is enabled. + */ + public static boolean isSimplifiedNtpAblationEnabled() { + return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( + ChromeFeatureList.SIMPLIFIED_NTP, PARAM_SIMPLIFIED_NTP_ABLATION, false); + } + + /** + * A delegate used to obtain information about scroll state and perform various scroll + * functions. + */ + public interface ScrollDelegate { + /** + * @return Whether the scroll view is initialized. If false, the other delegate methods + * may not be valid. + */ + boolean isScrollViewInitialized(); + + /** + * Checks whether the child at a given position is visible. + * @param position The position of the child to check. + * @return True if the child is at least partially visible. + */ + boolean isChildVisibleAtPosition(int position); + + /** + * @return The vertical scroll offset of the view containing this layout in pixels. Not + * valid until scroll view is initialized. + */ + int getVerticalScrollOffset(); + + /** + * Snaps the scroll point of the scroll view to prevent the user from scrolling to midway + * through a transition. + */ + void snapScroll(); + } /** * Constructor for inflating from XML. @@ -60,7 +190,233 @@ } } - public void insertSiteSectionView() { + /** + * Initializes the NewTabPageLayout. This must be called immediately after inflation, before + * this object is used in any other way. + * + * @param manager NewTabPageManager used to perform various actions when the user interacts + * with the page. + * @param tab The Tab that is showing this new tab page. + * @param searchProviderHasLogo Whether the search provider has a logo. + * @param searchProviderIsGoogle Whether the search provider is Google. + * @param scrollDelegate The delegate used to obtain information about scroll state. + * @param contextMenuManager The manager for long-press context menus. + * @param uiConfig UiConfig that provides display information about this view. + */ + public void initialize(NewTabPageManager manager, Tab tab, TileGroup.Delegate tileGroupDelegate, + boolean searchProviderHasLogo, boolean searchProviderIsGoogle, + ScrollDelegate scrollDelegate, ContextMenuManager contextMenuManager, + UiConfig uiConfig) { + TraceEvent.begin(TAG + ".initialize()"); + mScrollDelegate = scrollDelegate; + mTab = tab; + mManager = manager; + mUiConfig = uiConfig; + + Profile profile = Profile.getLastUsedProfile(); + OfflinePageBridge offlinePageBridge = + SuggestionsDependencyFactory.getInstance().getOfflinePageBridge(profile); + TileRenderer tileRenderer = + new TileRenderer(mTab.getActivity(), SuggestionsConfig.getTileStyle(mUiConfig), + getTileTitleLines(), mManager.getImageFetcher()); + mTileGroup = new TileGroup(tileRenderer, mManager, contextMenuManager, tileGroupDelegate, + /* observer = */ this, offlinePageBridge); + + mSiteSectionViewHolder = SiteSection.createViewHolder(getSiteSectionView(), mUiConfig); + mSiteSectionViewHolder.bindDataSource(mTileGroup, tileRenderer); + + if (ChromeFeatureList.isEnabled(ChromeFeatureList.EXPLORE_SITES)) { + mExploreSection = new ExploreSitesSection( + mExploreSectionView, profile, mManager.getNavigationDelegate()); + } + + mSearchProviderLogoView = findViewById(R.id.search_provider_logo); + mLogoDelegate = new LogoDelegateImpl( + mManager.getNavigationDelegate(), mSearchProviderLogoView, profile); + + mSearchBoxView = findViewById(R.id.search_box); + if (SuggestionsConfig.useModernLayout()) { + mSearchBoxView.setBackgroundResource(R.drawable.ntp_search_box); + mSearchBoxView.getLayoutParams().height = + getResources().getDimensionPixelSize(R.dimen.ntp_search_box_height_modern); + + if (!DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid())) { + mSearchBoxBoundsVerticalInset = getResources().getDimensionPixelSize( + R.dimen.ntp_search_box_bounds_vertical_inset_modern); + } + } + mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer); + + initializeShortcuts(); + initializeSearchBoxTextView(); + initializeVoiceSearchButton(); + initializeLayoutChangeListener(); + setSearchProviderInfo(searchProviderHasLogo, searchProviderIsGoogle); + mSearchProviderLogoView.showSearchProviderInitialView(); + + mTileGroup.startObserving(getMaxTileRows() * getMaxTileColumns()); + + VrShellDelegate.registerVrModeObserver(this); + if (VrShellDelegate.isInVr()) onEnterVr(); + + manager.addDestructionObserver(NewTabPageLayout.this ::onDestroy); + + mInitialized = true; + + TraceEvent.end(TAG + ".initialize()"); + } + + /** + * Sets up the hint text and event handlers for the search box text view. + */ + private void initializeSearchBoxTextView() { + TraceEvent.begin(TAG + ".initializeSearchBoxTextView()"); + + final TextView searchBoxTextView = mSearchBoxView.findViewById(R.id.search_box_text); + String hintText = getResources().getString(R.string.search_or_type_web_address); + if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext()) + || SuggestionsConfig.useModernLayout()) { + searchBoxTextView.setHint(hintText); + } else { + searchBoxTextView.setContentDescription(hintText); + } + searchBoxTextView.setOnClickListener(v -> mManager.focusSearchBox(false, null)); + searchBoxTextView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + if (s.length() == 0) return; + mManager.focusSearchBox(false, s.toString()); + searchBoxTextView.setText(""); + } + }); + TraceEvent.end(TAG + ".initializeSearchBoxTextView()"); + } + + /** + * Updates the small search engine logo shown in the search box. + */ + private void updateSearchBoxLogo() { + TextView searchBoxTextView = mSearchBoxView.findViewById(R.id.search_box_text); + LocaleManager localeManager = LocaleManager.getInstance(); + if (mSearchProviderIsGoogle && !localeManager.hasCompletedSearchEnginePromo() + && !localeManager.hasShownSearchEnginePromoThisSession() + && ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SHOW_GOOGLE_G_IN_OMNIBOX)) { + searchBoxTextView.setCompoundDrawablePadding( + getResources().getDimensionPixelOffset(R.dimen.ntp_search_box_logo_padding)); + ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds( + searchBoxTextView, R.drawable.ic_logo_googleg_24dp, 0, 0, 0); + } else { + searchBoxTextView.setCompoundDrawablePadding(0); + + // Not using the relative version of this call because we only want to clear + // the drawables. + searchBoxTextView.setCompoundDrawables(null, null, null, null); + } + } + + private void initializeVoiceSearchButton() { + TraceEvent.begin(TAG + ".initializeVoiceSearchButton()"); + mVoiceSearchButton = findViewById(R.id.voice_search_button); + mVoiceSearchButton.setOnClickListener(v -> mManager.focusSearchBox(true, null)); + + if (SuggestionsConfig.useModernLayout() + && !DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid())) { + MarginLayoutParamsCompat.setMarginEnd( + (MarginLayoutParams) mVoiceSearchButton.getLayoutParams(), + getResources().getDimensionPixelSize( + R.dimen.ntp_search_box_voice_search_margin_end_modern)); + } + + TraceEvent.end(TAG + ".initializeVoiceSearchButton()"); + } + + private void initializeLayoutChangeListener() { + TraceEvent.begin(TAG + ".initializeLayoutChangeListener()"); + addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + int oldHeight = oldBottom - oldTop; + int newHeight = bottom - top; + + if (oldHeight == newHeight && !mTileCountChanged) return; + mTileCountChanged = false; + + // Re-apply the url focus change amount after a rotation to ensure the views are + // correctly placed with their new layout configurations. + onUrlFocusAnimationChanged(); + updateSearchBoxOnScroll(); + + // The positioning of elements may have been changed (since the elements expand + // to fill the available vertical space), so adjust the scroll. + mScrollDelegate.snapScroll(); + }); + TraceEvent.end(TAG + ".initializeLayoutChangeListener()"); + } + + /** + * Updates the search box when the parent view's scroll position is changed. + */ + void updateSearchBoxOnScroll() { + if (mDisableUrlFocusChangeAnimations || mIsViewMoving) return; + + // When the page changes (tab switching or new page loading), it is possible that events + // (e.g. delayed view change notifications) trigger calls to these methods after + // the current page changes. We check it again to make sure we don't attempt to update the + // wrong page. + if (!mManager.isCurrentPage()) return; + + if (mSearchBoxScrollListener != null) { + mSearchBoxScrollListener.onNtpScrollChanged(getToolbarTransitionPercentage()); + } + } + + /** + * Calculates the percentage (between 0 and 1) of the transition from the search box to the + * omnibox at the top of the New Tab Page, which is determined by the amount of scrolling and + * the position of the search box. + * + * @return the transition percentage + */ + private float getToolbarTransitionPercentage() { + // During startup the view may not be fully initialized. + if (!mScrollDelegate.isScrollViewInitialized()) return 0f; + + if (!mScrollDelegate.isChildVisibleAtPosition(0)) { + // getVerticalScrollOffset is valid only for the scroll view if the first item is + // visible. If the first item is not visible, we must have scrolled quite far and we + // know the toolbar transition should be 100%. This might be the initial scroll position + // due to the scroll restore feature, so the search box will not have been laid out yet. + return 1f; + } + + // During startup the view may not be fully initialized, so we only calculate the current + // percentage if some basic view properties (position of the search box) are sane. + int searchBoxTop = mSearchBoxView.getTop(); + if (searchBoxTop == 0) return 0f; + + // For all other calculations, add the search box padding, because it defines where the + // visible "border" of the search box is. + searchBoxTop += mSearchBoxView.getPaddingTop(); + + final int scrollY = mScrollDelegate.getVerticalScrollOffset(); + final float transitionLength = + getResources().getDimension(R.dimen.ntp_search_box_transition_length); + // Tab strip height is zero on phones, nonzero on tablets. + int tabStripHeight = getResources().getDimensionPixelSize(R.dimen.tab_strip_height); + + // |scrollY - searchBoxTop + tabStripHeight| gives the distance the search bar is from the + // top of the tab. + return MathUtils.clamp( + (scrollY - searchBoxTop + tabStripHeight + transitionLength) / transitionLength, 0f, + 1f); + } + + private void insertSiteSectionView() { mSiteSectionView = SiteSection.inflateSiteSection(this); ViewGroup.LayoutParams layoutParams = mSiteSectionView.getLayoutParams(); layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; @@ -78,11 +434,10 @@ } /** - * @return the embedded explore sites section. + * @return The fake search box view. */ - @Nullable - public View getExploreSectionView() { - return mExploreSectionView; + public View getSearchBoxView() { + return mSearchBoxView; } @Override @@ -92,6 +447,442 @@ } /** + * @return The placeholder that is shown above the fold when there is no other content to show, + * or null if it has not been inflated yet. + */ + @VisibleForTesting + @Nullable + public View getPlaceholder() { + return mTileGridPlaceholder; + } + + @VisibleForTesting + public TileGroup getTileGroup() { + return mTileGroup; + } + + /** + * Should be called every time one of the flags used to track initialization progress changes. + * Finalizes initialization once all the preliminary steps are complete. + * + * @see #mHasShownView + * @see #mTilesLoaded + */ + private void onInitializationProgressChanged() { + if (!hasLoadCompleted()) return; + + mManager.onLoadingComplete(); + + // Load the logo after everything else is finished, since it's lower priority. + loadSearchProviderLogo(); + } + + /** + * To be called to notify that the tiles have finished loading. Will do nothing if a load was + * previously completed. + */ + public void onTilesLoaded() { + if (mTilesLoaded) return; + mTilesLoaded = true; + + onInitializationProgressChanged(); + } + + /** + * Loads the search provider logo (e.g. Google doodle), if any. + */ + public void loadSearchProviderLogo() { + if (!mSearchProviderHasLogo) return; + + mSearchProviderLogoView.showSearchProviderInitialView(); + + mLogoDelegate.getSearchProviderLogo((logo, fromCache) -> { + if (logo == null && fromCache) return; + + mSearchProviderLogoView.setDelegate(mLogoDelegate); + mSearchProviderLogoView.updateLogo(logo); + mSnapshotTileGridChanged = true; + }); + } + + /** + * Changes the layout depending on whether the selected search provider (e.g. Google, Bing) + * has a logo. + * @param hasLogo Whether the search provider has a logo. + * @param isGoogle Whether the search provider is Google. + */ + public void setSearchProviderInfo(boolean hasLogo, boolean isGoogle) { + if (hasLogo == mSearchProviderHasLogo && isGoogle == mSearchProviderIsGoogle + && mInitialized) { + return; + } + mSearchProviderHasLogo = hasLogo; + mSearchProviderIsGoogle = isGoogle; + + updateTileGridPadding(); + + // Hide or show the views above the tile grid as needed, including logo, search box, and + // spacers. + int visibility = mSearchProviderHasLogo ? View.VISIBLE : View.GONE; + int logoVisibility = shouldShowLogo() ? View.VISIBLE : View.GONE; + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = getChildAt(i); + if (mShortcutsView != null && child == mShortcutsView) break; + if (child == mSiteSectionViewHolder.itemView) break; + + // Don't change the visibility of a ViewStub as that will automagically inflate it. + if (child instanceof ViewStub) continue; + + if (child == mSearchProviderLogoView) { + child.setVisibility(logoVisibility); + } else { + child.setVisibility(visibility); + } + } + + updateTileGridPlaceholderVisibility(); + + onUrlFocusAnimationChanged(); + + updateSearchBoxLogo(); + + mSnapshotTileGridChanged = true; + } + + /** + * Updates the padding for the tile grid based on what is shown above it. + */ + private void updateTileGridPadding() { + int paddingTop; + if (mShortcutsView != null) { + // If the shortcuts view is visible, padding will be built into that view. + paddingTop = 0; + } else { + int paddingWithLogoId = SuggestionsConfig.useModernLayout() + ? R.dimen.tile_grid_layout_modern_padding_top + : R.dimen.tile_grid_layout_padding_top; + // Set a bit more top padding on the tile grid if there is no logo. + paddingTop = getResources().getDimensionPixelSize(shouldShowLogo() + ? paddingWithLogoId + : R.dimen.tile_grid_layout_no_logo_padding_top); + } + + mSiteSectionViewHolder.itemView.setPadding( + 0, paddingTop, 0, mSiteSectionViewHolder.itemView.getPaddingBottom()); + } + + /** + * Updates whether the NewTabPage should animate on URL focus changes. + * @param disable Whether to disable the animations. + */ + void setUrlFocusAnimationsDisabled(boolean disable) { + if (disable == mDisableUrlFocusChangeAnimations) return; + mDisableUrlFocusChangeAnimations = disable; + if (!disable) onUrlFocusAnimationChanged(); + } + + /** + * @return Whether URL focus animations are currently disabled. + */ + boolean urlFocusAnimationsDisabled() { + return mDisableUrlFocusChangeAnimations; + } + + /** + * Specifies the percentage the URL is focused during an animation. 1.0 specifies that the URL + * bar has focus and has completed the focus animation. 0 is when the URL bar is does not have + * any focus. + * + * @param percent The percentage of the URL bar focus animation. + */ + void setUrlFocusChangeAnimationPercent(float percent) { + mUrlFocusChangePercent = percent; + onUrlFocusAnimationChanged(); + } + + /** + * @return The percentage that the URL bar is focused during an animation. + */ + @VisibleForTesting + float getUrlFocusChangeAnimationPercent() { + return mUrlFocusChangePercent; + } + + void onUrlFocusAnimationChanged() { + if (mDisableUrlFocusChangeAnimations || mIsViewMoving) return; + + // Translate so that the search box is at the top, but only upwards. + float percent = mSearchProviderHasLogo ? mUrlFocusChangePercent : 0; + int basePosition = mScrollDelegate.getVerticalScrollOffset() + getPaddingTop(); + int target = Math.max(basePosition, + mSearchBoxView.getBottom() - mSearchBoxView.getPaddingBottom() + - mSearchBoxBoundsVerticalInset); + + setTranslationY(percent * (basePosition - target)); + } + + /** + * Sets whether this view is currently moving within its parent view. When the view is moving + * certain animations will be disabled or prevented. + * @param isViewMoving Whether this view is currently moving. + */ + void setIsViewMoving(boolean isViewMoving) { + mIsViewMoving = isViewMoving; + } + + /** + * Updates the opacity of the search box when scrolling. + * + * @param alpha opacity (alpha) value to use. + */ + public void setSearchBoxAlpha(float alpha) { + mSearchBoxView.setAlpha(alpha); + + // Disable the search box contents if it is the process of being animated away. + ViewUtils.setEnabledRecursive(mSearchBoxView, mSearchBoxView.getAlpha() == 1.0f); + } + + /** + * Updates the opacity of the search provider logo when scrolling. + * + * @param alpha opacity (alpha) value to use. + */ + public void setSearchProviderLogoAlpha(float alpha) { + mSearchProviderLogoView.setAlpha(alpha); + } + + /** + * Set the search box background drawable. + * + * @param drawable The search box background. + */ + public void setSearchBoxBackground(Drawable drawable) { + mSearchBoxView.setBackground(drawable); + } + + /** + * Get the bounds of the search box in relation to the top level {@code parentView}. + * + * @param bounds The current drawing location of the search box. + * @param translation The translation applied to the search box by the parent view hierarchy up + * to the {@code parentView}. + * @param parentView The top level parent view used to translate search box bounds. + */ + void getSearchBoxBounds(Rect bounds, Point translation, View parentView) { + int searchBoxX = (int) mSearchBoxView.getX(); + int searchBoxY = (int) mSearchBoxView.getY(); + bounds.set(searchBoxX + mSearchBoxView.getPaddingLeft(), + searchBoxY + mSearchBoxView.getPaddingTop(), + searchBoxX + mSearchBoxView.getWidth() - mSearchBoxView.getPaddingRight(), + searchBoxY + mSearchBoxView.getHeight() - mSearchBoxView.getPaddingBottom()); + + translation.set(0, 0); + + View view = mSearchBoxView; + while (true) { + view = (View) view.getParent(); + if (view == null) { + // The |mSearchBoxView| is not a child of this view. This can happen if the + // RecyclerView detaches the NewTabPageLayout after it has been scrolled out of + // view. Set the translation to the minimum Y value as an approximation. + translation.y = Integer.MIN_VALUE; + break; + } + translation.offset(-view.getScrollX(), -view.getScrollY()); + if (view == parentView) break; + translation.offset((int) view.getX(), (int) view.getY()); + } + bounds.offset(translation.x, translation.y); + + if (translation.y != Integer.MIN_VALUE) { + bounds.inset(0, mSearchBoxBoundsVerticalInset); + } + } + + /** + * Sets the listener for search box scroll changes. + * @param listener The listener to be notified on changes. + */ + void setSearchBoxScrollListener(OnSearchBoxScrollListener listener) { + mSearchBoxScrollListener = listener; + if (mSearchBoxScrollListener != null) updateSearchBoxOnScroll(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + assert mManager != null; + + if (!mHasShownView) { + mHasShownView = true; + onInitializationProgressChanged(); + NewTabPageUma.recordSearchAvailableLoadTime(mTab.getActivity()); + TraceEvent.instant("NewTabPageSearchAvailable)"); + } else { + // Trigger a scroll update when reattaching the window to signal the toolbar that + // it needs to reset the NTP state. + if (mManager.isLocationBarShownInNTP()) updateSearchBoxOnScroll(); + } + } + + /** + * Update the visibility of the voice search button based on whether the feature is currently + * enabled. + */ + void updateVoiceSearchButtonVisibility() { + mVoiceSearchButton.setVisibility(mManager.isVoiceSearchEnabled() ? VISIBLE : GONE); + } + + @Override + protected void onWindowVisibilityChanged(int visibility) { + super.onWindowVisibilityChanged(visibility); + + // On first run, the NewTabPageLayout is initialized behind the First Run Experience, + // meaning the UiConfig will pickup the screen layout then. However onConfigurationChanged + // is not called on orientation changes until the FRE is completed. This means that if a + // user starts the FRE in one orientation, changes an orientation and then leaves the FRE + // the UiConfig will have the wrong orientation. https://crbug.com/683886. + mUiConfig.updateDisplayStyle(); + + if (visibility == VISIBLE) { + updateVoiceSearchButtonVisibility(); + } + } + + /** + * @see InvalidationAwareThumbnailProvider#shouldCaptureThumbnail() + */ + public boolean shouldCaptureThumbnail() { + return mSnapshotTileGridChanged; + } + + /** + * Should be called before a thumbnail of the parent view is captured. + * @see InvalidationAwareThumbnailProvider#captureThumbnail(Canvas) + */ + public void onPreCaptureThumbnail() { + mSearchProviderLogoView.endFadeAnimation(); + mSnapshotTileGridChanged = false; + } + + /** + * Shows the most visited placeholder ("Nothing to see here") if there are no most visited + * items and there is no search provider logo. + */ + private void updateTileGridPlaceholderVisibility() { + boolean showPlaceholder = + mTileGroup.hasReceivedData() && mTileGroup.isEmpty() && !mSearchProviderHasLogo; + + mNoSearchLogoSpacer.setVisibility( + (mSearchProviderHasLogo || showPlaceholder) ? View.GONE : View.INVISIBLE); + + mSiteSectionViewHolder.itemView.setVisibility(showPlaceholder ? GONE : VISIBLE); + + if (showPlaceholder) { + if (mTileGridPlaceholder == null) { + ViewStub placeholderStub = findViewById(R.id.tile_grid_placeholder_stub); + mTileGridPlaceholder = placeholderStub.inflate(); + } + mTileGridPlaceholder.setVisibility(VISIBLE); + } else if (mTileGridPlaceholder != null) { + mTileGridPlaceholder.setVisibility(GONE); + } + } + + private static int getMaxTileRows() { + return 2; + } + + /** + * Determines The maximum number of tiles to try and fit in a row. On smaller screens, there + * may not be enough space to fit all of them. + */ + private int getMaxTileColumns() { + if (!mUiConfig.getCurrentDisplayStyle().isSmall() + && SuggestionsConfig.getTileStyle(mUiConfig) == TileView.Style.CLASSIC_CONDENSED) { + return 5; + } + return 4; + } + + private static int getTileTitleLines() { + return 1; + } + + private boolean shouldShowLogo() { + return mSearchProviderHasLogo; + } + + private boolean hasLoadCompleted() { + return mHasShownView && mTilesLoaded; + } + + // TileGroup.Observer interface. + + @Override + public void onTileDataChanged() { + mSiteSectionViewHolder.refreshData(); + mSnapshotTileGridChanged = true; + + // The page contents are initially hidden; otherwise they'll be drawn centered on the page + // before the tiles are available and then jump upwards to make space once the tiles are + // available. + if (getVisibility() != View.VISIBLE) setVisibility(View.VISIBLE); + } + + @Override + public void onTileCountChanged() { + // If the number of tile rows change while the URL bar is focused, the icons' + // position will be wrong. Schedule the translation to be updated. + if (mUrlFocusChangePercent == 1f) mTileCountChanged = true; + updateTileGridPlaceholderVisibility(); + } + + @Override + public void onTileIconChanged(Tile tile) { + mSiteSectionViewHolder.updateIconView(tile); + mSnapshotTileGridChanged = true; + } + + @Override + public void onTileOfflineBadgeVisibilityChanged(Tile tile) { + mSiteSectionViewHolder.updateOfflineBadge(tile); + mSnapshotTileGridChanged = true; + } + + @Override + public void onEnterVr() { + mSearchBoxView.setVisibility(GONE); + } + + @Override + public void onExitVr() { + mSearchBoxView.setVisibility(VISIBLE); + } + + private void onDestroy() { + VrShellDelegate.unregisterVrModeObserver(this); + } + + private void initializeShortcuts() { + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SIMPLIFIED_NTP) + || isSimplifiedNtpAblationEnabled()) { + return; + } + + ViewStub shortcutsStub = findViewById(R.id.shortcuts_stub); + mShortcutsView = (ViewGroup) shortcutsStub.inflate(); + + mShortcutsView.findViewById(R.id.bookmarks_button) + .setOnClickListener(view -> mManager.getNavigationDelegate().navigateToBookmarks()); + + mShortcutsView.findViewById(R.id.downloads_button) + .setOnClickListener( + view -> mManager.getNavigationDelegate().navigateToDownloadManager()); + } + + /** * Makes the Search Box and Logo as wide as Most Visited. */ private void unifyElementWidths() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java index 300794b..6094c04 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -9,120 +9,54 @@ import android.graphics.Canvas; import android.graphics.Point; import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.support.annotation.Nullable; -import android.support.v4.view.MarginLayoutParamsCompat; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.AdapterDataObserver; import android.support.v7.widget.RecyclerView.ViewHolder; -import android.text.Editable; -import android.text.TextWatcher; import android.util.AttributeSet; import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewStub; import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.TraceEvent; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider; -import org.chromium.chrome.browser.explore_sites.ExploreSitesSection; -import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.ntp.NewTabPage.FakeboxDelegate; -import org.chromium.chrome.browser.ntp.NewTabPage.OnSearchBoxScrollListener; import org.chromium.chrome.browser.ntp.cards.NewTabPageAdapter; import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.suggestions.SiteSection; -import org.chromium.chrome.browser.suggestions.SiteSectionViewHolder; import org.chromium.chrome.browser.suggestions.SuggestionsConfig; import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; -import org.chromium.chrome.browser.suggestions.Tile; import org.chromium.chrome.browser.suggestions.TileGroup; -import org.chromium.chrome.browser.suggestions.TileRenderer; -import org.chromium.chrome.browser.suggestions.TileView; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.util.MathUtils; import org.chromium.chrome.browser.util.ViewUtils; -import org.chromium.chrome.browser.vr_shell.VrShellDelegate; import org.chromium.chrome.browser.widget.displaystyle.UiConfig; -import org.chromium.ui.base.DeviceFormFactor; /** * The native new tab page, represented by some basic data such as title and url, and an Android * View that displays the page. */ -public class NewTabPageView - extends FrameLayout implements TileGroup.Observer, VrShellDelegate.VrModeObserver { +public class NewTabPageView extends FrameLayout { private static final String TAG = "NewTabPageView"; private static final long SNAP_SCROLL_DELAY_MS = 30; - /** - * Parameter for the simplified NTP ablation experiment arm which removes the additional - * suggestions sections without replacing them with shortcut buttons. - */ - private static final String PARAM_SIMPLIFIED_NTP_ABLATION = "simplified_ntp_ablation"; - private NewTabPageRecyclerView mRecyclerView; private NewTabPageLayout mNewTabPageLayout; - private LogoView mSearchProviderLogoView; - private View mSearchBoxView; - private ImageView mVoiceSearchButton; - private SiteSectionViewHolder mSiteSectionViewHolder; - private View mTileGridPlaceholder; - private View mNoSearchLogoSpacer; - private ViewGroup mShortcutsView; - - @Nullable - private ExploreSitesSection mExploreSection; // Null when explore sites disabled. - - private OnSearchBoxScrollListener mSearchBoxScrollListener; private NewTabPageManager mManager; private Tab mTab; - private LogoDelegateImpl mLogoDelegate; - private TileGroup mTileGroup; private UiConfig mUiConfig; private Runnable mSnapScrollRunnable; private Runnable mUpdateSearchBoxOnScrollRunnable; - /** - * Whether the tiles shown in the layout have finished loading. - * With {@link #mHasShownView}, it's one of the 2 flags used to track initialisation progress. - */ - private boolean mTilesLoaded; - - /** - * Whether the view has been shown at least once. - * With {@link #mTilesLoaded}, it's one of the 2 flags used to track initialization progress. - */ - private boolean mHasShownView; - - private boolean mSearchProviderHasLogo = true; - private boolean mSearchProviderIsGoogle; - private boolean mPendingSnapScroll; - private boolean mInitialized; private int mLastScrollY = -1; - private float mUrlFocusChangePercent; - private boolean mDisableUrlFocusChangeAnimations; - private boolean mIsMovingNewTabPageView; - - /** Flag used to request some layout changes after the next layout pass is completed. */ - private boolean mTileCountChanged; - private boolean mSnapshotTileGridChanged; private boolean mNewTabPageRecyclerViewChanged; private int mSnapshotWidth; private int mSnapshotHeight; @@ -130,21 +64,6 @@ private ContextMenuManager mContextMenuManager; /** - * Vertical inset to add to the top and bottom of the search box bounds. May be 0 if no inset - * should be applied. See {@link Rect#inset(int, int)}. - */ - private int mSearchBoxBoundsVerticalInset; - - /** - * @return Whether the simplified NTP ablation experiment arm which removes the additional - * suggestions sections without replacing them with shortcut buttons is enabled. - */ - public static boolean isSimplifiedNtpAblationEnabled() { - return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( - ChromeFeatureList.SIMPLIFIED_NTP, PARAM_SIMPLIFIED_NTP_ABLATION, false); - } - - /** * Manages the view interaction with the rest of the system. */ public interface NewTabPageManager extends SuggestionsUiDelegate { @@ -179,6 +98,11 @@ */ public NewTabPageView(Context context, AttributeSet attrs) { super(context, attrs); + + mRecyclerView = new NewTabPageRecyclerView(getContext()); + + // Don't attach now, the recyclerView itself will determine when to do it. + mNewTabPageLayout = mRecyclerView.getAboveTheFoldView(); } /** @@ -201,13 +125,19 @@ assert manager.getSuggestionsSource() != null; - mRecyclerView = new NewTabPageRecyclerView(getContext()); + // Don't store a direct reference to the activity, because it might change later if the tab + // is reparented. + Runnable closeContextMenuCallback = () -> mTab.getActivity().closeContextMenu(); + mContextMenuManager = new ContextMenuManager(mManager.getNavigationDelegate(), + mRecyclerView::setTouchEnabled, closeContextMenuCallback); + mTab.getWindowAndroid().addContextMenuCloseListener(mContextMenuManager); + + mNewTabPageLayout.initialize(manager, tab, tileGroupDelegate, searchProviderHasLogo, + searchProviderIsGoogle, mRecyclerView, mContextMenuManager, mUiConfig); + mRecyclerView.setContainsLocationBar(manager.isLocationBarShownInNTP()); addView(mRecyclerView); - // Don't attach now, the recyclerView itself will determine when to do it. - mNewTabPageLayout = mRecyclerView.getAboveTheFoldView(); - mRecyclerView.setItemAnimator(new DefaultItemAnimator() { @Override public boolean animateMove(ViewHolder holder, int fromX, int fromY, int toX, int toY) { @@ -215,7 +145,7 @@ // was dismissed, avoid also manipulating its vertical offset in our scroll handling // at the same time. The onScrolled() method is called when an item is dismissed and // the item at the top of the viewport is repositioned. - if (holder.itemView == mNewTabPageLayout) mIsMovingNewTabPageView = true; + if (holder.itemView == mNewTabPageLayout) mNewTabPageLayout.setIsViewMoving(true); // Cancel any pending scroll update handling, a new one will be scheduled in // onAnimationFinished(). @@ -235,65 +165,23 @@ // from here, as the RecyclerView will animate multiple items when one is dismissed, // and some will "finish" synchronously if they are already in the correct place, // before other moves have even been scheduled. - if (viewHolder.itemView == mNewTabPageLayout) mIsMovingNewTabPageView = false; + if (viewHolder.itemView == mNewTabPageLayout) { + mNewTabPageLayout.setIsViewMoving(false); + } mRecyclerView.removeCallbacks(mUpdateSearchBoxOnScrollRunnable); mRecyclerView.post(mUpdateSearchBoxOnScrollRunnable); } }); - // Don't store a direct reference to the activity, because it might change later if the tab - // is reparented. - Runnable closeContextMenuCallback = () -> mTab.getActivity().closeContextMenu(); - mContextMenuManager = new ContextMenuManager(mManager.getNavigationDelegate(), - mRecyclerView::setTouchEnabled, closeContextMenuCallback); - mTab.getWindowAndroid().addContextMenuCloseListener(mContextMenuManager); - Profile profile = Profile.getLastUsedProfile(); OfflinePageBridge offlinePageBridge = SuggestionsDependencyFactory.getInstance().getOfflinePageBridge(profile); - TileRenderer tileRenderer = - new TileRenderer(mTab.getActivity(), SuggestionsConfig.getTileStyle(mUiConfig), - getTileTitleLines(), mManager.getImageFetcher()); - mTileGroup = new TileGroup(tileRenderer, mManager, mContextMenuManager, tileGroupDelegate, - /* observer = */ this, offlinePageBridge); - - mSiteSectionViewHolder = - SiteSection.createViewHolder(mNewTabPageLayout.getSiteSectionView(), mUiConfig); - mSiteSectionViewHolder.bindDataSource(mTileGroup, tileRenderer); - - if (ChromeFeatureList.isEnabled(ChromeFeatureList.EXPLORE_SITES)) { - mExploreSection = new ExploreSitesSection(mNewTabPageLayout.getExploreSectionView(), - profile, mManager.getNavigationDelegate()); - } - - mSearchProviderLogoView = mNewTabPageLayout.findViewById(R.id.search_provider_logo); - mLogoDelegate = new LogoDelegateImpl( - mManager.getNavigationDelegate(), mSearchProviderLogoView, profile); - - mSearchBoxView = mNewTabPageLayout.findViewById(R.id.search_box); - if (SuggestionsConfig.useModernLayout()) { - mSearchBoxView.setBackgroundResource(R.drawable.ntp_search_box); - mSearchBoxView.getLayoutParams().height = - getResources().getDimensionPixelSize(R.dimen.ntp_search_box_height_modern); - - if (!DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid())) { - mSearchBoxBoundsVerticalInset = getResources().getDimensionPixelSize( - R.dimen.ntp_search_box_bounds_vertical_inset_modern); - } - } - mNoSearchLogoSpacer = mNewTabPageLayout.findViewById(R.id.no_search_logo_spacer); mSnapScrollRunnable = new SnapScrollRunnable(); - mUpdateSearchBoxOnScrollRunnable = new UpdateSearchBoxOnScrollRunnable(); + mUpdateSearchBoxOnScrollRunnable = mNewTabPageLayout::updateSearchBoxOnScroll; - initializeShortcuts(); - initializeSearchBoxTextView(); - initializeVoiceSearchButton(); - initializeLayoutChangeListeners(); + initializeLayoutChangeListener(); setSearchProviderInfo(searchProviderHasLogo, searchProviderIsGoogle); - mSearchProviderLogoView.showSearchProviderInitialView(); - - mTileGroup.startObserving(getMaxTileRows() * getMaxTileColumns()); mRecyclerView.init(mUiConfig, mContextMenuManager); @@ -335,116 +223,29 @@ } }); - VrShellDelegate.registerVrModeObserver(this); - if (VrShellDelegate.isInVr()) onEnterVr(); - manager.addDestructionObserver(NewTabPageView.this::onDestroy); - mInitialized = true; - TraceEvent.end(TAG + ".initialize()"); } /** + * @return The {@link NewTabPageLayout} displayed in this NewTabPageView. + */ + NewTabPageLayout getNewTabPageLayout() { + return mNewTabPageLayout; + } + + /** * Sets the {@link FakeboxDelegate} associated with the new tab page. * @param fakeboxDelegate The {@link FakeboxDelegate} used to determine whether the URL bar * has focus. */ public void setFakeboxDelegate(FakeboxDelegate fakeboxDelegate) { - mRecyclerView.setFakeboxDelegate(fakeboxDelegate); + mRecyclerView.setFakeboxDelegate(fakeboxDelegate, mNewTabPageLayout.getSearchBoxView()); } - /** - * Sets up the hint text and event handlers for the search box text view. - */ - private void initializeSearchBoxTextView() { - TraceEvent.begin(TAG + ".initializeSearchBoxTextView()"); - - final TextView searchBoxTextView = mSearchBoxView.findViewById(R.id.search_box_text); - String hintText = getResources().getString(R.string.search_or_type_web_address); - if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext()) - || SuggestionsConfig.useModernLayout()) { - searchBoxTextView.setHint(hintText); - } else { - searchBoxTextView.setContentDescription(hintText); - } - searchBoxTextView.setOnClickListener(v -> mManager.focusSearchBox(false, null)); - searchBoxTextView.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - if (s.length() == 0) return; - mManager.focusSearchBox(false, s.toString()); - searchBoxTextView.setText(""); - } - }); - TraceEvent.end(TAG + ".initializeSearchBoxTextView()"); - } - - /** - * Updates the small search engine logo shown in the search box. - */ - private void updateSearchBoxLogo() { - TextView searchBoxTextView = mSearchBoxView.findViewById(R.id.search_box_text); - LocaleManager localeManager = LocaleManager.getInstance(); - if (mSearchProviderIsGoogle && !localeManager.hasCompletedSearchEnginePromo() - && !localeManager.hasShownSearchEnginePromoThisSession() - && ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SHOW_GOOGLE_G_IN_OMNIBOX)) { - searchBoxTextView.setCompoundDrawablePadding( - getResources().getDimensionPixelOffset(R.dimen.ntp_search_box_logo_padding)); - ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds( - searchBoxTextView, R.drawable.ic_logo_googleg_24dp, 0, 0, 0); - } else { - searchBoxTextView.setCompoundDrawablePadding(0); - - // Not using the relative version of this call because we only want to clear - // the drawables. - searchBoxTextView.setCompoundDrawables(null, null, null, null); - } - } - - private void initializeVoiceSearchButton() { - TraceEvent.begin(TAG + ".initializeVoiceSearchButton()"); - mVoiceSearchButton = mNewTabPageLayout.findViewById(R.id.voice_search_button); - mVoiceSearchButton.setOnClickListener(v -> mManager.focusSearchBox(true, null)); - - if (SuggestionsConfig.useModernLayout() - && !DeviceFormFactor.isWindowOnTablet(mTab.getWindowAndroid())) { - MarginLayoutParamsCompat.setMarginEnd( - (MarginLayoutParams) mVoiceSearchButton.getLayoutParams(), - getResources().getDimensionPixelSize( - R.dimen.ntp_search_box_voice_search_margin_end_modern)); - } - - TraceEvent.end(TAG + ".initializeVoiceSearchButton()"); - } - - private void initializeLayoutChangeListeners() { - TraceEvent.begin(TAG + ".initializeLayoutChangeListeners()"); - mNewTabPageLayout.addOnLayoutChangeListener( - (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - int oldHeight = oldBottom - oldTop; - int newHeight = bottom - top; - - if (oldHeight == newHeight && !mTileCountChanged) return; - mTileCountChanged = false; - - // Re-apply the url focus change amount after a rotation to ensure the views are - // correctly placed with their new layout configurations. - onUrlFocusAnimationChanged(); - updateSearchBoxOnScroll(); - - // The positioning of elements may have been changed (since the elements expand - // to fill the available vertical space), so adjust the scroll. - mRecyclerView.snapScroll(mSearchBoxView, getHeight()); - }); + private void initializeLayoutChangeListener() { + TraceEvent.begin(TAG + ".initializeLayoutChangeListener()"); // Listen for layout changes on the NewTabPageView itself to catch changes in scroll // position that are due to layout changes after e.g. device rotation. This contrasts with @@ -457,61 +258,7 @@ handleScroll(); } }); - TraceEvent.end(TAG + ".initializeLayoutChangeListeners()"); - } - - private void updateSearchBoxOnScroll() { - if (mDisableUrlFocusChangeAnimations || mIsMovingNewTabPageView) return; - - // When the page changes (tab switching or new page loading), it is possible that events - // (e.g. delayed RecyclerView change notifications) trigger calls to these methods after - // the current page changes. We check it again to make sure we don't attempt to update the - // wrong page. - if (!mManager.isCurrentPage()) return; - - if (mSearchBoxScrollListener != null) { - mSearchBoxScrollListener.onNtpScrollChanged(getToolbarTransitionPercentage()); - } - } - - /** - * Calculates the percentage (between 0 and 1) of the transition from the search box to the - * omnibox at the top of the New Tab Page, which is determined by the amount of scrolling and - * the position of the search box. - * - * @return the transition percentage - */ - private float getToolbarTransitionPercentage() { - // During startup the view may not be fully initialized, so we only calculate the current - // percentage if some basic view properties (height of the containing view, position of the - // search box) are sane. - if (getRecyclerView().getHeight() == 0) return 0f; - - if (!mRecyclerView.isFirstItemVisible()) { - // getVerticalScroll is valid only for the RecyclerView if the first item is visible. - // If the first item is not visible, we must have scrolled quite far and we know the - // toolbar transition should be 100%. This might be the initial scroll position due to - // the scroll restore feature, so the search box will not have been laid out yet. - return 1f; - } - - int searchBoxTop = mSearchBoxView.getTop(); - if (searchBoxTop == 0) return 0f; - - // For all other calculations, add the search box padding, because it defines where the - // visible "border" of the search box is. - searchBoxTop += mSearchBoxView.getPaddingTop(); - - final int scrollY = mRecyclerView.computeVerticalScrollOffset(); - final float transitionLength = - getResources().getDimension(R.dimen.ntp_search_box_transition_length); - // Tab strip height is zero on phones, nonzero on tablets. - int tabStripHeight = getResources().getDimensionPixelSize(R.dimen.tab_strip_height); - - // |scrollY - searchBoxTop + tabStripHeight| gives the distance the search bar is from the - // top of the tab. - return MathUtils.clamp((scrollY - searchBoxTop + transitionLength + tabStripHeight) - / transitionLength, 0f, 1f); + TraceEvent.end(TAG + ".initializeLayoutChangeListener()"); } @VisibleForTesting @@ -520,21 +267,6 @@ } /** - * @return The placeholder that is shown above the fold when there is no other content to show, - * or null if it has not been inflated yet. - */ - @VisibleForTesting - @Nullable - public View getPlaceholder() { - return mTileGridPlaceholder; - } - - @VisibleForTesting - public TileGroup getTileGroup() { - return mTileGroup; - } - - /** * Adds listeners to scrolling to take care of snap scrolling and updating the search box on * scroll. */ @@ -570,51 +302,7 @@ mRecyclerView.removeCallbacks(mSnapScrollRunnable); mRecyclerView.postDelayed(mSnapScrollRunnable, SNAP_SCROLL_DELAY_MS); } - updateSearchBoxOnScroll(); - } - - /** - * Should be called every time of the flags used to track initialisation progress changes. - * Finalises initialisation once all the preliminary steps are complete. - * - * @see #mHasShownView - * @see #mTilesLoaded - */ - private void onInitialisationProgressChanged() { - if (!hasLoadCompleted()) return; - - mManager.onLoadingComplete(); - - // Load the logo after everything else is finished, since it's lower priority. - loadSearchProviderLogo(); - } - - /** - * To be called to notify that the tiles have finished loading. Will do nothing if a load was - * previously completed. - */ - public void onTilesLoaded() { - if (mTilesLoaded) return; - mTilesLoaded = true; - - onInitialisationProgressChanged(); - } - - /** - * Loads the search provider logo (e.g. Google doodle), if any. - */ - public void loadSearchProviderLogo() { - if (!mSearchProviderHasLogo) return; - - mSearchProviderLogoView.showSearchProviderInitialView(); - - mLogoDelegate.getSearchProviderLogo((logo, fromCache) -> { - if (logo == null && fromCache) return; - - mSearchProviderLogoView.setDelegate(mLogoDelegate); - mSearchProviderLogoView.updateLogo(logo); - mSnapshotTileGridChanged = true; - }); + mNewTabPageLayout.updateSearchBoxOnScroll(); } /** @@ -624,148 +312,10 @@ * @param isGoogle Whether the search provider is Google. */ public void setSearchProviderInfo(boolean hasLogo, boolean isGoogle) { - if (hasLogo == mSearchProviderHasLogo && isGoogle == mSearchProviderIsGoogle - && mInitialized) { - return; - } - mSearchProviderHasLogo = hasLogo; - mSearchProviderIsGoogle = isGoogle; - - updateTileGridPadding(); - - // Hide or show the views above the tile grid as needed, including logo, search box, and - // spacers. - int visibility = mSearchProviderHasLogo ? View.VISIBLE : View.GONE; - int logoVisibility = shouldShowLogo() ? View.VISIBLE : View.GONE; - int childCount = mNewTabPageLayout.getChildCount(); - for (int i = 0; i < childCount; i++) { - View child = mNewTabPageLayout.getChildAt(i); - if (mShortcutsView != null && child == mShortcutsView) break; - if (child == mSiteSectionViewHolder.itemView) break; - - // Don't change the visibility of a ViewStub as that will automagically inflate it. - if (child instanceof ViewStub) continue; - - if (child == mSearchProviderLogoView) { - child.setVisibility(logoVisibility); - } else { - child.setVisibility(visibility); - } - } - // Update snap scrolling for the fakebox. mRecyclerView.setContainsLocationBar(mManager.isLocationBarShownInNTP()); - updateTileGridPlaceholderVisibility(); - - onUrlFocusAnimationChanged(); - - updateSearchBoxLogo(); - - mSnapshotTileGridChanged = true; - } - - /** - * Updates the padding for the tile grid based on what is shown above it. - */ - private void updateTileGridPadding() { - int paddingTop; - if (mShortcutsView != null) { - // If the shortcuts view is visible, padding will be built into that view. - paddingTop = 0; - } else { - int paddingWithLogoId = SuggestionsConfig.useModernLayout() - ? R.dimen.tile_grid_layout_modern_padding_top - : R.dimen.tile_grid_layout_padding_top; - // Set a bit more top padding on the tile grid if there is no logo. - paddingTop = getResources().getDimensionPixelSize(shouldShowLogo() - ? paddingWithLogoId - : R.dimen.tile_grid_layout_no_logo_padding_top); - } - - mSiteSectionViewHolder.itemView.setPadding( - 0, paddingTop, 0, mSiteSectionViewHolder.itemView.getPaddingBottom()); - } - - /** - * Updates whether the NewTabPage should animate on URL focus changes. - * @param disable Whether to disable the animations. - */ - void setUrlFocusAnimationsDisabled(boolean disable) { - if (disable == mDisableUrlFocusChangeAnimations) return; - mDisableUrlFocusChangeAnimations = disable; - if (!disable) onUrlFocusAnimationChanged(); - } - - /** - * @return Whether URL focus animations are currently disabled. - */ - boolean urlFocusAnimationsDisabled() { - return mDisableUrlFocusChangeAnimations; - } - - /** - * Specifies the percentage the URL is focused during an animation. 1.0 specifies that the URL - * bar has focus and has completed the focus animation. 0 is when the URL bar is does not have - * any focus. - * - * @param percent The percentage of the URL bar focus animation. - */ - void setUrlFocusChangeAnimationPercent(float percent) { - mUrlFocusChangePercent = percent; - onUrlFocusAnimationChanged(); - } - - /** - * @return The percentage that the URL bar is focused during an animation. - */ - @VisibleForTesting - float getUrlFocusChangeAnimationPercent() { - return mUrlFocusChangePercent; - } - - private void onUrlFocusAnimationChanged() { - if (mDisableUrlFocusChangeAnimations || mIsMovingNewTabPageView) return; - - // Translate so that the search box is at the top, but only upwards. - float percent = mSearchProviderHasLogo ? mUrlFocusChangePercent : 0; - int basePosition = mRecyclerView.computeVerticalScrollOffset() - + mNewTabPageLayout.getPaddingTop(); - int target = Math.max(basePosition, - mSearchBoxView.getBottom() - mSearchBoxView.getPaddingBottom() - - mSearchBoxBoundsVerticalInset); - - mNewTabPageLayout.setTranslationY(percent * (basePosition - target)); - } - - /** - * Updates the opacity of the search box when scrolling. - * - * @param alpha opacity (alpha) value to use. - */ - public void setSearchBoxAlpha(float alpha) { - mSearchBoxView.setAlpha(alpha); - - // Disable the search box contents if it is the process of being animated away. - ViewUtils.setEnabledRecursive(mSearchBoxView, mSearchBoxView.getAlpha() == 1.0f); - } - - /** - * Updates the opacity of the search provider logo when scrolling. - * - * @param alpha opacity (alpha) value to use. - */ - public void setSearchProviderLogoAlpha(float alpha) { - mSearchProviderLogoView.setAlpha(alpha); - } - - /** - * Set the search box background drawable. - * - * @param drawable The search box background. - */ - public void setSearchBoxBackground(Drawable drawable) { - mSearchBoxView.setBackground(drawable); + mNewTabPageLayout.setSearchProviderInfo(hasLogo, isGoogle); } /** @@ -776,84 +326,7 @@ * to the NewTabPage view. */ void getSearchBoxBounds(Rect bounds, Point translation) { - int searchBoxX = (int) mSearchBoxView.getX(); - int searchBoxY = (int) mSearchBoxView.getY(); - bounds.set(searchBoxX + mSearchBoxView.getPaddingLeft(), - searchBoxY + mSearchBoxView.getPaddingTop(), - searchBoxX + mSearchBoxView.getWidth() - mSearchBoxView.getPaddingRight(), - searchBoxY + mSearchBoxView.getHeight() - mSearchBoxView.getPaddingBottom()); - - translation.set(0, 0); - - View view = mSearchBoxView; - while (true) { - view = (View) view.getParent(); - if (view == null) { - // The |mSearchBoxView| is not a child of this view. This can happen if the - // RecyclerView detaches the NewTabPageLayout after it has been scrolled out of - // view. Set the translation to the minimum Y value as an approximation. - translation.y = Integer.MIN_VALUE; - break; - } - translation.offset(-view.getScrollX(), -view.getScrollY()); - if (view == this) break; - translation.offset((int) view.getX(), (int) view.getY()); - } - bounds.offset(translation.x, translation.y); - - if (translation.y != Integer.MIN_VALUE) { - bounds.inset(0, mSearchBoxBoundsVerticalInset); - } - } - - /** - * Sets the listener for search box scroll changes. - * @param listener The listener to be notified on changes. - */ - void setSearchBoxScrollListener(OnSearchBoxScrollListener listener) { - mSearchBoxScrollListener = listener; - if (mSearchBoxScrollListener != null) updateSearchBoxOnScroll(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - assert mManager != null; - - if (!mHasShownView) { - mHasShownView = true; - onInitialisationProgressChanged(); - NewTabPageUma.recordSearchAvailableLoadTime(mTab.getActivity()); - TraceEvent.instant("NewTabPageSearchAvailable)"); - } else { - // Trigger a scroll update when reattaching the window to signal the toolbar that - // it needs to reset the NTP state. - if (mManager.isLocationBarShownInNTP()) updateSearchBoxOnScroll(); - } - } - - /** - * Update the visibility of the voice search button based on whether the feature is currently - * enabled. - */ - void updateVoiceSearchButtonVisibility() { - mVoiceSearchButton.setVisibility(mManager.isVoiceSearchEnabled() ? VISIBLE : GONE); - } - - @Override - protected void onWindowVisibilityChanged(int visibility) { - super.onWindowVisibilityChanged(visibility); - - // On first run, the NewTabPageView is initialized behind the First Run Experience, meaning - // the UiConfig will pickup the screen layout then. However onConfigurationChanged is not - // called on orientation changes until the FRE is completed. This means that if a user - // starts the FRE in one orientation, changes an orientation and then leaves the FRE the - // UiConfig will have the wrong orientation. https://crbug.com/683886. - mUiConfig.updateDisplayStyle(); - - if (visibility == VISIBLE) { - updateVoiceSearchButtonVisibility(); - } + mNewTabPageLayout.getSearchBoxBounds(bounds, translation, this); } /** @@ -862,7 +335,7 @@ boolean shouldCaptureThumbnail() { if (getWidth() == 0 || getHeight() == 0) return false; - return mNewTabPageRecyclerViewChanged || mSnapshotTileGridChanged + return mNewTabPageRecyclerViewChanged || mNewTabPageLayout.shouldCaptureThumbnail() || getWidth() != mSnapshotWidth || getHeight() != mSnapshotHeight || mRecyclerView.computeVerticalScrollOffset() != mSnapshotScrollY; } @@ -871,65 +344,15 @@ * @see InvalidationAwareThumbnailProvider#captureThumbnail(Canvas) */ void captureThumbnail(Canvas canvas) { - mSearchProviderLogoView.endFadeAnimation(); + mNewTabPageLayout.onPreCaptureThumbnail(); ViewUtils.captureBitmap(this, canvas); mSnapshotWidth = getWidth(); mSnapshotHeight = getHeight(); mSnapshotScrollY = mRecyclerView.computeVerticalScrollOffset(); - mSnapshotTileGridChanged = false; mNewTabPageRecyclerViewChanged = false; } /** - * Shows the most visited placeholder ("Nothing to see here") if there are no most visited - * items and there is no search provider logo. - */ - private void updateTileGridPlaceholderVisibility() { - boolean showPlaceholder = - mTileGroup.hasReceivedData() && mTileGroup.isEmpty() && !mSearchProviderHasLogo; - - mNoSearchLogoSpacer.setVisibility( - (mSearchProviderHasLogo || showPlaceholder) ? View.GONE : View.INVISIBLE); - - mSiteSectionViewHolder.itemView.setVisibility(showPlaceholder ? GONE : VISIBLE); - - if (showPlaceholder) { - if (mTileGridPlaceholder == null) { - ViewStub placeholderStub = - mNewTabPageLayout.findViewById(R.id.tile_grid_placeholder_stub); - mTileGridPlaceholder = placeholderStub.inflate(); - } - mTileGridPlaceholder.setVisibility(VISIBLE); - } else if (mTileGridPlaceholder != null) { - mTileGridPlaceholder.setVisibility(GONE); - } - } - - private static int getMaxTileRows() { - return 2; - } - - /** - * Determines The maximum number of tiles to try and fit in a row. On smaller screens, there - * may not be enough space to fit all of them. - */ - private int getMaxTileColumns() { - if (!mUiConfig.getCurrentDisplayStyle().isSmall() - && SuggestionsConfig.getTileStyle(mUiConfig) == TileView.Style.CLASSIC_CONDENSED) { - return 5; - } - return 4; - } - - private static int getTileTitleLines() { - return 1; - } - - private boolean shouldShowLogo() { - return mSearchProviderHasLogo; - } - - /** * Scrolls to the top of content suggestions header if one exists. If not, scrolls to the top * of the first article suggestion. Uses scrollToPositionWithOffset to position the suggestions * below the toolbar and not below the status bar. @@ -999,92 +422,17 @@ return mRecyclerView.getScrollPosition(); } - private boolean hasLoadCompleted() { - return mHasShownView && mTilesLoaded; - } - - // TileGroup.Observer interface. - - @Override - public void onTileDataChanged() { - mSiteSectionViewHolder.refreshData(); - mSnapshotTileGridChanged = true; - - // The page contents are initially hidden; otherwise they'll be drawn centered on the page - // before the tiles are available and then jump upwards to make space once the tiles are - // available. - if (mNewTabPageLayout.getVisibility() != View.VISIBLE) { - mNewTabPageLayout.setVisibility(View.VISIBLE); - } - } - - @Override - public void onTileCountChanged() { - // If the number of tile rows change while the URL bar is focused, the icons' - // position will be wrong. Schedule the translation to be updated. - if (mUrlFocusChangePercent == 1f) mTileCountChanged = true; - updateTileGridPlaceholderVisibility(); - } - - @Override - public void onTileIconChanged(Tile tile) { - mSiteSectionViewHolder.updateIconView(tile); - mSnapshotTileGridChanged = true; - } - - @Override - public void onTileOfflineBadgeVisibilityChanged(Tile tile) { - mSiteSectionViewHolder.updateOfflineBadge(tile); - mSnapshotTileGridChanged = true; - } - private class SnapScrollRunnable implements Runnable { @Override public void run() { assert mPendingSnapScroll; mPendingSnapScroll = false; - mRecyclerView.snapScroll(mSearchBoxView, getHeight()); + mRecyclerView.snapScroll(); } } - private class UpdateSearchBoxOnScrollRunnable implements Runnable { - @Override - public void run() { - updateSearchBoxOnScroll(); - } - } - - @Override - public void onEnterVr() { - mSearchBoxView.setVisibility(GONE); - } - - @Override - public void onExitVr() { - mSearchBoxView.setVisibility(VISIBLE); - } - private void onDestroy() { mTab.getWindowAndroid().removeContextMenuCloseListener(mContextMenuManager); - VrShellDelegate.unregisterVrModeObserver(this); - } - - private void initializeShortcuts() { - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SIMPLIFIED_NTP) - || isSimplifiedNtpAblationEnabled()) { - return; - } - - ViewStub shortcutsStub = - mRecyclerView.getAboveTheFoldView().findViewById(R.id.shortcuts_stub); - mShortcutsView = (ViewGroup) shortcutsStub.inflate(); - - mShortcutsView.findViewById(R.id.bookmarks_button) - .setOnClickListener(view -> mManager.getNavigationDelegate().navigateToBookmarks()); - - mShortcutsView.findViewById(R.id.downloads_button) - .setOnClickListener( - view -> mManager.getNavigationDelegate().navigateToDownloadManager()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java index 1d795da..7d5ed73 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
@@ -22,7 +22,8 @@ * Simple wrapper on top of a RecyclerView that will acquire focus when tapped. Ensures the * New Tab page receives focus when clicked. */ -public class NewTabPageRecyclerView extends SuggestionsRecyclerView { +public class NewTabPageRecyclerView + extends SuggestionsRecyclerView implements NewTabPageLayout.ScrollDelegate { private final int mToolbarHeight; private final int mSearchBoxTransitionLength; @@ -56,7 +57,12 @@ mContainsLocationBar = containsLocationBar; } - public void setFakeboxDelegate(FakeboxDelegate fakeboxDelegate) { + /** + * Sets the {@link FakeboxDelegate} associated with the new tab page. + * @param fakeboxDelegate The {@link FakeboxDelegate} used to determine whether the URL bar + * has focus. + */ + public void setFakeboxDelegate(FakeboxDelegate fakeboxDelegate, View fakeBox) { mFakeboxDelegate = fakeboxDelegate; } @@ -117,28 +123,14 @@ currentScroll, regionStart, regionEnd, (regionStart + regionEnd) / 2); } - /** - * Snaps the scroll point of the RecyclerView to prevent the user from scrolling to midway - * through a transition and to allow peeking card behaviour. - */ - public void snapScroll(View fakeBox, int parentHeight) { - int initialScroll = computeVerticalScrollOffset(); - - int scrollTo = calculateSnapPosition(initialScroll, fakeBox, parentHeight); - - // Calculating the snap position should be idempotent. - assert scrollTo == calculateSnapPosition(scrollTo, fakeBox, parentHeight); - - smoothScrollBy(0, scrollTo - initialScroll); - } - @VisibleForTesting - int calculateSnapPosition(int scrollPosition, View fakeBox, int parentHeight) { + int calculateSnapPosition(int scrollPosition, int parentHeight) { if (mContainsLocationBar) { // Snap scroll to prevent only part of the toolbar from showing. scrollPosition = calculateSnapPositionForRegion(scrollPosition, 0, mToolbarHeight); // Snap scroll to prevent resting in the middle of the omnibox transition. + View fakeBox = mAboveTheFoldView.getSearchBoxView(); int fakeBoxUpperBound = fakeBox.getTop() + fakeBox.getPaddingTop(); scrollPosition = calculateSnapPositionForRegion(scrollPosition, fakeBoxUpperBound - mSearchBoxTransitionLength, fakeBoxUpperBound); @@ -152,4 +144,37 @@ ViewUtils.gatherTransparentRegionsForOpaqueView(this, region); return true; } + + // NewTabPageLayout.ScrollDelegate interface. + + @Override + public boolean isScrollViewInitialized() { + // During startup the view may not be fully initialized, so we check to see if some basic + // view properties (height of the RecyclerView) are sane. + return getHeight() > 0; + } + + @Override + public int getVerticalScrollOffset() { + return computeVerticalScrollOffset(); + } + + @Override + public boolean isChildVisibleAtPosition(int position) { + return position >= getLinearLayoutManager().findFirstVisibleItemPosition() + && position <= getLinearLayoutManager().findLastVisibleItemPosition(); + } + + @Override + public void snapScroll() { + int parentHeight = ((View) getParent()).getHeight(); + int initialScroll = computeVerticalScrollOffset(); + + int scrollTo = calculateSnapPosition(initialScroll, parentHeight); + + // Calculating the snap position should be idempotent. + assert scrollTo == calculateSnapPosition(scrollTo, parentHeight); + + smoothScrollBy(0, scrollTo - initialScroll); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OWNERS index bb7ed84d..bf175ef9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OWNERS
@@ -1,4 +1,3 @@ -mariakhomenko@chromium.org tedchoc@chromium.org yusufo@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java index 11e0120c..e3da2b3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ExpandablePreferenceGroup.java
@@ -6,75 +6,69 @@ import android.content.Context; import android.graphics.drawable.Drawable; +import android.os.Build; import android.preference.PreferenceGroup; -import android.text.Spannable; -import android.text.SpannableStringBuilder; -import android.text.style.ForegroundColorSpan; +import android.support.v4.graphics.drawable.DrawableCompat; +import android.support.v7.content.res.AppCompatResources; import android.util.AttributeSet; import android.view.View; -import android.widget.ImageView; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; - -import java.util.Locale; +import org.chromium.ui.drawable.StateListDrawableBuilder; +import org.chromium.ui.widget.CheckableImageView; /** - * A preference category that accepts clicks for toggling on/off. + * A preference category that can be in either expanded or collapsed state. It shows expand/collapse + * arrow and changes content description for a11y according to the current state. Use + * {@link #setExpanded} to toggle collapsed/expanded state. Please note that this preference group + * won't modify the set of children preferences on expanded state change. */ public class ExpandablePreferenceGroup extends PreferenceGroup { + private boolean mExpanded = true; private Drawable mDrawable; - private ImageView mImageView; - - // Whether the PreferenceGroup is in an expanded or collapsed state. - private boolean mExpanded; public ExpandablePreferenceGroup(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.preferenceStyle); - setWidgetLayoutResource(R.layout.site_list_expandable_header); + setWidgetLayoutResource(R.layout.checkable_image_view_widget); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // Fix animations. Background: setWidgetLayout resource call above disables view + // recycling, thus breaking animations. Views recycling is safe in this case, as this + // Preference doesn't change view types on the fly. + setRecycleEnabled(true); + } + } + + /** Returns whether the preference group is expanded. */ + public boolean isExpanded() { + return mExpanded; } /** - * Set the title for the preference group. - * @param resourceId The resource id of the text to use. - * @param count The number of entries the preference group contains. + * Set the expanded/collapsed state for the preference group. + * @param expanded The new expanded state. */ - public void setGroupTitle(int resourceId, int count) { - SpannableStringBuilder spannable = - new SpannableStringBuilder(getContext().getResources().getString(resourceId)); - String prefCount = String.format(Locale.getDefault(), " - %d", count); - spannable.append(prefCount); - - // Color the first part of the title blue. - ForegroundColorSpan blueSpan = new ForegroundColorSpan(ApiCompatibilityUtils.getColor( - getContext().getResources(), R.color.google_blue_700)); - spannable.setSpan(blueSpan, 0, spannable.length() - prefCount.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - - // Gray out the total count of items. - int gray = - ApiCompatibilityUtils.getColor(getContext().getResources(), R.color.black_alpha_54); - spannable.setSpan(new ForegroundColorSpan(gray), - spannable.length() - prefCount.length(), - spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - setTitle(spannable); - } - - public void setExpanded(boolean expanded) { + public final void setExpanded(boolean expanded) { + if (mExpanded == expanded) return; mExpanded = expanded; + onExpandedChanged(expanded); + notifyChanged(); } - @Override - public void setIcon(Drawable drawable) { - mDrawable = drawable; - if (mImageView != null) mImageView.setImageDrawable(mDrawable); - } + /** Subclasses may override this method to handle changes to the expanded/collapsed state. */ + protected void onExpandedChanged(boolean expanded) {} @Override protected void onBindView(View view) { super.onBindView(view); - mImageView = (ImageView) view.findViewById(R.id.expando); - if (mDrawable != null) mImageView.setImageDrawable(mDrawable); + + if (mDrawable == null) { + mDrawable = createDrawable(getContext()); + } + CheckableImageView imageView = + (CheckableImageView) view.findViewById(R.id.checkable_image_view); + imageView.setImageDrawable(mDrawable); + imageView.setChecked(mExpanded); // For accessibility, read out the whole title and whether the group is collapsed/expanded. String description = getTitle() + getContext().getResources().getString(mExpanded @@ -82,4 +76,21 @@ : R.string.accessibility_collapsed_group); view.setContentDescription(description); } + + private static Drawable createDrawable(Context context) { + StateListDrawableBuilder builder = new StateListDrawableBuilder(context); + StateListDrawableBuilder.State checked = builder.addState( + R.drawable.ic_expand_less_black_24dp, android.R.attr.state_checked); + StateListDrawableBuilder.State unchecked = + builder.addState(R.drawable.ic_expand_more_black_24dp); + builder.addTransition( + checked, unchecked, R.drawable.transition_expand_less_expand_more_black_24dp); + builder.addTransition( + unchecked, checked, R.drawable.transition_expand_more_expand_less_black_24dp); + + Drawable tintableDrawable = DrawableCompat.wrap(builder.build()); + DrawableCompat.setTintList(tintableDrawable, + AppCompatResources.getColorStateList(context, R.color.dark_mode_tint)); + return tintableDrawable; + } }
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 31ef9023..5ef93b1d 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
@@ -35,7 +35,9 @@ */ public class MainPreferences extends PreferenceFragment implements SigninManager.SignInStateObserver, TemplateUrlService.LoadListener { + public static final String PREF_ACCOUNT_SECTION = "account_section"; public static final String PREF_SIGN_IN = "sign_in"; + public static final String PREF_SYNC_AND_SERVICES = "sync_and_services"; public static final String PREF_AUTOFILL_SETTINGS = "autofill_settings"; public static final String PREF_SEARCH_ENGINE = "search_engine"; public static final String PREF_SAVED_PASSWORDS = "saved_passwords"; @@ -93,8 +95,14 @@ private void createPreferences() { PreferenceUtils.addPreferencesFromResource(this, R.xml.main_preferences); - cachePreferences(); + + // Remove UnifiedConsent preferences if the feature isn't enabled. + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT)) { + getPreferenceScreen().removePreference(findPreference(PREF_ACCOUNT_SECTION)); + getPreferenceScreen().removePreference(findPreference(PREF_SYNC_AND_SERVICES)); + } + setManagedPreferenceDelegateForPreference(PREF_SEARCH_ENGINE); setManagedPreferenceDelegateForPreference(PREF_AUTOFILL_SETTINGS); setManagedPreferenceDelegateForPreference(PREF_SAVED_PASSWORDS);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java index e83e1e8..81bbc4db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java
@@ -15,6 +15,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; import org.chromium.chrome.browser.signin.AccountManagementFragment; import org.chromium.chrome.browser.signin.AccountSigninActivity; @@ -171,7 +172,11 @@ private void setupGenericPromo() { setLayoutResource(R.layout.account_management_account_row); setTitle(R.string.sign_in_to_chrome); - setSummary(R.string.sign_in_to_chrome_summary); + + boolean unifiedConsent = ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT); + setSummary( + unifiedConsent ? R.string.signin_pref_summary : R.string.sign_in_to_chrome_summary); + setFragment(null); setIcon(AppCompatResources.getDrawable(getContext(), R.drawable.logo_avatar_anonymous)); setWidgetLayoutResource(0);
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 new file mode 100644 index 0000000..5d02611 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
@@ -0,0 +1,26 @@ +// 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; + +import android.os.Bundle; +import android.preference.PreferenceFragment; +import android.support.annotation.Nullable; + +import org.chromium.chrome.R; + +/** + * Settings fragment to customize Sync options (data types, encryption) and other services that + * communicate with Google. + */ +public class SyncAndServicesPreferences extends PreferenceFragment { + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getActivity().setTitle(R.string.prefs_sync_and_services); + + // TODO(https://crbug.com/814728): Add UnifiedConsent preferences here. + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java index 003ae83..e924307 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java
@@ -5,11 +5,10 @@ package org.chromium.chrome.browser.preferences.download; import android.content.Context; -import android.os.Environment; +import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.widget.TextViewCompat; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -19,11 +18,11 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.download.DirectoryOption; +import org.chromium.chrome.browser.download.DirectoryOption.AllDirectoriesTask; import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.widget.TintedImageView; -import java.io.File; import java.util.ArrayList; import java.util.List; @@ -32,6 +31,21 @@ * download location. */ public class DownloadDirectoryAdapter extends ArrayAdapter<Object> { + /** + * Delegate to handle directory options results and observe data changes. + */ + public interface Delegate { + /** + * Called after getting all download directories. + */ + void onDirectoryOptionsReady(); + + /** + * Called after the user selected another download directory option. + */ + void onDirectorySelectionChanged(); + } + public static int NO_SELECTED_ITEM_ID = -1; public static int SELECTED_ITEM_NOT_INITIALIZED = -2; @@ -39,15 +53,18 @@ private Context mContext; private LayoutInflater mLayoutInflater; + protected Delegate mDelegate; private List<DirectoryOption> mCanonicalOptions = new ArrayList<>(); private List<DirectoryOption> mAdditionalOptions = new ArrayList<>(); private List<DirectoryOption> mErrorOptions = new ArrayList<>(); + boolean mIsDirectoryOptionsReady; - public DownloadDirectoryAdapter(@NonNull Context context) { + public DownloadDirectoryAdapter(@NonNull Context context, Delegate delegate) { super(context, android.R.layout.simple_spinner_item); mContext = context; + mDelegate = delegate; mLayoutInflater = LayoutInflater.from(context); refreshData(); @@ -153,6 +170,8 @@ * NO_SELECTED_ITEM_ID if no item matches the default path. */ public int getSelectedItemId() { + assert mIsDirectoryOptionsReady : "Must be called after directory options query is done"; + if (mSelectedPosition == SELECTED_ITEM_NOT_INITIALIZED) { mSelectedPosition = initSelectedIdFromPref(); } @@ -199,48 +218,55 @@ return mErrorOptions.isEmpty(); } + boolean isDirectoryOptionsReady() { + return mIsDirectoryOptionsReady; + } + private void refreshData() { - setCanonicalDirectoryOptions(); - setAdditionalDirectoryOptions(); - adjustErrorDirectoryOption(); - } - - private void setCanonicalDirectoryOptions() { mCanonicalOptions.clear(); - File directoryLocation = - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - mCanonicalOptions.add(new DirectoryOption(mContext.getString(R.string.menu_downloads), - directoryLocation.getAbsolutePath(), directoryLocation.getUsableSpace(), - directoryLocation.getTotalSpace(), DirectoryOption.DEFAULT_OPTION)); - } - - private void setAdditionalDirectoryOptions() { mAdditionalOptions.clear(); + mErrorOptions.clear(); - // If there are no more additional directories, it is only the primary storage available. - String[] externalDirs = DownloadUtils.getAllDownloadDirectories(); - if (externalDirs.length <= 1) return; + // Retrieve all download directories. + AllDirectoriesTask task = new AllDirectoriesTask() { + @Override + protected void onPostExecute(ArrayList<DirectoryOption> dirs) { + int numOtherAdditionalDirectories = 0; - int numOtherAdditionalDirectories = 0; - for (String dir : externalDirs) { - if (TextUtils.isEmpty(dir)) continue; + for (DirectoryOption directory : dirs) { + switch (directory.type) { + case DirectoryOption.DEFAULT_OPTION: + directory.name = mContext.getString(R.string.menu_downloads); + mCanonicalOptions.add(directory); + break; + case DirectoryOption.ADDITIONAL_OPTION: + String directoryName = (numOtherAdditionalDirectories > 0) + ? mContext.getString(org.chromium.chrome.R.string + .downloads_location_sd_card_number, + numOtherAdditionalDirectories + 1) + : mContext.getString(org.chromium.chrome.R.string + .downloads_location_sd_card); + directory.name = directoryName; + mAdditionalOptions.add(directory); + numOtherAdditionalDirectories++; + break; + case DirectoryOption.ERROR_OPTION: + directory.name = mContext.getString( + R.string.download_location_no_available_locations); + mErrorOptions.add(directory); + break; + default: + break; + } + } - // Skip the directory that is in primary storage. - if (dir.contains(Environment.getExternalStorageDirectory().getAbsolutePath())) continue; - - // Add index (ie. SD Card 2) if there is more than one secondary storage option. - String directoryName = (numOtherAdditionalDirectories > 0) - ? mContext.getString( - org.chromium.chrome.R.string.downloads_location_sd_card_number, - numOtherAdditionalDirectories + 1) - : mContext.getString(org.chromium.chrome.R.string.downloads_location_sd_card); - - File file = new File(dir); - mAdditionalOptions.add(new DirectoryOption(directoryName, file.getAbsolutePath(), - file.getUsableSpace(), file.getTotalSpace(), - DirectoryOption.ADDITIONAL_OPTION)); - numOtherAdditionalDirectories++; - } + // After all directory retrieved, update the UI. + // notifyDataSetChanged(); + mIsDirectoryOptionsReady = true; + if (mDelegate != null) mDelegate.onDirectoryOptionsReady(); + } + }; + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private void adjustErrorDirectoryOption() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java index b3aac9fc..5d8a8fc3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java
@@ -20,9 +20,11 @@ /** * The preference used to save the download directory in download settings page. */ -public class DownloadLocationPreference extends DialogPreference { +public class DownloadLocationPreference + extends DialogPreference implements DownloadDirectoryAdapter.Delegate { /** - * Provides data for the list of available download directories options. + * Provides data for the list of available download directories options. Uses an asynchronous + * operation to query the directory options. */ private DownloadLocationPreferenceAdapter mAdapter; @@ -36,13 +38,15 @@ */ public DownloadLocationPreference(Context context, AttributeSet attrs) { super(context, attrs); - mAdapter = new DownloadLocationPreferenceAdapter(context, this); + mAdapter = new DownloadLocationPreferenceAdapter(getContext(), this); } /** * Updates the summary that shows the download location directory. */ public void updateSummary() { + if (!mAdapter.isDirectoryOptionsReady()) return; + DirectoryOption directoryOption = (DirectoryOption) mAdapter.getItem(mAdapter.getSelectedItemId()); final SpannableStringBuilder summaryBuilder = new SpannableStringBuilder(); @@ -60,7 +64,28 @@ View view = LayoutInflater.from(getContext()) .inflate(R.layout.download_location_preference, null); mListView = (ListView) (view.findViewById(R.id.location_preference_list_view)); - mListView.setAdapter(mAdapter); + + // Hook to the adapter if |onDirectoryOptionsReady| is called before |onCreateDialogView|. + if (mAdapter.isDirectoryOptionsReady()) { + mListView.setAdapter(mAdapter); + } return view; } + + @Override + public void onDirectoryOptionsReady() { + if (mAdapter.getSelectedItemId() == DownloadDirectoryAdapter.NO_SELECTED_ITEM_ID) { + mAdapter.useFirstValidSelectableItemId(); + } + + // Hook to the adapter if |onCreateDialogView| is called before |onDirectoryOptionsReady|. + if (mListView != null) mListView.setAdapter(mAdapter); + + updateSummary(); + } + + @Override + public void onDirectorySelectionChanged() { + updateSummary(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreferenceAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreferenceAdapter.java index 179020b..abd8af3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreferenceAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreferenceAdapter.java
@@ -26,19 +26,11 @@ */ public class DownloadLocationPreferenceAdapter extends DownloadDirectoryAdapter implements OnClickListener { - private DownloadLocationPreference mPreference; - /** * Constructor of DownloadLocationPreferenceAdapter. */ - public DownloadLocationPreferenceAdapter( - Context context, DownloadLocationPreference preference) { - super(context); - mPreference = preference; - - if (getSelectedItemId() == NO_SELECTED_ITEM_ID) { - useFirstValidSelectableItemId(); - } + public DownloadLocationPreferenceAdapter(Context context, Delegate delegate) { + super(context, delegate); } @Override @@ -114,7 +106,7 @@ mSelectedPosition = selectedId; // Update the preference after selected position is updated. - mPreference.updateSummary(); + if (mDelegate != null) mDelegate.onDirectorySelectionChanged(); option.recordDirectoryOptionType();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleCategoryPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleCategoryPreferences.java index dcc55ef..cfc1f729 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleCategoryPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleCategoryPreferences.java
@@ -17,7 +17,10 @@ import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AlertDialog; import android.support.v7.widget.SearchView; +import android.text.Spannable; +import android.text.SpannableStringBuilder; import android.text.format.Formatter; +import android.text.style.ForegroundColorSpan; import android.util.Pair; import android.view.LayoutInflater; import android.view.Menu; @@ -30,6 +33,7 @@ import android.widget.ListView; import android.widget.TextView; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.help.HelpAndFeedback; @@ -47,7 +51,6 @@ import org.chromium.chrome.browser.preferences.ProtectedContentResetCredentialConfirmDialogFragment; import org.chromium.chrome.browser.preferences.website.Website.StoredDataClearedCallback; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.ui.widget.Toast; import java.util.ArrayList; @@ -55,6 +58,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; /** @@ -209,14 +213,8 @@ int resourceId = toggleValue ? R.string.website_settings_allowed_group_heading : R.string.website_settings_exceptions_group_heading; - - // Set the title and arrow icons for the header. - allowedGroup.setGroupTitle(resourceId, numAllowed); - TintedDrawable icon = TintedDrawable.constructTintedDrawable(getActivity(), - mAllowListExpanded ? R.drawable.ic_expand_more_black_24dp - : R.drawable.ic_expand_less_black_24dp); + allowedGroup.setTitle(getHeaderTitle(resourceId, numAllowed)); allowedGroup.setExpanded(mAllowListExpanded); - allowedGroup.setIcon(icon); } private void updateBlockedHeader(int numBlocked) { @@ -232,12 +230,27 @@ int resourceId = mCategory.showSoundSites() ? R.string.website_settings_blocked_group_heading_sound : R.string.website_settings_blocked_group_heading; - blockedGroup.setGroupTitle(resourceId, numBlocked); - TintedDrawable icon = TintedDrawable.constructTintedDrawable(getActivity(), - mBlockListExpanded ? R.drawable.ic_expand_more_black_24dp - : R.drawable.ic_expand_less_black_24dp); + blockedGroup.setTitle(getHeaderTitle(resourceId, numBlocked)); blockedGroup.setExpanded(mBlockListExpanded); - blockedGroup.setIcon(icon); + } + + private CharSequence getHeaderTitle(int resourceId, int count) { + SpannableStringBuilder spannable = + new SpannableStringBuilder(getResources().getString(resourceId)); + String prefCount = String.format(Locale.getDefault(), " - %d", count); + spannable.append(prefCount); + + // Color the first part of the title blue. + ForegroundColorSpan blueSpan = new ForegroundColorSpan( + ApiCompatibilityUtils.getColor(getResources(), R.color.google_blue_700)); + spannable.setSpan(blueSpan, 0, spannable.length() - prefCount.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + + // Gray out the total count of items. + int gray = ApiCompatibilityUtils.getColor(getResources(), R.color.black_alpha_54); + spannable.setSpan(new ForegroundColorSpan(gray), spannable.length() - prefCount.length(), + spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return spannable; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java index eb9b65a..26afb4e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java
@@ -12,6 +12,7 @@ import com.google.android.gms.gcm.GcmListenerService; import com.google.ipc.invalidation.ticl.android2.channel.AndroidGcmController; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.ProcessInitException; @@ -38,7 +39,7 @@ @Override public void onMessageReceived(final String from, final Bundle data) { boolean hasCollapseKey = !TextUtils.isEmpty(data.getString("collapse_key")); - GcmUma.recordDataMessageReceived(getApplicationContext(), hasCollapseKey); + GcmUma.recordDataMessageReceived(ContextUtils.getApplicationContext(), hasCollapseKey); String invalidationSenderId = AndroidGcmController.get(this).getSenderId(); if (from.equals(invalidationSenderId)) { @@ -46,8 +47,6 @@ return; } - final Context applicationContext = getApplicationContext(); - // Dispatch the message to the GCM Driver for native features. ThreadUtils.runOnUiThread(new Runnable() { @Override @@ -60,7 +59,7 @@ return; } - scheduleOrDispatchMessageToDriver(applicationContext, message); + scheduleOrDispatchMessageToDriver(message); } }); } @@ -68,13 +67,15 @@ @Override public void onMessageSent(String msgId) { Log.d(TAG, "Message sent successfully. Message id: " + msgId); - GcmUma.recordGcmUpstreamHistogram(getApplicationContext(), GcmUma.UMA_UPSTREAM_SUCCESS); + GcmUma.recordGcmUpstreamHistogram( + ContextUtils.getApplicationContext(), GcmUma.UMA_UPSTREAM_SUCCESS); } @Override public void onSendError(String msgId, String error) { Log.w(TAG, "Error in sending message. Message id: " + msgId + " Error: " + error); - GcmUma.recordGcmUpstreamHistogram(getApplicationContext(), GcmUma.UMA_UPSTREAM_SEND_FAILED); + GcmUma.recordGcmUpstreamHistogram( + ContextUtils.getApplicationContext(), GcmUma.UMA_UPSTREAM_SEND_FAILED); } @Override @@ -82,7 +83,7 @@ // TODO(johnme): Ask GCM to include the subtype in this event. Log.w(TAG, "Push messages were deleted, but we can't tell the Service Worker as we don't" + "know what subtype (app ID) it occurred for."); - GcmUma.recordDeletedMessages(getApplicationContext()); + GcmUma.recordDeletedMessages(ContextUtils.getApplicationContext()); } /** @@ -91,7 +92,7 @@ * Must be called on the UI thread both for the BackgroundTaskScheduler and for dispatching * the |message| to the GCMDriver. */ - static void scheduleOrDispatchMessageToDriver(Context context, GCMMessage message) { + static void scheduleOrDispatchMessageToDriver(GCMMessage message) { ThreadUtils.assertOnUiThread(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { @@ -103,10 +104,11 @@ .setExtras(extras) .build(); - BackgroundTaskSchedulerFactory.getScheduler().schedule(context, backgroundTask); + BackgroundTaskSchedulerFactory.getScheduler().schedule( + ContextUtils.getApplicationContext(), backgroundTask); } else { - dispatchMessageToDriver(context, message); + dispatchMessageToDriver(ContextUtils.getApplicationContext(), message); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java index 257b716..af3f831 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java
@@ -16,6 +16,7 @@ import com.google.android.gms.gcm.GoogleCloudMessaging; import com.google.ipc.invalidation.ticl.android2.channel.GcmUpstreamSenderService; +import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.init.ProcessInitializationHandler; import org.chromium.chrome.browser.signin.OAuth2TokenService; @@ -40,12 +41,11 @@ @Override public void deliverMessage(final String to, final Bundle data) { final Bundle dataToSend = createDeepCopy(data); - final Context applicationContext = getApplicationContext(); ThreadUtils.postOnUiThread(new Runnable() { @Override public void run() { - doDeliverMessage(applicationContext, to, dataToSend); + doDeliverMessage(ContextUtils.getApplicationContext(), to, dataToSend); } }); } @@ -82,8 +82,8 @@ @Override public void tokenUnavailable(boolean isTransientError) { - GcmUma.recordGcmUpstreamHistogram( - getApplicationContext(), GcmUma.UMA_UPSTREAM_TOKEN_REQUEST_FAILED); + GcmUma.recordGcmUpstreamHistogram(ContextUtils.getApplicationContext(), + GcmUma.UMA_UPSTREAM_TOKEN_REQUEST_FAILED); } }); } @@ -100,7 +100,8 @@ } String msgId = UUID.randomUUID().toString(); try { - GoogleCloudMessaging.getInstance(getApplicationContext()).send(to, msgId, 1, data); + GoogleCloudMessaging.getInstance(ContextUtils.getApplicationContext()) + .send(to, msgId, 1, data); } catch (IOException | IllegalArgumentException exception) { Log.w(TAG, "Send message failed"); GcmUma.recordGcmUpstreamHistogram(context, GcmUma.UMA_UPSTREAM_SEND_FAILED);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java index 231cfdf..a81fbbb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsBinder.java
@@ -62,10 +62,12 @@ private final TintedImageView mThumbnailView; private final @Nullable ImageView mVideoBadge; private final ImageView mOfflineBadge; + private final @Nullable ImageView mOfflineBadgePublisherRow; private final View mPublisherBar; private final int mThumbnailSize; private final int mSmallThumbnailCornerRadius; + boolean mShowThumbnail; boolean mHasVideoBadge; boolean mHasOfflineBadge; @@ -95,6 +97,8 @@ mAgeTextView = mCardContainerView.findViewById(R.id.article_age); mVideoBadge = mCardContainerView.findViewById(R.id.video_badge); mOfflineBadge = mCardContainerView.findViewById(R.id.offline_icon); + mOfflineBadgePublisherRow = + mCardContainerView.findViewById(R.id.offline_icon_publisher_row); mPublisherBar = mCardContainerView.findViewById(R.id.publisher_bar); if (mIsContextual) { @@ -132,6 +136,7 @@ showSnippet ? MAX_HEADER_LINES_WITH_SNIPPET : MAX_HEADER_LINES); mThumbnailView.setVisibility(showThumbnail ? View.VISIBLE : View.GONE); mHasVideoBadge = showThumbnailVideoBadge; + mShowThumbnail = showThumbnail; updateVisibilityForBadges(); ViewGroup.MarginLayoutParams publisherBarParams = @@ -170,7 +175,15 @@ mVideoBadge.setVisibility( mHasVideoBadge && !mHasOfflineBadge ? View.VISIBLE : View.GONE); } - mOfflineBadge.setVisibility(mHasOfflineBadge ? View.VISIBLE : View.GONE); + + boolean showPublisherRowOfflineBadge = + mOfflineBadgePublisherRow != null && mHasOfflineBadge && !mShowThumbnail; + mOfflineBadge.setVisibility( + mHasOfflineBadge && !showPublisherRowOfflineBadge ? View.VISIBLE : View.GONE); + if (mOfflineBadgePublisherRow != null) { + mOfflineBadgePublisherRow.setVisibility( + showPublisherRowOfflineBadge ? View.VISIBLE : View.GONE); + } } private void setFavicon() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 8d1c956..75097c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -58,7 +58,6 @@ import org.chromium.chrome.browser.WebContentsFactory; import org.chromium.chrome.browser.banners.AppBannerManager; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; -import org.chromium.chrome.browser.content.ContentUtils; import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator; import org.chromium.chrome.browser.contextualsearch.ContextualSearchTabHelper; import org.chromium.chrome.browser.crypto.CipherFactory; @@ -1811,7 +1810,6 @@ } mWebContents = webContents; - ContentUtils.setUserAgentOverride(mWebContents); mContentViewCore = cvc; mContentView = webContents.getViewAndroidDelegate().getContainerView();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarCoordinator.java index 0aaad06..765028f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarCoordinator.java
@@ -96,6 +96,7 @@ searchAcceleratorListener, homeButtonListener, menuButtonListener); mMediator.setLayoutManager(layoutManager); mMediator.setOverviewModeBehavior(overviewModeBehavior); + mMediator.setToolbarSwipeHandler(layoutManager.getToolbarSwipeHandler()); mTabSwitcherButtonCoordinator.setTabSwitcherListener(tabSwitcherListener); mTabSwitcherButtonCoordinator.setTabModelSelector(tabModelSelector);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java index 39f767b..f367dd18 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java
@@ -12,6 +12,7 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutManager; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; +import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; @@ -50,6 +51,13 @@ } /** + * @param swipeHandler The handler that controls the toolbar swipe behavior. + */ + void setToolbarSwipeHandler(EdgeSwipeHandler swipeHandler) { + mModel.setValue(BottomToolbarModel.TOOLBAR_SWIPE_HANDLER, swipeHandler); + } + + /** * Clean up anything that needs to be when the bottom toolbar is destroyed. */ public void destroy() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java index cc66e6c..8be93b3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java
@@ -8,6 +8,7 @@ import android.view.View.OnTouchListener; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.modelutil.PropertyModel; /** @@ -41,10 +42,14 @@ /** Whether or not the update badge is visible. */ public static final BooleanPropertyKey UPDATE_BADGE_VISIBLE = new BooleanPropertyKey(); + /** A handler for swipe events on the toolbar. */ + public static final ObjectPropertyKey<EdgeSwipeHandler> TOOLBAR_SWIPE_HANDLER = + new ObjectPropertyKey<>(); + /** Default constructor. */ public BottomToolbarModel() { super(Y_OFFSET, ANDROID_VIEW_VISIBLE, SEARCH_ACCELERATOR_LISTENER, HOME_BUTTON_LISTENER, MENU_BUTTON_LISTENER, LAYOUT_MANAGER, SEARCH_ACCELERATOR_VISIBLE, - UPDATE_BADGE_VISIBLE); + UPDATE_BADGE_VISIBLE, TOOLBAR_SWIPE_HANDLER); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java index 4acd043..9b36d64 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java
@@ -80,6 +80,9 @@ .setVisibility(model.getValue(BottomToolbarModel.UPDATE_BADGE_VISIBLE) ? View.VISIBLE : View.GONE); + } else if (BottomToolbarModel.TOOLBAR_SWIPE_HANDLER == propertyKey) { + view.toolbarRoot.setSwipeDetector( + model.getValue(BottomToolbarModel.TOOLBAR_SWIPE_HANDLER)); } else { assert false : "Unhandled property detected in BottomToolbarViewBinder!"; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java index 8ac9ea8..0aeac71 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java
@@ -9,7 +9,10 @@ import android.graphics.PorterDuff; import android.graphics.Rect; import android.util.AttributeSet; +import android.view.MotionEvent; +import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; +import org.chromium.chrome.browser.contextualsearch.SwipeRecognizer; import org.chromium.chrome.browser.widget.ViewResourceFrameLayout; import org.chromium.ui.resources.dynamics.ViewResourceAdapter; @@ -24,10 +27,43 @@ /** The height of the shadow sitting above the bottom view in px. */ private int mTopShadowHeightPx; + /** A swipe recognizer for handling swipe gestures. */ + private SwipeRecognizer mSwipeRecognizer; + public ScrollingBottomViewResourceFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } + /** + * Set the swipe handler for this view and set {@link #isClickable()} to true to allow motion + * events to be intercepted by the view itself. + * @param handler A handler for swipe events on this view. + */ + public void setSwipeDetector(EdgeSwipeHandler handler) { + mSwipeRecognizer = new SwipeRecognizer(getContext()); + mSwipeRecognizer.setSwipeHandler(handler); + + // TODO(mdjones): This line of code makes it impossible to scroll through the bottom + // toolbar. If the user accidentally swipes up on this view, the scroll no longer goes + // through to the web contents. We should figure out how to make this work while also + // supporting the toolbar swipe behavior. + setClickable(true); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + boolean handledEvent = false; + if (mSwipeRecognizer != null) handledEvent = mSwipeRecognizer.onTouchEvent(event); + return handledEvent || super.onInterceptTouchEvent(event); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + boolean handledEvent = false; + if (mSwipeRecognizer != null) handledEvent = mSwipeRecognizer.onTouchEvent(event); + return handledEvent || super.onTouchEvent(event); + } + @Override protected ViewResourceAdapter createResourceAdapter() { return new ViewResourceAdapter(this) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java index 8ee27d8..7dcba489 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java
@@ -114,17 +114,15 @@ /** * @param activity The Activity to check. * @param intent The intent the Activity was launched with. - * @return Whether this Activity is launching into VR, or is already in VR. + * @return Whether this Activity is launching into VR. */ public static boolean isLaunchingIntoVr(Activity activity, Intent intent) { if (!VrShellDelegate.deviceSupportsVrLaunches()) return false; - return VrShellDelegate.isInVr() || VrShellDelegate.isVrModeEnabled(activity) - || isLaunchingIntoVrBrowsing(activity, intent) || isCustomTabVrIntent(intent); + return isLaunchingIntoVrBrowsing(activity, intent) || isCustomTabVrIntent(intent); } private static boolean isLaunchingIntoVrBrowsing(Activity activity, Intent intent) { - return (isVrIntent(intent) || VrIntentUtils.wouldUse2DInVrRenderingMode(activity)) - && VrShellDelegate.activitySupportsVrBrowsing(activity); + return isVrIntent(intent) && VrShellDelegate.activitySupportsVrBrowsing(activity); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 5e8aba1..52c52365 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -33,6 +33,7 @@ import android.widget.FrameLayout; import org.chromium.base.ActivityState; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationStatus; import org.chromium.base.CollectionUtil; import org.chromium.base.ContextUtils; @@ -58,6 +59,7 @@ import org.chromium.content_public.browser.ScreenOrientationDelegate; import org.chromium.content_public.browser.ScreenOrientationProvider; import org.chromium.ui.UiUtils; +import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.display.DisplayAndroidManager; import org.chromium.ui.widget.UiWidgetFactory; @@ -652,6 +654,7 @@ * This is called every time ChromeActivity gets a new intent. */ public static void onNewIntentWithNative(ChromeActivity activity, Intent intent) { + if (activity.isFinishing()) return; if (!VrIntentUtils.isLaunchingIntoVr(activity, intent)) return; VrShellDelegate instance = getInstance(activity); @@ -663,11 +666,30 @@ * This is called when ChromeTabbedActivity gets a new intent before native is initialized. */ public static void maybeHandleVrIntentPreNative(ChromeActivity activity, Intent intent) { - if (!VrIntentUtils.isVrIntent(intent)) { - if (!VrIntentUtils.isLaunchingIntoVr(activity, intent)) return; - // This is to handle intents that are sent directly to ChromeActivitys, bypassing the - // launcher. - intent.addCategory(VrIntentUtils.DAYDREAM_CATEGORY); + boolean launchingIntoVr = VrIntentUtils.isLaunchingIntoVr(activity, intent); + + if (!launchingIntoVr) { + // We trust that if an intent is targeted for 2D, that Chrome should switch to 2D + // regardless of whether the user is in headset. + if (VrShellDelegate.isInVr()) VrShellDelegate.forceExitVrImmediately(); + return; + } + + if (VrShellDelegate.bootsToVr() && launchingIntoVr) { + boolean onMainDisplay = DisplayAndroid.getNonMultiDisplay(activity).getDisplayId() + == Display.DEFAULT_DISPLAY; + // TODO(mthiesse): There's a known race when switching displays on Android O/P that can + // lead us to actually be on the main display, but our context still thinks it's on + // the virtual display. This is intended to be fixed for Android Q+, but we can work + // around the race by explicitly relaunching ourselves to the main display. + if (!onMainDisplay) { + Log.i(TAG, "Relaunching Chrome onto the main display."); + activity.finish(); + activity.startActivity(intent, + ApiCompatibilityUtils.createLaunchDisplayIdActivityOptions( + Display.DEFAULT_DISPLAY)); + return; + } } if (sInstance != null && !sInstance.mInternalIntentUsedToStartVr) { @@ -1510,6 +1532,10 @@ private void presentRequested() { if (DEBUG_LOGS) Log.i(TAG, "WebVR page requested presentation"); mRequestedWebVr = true; + if (VrShellDelegate.bootsToVr() && !mInVr) { + maybeSetPresentResult(false, false); + return; + } switch (enterVrInternal()) { case ENTER_VR_NOT_NECESSARY: mVrShell.setWebVrModeEnabled(true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java index 18afae3..d631155 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webauth/AuthenticatorImpl.java
@@ -47,7 +47,7 @@ } mIsOperationPending = true; - onError(AuthenticatorStatus.NOT_IMPLEMENTED); + Fido2ApiHandler.getInstance().makeCredential(options, mRenderFrameHost, this); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webauth/Fido2ApiHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/webauth/Fido2ApiHandler.java index 1204799..8d5df87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webauth/Fido2ApiHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webauth/Fido2ApiHandler.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.webauth; import org.chromium.base.ThreadUtils; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.AppHooks; import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.webauth.mojom.PublicKeyCredentialCreationOptions; @@ -17,6 +18,11 @@ public class Fido2ApiHandler { private static Fido2ApiHandler sInstance; + @VisibleForTesting + static void overrideInstanceForTesting(Fido2ApiHandler instance) { + sInstance = instance; + } + /** * @return The Fido2ApiHandler for use during the lifetime of the browser process. */ @@ -33,10 +39,4 @@ protected void getAssertion(PublicKeyCredentialRequestOptions options, RenderFrameHost frameHost, HandlerResponseCallback callback) {} - - protected void makeCredential( - PublicKeyCredentialCreationOptions options, HandlerResponseCallback callback) {} - - protected void getAssertion( - PublicKeyCredentialRequestOptions options, HandlerResponseCallback callback) {} }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 25fbf73f..72c9385 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -278,13 +278,22 @@ Sites </message> - <!-- Sign-in preference --> + <!-- Sign-in, sync and personalization preferences --> + <message name="IDS_PREFS_SECTION_ACCOUNT" desc="Title for the group of account-related entries in Settings. [CHAR-LIMIT=32]"> + Account + </message> <message name="IDS_SIGN_IN_TO_CHROME" desc="Title for the button to sign in to Chrome using one's Google account. [CHAR-LIMIT=27]"> Sign in to Chrome </message> + <message name="IDS_PREFS_SYNC_AND_SERVICES" desc="Title for Settings section to manage data collection for Sync and Google services. [CHAR-LIMIT=32]"> + Sync and Google services + </message> <message name="IDS_SIGN_IN_TO_CHROME_SUMMARY" desc="Summary for the button to sign in to Chrome, explaining benefits of signing in."> Sign in to get your bookmarks, history, passwords, and other settings on all your devices </message> + <message name="IDS_SIGNIN_PREF_SUMMARY" desc="Summary for the entry in Settings to sign in to Chrome, explaining benefits of signing in."> + Sync and personalize across devices + </message> <message name="IDS_SIGN_IN_TO_CHROME_DISABLED_SUMMARY" desc="A descriptive line of text that appears under the 'Sign in to Chrome' option, in Chrome Settings on Android. The text explains why 'Sign in to Chrome' is disabled. 'Administrator' refers to the IT administrator of the company/organization that owns the user’s device."> Disabled by the administrator of this device </message>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_am.xtb b/chrome/android/java/strings/translations/android_chrome_strings_am.xtb index 9e5a132..d93ebfe3 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_am.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_am.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">የአጠቃቀም እና የብልሽት ሪፖርቶች</translation> <translation id="11221688409173367">ለእርስዎ በተለይ የተመረጡ ጽሑፎችን ለማየት የመነሻ አዝራሩን መታ ያድርጉ</translation> <translation id="1129510026454351943">ዝርዝሮች፦ <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 ውርድን በመጠባበቅ ላይ}one{# ውርዶችን በመጠባበቅ ላይ}other{# ውርዶችን በመጠባበቅ ላይ}}</translation> <translation id="1145536944570833626">ነባሩን ውሂብ ይሰርዙ።</translation> <translation id="1146678959555564648">ምናባዊ ዕውነታ አስገባ</translation> <translation id="114721135501989771">Google ዘመናዊ ነገሮችን በChrome ላይ ያግኙ</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">እባክዎ የመግቢያ ዝርዝሮችዎን ያዘምኑ።</translation> <translation id="1974060860693918893">የላቀ</translation> <translation id="1984937141057606926">የተፈቀደ፣ ከሶስተኛ ወገን በቀር</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> አዝራር</translation> <translation id="1989112275319619282">አስስ</translation> <translation id="1993768208584545658"><ph name="SITE" /> መጣመር ይፈልጋል</translation> <translation id="1994173015038366702">የጣቢያ ዩአርኤል</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">የማያስፈልግ ማከማቻ</translation> <translation id="4002066346123236978">ርዕስ</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# ሰዓ}one{# ሰዓቶች}other{# ሰዓቶች}}</translation> <translation id="4042870126885713738">አንድ የድር አድራሻ መፍትሔ ካላመጣ ወይም ግንኙነት ሊፈጠር ካልቻለ ጥቆማዎችን አሳይ</translation> <translation id="4046123991198612571">ቀጣይ ትራክ</translation> <translation id="4048707525896921369">ገጹን ትተው ሳይሄዱ በድር ጣቢያዎች ላይ ስላሉ ርዕሶች ይወቁ። ለመፈለግ መታ ያድርጉ አንድ ቃል እና በዙሪያው ያለውን አውድ ወደ Google ፍለጋ ይልክና ትርጓሜዎችን፣ ስዕሎችን፣ የፍለጋ ውጤቶችን እና ሌሎች ዝርዝሮችን ይመልሳል። @@ -402,6 +405,7 @@ <translation id="4581964774250883625">ወደ ማንነት የማያሳውቅ ሁነታ ሄደዋል።</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{ከ# ደቂቃ በፊት}one{ከ# ደቂቃዎች በፊት}other{ከ# ደቂቃዎች በፊት}}</translation> <translation id="4587589328781138893">ጣቢያዎች</translation> +<translation id="4594952190837476234">ይህ የ<ph name="CREATION_TIME" /> የመስመር ውጭ ገጽ ከመስመር ላይ ስሪቱ የተለየ ሊሆን ይችላል።</translation> <translation id="4605958867780575332">ንጥል ተወግዷል፦ <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" />ን ይክፈቱ</translation> <translation id="4645575059429386691">በእርስዎ ወላጅ የሚቀናበር</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">አዲስ ትር ክፈት</translation> <translation id="4751476147751820511">የእንቅስቃሴ ወይም የብርሃን ዳሳሾች</translation> <translation id="4759238208242260848">የወረዱ</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 ውርድ ተጠናቅቋል}one{# ውርዶች ተጠናቅቀዋል}other{# ውርዶች ተጠናቅቀዋል}}</translation> <translation id="4766369052440583386">ውሂብ ቆጣቢ በርቷል</translation> <translation id="4797039098279997504">ወደ <ph name="URL_OF_THE_CURRENT_TAB" /> ለመመለስ ይንኩ</translation> <translation id="4807098396393229769">በካርድ ላይ ያለ ስም</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">የእርስዎ የይለፍ ቃላት፣ ታሪክ እና ተጨማሪ ነገሮች በሁሉም መሣሪያዎችዎ ላይ</translation> <translation id="4961700429721424617">በ<ph name="MANAGED_DOMAIN" /> ከሚተዳደር መለያ ዘግተው እየወጡ ነው። ይሄ የChrome ውሂብዎን ከዚህ መሣሪያ ይሰርዘዋል፣ ነገር ግን ውሂብዎ አሁንም በእርስዎ የGoogle መለያ ውስጥ እንዳለ ይቀራል።</translation> <translation id="497421865427891073">ወደ ፊት ሂድ</translation> +<translation id="4988210275050210843">ፋይልን በማውረድ ላይ (<ph name="MEGABYTES" />)።</translation> <translation id="4988526792673242964">ገፆች</translation> <translation id="4996978546172906250">ያጋሩ በ</translation> <translation id="5004339818306944878">እስከ 60% ያነሰ ውሂብ ይጠቀሙና ድሩን ያፍጥኑት። Google አገልጋዮች እርስዎ የሚጎበኟቸውን ገጾች ያተባሉ።</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">የተከማቸ ውሂብን አጽዳ</translation> <translation id="5152843274749979095">ምንም የሚደገፉ መተግበሪያዎች አልተጫኑም</translation> <translation id="5161254044473106830">ርዕስ ያስፈልጋል</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 ውርድ አልተሳካም።}one{# ውርዶች አልተሳኩም።}other{# ውርዶች አልተሳኩም።}}</translation> <translation id="5168917394043976756">የአሰሳ መሳቢያ ክፈት</translation> <translation id="5171365962177408781">አዲሱን የትር ገጽ ለመጫን እና የተጠቆሙትን ጽሑፎች ለመመልከት መታ ያድርጉ</translation> <translation id="5184329579814168207">በChrome ውስጥ ክፈት</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">በጣም በብዛት የተጎበኙ ገጾችዎ እዚህ ይመጣሉ</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> ጊባ ይገኛል</translation> <translation id="5433691172869980887">የተጠቃሚ ስም ተቀድቷል</translation> +<translation id="543509235395288790"><ph name="COUNT" /> ፋይሎችን በማውረድ ላይ (<ph name="MEGABYTES" />)።</translation> <translation id="5441522332038954058">ወደ የአድራሻው አሞሌ ዘልለህ ሂድ</translation> <translation id="5447201525962359567">ኩኪዎች እና ሌላ በአከባቢያዊ የተከማቸ ውሂብን ጨምሮ ሁሉም የጣቢያ ማከማቻ</translation> <translation id="5447765697759493033">ይህ ጣቢያ አይተረጎምም</translation> +<translation id="545042621069398927">ውርድዎን በማፍጠን ላይ።</translation> <translation id="5456381639095306749">ገጽ አውርድ</translation> <translation id="548278423535722844">በካርታዎች መተግበሪያ ውስጥ ይክፈቱ</translation> <translation id="5487521232677179737">ውሂብን አጽዳ</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">ከ30 ቀናት በላይ የቆየ</translation> <translation id="5858741533101922242">Chrome የብሉቱዝ አስማሚውን ማብራት አልቻለም</translation> <translation id="5860033963881614850">አጥፋ</translation> +<translation id="5864174910718532887">ዝርዝሮች፦ በጣቢያ ስም የተለየ</translation> <translation id="5864419784173784555">ሌላ ውርድን በመጠበቅ ላይ…</translation> <translation id="5869522115854928033">የተቀመጡ የይለፍ ቃሎች</translation> <translation id="5878455346526065919">ጣልቃ ገቢ ማስታወቂያዎችን የማሳየት አዝማሚያ ካለው ጣቢያ የሚመጡ ጣቢያዎችን አግድ</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">የይዘት አስተያየት ጥቆማዎች</translation> <translation id="6277522088822131679">ገጹን ማተም ላይ ችግር ነበር። እባክዎ እንደገና ይሞክሩ።</translation> <translation id="6295158916970320988">ሁሉም ጣቢያዎች</translation> +<translation id="629730747756840877">መለያ</translation> <translation id="6320088164292336938">ንዘር</translation> <translation id="6324034347079777476">የAndroid ሥርዓት ስምረት ተሰናክሏል</translation> <translation id="6333140779060797560">በ<ph name="APPLICATION" /> በኩል ያጋሩ</translation> <translation id="6337234675334993532">ምስጠራ</translation> +<translation id="6341580099087024258">ፋይሎች የት እንደሚቀመጡ ይጠይቁ</translation> <translation id="6343192674172527289">ምንም ውርዶች አልተገኙም</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 እና <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ተጨማሪ}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 እና <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ተጨማሪ}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 እና <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ተጨማሪ}}</translation> <translation id="6364438453358674297">ጥቆማው ከታሪክ ይወገድ?</translation> +<translation id="6378173571450987352">ዝርዝሮች፦ ጥቅም ላይ በዋለው የውሂብ መጠን ተደርድረዋል</translation> <translation id="6383961787135158834">የጣቢያ ማከማቻን አጽዳ…</translation> <translation id="6388207532828177975">አጽዳ እና ዳግም አስጀምር</translation> <translation id="6393863479814692971">Chrome ለዚህ ጣቢያ የእርስዎን ካሜራ እና ማይክራፎን ለመድረስ ፈቃድ ይፈልጋል።</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">በመሣሪያዎ ቅንብሮች መተግበሪያ ውስጥ ካለው የመለያዎች ገጽ ሆነው የGoogle መለያ ያክሉ።</translation> <translation id="7274013316676448362">የታገደ ጣቢያ</translation> <translation id="729975465115245577">የእርስዎ መሣሪያ የይለፍ ቃላት ፋይሉን የሚያከማችበት መተግበሪያ የለውም።</translation> +<translation id="7302081693174882195">ዝርዝሮች፦ በተቀመጠው የውሂብ መጠን ተደርድረዋል</translation> <translation id="7333031090786104871">አሁንም ቀዳሚ ጣቢያን በማከል ላይ</translation> <translation id="7352939065658542140">ቪድዮ</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{1 የተመረጠ ንጥል አጋራ}one{# የተመረጡ ንጥሎችን አጋራ}other{# የተመረጡ ንጥሎችን አጋራ}}</translation> <translation id="7359002509206457351">የመዳረሻ መክፈያ ዘዴዎች</translation> <translation id="7366340029385295517">ወደ <ph name="SCREEN_NAME" /> በመውሰድ ላይ</translation> <translation id="7375125077091615385">ዓይነት፦</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />።</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Chrome የመጀመሪያ አሂድ ተሞክሮ</translation> <translation id="741204030948306876">አዎ፣ ገብቼያለሁ</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">መጀመሪያ ጠይቅ</translation> <translation id="7423538860840206698">ቅንጥብ ሰሌዳን ከማንበብ ታግዷል</translation> <translation id="7437998757836447326">ዘግተው ከChrome ይውጡ</translation> +<translation id="7444811645081526538">ተጨማሪ ምድቦች</translation> <translation id="7445411102860286510">ጣቢያዎች ድምፀ-ከል የተደረገባቸው ቪዲዮዎችን በራስ-ሰር እንዲያጫውቱ ይፍቀዱላቸው (የሚመከር)</translation> <translation id="7453467225369441013">ከአብዛኛዎቹ ጣቢያዎች ዘግተው ያስወጣዎታል። ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም።</translation> <translation id="7454641608352164238">በቂ ቦታ የለም</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">ሁሉንም አስወግድ</translation> <translation id="7882131421121961860">ምንም ታሪክ አልተገኘም</translation> <translation id="7882806643839505685">ለተወሰነ ጣቢያ ድምጽ ፍቀድ።</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{ፋይልን በማውረድ ላይ።}one{# ፋይሎች በማውረድ ላይ።}other{# ፋይሎች በማውረድ ላይ።}}</translation> <translation id="7929962904089429003">ምናሌውን ክፈት</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> ጊዜው ያለፈበት ነው።</translation> <translation id="7947953824732555851">ተቀበል እና ግባ</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">በአንዳንድ ድር ጣቢያዎች ላይ ከላይ ባሉ የሚደገፉ የክፍያ መተግበሪያዎች በመሣሪያዎ ላይ መክፈል ይችላሉ።</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> በChrome ውስጥ ይከፈታል። በመቀጠልዎ በChrome <ph name="BEGIN_LINK1" />አገልግሎት ውል<ph name="END_LINK1" /> እና <ph name="BEGIN_LINK2" />የግላዊነት ማስታወቂያ<ph name="END_LINK2" />፣ እና በ<ph name="BEGIN_LINK3" />በFamily Link የሚተዳደሩ የGoogle መለያዎች ግላዊነት ማስታወቂያ<ph name="END_LINK3" /> ተስማምተዋል።</translation> <translation id="8820817407110198400">ዕልባቶች</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">ይዘቱን በማውረድ ላይ ሳለ አንድ ስህተት ተከስቷል።</translation> <translation id="8840953339110955557">ይህ ገጽ ከመስመር ላይ ስሪቱ የተለየ ሊሆን ይችላል።</translation> <translation id="8847988622838149491">ዩ ኤስ ቢ</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb index 8fdbf615..e140685d 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">تقارير الاستخدام والأعطال</translation> <translation id="11221688409173367">انقر على زر "الصفحة الرئيسية" لعرض المقالات المُختارة خصيصًا لك.</translation> <translation id="1129510026454351943">التفاصيل: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{هناك تنزيل واحد مُعلَّق.}zero{هناك # تنزيل مُعلَّق.}two{هناك تنزيلان (#) مُعلَّقان.}few{هناك # تنزيلات مُعلَّقة.}many{هناك # تنزيلاً مُعلَّقًا.}other{هناك # تنزيل مُعلَّق.}}</translation> <translation id="1145536944570833626">يمكنك حذف البيانات الحالية.</translation> <translation id="1146678959555564648">إدخال VR</translation> <translation id="114721135501989771">الحصول على ميزات Google الذكية في Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">يُرجى تحديث تفاصيل تسجيل الدخول.</translation> <translation id="1974060860693918893">إعدادات متقدمة</translation> <translation id="1984937141057606926">مسموح باستثناء الجهات الخارجية</translation> +<translation id="1987739130650180037">الزر <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">تصفّح</translation> <translation id="1993768208584545658">يريد <ph name="SITE" /> الاقتران</translation> <translation id="1994173015038366702">عنوان URL للموقع</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">سعة تخزين غير مهمة</translation> <translation id="4002066346123236978">العنوان</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{ساعة واحدة (#)}zero{# ساعة}two{ساعتان (#)}few{# ساعات}many{# ساعةً}other{# ساعة}}</translation> <translation id="4042870126885713738">عرض اقتراحات عند تعذر فتح عنوان ويب أو تعذر إجراء اتصال</translation> <translation id="4046123991198612571">المقطع الصوتي التالي</translation> <translation id="4048707525896921369">يمكنك معرفة معلومات عن مواضيع على المواقع الإلكترونية بدون مغادرة الصفحة. تُرسل ميزة "البحث بالنقر" الكلمة والسياق المحيط بها إلى بحث Google، إلى جانب عرض التعريفات، والصور، ونتائج البحث، وتفاصيل أخرى. @@ -403,6 +406,7 @@ <translation id="4581964774250883625">لقد انتقلت إلى التصفح المتخفي.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{قبل دقيقة واحدة (#)}zero{قبل # دقيقة}two{قبل دقيقتين (#)}few{قبل # دقائق}many{قبل # دقيقة}other{قبل # دقيقة}}</translation> <translation id="4587589328781138893">المواقع</translation> +<translation id="4594952190837476234">تم إنشاء هذه الصفحة المتوفّرة بلا اتصال بالإنترنت في <ph name="CREATION_TIME" />، وقد تختلف عن الإصدار المتوفِّر على الإنترنت.</translation> <translation id="4605958867780575332">تمت إزالة العنصر: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">فتح <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">يديره والداك</translation> @@ -423,6 +427,7 @@ <translation id="4749960740855309258">فتح علامة تبويب جديدة</translation> <translation id="4751476147751820511">أجهزة استشعار الإضاءة أو الحركة</translation> <translation id="4759238208242260848">التنزيلات</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{اكتمل تنزيل واحد.}zero{اكتمل # تنزيل.}two{اكتمل تنزيلان (#).}few{اكتملت # تنزيلات.}many{اكتمل # تنزيلاً.}other{اكتمل # تنزيل.}}</translation> <translation id="4766369052440583386">تم تشغيل توفير البيانات</translation> <translation id="4797039098279997504">المس للعودة إلى <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">الاسم كما على البطاقة</translation> @@ -449,6 +454,7 @@ <translation id="4961334780091921942">كلمات المرور والسجلّ والمزيد على كل الأجهزة</translation> <translation id="4961700429721424617">أنت بصدد الخروج من حساب تتم إدارته من خلال <ph name="MANAGED_DOMAIN" />. سيؤدي ذلك إلى حذف بيانات Chrome من هذا الجهاز، ولكن ستظل البيانات في حسابك في Google.</translation> <translation id="497421865427891073">انتقال للأمام</translation> +<translation id="4988210275050210843">جارٍ تنزيل الملف (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">صفحات</translation> <translation id="4996978546172906250">مشاركة عن طريق</translation> <translation id="5004339818306944878">يمكنك خفض استخدام البيانات بنسبة تصل إلى 60%، إلى جانب تسريع الويب. كما ستعمل خوادم Google على تحسين الصفحات التي تزورها.</translation> @@ -468,6 +474,7 @@ <translation id="515227803646670480">محو البيانات المخزنة</translation> <translation id="5152843274749979095">ليس هناك أي تطبيق مثبّت متوافق</translation> <translation id="5161254044473106830">العنوان مطلوب</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{تعذَّر تنزيل واحد.}zero{تعذَّر # تنزيل.}two{تعذَّر تنزيلان (#).}few{تعذَّرت # تنزيلات.}many{تعذَّر # تنزيلاً.}other{تعذَّر # تنزيل.}}</translation> <translation id="5168917394043976756">فتح لائحة التنقل</translation> <translation id="5171365962177408781">انقر لتحميل صفحة علامة التبويب الجديدة وعرض المقالات المقترحة.</translation> <translation id="5184329579814168207">فتح في Chrome</translation> @@ -497,9 +504,11 @@ <translation id="5423934151118863508">ستظهر صفحاتك الأكثر زيارة هنا</translation> <translation id="5424588387303617268">يتوفر <ph name="GIGABYTES" /> غيغابايت</translation> <translation id="5433691172869980887">تم نسخ اسم المستخدم</translation> +<translation id="543509235395288790">جارٍ تنزيل <ph name="COUNT" /> من الملفات (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">الانتقال السريع إلى شريط العناوين</translation> <translation id="5447201525962359567">سعة التخزين في الموقع كاملة، بما في ذلك ملفات تعريف الارتباط وغيرها من البيانات المُخزَّنَة محليًا</translation> <translation id="5447765697759493033">لن تتم ترجمة هذا الموقع</translation> +<translation id="545042621069398927">جارٍ تسريع التنزيل.</translation> <translation id="5456381639095306749">تنزيل الصفحة</translation> <translation id="548278423535722844">فتح في تطبيق الخرائط</translation> <translation id="5487521232677179737">محو البيانات</translation> @@ -560,6 +569,7 @@ <translation id="5854790677617711513">مرّ عليها أكثر من 30 يومًا</translation> <translation id="5858741533101922242">يتعذر على Chrome تشغيل محوّل البلوتوث</translation> <translation id="5860033963881614850">إيقاف</translation> +<translation id="5864174910718532887">التفاصيل: تم الترتيب بحسب اسم موقع الويب</translation> <translation id="5864419784173784555">في انتظار تنزيل آخر…</translation> <translation id="5869522115854928033">كلمات المرور المحفوظة</translation> <translation id="5878455346526065919">حظر الإعلانات من المواقع التي تميل إلى عرض إعلانات متداخلة</translation> @@ -606,13 +616,16 @@ <translation id="6255999984061454636">اقتراحات المحتوى</translation> <translation id="6277522088822131679">حدثت مشكلة أثناء طباعة الصفحة. يُرجى إعادة المحاولة.</translation> <translation id="6295158916970320988">جميع المواقع</translation> +<translation id="629730747756840877">الحساب</translation> <translation id="6320088164292336938">اهتزاز</translation> <translation id="6324034347079777476">تمّ إيقاف مزامنة نظام Android</translation> <translation id="6333140779060797560">مشاركة عن طريق <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">تشفير</translation> +<translation id="6341580099087024258">السؤال عن مكان حفظ الملفات</translation> <translation id="6343192674172527289">لم يتم العثور على أي تنزيلات</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 وعنوان إضافي واحد (<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />)}zero{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عنوان إضافي}two{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 وعنوانان إضافيان (<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />)}few{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عناوين إضافية}many{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عنوانًا إضافيًا}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عنوان إضافي}}</translation> <translation id="6364438453358674297">هل تريد إزالة اقتراح من السجل؟</translation> +<translation id="6378173571450987352">التفاصيل: تم الترتيب بحسب مقدار البيانات المُستخدَمة</translation> <translation id="6383961787135158834">محو سعة تخزين الموقع...</translation> <translation id="6388207532828177975">مسح وإعادة التعيين</translation> <translation id="6393863479814692971">يحتاج Chrome إلى إذن لاستخدام الكاميرا والميكروفون لموقع الويب هذا.</translation> @@ -724,12 +737,14 @@ <translation id="7253272406652746122">أضف حساب Google من صفحة "الحسابات" في تطبيق إعدادات جهازك.</translation> <translation id="7274013316676448362">الموقع المحظور</translation> <translation id="729975465115245577">لا يتضمن جهازك تطبيقًا لتخزين ملف كلمات المرور.</translation> +<translation id="7302081693174882195">التفاصيل: تم الترتيب بحسب مقدار البيانات المحفوظة</translation> <translation id="7333031090786104871">لا تزال عملية إضافة موقع الويب السابق جارية</translation> <translation id="7352939065658542140">فيديو</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{مشاركة عنصر واحد محدد}zero{مشاركة # عنصر محدد}two{مشاركة عنصرين (#) محددين}few{مشاركة # عناصر محددة}many{مشاركة # عنصرًا محددًا}other{مشاركة # عنصر محدد}}</translation> <translation id="7359002509206457351">الوصول إلى طرق الدفع</translation> <translation id="7366340029385295517">جارٍ الإرسال إلى <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">النوع:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">عنوان URL</translation> <translation id="7403691278183511381">أول تجربة تشغيل لمتصفح Chrome</translation> <translation id="741204030948306876">نعم، موافق</translation> @@ -737,6 +752,7 @@ <translation id="7423098979219808738">السؤال أولاً</translation> <translation id="7423538860840206698">تم الحظر من قراءة الحافظة</translation> <translation id="7437998757836447326">الخروج من Chrome</translation> +<translation id="7444811645081526538">مزيد من الفئات</translation> <translation id="7445411102860286510">السماح للمواقع بتشغيل الفيديوهات مكتومة الصوت تلقائيًا (مُستحسن)</translation> <translation id="7453467225369441013">سيتم تسجيل الخروج من معظم مواقع الويب لكن لن يتم تسجيل الخروج من حسابك في Google.</translation> <translation id="7454641608352164238">سعة التخزين غير كافية</translation> @@ -791,6 +807,7 @@ <translation id="7876243839304621966">إزالة الكل</translation> <translation id="7882131421121961860">لم يتم العثور على أي سجلّ</translation> <translation id="7882806643839505685">السماح بتشغيل الصوت لموقع معين.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{جارٍ تنزيل ملف واحد.}zero{جارٍ تنزيل # ملف}two{جارٍ تنزيل ملفين (#).}few{جارٍ تنزيل # ملفات.}many{جارٍ تنزيل # ملفًا.}other{جارٍ تنزيل # ملف.}}</translation> <translation id="7929962904089429003">فتح القائمة</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> قديم.</translation> <translation id="7947953824732555851">قبول وتسجيل الدخول</translation> @@ -886,6 +903,7 @@ <translation id="8812260976093120287">يمكنك على مواقع ويب معيّنة الدفع باستخدام تطبيقات الدفع المتوافقة أعلاه على جهازك.</translation> <translation id="8816439037877937734">سيتم فتح <ph name="APP_NAME" /> في Chrome. بالمتابعة، أنت توافق على <ph name="BEGIN_LINK1" />بنود الخدمة<ph name="END_LINK1" /> و<ph name="BEGIN_LINK2" />إشعار الخصوصية<ph name="END_LINK2" /> في Chrome، و<ph name="BEGIN_LINK3" />إشعار الخصوصية لحسابات Google المُدارة من خلال Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">إشارات</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">حدث خطأ أثناء تنزيل المحتوى.</translation> <translation id="8840953339110955557">قد تختلف هذه الصفحة عن الإصدار الوارد على الإنترنت.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb b/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb index 8abd8e7..968272f 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Отчети за употребата и сигнали за сривове</translation> <translation id="11221688409173367">Докоснете бутона „Начало“, за да видите статии, избрани специално за вас</translation> <translation id="1129510026454351943">Подробности: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{Предстои 1 изтегляне.}other{Предстоят # изтегляния.}}</translation> <translation id="1145536944570833626">Изтриване на съществуващите данни.</translation> <translation id="1146678959555564648">Вход във VR</translation> <translation id="114721135501989771">Chrome с интелекта на Google</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Моля, актуализирайте данните си за вход.</translation> <translation id="1974060860693918893">Разширени</translation> <translation id="1984937141057606926">Разрешено, но не и за трети страни</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> бутон „<ph name="LINK_NAME" />“</translation> <translation id="1989112275319619282">Сърфиране</translation> <translation id="1993768208584545658"><ph name="SITE" /> иска да се сдвои</translation> <translation id="1994173015038366702">URL адрес на сайт</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> от ?</translation> <translation id="3997476611815694295">Маловажни данни в хранилището</translation> <translation id="4002066346123236978">Заглавие</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# ч}other{# ч}}</translation> <translation id="4042870126885713738">Показване на предложения, когато даден уеб адрес не може да бъде преобразуван или не може да бъде осъществена връзка</translation> <translation id="4046123991198612571">Следващ запис</translation> <translation id="4048707525896921369">Научавайте за темите в уебсайтовете, без да напускате страницата. Функцията за търсене с докосване изпраща до Google Търсене определени думи и заобикалящия ги текст и така извежда определения, снимки, резултати и други подробности. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Преминахте в режим „инкогнито“.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{преди # минута}other{преди # минути}}</translation> <translation id="4587589328781138893">Сайтове</translation> +<translation id="4594952190837476234">Тази офлайн страница е от <ph name="CREATION_TIME" /> и може да се различава от онлайн версията.</translation> <translation id="4605958867780575332">Елементът бе премахнат: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Отваряне на <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Управлява се от ваш родител</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Отваряне на нов раздел</translation> <translation id="4751476147751820511">Сензори за движение или светлина</translation> <translation id="4759238208242260848">Изтегляния</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 изтегляне завърши.}other{# изтегляния завършиха.}}</translation> <translation id="4766369052440583386">Функцията Икономия на данни е включена</translation> <translation id="4797039098279997504">Докоснете, за да се върнете към <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Име върху картата</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Вашите пароли, история и др. на всички устройства</translation> <translation id="4961700429721424617">Излизате от профил, управляван от <ph name="MANAGED_DOMAIN" />. Данните ви в Chrome ще се изтрият от това устройство, но ще останат в профила ви в Google.</translation> <translation id="497421865427891073">Преминаване напред</translation> +<translation id="4988210275050210843">Изтегля се файл (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Страници</translation> <translation id="4996978546172906250">Споделяне чрез</translation> <translation id="5004339818306944878">Използвайте до 60% по-малко данни и сърфирайте по-бързо в мрежата. Сървърите на Google ще оптимизират посещаваните от вас страници.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Изчистване на съхраняваните данни</translation> <translation id="5152843274749979095">Никое от поддържаните приложения не е инсталирано</translation> <translation id="5161254044473106830">Изисква се заглавие</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 изтегляне не бе успешно.}other{# изтегляния не бяха успешни.}}</translation> <translation id="5168917394043976756">Отваряне на слоя за навигация</translation> <translation id="5171365962177408781">Докоснете, за да се зареди нов раздел и да видите предложени статии</translation> <translation id="5184329579814168207">Отваряне в Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Най-посещаваните от вас страници ще се показват тук</translation> <translation id="5424588387303617268">Налични: <ph name="GIGABYTES" /> ГБ</translation> <translation id="5433691172869980887">Потребителското име е копирано</translation> +<translation id="543509235395288790">Изтеглят се <ph name="COUNT" /> файла (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Преминаване към адресната лента</translation> <translation id="5447201525962359567">Всички данни от сайтове, включително „бисквитки“ и друга локално съхранявана информация</translation> <translation id="5447765697759493033">Този сайт няма да се превежда</translation> +<translation id="545042621069398927">Изтеглянето се ускорява.</translation> <translation id="5456381639095306749">Изтегляне на страницата</translation> <translation id="548278423535722844">Отваряне в приложение за карти</translation> <translation id="5487521232677179737">Изчиств. на данните</translation> @@ -560,6 +569,7 @@ <translation id="5854790677617711513">По-стари от 30 дни</translation> <translation id="5858741533101922242">Chrome не може да включи адаптера за Bluetooth</translation> <translation id="5860033963881614850">Изключено</translation> +<translation id="5864174910718532887">Подробности: сортирани по име на сайта</translation> <translation id="5864419784173784555">Изчаква се друго изтегляне…</translation> <translation id="5869522115854928033">Запазени пароли</translation> <translation id="5878455346526065919">Блокиране на рекламите от сайтове, на които обикновено се показват натрапчиви реклами</translation> @@ -606,13 +616,16 @@ <translation id="6255999984061454636">Предложения за съдържание</translation> <translation id="6277522088822131679">При отпечатването на страницата възникна проблем. Моля, опитайте отново.</translation> <translation id="6295158916970320988">Всички сайтове</translation> +<translation id="629730747756840877">Профил</translation> <translation id="6320088164292336938">Вибриране</translation> <translation id="6324034347079777476">Системното синхронизиране под Android е деактивирано</translation> <translation id="6333140779060797560">Споделяне чрез <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Шифроване</translation> +<translation id="6341580099087024258">Извеждане на запитване къде да се запазват файловете</translation> <translation id="6343192674172527289">Няма намерени изтегляния</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 и още <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 и още <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Предложението да се премахне ли от историята?</translation> +<translation id="6378173571450987352">Подробности: сортирани по количество използвани данни</translation> <translation id="6383961787135158834">Изчистване на данните…</translation> <translation id="6388207532828177975">Изчистване и нулиране</translation> <translation id="6393863479814692971">Chrome се нуждае от разрешение за достъп до камерата и микрофона ви за този сайт.</translation> @@ -724,12 +737,14 @@ <translation id="7253272406652746122">Добавете профил в Google от страницата „Профили“ в приложението Настройки на устройството ви.</translation> <translation id="7274013316676448362">Блокиран сайт</translation> <translation id="729975465115245577">На устройството ви няма приложение за съхраняване на файла с паролите.</translation> +<translation id="7302081693174882195">Подробности: сортирани по количество спестени данни</translation> <translation id="7333031090786104871">Още се добавя предишният сайт</translation> <translation id="7352939065658542140">ВИДЕОКЛИП</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Споделяне на 1 избран елемент}other{Споделяне на # избрани елемента}}</translation> <translation id="7359002509206457351">Достъп до начините на плащане</translation> <translation id="7366340029385295517">Предава се към „<ph name="SCREEN_NAME" />“</translation> <translation id="7375125077091615385">Тип:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL адрес</translation> <translation id="7403691278183511381">Представяне при първо стартиране на Chrome</translation> <translation id="741204030948306876">Да, ще участвам</translation> @@ -737,6 +752,7 @@ <translation id="7423098979219808738">Първо ще се извежда запитване</translation> <translation id="7423538860840206698">Достъпът за четене до буферната памет е блокиран</translation> <translation id="7437998757836447326">Изход от Chrome</translation> +<translation id="7444811645081526538">Още категории</translation> <translation id="7445411102860286510">Разрешаване на сайтовете автоматично да възпроизвеждат видеоклипове със заглушен звук (препоръчително)</translation> <translation id="7453467225369441013">Ще излезете от повечето сайтове, но не и от профила си в Google.</translation> <translation id="7454641608352164238">Няма достатъчно място</translation> @@ -791,6 +807,7 @@ <translation id="7876243839304621966">Премахване на всички</translation> <translation id="7882131421121961860">Няма намерена история</translation> <translation id="7882806643839505685">Разрешаване на звука за конкретен сайт.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Изтегля се файл.}other{Изтеглят се # файла.}}</translation> <translation id="7929962904089429003">Отваряне на менюто</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> не е актуален.</translation> <translation id="7947953824732555851">Приемам и влизам</translation> @@ -886,6 +903,7 @@ <translation id="8812260976093120287">На някои уебсайтове можете да извършвате плащания чрез посочените по-горе поддържани приложения за плащане на устройството ви.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> ще се отвори в Chrome. С продължаването си приемате <ph name="BEGIN_LINK1" />Общите условия<ph name="END_LINK1" /> и <ph name="BEGIN_LINK2" />Съобщението за поверителност<ph name="END_LINK2" /> на браузъра, както и <ph name="BEGIN_LINK3" />Съобщението за поверителност за профили в Google, управлявани чрез Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Отметки</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">При изтеглянето на съдържанието възникна грешка.</translation> <translation id="8840953339110955557">Тази страница може да се различава от онлайн версията.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb index ea36c7c..12c7871 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb
@@ -18,7 +18,7 @@ <translation id="1141800923049248244">{FILE_COUNT,plural, =1{Hi ha 1 baixada pendent.}other{Hi ha # baixades pendents.}}</translation> <translation id="1145536944570833626">Suprimeix les dades existents.</translation> <translation id="1146678959555564648">Activa el mode RV</translation> -<translation id="114721135501989771">Gaudeix de les eines intel·ligents de Google a Chrome</translation> +<translation id="114721135501989771">Eines intel·ligents a Chrome</translation> <translation id="116280672541001035">Dades utilitzades</translation> <translation id="1172593791219290334">Pàgina d'inici</translation> <translation id="1178581264944972037">Posa en pausa</translation> @@ -450,7 +450,7 @@ <translation id="4915549754973153784"><ph name="BEGIN_LINK" />Obtén ajuda<ph name="END_LINK" /> mentre se cerquen dispositius…</translation> <translation id="4943872375798546930">No hi ha resultats</translation> <translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> comparteix la teva pantalla</translation> -<translation id="4961334780091921942">Tindràs les contrasenyes, l'historial i altres elements en tots els dispositius</translation> +<translation id="4961334780091921942">Les contrasenyes, l'historial i altres elements en tots els dispositius</translation> <translation id="4961700429721424617">Estàs tancant la sessió d'un compte gestionat per <ph name="MANAGED_DOMAIN" />. Se suprimiran les teves dades de Chrome en aquest dispositiu, però continuaran al teu compte de Google.</translation> <translation id="497421865427891073">Ves endavant</translation> <translation id="4988210275050210843">S'està baixant el fitxer (<ph name="MEGABYTES" />).</translation> @@ -550,7 +550,7 @@ Tanmateix, no sou invisible. El vostre cap, el vostre proveïdor de serveis d'Internet i els llocs web que visiteu poden veure la vostra navegació d'incògnit.</translation> <translation id="572328651809341494">Pestanyes recents</translation> <translation id="5726692708398506830">Augmenta la mida de tots els elements de la pàgina</translation> -<translation id="5731185123186077399">Gaudeix de serveis de Google personalitzats, com ara Google Pay</translation> +<translation id="5731185123186077399">Serveis de Google personalitzats, com ara Google Pay</translation> <translation id="5738816946784116349">Baixades de Chrome</translation> <translation id="5748802427693696783">S'ha canviat a les pestanyes estàndard</translation> <translation id="5749068826913805084">Chrome necessita accedir a l'emmagatzematge per poder baixar fitxers.</translation> @@ -615,6 +615,7 @@ <translation id="6255999984061454636">Suggeriments de contingut</translation> <translation id="6277522088822131679">S'ha produït un problema en imprimir la pàgina. Torneu-ho a provar.</translation> <translation id="6295158916970320988">Tots els llocs</translation> +<translation id="629730747756840877">Compte</translation> <translation id="6320088164292336938">Vibració</translation> <translation id="6324034347079777476">La sincronització del sistema Android està desactivada</translation> <translation id="6333140779060797560">Comparteix mitjançant <ph name="APPLICATION" />.</translation> @@ -912,7 +913,7 @@ <translation id="8912362522468806198">Compte de Google</translation> <translation id="8920114477895755567">S'està esperant la informació parental.</translation> <translation id="8922289737868596582">Baixa pàgines amb el botó Més opcions per utilitzar-les sense connexió</translation> -<translation id="8934029156920711950">Toca el botó d'inici per veure els articles seleccionats expressament per a tu</translation> +<translation id="8934029156920711950">Toca per veure els articles seleccionats expressament per a tu</translation> <translation id="8941729603749328384">www.example.com</translation> <translation id="8942627711005830162">Obre en una altra finestra</translation> <translation id="8951232171465285730">Chrome t'ha estalviat <ph name="MEGABYTES" /> MB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb b/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb index ebc47ea..728e41c 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Návrhy obsahu</translation> <translation id="6277522088822131679">Při tištění stránky došlo k problému. Zkuste to prosím znovu.</translation> <translation id="6295158916970320988">Všechny weby</translation> +<translation id="629730747756840877">Účet</translation> <translation id="6320088164292336938">Vibrovat</translation> <translation id="6324034347079777476">Synchronizace systému Android je vypnuta.</translation> <translation id="6333140779060797560">Sdílet prostřednictvím aplikace <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_da.xtb b/chrome/android/java/strings/translations/android_chrome_strings_da.xtb index 6de2a951..79255a78 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_da.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_da.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Forbrugs- og nedbrudsrapporter</translation> <translation id="11221688409173367">Tryk på knappen Hjem for at få vist artikler, der er særligt udvalgt til dig</translation> <translation id="1129510026454351943">Oplysninger: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download afventer.}one{# download afventer.}other{# downloads afventer.}}</translation> <translation id="1145536944570833626">Slet eksisterende data.</translation> <translation id="1146678959555564648">Angiv VR</translation> <translation id="114721135501989771">Få Googles smarte funktioner i Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Opdater dine loginoplysninger.</translation> <translation id="1974060860693918893">Avanceret</translation> <translation id="1984937141057606926">Tilladt, undtagen tredjepartscookies</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />-knap</translation> <translation id="1989112275319619282">Gennemse</translation> <translation id="1993768208584545658"><ph name="SITE" /> vil gerne parre</translation> <translation id="1994173015038366702">Webadresse</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Lagerplads, der ikke er vigtig</translation> <translation id="4002066346123236978">Titel</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# t.}one{# t.}other{# t.}}</translation> <translation id="4042870126885713738">Vis forslag, hvis en webadresse ikke bliver fundet, eller hvis der ikke kan oprettes forbindelse</translation> <translation id="4046123991198612571">Næste nummer</translation> <translation id="4048707525896921369">Få oplysninger om emner på websites uden at forlade siden. "Tryk for at søge" sender et ord og ordets kontekst til Google Søgning og giver dig definitioner, billeder, søgeresultater og andre oplysninger. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Du er nu i inkognito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{For # minut siden}one{For # minut siden}other{For # minutter siden}}</translation> <translation id="4587589328781138893">Websites</translation> +<translation id="4594952190837476234">Denne offlineside er fra <ph name="CREATION_TIME" /> og kan afvige fra onlineversionen.</translation> <translation id="4605958867780575332">Element fjernet: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Åbn <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Administreret af en af dine forældre</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Åbn en ny fane</translation> <translation id="4751476147751820511">Bevægelses- eller lyssensorer</translation> <translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download er fuldført.}one{# download er fuldført.}other{# downloads er fuldført.}}</translation> <translation id="4766369052440583386">Datasparefunktionen er slået til</translation> <translation id="4797039098279997504">Tryk for at gå tilbage til <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Navn på kort</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Dine adgangskoder, din historik og meget mere på alle enheder</translation> <translation id="4961700429721424617">Du er ved at logge ud af en konto, der administreres af <ph name="MANAGED_DOMAIN" />. Denne handling sletter dine Chrome-data fra denne enhed, men dine data forbliver på din Google-konto.</translation> <translation id="497421865427891073">Gå fremad</translation> +<translation id="4988210275050210843">Downloader fil (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Sider</translation> <translation id="4996978546172906250">Del via</translation> <translation id="5004339818306944878">Brug op til 60 % færre data, og gør nettet hurtigere. Google-servere optimerer de sider, du besøger.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Ryd lagrede data</translation> <translation id="5152843274749979095">Der er ikke installeret nogen understøttede apps</translation> <translation id="5161254044473106830">Der skal angives en titel</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download mislykkedes.}one{# download mislykkedes.}other{# downloads mislykkedes.}}</translation> <translation id="5168917394043976756">Åbn sidemenuen</translation> <translation id="5171365962177408781">Tryk for at indlæse siden Ny fane og få vist foreslåede artikler</translation> <translation id="5184329579814168207">Åbn i Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Dine mest besøgte sider vises her</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB ledig plads</translation> <translation id="5433691172869980887">Brugernavnet er kopieret</translation> +<translation id="543509235395288790">Downloader <ph name="COUNT" /> filer (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Gå til adresselinjen</translation> <translation id="5447201525962359567">Al websitelagerplads, herunder cookies og andre data, der er gemt lokalt</translation> <translation id="5447765697759493033">Dette website kan ikke oversættes</translation> +<translation id="545042621069398927">Øger hastigheden på din download.</translation> <translation id="5456381639095306749">Download siden</translation> <translation id="548278423535722844">Åbn i kortapp</translation> <translation id="5487521232677179737">Ryd data</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Ældre end 30 dage</translation> <translation id="5858741533101922242">Chrome kan ikke slå Bluetooth-adapteren til</translation> <translation id="5860033963881614850">Fra</translation> +<translation id="5864174910718532887">Oplysninger: Sorteret efter navn på website</translation> <translation id="5864419784173784555">Venter på en anden download…</translation> <translation id="5869522115854928033">Gemte adgangskoder</translation> <translation id="5878455346526065919">Bloker annoncer fra websites, der har tendens til at vise påtrængende annoncer</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Indholdsforslag</translation> <translation id="6277522088822131679">Der opstod et problem med udskrivning af siden. Prøv igen.</translation> <translation id="6295158916970320988">Alle websites</translation> +<translation id="629730747756840877">Konto</translation> <translation id="6320088164292336938">Vibrer</translation> <translation id="6324034347079777476">Synkronisering af Android-systemet blev deaktiveret</translation> <translation id="6333140779060797560">Del via <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Kryptering</translation> +<translation id="6341580099087024258">Spørg om, hvor filer skal gemmes</translation> <translation id="6343192674172527289">Der blev ikke fundet nogen downloads</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> mere}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> mere}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> mere}}</translation> <translation id="6364438453358674297">Vil du fjerne forslaget fra historikken?</translation> +<translation id="6378173571450987352">Oplysninger: Sorteret efter mængden af brugte data</translation> <translation id="6383961787135158834">Ryd websitelagerplads…</translation> <translation id="6388207532828177975">Ryd og nulstil</translation> <translation id="6393863479814692971">Chrome skal have tilladelse til at bruge dit kamera og din mikrofon på dette website.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Tilføj en Google-konto fra siden Konti i appen Indstillinger på din enhed.</translation> <translation id="7274013316676448362">Blokeret website</translation> <translation id="729975465115245577">Der er ikke nogen app på din enhed, hvor filen med adgangskoder kan gemmes.</translation> +<translation id="7302081693174882195">Oplysninger: Sorteret efter mængden af sparede data</translation> <translation id="7333031090786104871">Det forrige website er stadig ved at blive tilføjet</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Del 1 valgt element}one{Del # valgt element}other{Del # valgte elementer}}</translation> <translation id="7359002509206457351">Adgang til betalingsmetoder</translation> <translation id="7366340029385295517">Caster til <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">Webadresse</translation> <translation id="7403691278183511381">Førstegangsoplevelse af Chrome</translation> <translation id="741204030948306876">Ja tak</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Spørg først</translation> <translation id="7423538860840206698">Blokeret fra at læse udklipsholderen</translation> <translation id="7437998757836447326">Log ud af Chrome</translation> +<translation id="7444811645081526538">Flere kategorier</translation> <translation id="7445411102860286510">Tillad, at websites automatisk afspiller videoer med lyden slået fra (anbefales)</translation> <translation id="7453467225369441013">Logger dig ud af de fleste websites. Du bliver ikke logget ud af din Google-konto.</translation> <translation id="7454641608352164238">Der er ikke nok plads</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Fjern alt</translation> <translation id="7882131421121961860">Der blev ikke fundet nogen historik</translation> <translation id="7882806643839505685">Tillad, at et bestemt website afspiller lyd.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloader fil.}one{Downloader # fil.}other{Downloader # filer.}}</translation> <translation id="7929962904089429003">Åbn menuen</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> er forældet.</translation> <translation id="7947953824732555851">Acceptér og log ind</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">På nogle websites kan du betale med ovenstående understøttede betalingsapps på din enhed.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> åbnes i Chrome. Når du fortsætter, accepterer du Chromes <ph name="BEGIN_LINK1" />servicevilkår<ph name="END_LINK1" /> og <ph name="BEGIN_LINK2" />erklæring om privatliv<ph name="END_LINK2" /> samt <ph name="BEGIN_LINK3" />erklæringen om privatliv for Google-konti, der administreres med Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Bogmærker</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Der opstod en fejl under download af indholdet.</translation> <translation id="8840953339110955557">Denne side kan afvige fra onlineversionen.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_de.xtb b/chrome/android/java/strings/translations/android_chrome_strings_de.xtb index 2a24d8d4..5797a90 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_de.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_de.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Nutzungs- und Absturzberichte</translation> <translation id="11221688409173367">Tippen Sie auf die Schaltfläche "Startseite", um sich speziell für Sie ausgewählte Artikel anzeigen zu lassen</translation> <translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 Download ausstehend.}other{# Downloads ausstehend.}}</translation> <translation id="1145536944570833626">Vorhandene Daten löschen</translation> <translation id="1146678959555564648">VR aktivieren</translation> <translation id="114721135501989771">Chrome intelligent nutzen mit Google</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Bitte aktualisieren Sie Ihre Anmeldeinformationen.</translation> <translation id="1974060860693918893">Erweitert</translation> <translation id="1984937141057606926">Zugelassen, außer Cookies Dritter</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> – Schaltfläche "<ph name="LINK_NAME" />"</translation> <translation id="1989112275319619282">Durchsuchen</translation> <translation id="1993768208584545658"><ph name="SITE" /> möchte eine Kopplung durchführen</translation> <translation id="1994173015038366702">Website-URL</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> von ?</translation> <translation id="3997476611815694295">Speicher für unwichtige Websites</translation> <translation id="4002066346123236978">Titel</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4042870126885713738">Vorschläge einblenden, wenn eine Webadresse nicht gefunden oder keine Verbindung hergestellt werden kann</translation> <translation id="4046123991198612571">Nächster Titel</translation> <translation id="4048707525896921369">Erfahren Sie mehr zu Themen auf einer Website, ohne die Seite verlassen zu müssen. Mit der Option "Zum Suchen tippen" wird ein Wort sowie dessen Kontext an die Google-Suche gesendet. Daraufhin erhalten Sie Definitionen, Bilder, Suchergebnisse und andere Details. @@ -403,6 +406,7 @@ <translation id="4581964774250883625">Sie befinden sich jetzt im Inkognitomodus.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Vor # Minute}other{Vor # Minuten}}</translation> <translation id="4587589328781138893">Websites</translation> +<translation id="4594952190837476234">Diese Offlineseite ist vom <ph name="CREATION_TIME" /> und unterscheidet sich gegebenenfalls von der Onlineversion.</translation> <translation id="4605958867780575332">Element entfernt: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> öffnen</translation> <translation id="4645575059429386691">Von deinen Eltern verwaltet</translation> @@ -423,6 +427,7 @@ <translation id="4749960740855309258">Neuen Tab öffnen</translation> <translation id="4751476147751820511">Bewegungs- oder Lichtsensoren</translation> <translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 Download abgeschlossen.}other{# Downloads abgeschlossen.}}</translation> <translation id="4766369052440583386">Datensparmodus aktiviert</translation> <translation id="4797039098279997504">Tippen, um zu <ph name="URL_OF_THE_CURRENT_TAB" /> zurückzukehren</translation> <translation id="4807098396393229769">Name auf Karte</translation> @@ -449,6 +454,7 @@ <translation id="4961334780091921942">Ihre Passwörter, Ihr Verlauf und mehr auf allen Geräten</translation> <translation id="4961700429721424617">Sie melden sich von einem Konto ab, das von <ph name="MANAGED_DOMAIN" /> verwaltet wird. Dadurch werden Ihre Chrome-Daten von diesem Gerät gelöscht, bleiben jedoch in Ihrem Google-Konto erhalten.</translation> <translation id="497421865427891073">Weiter</translation> +<translation id="4988210275050210843">Datei wird heruntergeladen (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Seiten</translation> <translation id="4996978546172906250">Teilen über</translation> <translation id="5004339818306944878">Bis zu 60 % weniger Datenverbrauch und schnelleres Internet. Google-Server optimieren die Seiten, die Sie besuchen.</translation> @@ -468,6 +474,7 @@ <translation id="515227803646670480">Gespeich. Daten löschen</translation> <translation id="5152843274749979095">Keine unterstützten Apps installiert</translation> <translation id="5161254044473106830">Titel erforderlich</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 Download fehlgeschlagen.}other{# Downloads fehlgeschlagen.}}</translation> <translation id="5168917394043976756">Navigationsleiste öffnen</translation> <translation id="5171365962177408781">Tippen Sie, um die "Neuer Tab"-Seite zu laden und sich vorgeschlagene Artikel anzeigen zu lassen</translation> <translation id="5184329579814168207">In Chrome öffnen</translation> @@ -497,9 +504,11 @@ <translation id="5423934151118863508">Hier werden Ihre am meisten aufgerufenen Seiten angezeigt.</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB verfügbar</translation> <translation id="5433691172869980887">Nutzername kopiert</translation> +<translation id="543509235395288790"><ph name="COUNT" /> Dateien (<ph name="MEGABYTES" /> MB) werden heruntergeladen.</translation> <translation id="5441522332038954058">Zur Adressleiste wechseln</translation> <translation id="5447201525962359567">Gesamter Websitespeicher einschließlich Cookies und anderer lokal gespeicherter Daten</translation> <translation id="5447765697759493033">Diese Website wird nicht übersetzt</translation> +<translation id="545042621069398927">Download wird beschleunigt.</translation> <translation id="5456381639095306749">Seite herunterladen</translation> <translation id="548278423535722844">In einer Karten-App öffnen</translation> <translation id="5487521232677179737">Daten löschen</translation> @@ -560,6 +569,7 @@ <translation id="5854790677617711513">Älter als 30 Tage</translation> <translation id="5858741533101922242">Chrome kann den Bluetooth-Adapter nicht aktivieren</translation> <translation id="5860033963881614850">Aus</translation> +<translation id="5864174910718532887">Details: Nach Websitename sortiert</translation> <translation id="5864419784173784555">Warten auf weiteren Download…</translation> <translation id="5869522115854928033">Gespeicherte Passwörter</translation> <translation id="5878455346526065919">Werbung auf Websites blockieren, die für gewöhnlich aufdringliche Werbung anzeigen</translation> @@ -606,13 +616,16 @@ <translation id="6255999984061454636">Inhaltsvorschläge</translation> <translation id="6277522088822131679">Beim Drucken der Seite ist ein Problem aufgetreten. Bitte versuchen Sie es erneut.</translation> <translation id="6295158916970320988">Alle Websites</translation> +<translation id="629730747756840877">Konto</translation> <translation id="6320088164292336938">Vibrieren</translation> <translation id="6324034347079777476">Android-Systemsynchronisierung deaktiviert</translation> <translation id="6333140779060797560">Über <ph name="APPLICATION" /> teilen</translation> <translation id="6337234675334993532">Verschlüsselung</translation> +<translation id="6341580099087024258">Fragen, wo Dateien gespeichert werden sollen</translation> <translation id="6343192674172527289">Keine Downloads gefunden</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 und <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> weitere}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 und <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> weitere}}</translation> <translation id="6364438453358674297">Vorschlag aus Verlauf entfernen?</translation> +<translation id="6378173571450987352">Details: Nach der Menge der verwendeten Daten sortiert</translation> <translation id="6383961787135158834">Websitespeicher löschen...</translation> <translation id="6388207532828177975">Löschen & zurücksetzen</translation> <translation id="6393863479814692971">Chrome benötigt für diese Website die Berechtigung, auf Ihre Kamera und Ihr Mikrofon zuzugreifen.</translation> @@ -724,12 +737,14 @@ <translation id="7253272406652746122">Fügen Sie ein Google-Konto über die Seite "Konten" der App "Einstellungen" Ihres Geräts hinzu.</translation> <translation id="7274013316676448362">Blockierte Website</translation> <translation id="729975465115245577">Auf Ihrem Gerät befindet sich keine App zum Speichern der Passwortdatei.</translation> +<translation id="7302081693174882195">Details: Nach der Menge der gespeicherte Daten sortiert</translation> <translation id="7333031090786104871">Vorherige Website wird noch hinzugefügt</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{1 ausgewähltes Element teilen}other{# ausgewählte Elemente teilen}}</translation> <translation id="7359002509206457351">Auf Zahlungsmethoden zugreifen</translation> <translation id="7366340029385295517">Übertragung an <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Typ:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Eindruck beim ersten Ausführen von Chrome</translation> <translation id="741204030948306876">Ja, bitte</translation> @@ -737,6 +752,7 @@ <translation id="7423098979219808738">Zuerst fragen</translation> <translation id="7423538860840206698">Es dürfen keine Dateien aus der Zwischenablage abgerufen werden</translation> <translation id="7437998757836447326">Von Chrome abmelden</translation> +<translation id="7444811645081526538">Weitere Kategorien</translation> <translation id="7445411102860286510">Automatische Wiedergabe stummgeschalteter Videos auf Websites zulassen (empfohlen)</translation> <translation id="7453467225369441013">Sie werden von den meisten Websites, aber nicht aus Ihrem Google-Konto abgemeldet.</translation> <translation id="7454641608352164238">Zu wenig Speicherplatz</translation> @@ -791,6 +807,7 @@ <translation id="7876243839304621966">Alle entfernen</translation> <translation id="7882131421121961860">Kein Verlauf gefunden</translation> <translation id="7882806643839505685">Wiedergabe von Ton auf einer bestimmten Website zulassen.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Datei wird heruntergeladen.}other{# Dateien werden heruntergeladen.}}</translation> <translation id="7929962904089429003">Menü öffnen</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> ist veraltet.</translation> <translation id="7947953824732555851">Akzeptieren und anmelden</translation> @@ -886,6 +903,7 @@ <translation id="8812260976093120287">Auf manchen Websites können Sie über Ihr Gerät mit den obigen unterstützten Zahlungs-Apps bezahlen.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> wird in Chrome geöffnet. Wenn Sie fortfahren, stimmen Sie den <ph name="BEGIN_LINK1" />Nutzungsbedingungen<ph name="END_LINK1" /> und <ph name="BEGIN_LINK2" />Datenschutzhinweisen<ph name="END_LINK2" /> von Chrome sowie den <ph name="BEGIN_LINK3" />Datenschutzhinweisen für mit Family Link verwaltete Google-Konten<ph name="END_LINK3" /> zu.</translation> <translation id="8820817407110198400">Lesezeichen</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Beim Herunterladen des Inhalts ist ein Fehler aufgetreten.</translation> <translation id="8840953339110955557">Diese Seite unterscheidet sich gegebenenfalls von der Onlineversion.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_el.xtb b/chrome/android/java/strings/translations/android_chrome_strings_el.xtb index c6df7c1..0b3bd5b 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_el.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_el.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Αναφορές χρήσης και σφαλμάτων</translation> <translation id="11221688409173367">Πατήστε το κουμπί αρχικής οθόνης για να δείτε άρθρα που έχουν επιλεγεί ειδικά για εσάς</translation> <translation id="1129510026454351943">Λεπτομέρειες: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 λήψη σε εκκρεμότητα.}other{# λήψεις σε εκκρεμότητα.}}</translation> <translation id="1145536944570833626">Διαγραφή υπαρχόντων δεδομένων.</translation> <translation id="1146678959555564648">Εισαγωγή VR</translation> <translation id="114721135501989771">Έξυπνες λειτουργίες Google στο Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Ενημερώστε τα στοιχεία σύνδεσής σας.</translation> <translation id="1974060860693918893">Σύνθετες</translation> <translation id="1984937141057606926">Να επιτρέπονται, εκτός από τα cookie τρίτου μέρους</translation> +<translation id="1987739130650180037">Κουμπί <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Περιήγηση</translation> <translation id="1993768208584545658">Ο ιστότοπος <ph name="SITE" /> επιθυμεί σύζευξη</translation> <translation id="1994173015038366702">URL ιστότοπου</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">Ασήμαντος αποθηκευτικός χώρος</translation> <translation id="4002066346123236978">Τίτλος</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# ω.}other{# ω.}}</translation> <translation id="4042870126885713738">Εμφάνιση προτάσεων όταν μια διεύθυνση ιστού δεν αναλύεται σωστά ή δεν είναι δυνατό να πραγματοποιηθεί σύνδεση</translation> <translation id="4046123991198612571">Επόμενο κομμάτι</translation> <translation id="4048707525896921369">Ενημερωθείτε σχετικά με τα θέματα των ιστοτόπων, χωρίς να αποχωρήσετε από τη σελίδα. Η λειτουργία "Πατήστε για αναζήτηση" στέλνει μια λέξη και τα συμφραζόμενά της στην Αναζήτηση Google και εμφανίζει ορισμούς, εικόνες, αποτελέσματα αναζήτησης και άλλες λεπτομέρειες. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Πραγματοποιείτε ανώνυμη περιήγηση</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Πριν από # λεπτό}other{Πριν από # λεπτά}}</translation> <translation id="4587589328781138893">Ιστότοποι</translation> +<translation id="4594952190837476234">Αυτή η σελίδα εκτός σύνδεσης δημιουργήθηκε στις <ph name="CREATION_TIME" /> και μπορεί να διαφέρει από την έκδοση στο διαδίκτυο.</translation> <translation id="4605958867780575332">Το στοιχείο καταργήθηκε <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Ανοίξτε <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Διαχειρίζεται από τους γονείς σου</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Άνοιγμα νέας καρτέλας</translation> <translation id="4751476147751820511">Αισθητήρες κίνησης ή φωτός</translation> <translation id="4759238208242260848">Λήψεις</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 ολοκληρωμένη λήψη.}other{# ολοκληρωμένες λήψεις.}}</translation> <translation id="4766369052440583386">Η Εξοικονόμηση δεδομένων είναι ενεργή</translation> <translation id="4797039098279997504">Αγγίξτε για να επιστρέψετε στη διεύθυνση <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Όνομα στην κάρτα</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Οι κωδικοί πρόσβασης, το ιστορικό και πολλά άλλα σε όλες τις συσκευές</translation> <translation id="4961700429721424617">Πρόκειται να αποσυνδεθείτε από έναν λογαριασμό του οποίου η διαχείριση γίνεται από <ph name="MANAGED_DOMAIN" />. Αυτή η ενέργεια θα διαγράψει τα δεδομένα σας στο Chrome από αυτήν τη συσκευή, αλλά θα διατηρηθούν στον Λογαριασμό σας Google.</translation> <translation id="497421865427891073">Μετάβαση προς τα εμπρός</translation> +<translation id="4988210275050210843">Λήψη αρχείου (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Σελίδες</translation> <translation id="4996978546172906250">Μοιραστείτε μέσω</translation> <translation id="5004339818306944878">Χρησιμοποιήστε έως 60% λιγότερα δεδομένα και αυξήστε την ταχύτητα του ιστού. Οι διακομιστές της Google θα βελτιστοποιήσουν τις σελίδες που επισκέπτεστε.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Διαγραφή αποθηκευμένων δεδομένων</translation> <translation id="5152843274749979095">Δεν έχουν εγκατασταθεί υποστηριζόμενες εφαρμογές</translation> <translation id="5161254044473106830">Απαιτείται τίτλος</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 λήψη απέτυχε.}other{# λήψεις απέτυχαν.}}</translation> <translation id="5168917394043976756">Άνοιγμα συρταριού πλοήγησης</translation> <translation id="5171365962177408781">Πατήστε για να φορτώσετε τη σελίδα σε νέα καρτέλα και να δείτε προτεινόμενα άρθρα</translation> <translation id="5184329579814168207">Άνοιγμα στο Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Οι πιο δημοφιλείς σελίδες σας θα εμφανίζονται εδώ</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB διαθέσιμα</translation> <translation id="5433691172869980887">Το όνομα χρήστη αντιγράφηκε</translation> +<translation id="543509235395288790">Λήψη <ph name="COUNT" /> αρχείων (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Μετάβαση στη γραμμή διευθύνσεων</translation> <translation id="5447201525962359567">Όλος ο αποθηκευτικός χώρος ιστοτόπων, συμπεριλαμβανομένων των cookie και άλλων τοπικά αποθηκευμένων δεδομένων</translation> <translation id="5447765697759493033">Αυτός ο ιστότοπος δεν θα μεταφραστεί</translation> +<translation id="545042621069398927">Επιτάχυνση της λήψης σας.</translation> <translation id="5456381639095306749">Λήψη σελίδας</translation> <translation id="548278423535722844">Άνοιγμα σε εφαρμογή χαρτών</translation> <translation id="5487521232677179737">Διαγραφή δεδομένων</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Παλαιότερο από 30 ημέρες</translation> <translation id="5858741533101922242">Το Chrome δεν είναι δυνατό να ενεργοποιήσει τον προσαρμογέα Bluetooth</translation> <translation id="5860033963881614850">Απενεργοποιημένη</translation> +<translation id="5864174910718532887">Λεπτομέρειες: Ταξινομήθηκαν κατά όνομα ιστοτόπου</translation> <translation id="5864419784173784555">Αναμονή για άλλη λήψη…</translation> <translation id="5869522115854928033">Αποθηκευμένοι κωδικοί πρόσβασης</translation> <translation id="5878455346526065919">Αποκλεισμός διαφημίσεων από ιστοτόπους που τείνουν να εμφανίζουν παρεμβατικές διαφημίσεις</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Προτάσεις περιεχομένου</translation> <translation id="6277522088822131679">Παρουσιάστηκε ένα πρόβλημα κατά την εκτύπωση της σελίδας. Δοκιμάστε ξανά.</translation> <translation id="6295158916970320988">Όλοι οι ιστότοποι</translation> +<translation id="629730747756840877">Λογαριασμός</translation> <translation id="6320088164292336938">Δόνηση</translation> <translation id="6324034347079777476">Ο συγχρονισμός συστήματος Android απενεργοποιήθηκε</translation> <translation id="6333140779060797560">Μοιραστείτε μέσω <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Κρυπτογράφηση</translation> +<translation id="6341580099087024258">Να γίνεται ερώτηση σχετικά με την τοποθεσία αποθήκευσης των αρχείων</translation> <translation id="6343192674172527289">Δεν βρέθηκαν λήψεις</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 και <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ακόμη}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 και <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ακόμη}}</translation> <translation id="6364438453358674297">Κατάργηση πρότασης από το ιστορικό;</translation> +<translation id="6378173571450987352">Λεπτομέρειες: Ταξινομήθηκαν βάσει του όγκου των δεδομένων που χρησιμοποιήθηκαν</translation> <translation id="6383961787135158834">Διαγρ. αποθ. χώρ. ιστότ…</translation> <translation id="6388207532828177975">Διαγραφή και επαναφορά</translation> <translation id="6393863479814692971">Το Chrome χρειάζεται άδεια, για να αποκτήσει πρόσβαση στην κάμερα και το μικρόφωνο για αυτόν τον ιστότοπο.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Προσθέστε έναν Λογαριασμό Google από τη σελίδα "Λογαριασμοί" της εφαρμογής Ρυθμίσεις της συσκευής σας.</translation> <translation id="7274013316676448362">Αποκλεισμένος ιστότοπος</translation> <translation id="729975465115245577">Η συσκευή σας δεν διαθέτει κάποια εφαρμογή για την αποθήκευση του αρχείου κωδικών πρόσβασης.</translation> +<translation id="7302081693174882195">Λεπτομέρειες: Ταξινομήθηκαν βάσει του όγκου των δεδομένων που αποθηκεύτηκαν</translation> <translation id="7333031090786104871">Η προσθήκη του προηγούμενου ιστοτόπου δεν έχει ολοκληρωθεί</translation> <translation id="7352939065658542140">ΒΙΝΤΕΟ</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Κοινοποίηση 1 επιλεγμένου στοιχείου}other{Κοινοποίηση # επιλεγμένων στοιχείων}}</translation> <translation id="7359002509206457351">Πρόσβαση σε τρόπους πληρωμής</translation> <translation id="7366340029385295517">Μετάδοση στη συσκευή <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Τύπος:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Εμπειρία πρώτης εκτέλεσης Chrome</translation> <translation id="741204030948306876">Ναι, συμφωνώ</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Να γίνεται ερώτηση πρώτα</translation> <translation id="7423538860840206698">Αποκλεισμός από ανάγνωση πρόχειρου</translation> <translation id="7437998757836447326">Αποσύνδεση από το Chrome</translation> +<translation id="7444811645081526538">Περισσότερες κατηγορίες</translation> <translation id="7445411102860286510">Να επιτρέπεται στους ιστότοπους η αυτόματη αναπαραγωγή βίντεο σε σίγαση (συνιστάται)</translation> <translation id="7453467225369441013">Θα αποσυνδεθείτε από τους περισσότερους ιστοτόπους. Δεν θα αποσυνδεθείτε από τον Λογαριασμό σας Google.</translation> <translation id="7454641608352164238">Ανεπαρκής χώρος</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Κατάργηση όλων</translation> <translation id="7882131421121961860">Δεν βρέθηκε ιστορικό</translation> <translation id="7882806643839505685">Να επιτρέπεται ο ήχος για έναν συγκεκριμένο ιστότοπο.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Λήψη αρχείου.}other{Λήψη # αρχείων.}}</translation> <translation id="7929962904089429003">Άνοιγμα μενού</translation> <translation id="7942131818088350342">Το <ph name="PRODUCT_NAME" /> δεν είναι ενημερωμένο.</translation> <translation id="7947953824732555851">Αποδοχή και σύνδεση</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Σε ορισμένους ιστοτόπους, μπορείτε να πληρώσετε χρησιμοποιώντας τις παραπάνω υποστηριζόμενες εφαρμογές πληρωμών στη συσκευή σας.</translation> <translation id="8816439037877937734">Η εφαρμογή <ph name="APP_NAME" /> θα ανοίξει στο Chrome. Εάν συνεχίσετε, συμφωνείτε με τους <ph name="BEGIN_LINK1" />Όρους Παροχής Υπηρεσιών<ph name="END_LINK1" /> και τη <ph name="BEGIN_LINK2" />Σημείωση απορρήτου<ph name="END_LINK2" /> του Chrome, καθώς και με τη <ph name="BEGIN_LINK3" />Σημείωση απορρήτου για Λογαριασμούς Google των οποίων η διαχείριση γίνεται μέσω του Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Σελιδοδείκτες</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Παρουσιάστηκε σφάλμα κατά τη λήψη του περιεχομένου.</translation> <translation id="8840953339110955557">Αυτή η σελίδα μπορεί να διαφέρει από την έκδοση στο διαδίκτυο.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb b/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb index 3a215e2..fd6d74a 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb
@@ -615,6 +615,7 @@ <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="6320088164292336938">Vibrate</translation> <translation id="6324034347079777476">Android system sync disabled</translation> <translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb b/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb index 9064bb3..6d60dfbc 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Informes de uso y de fallos</translation> <translation id="11221688409173367">Presiona el botón de inicio para ver artículos seleccionados específicamente para ti</translation> <translation id="1129510026454351943">Detalles: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 descarga pendiente}other{# descargas pendientes}}</translation> <translation id="1145536944570833626">Borra los datos existentes.</translation> <translation id="1146678959555564648">Entrar al modo RV</translation> <translation id="114721135501989771">Obtener las funciones inteligentes de Google en Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Actualiza los datos de acceso.</translation> <translation id="1974060860693918893">Avanzada</translation> <translation id="1984937141057606926">Permitidas, salvo de terceros</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> Botón <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Navegar</translation> <translation id="1993768208584545658"><ph name="SITE" /> desea sincronizarse</translation> <translation id="1994173015038366702">URL del sitio</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Almacenamiento no importante</translation> <translation id="4002066346123236978">Título</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4042870126885713738">Mostrar sugerencias cuando no se resuelve una dirección web o cuando no se puede establecer una conexión</translation> <translation id="4046123991198612571">Siguiente pista</translation> <translation id="4048707525896921369">Obtén información acerca de temas en sitios web sin salir de la página. "Presionar para buscar" envía una palabra y el contexto en el que se encuentra a la Búsqueda de Google, y muestra definiciones, fotos, resultados de la búsqueda y otros detalles. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Estás en modo incógnito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Hace # minuto}other{Hace # minutos}}</translation> <translation id="4587589328781138893">Sitios</translation> +<translation id="4594952190837476234">Esta página sin conexión se creó el <ph name="CREATION_TIME" /> y es posible que sea diferente con respecto a la versión en línea.</translation> <translation id="4605958867780575332">Se quitó el siguiente elemento: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Abrir <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Administrado por tus padres</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Abrir una pestaña nueva</translation> <translation id="4751476147751820511">Sensores de luz o movimiento</translation> <translation id="4759238208242260848">Descargas</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{Se completó la descarga.}other{Se completaron # descargas.}}</translation> <translation id="4766369052440583386">La extensión Ahorro de datos está activada</translation> <translation id="4797039098279997504">Toca para volver a <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Nombre en la tarjeta</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Tus contraseñas, historial y más en todos los dispositivos</translation> <translation id="4961700429721424617">Estás saliendo de una cuenta administrada por <ph name="MANAGED_DOMAIN" />. Esta acción borrará tus datos de Chrome en este dispositivo, pero permanecerán en tu cuenta de Google.</translation> <translation id="497421865427891073">Avanzar</translation> +<translation id="4988210275050210843">Descargando archivo (<ph name="MEGABYTES" />)</translation> <translation id="4988526792673242964">Páginas</translation> <translation id="4996978546172906250">Compartir mediante</translation> <translation id="5004339818306944878">Usa hasta un 60% menos de datos y acelera la navegación en la Web. Los servidores de Google optimizarán las páginas que visites.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Borrar datos almacenados</translation> <translation id="5152843274749979095">No hay apps compatibles instaladas</translation> <translation id="5161254044473106830">Se requiere un título</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{No se pudo realizar la descarga.}other{No se pudieron realizar # descargas.}}</translation> <translation id="5168917394043976756">Abrir panel lateral de navegación</translation> <translation id="5171365962177408781">Presiona para cargar la página Nueva pestaña y ver artículos sugeridos</translation> <translation id="5184329579814168207">Abrir en Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Aquí aparecerán las páginas que visites con más frecuencia</translation> <translation id="5424588387303617268">GB disponibles: <ph name="GIGABYTES" /></translation> <translation id="5433691172869980887">Se copió el nombre de usuario</translation> +<translation id="543509235395288790">Descargando <ph name="COUNT" /> archivos (<ph name="MEGABYTES" />)</translation> <translation id="5441522332038954058">Ir a la barra de direcciones</translation> <translation id="5447201525962359567">Todo el almacenamiento de sitios, lo que incluye cookies y otros datos almacenados de forma local</translation> <translation id="5447765697759493033">Este sitio no se traducirá</translation> +<translation id="545042621069398927">Acelerando la descarga</translation> <translation id="5456381639095306749">Descargar página</translation> <translation id="548278423535722844">Abrir en una app de mapas</translation> <translation id="5487521232677179737">Borrar datos</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Hace más de 30 días</translation> <translation id="5858741533101922242">Chrome no puede activar el adaptador Bluetooth</translation> <translation id="5860033963881614850">Desactivado</translation> +<translation id="5864174910718532887">Detalles: Ordenados por nombre de sitio</translation> <translation id="5864419784173784555">Esperando que finalice otra descarga…</translation> <translation id="5869522115854928033">Contraseñas almacenadas</translation> <translation id="5878455346526065919">Bloquear anuncios de sitios que tienden a mostrar anuncios intrusivos</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Sugerencias de contenido</translation> <translation id="6277522088822131679">Se produjo un error al imprimir la página. Vuelve a intentarlo.</translation> <translation id="6295158916970320988">Todos los sitios</translation> +<translation id="629730747756840877">Cuenta</translation> <translation id="6320088164292336938">Vibrar</translation> <translation id="6324034347079777476">Sincronización del sistema Android inhabilitada</translation> <translation id="6333140779060797560">Compartir mediante <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Encriptación</translation> +<translation id="6341580099087024258">Preguntar dónde guardar los archivos</translation> <translation id="6343192674172527289">No se encontraron descargas</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> más}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> más}}</translation> <translation id="6364438453358674297">¿Borrar la sugerencia del historial?</translation> +<translation id="6378173571450987352">Detalles: Ordenados por cantidad de datos utilizados</translation> <translation id="6383961787135158834">Borrar el almacenamiento de sitios…</translation> <translation id="6388207532828177975">Borrar y restablecer</translation> <translation id="6393863479814692971">Chrome necesita permiso para acceder a tu cámara y micrófono para este sitio.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Agrega una cuenta de Google desde la página Cuentas en la app de Configuración del dispositivo.</translation> <translation id="7274013316676448362">Sitio bloqueado</translation> <translation id="729975465115245577">Tu dispositivo no tiene una app que pueda almacenar el archivo de contraseñas.</translation> +<translation id="7302081693174882195">Detalles: Ordenados por cantidad de datos ahorrados</translation> <translation id="7333031090786104871">Aún se está agregando el sitio anterior</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Comparte 1 elemento seleccionado}other{Comparte # elementos seleccionados}}</translation> <translation id="7359002509206457351">Acceder a formas de pago</translation> <translation id="7366340029385295517">Transmitiendo a <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Tipo:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" /></translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Primera experiencia de ejecución de Chrome</translation> <translation id="741204030948306876">Sí, acepto</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Preguntar primero</translation> <translation id="7423538860840206698">Se impidió la lectura del portapapeles</translation> <translation id="7437998757836447326">Salir de Chrome</translation> +<translation id="7444811645081526538">Más categorías</translation> <translation id="7445411102860286510">Permitir que los sitios reproduzcan videos silenciados de forma automática (recomendado)</translation> <translation id="7453467225369441013">Esta acción te hace salir de la mayoría de los sitios. No saldrás de tu cuenta de Google.</translation> <translation id="7454641608352164238">No hay suficiente espacio</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Eliminar todo</translation> <translation id="7882131421121961860">No se encontraron entradas en el historial</translation> <translation id="7882806643839505685">Habilitar el sonido de un sitio específico.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Descargando archivo}other{Descargando # archivos}}</translation> <translation id="7929962904089429003">Abrir el menú</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> no está actualizado.</translation> <translation id="7947953824732555851">Aceptar y acceder</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">En algunos sitios web, puedes usar las apps compatibles que se enumeran anteriormente para hacer pagos en tu dispositivo.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> se abrirá en Chrome. Al continuar, aceptas las <ph name="BEGIN_LINK1" />Condiciones del servicio<ph name="END_LINK1" /> y el <ph name="BEGIN_LINK2" />Aviso de privacidad<ph name="END_LINK2" /> de Chrome, y el <ph name="BEGIN_LINK3" />Aviso de privacidad para las cuentas de Google administradas con Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Favoritos</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Se produjo un error al descargar el contenido.</translation> <translation id="8840953339110955557">Es posible que esta página sea diferente con respecto a la versión en línea.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_es.xtb b/chrome/android/java/strings/translations/android_chrome_strings_es.xtb index f513ba7..09c7dae 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_es.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_es.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Sugerencias de contenido</translation> <translation id="6277522088822131679">Se ha producido un problema al imprimir la página. Vuelve a intentarlo.</translation> <translation id="6295158916970320988">Todos los sitios</translation> +<translation id="629730747756840877">Cuenta</translation> <translation id="6320088164292336938">Vibrar</translation> <translation id="6324034347079777476">Sincronización del sistema Android inhabilitada</translation> <translation id="6333140779060797560">Compartir a través de <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb index e9506a8..4f409a9 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">آمار استفاده و گزارشهای خرابی</translation> <translation id="11221688409173367">برای مشاهده مقالههایی که بهطور خاص برای شما انتخاب شده است روی دکمه صفحه اصلی ضربه بزنید</translation> <translation id="1129510026454351943">جزئیات: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{۱ بارگیری در انتظار است.}one{# بارگیری در انتظار است.}other{# بارگیری در انتظار است.}}</translation> <translation id="1145536944570833626">حذف دادههای موجود.</translation> <translation id="1146678959555564648">VR را وارد کنید</translation> <translation id="114721135501989771">هوشمندیهای Google را در Chrome دریافت کنید</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">لطفاً جزئیات ورود به سیستم را بهروز کنید.</translation> <translation id="1974060860693918893">پیشرفته</translation> <translation id="1984937141057606926">مجاز، به غیر از طرف ثالث</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> دکمه <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">مشاهده محتوای موجود در فروشگاه ما</translation> <translation id="1993768208584545658"><ph name="SITE" /> میخواهد مرتبط شود</translation> <translation id="1994173015038366702">نشانی وب سایت</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> از ؟</translation> <translation id="3997476611815694295">فضای ذخیره غیرمهم</translation> <translation id="4002066346123236978">عنوان</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# ساعت}one{# ساعت}other{# ساعت}}</translation> <translation id="4042870126885713738">وقتی آدرس وب شناسایی نمیشود یا اتصال برقرار نمیشود، پیشنهاداتی نشان داده میشود</translation> <translation id="4046123991198612571">آهنگ بعدی</translation> <translation id="4048707525896921369">بدون ترک کردن صفحه با موضوعات وبسایتها آشنا شوید. «ضربه برای جستجو»، کلمه و متن اطراف آن را به «جستجوی Google» ارسال میکند و معانی، تصاویر، نتایج جستجو و سایر جزئیات را بازمیگرداند. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">اکنون در حالت ناشناس هستید.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# دقیقه قبل}one{# دقیقه قبل}other{# دقیقه قبل}}</translation> <translation id="4587589328781138893">سایتها</translation> +<translation id="4594952190837476234">این صفحه آفلاین مربوط به تاریخ <ph name="CREATION_TIME" /> است و ممکن است با نسخه آنلاین متفاوت باشد.</translation> <translation id="4605958867780575332">مورد حذف شد: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">باز کردن <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">مدیریت شده توسط والدین شما</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">باز کردن برگه جدید</translation> <translation id="4751476147751820511">حسگرهای نوری یا حرکتی</translation> <translation id="4759238208242260848">بارگیریها</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{۱ بارگیری کامل شد.}one{# بارگیری کامل شد.}other{# بارگیری کامل شد.}}</translation> <translation id="4766369052440583386">صرفهجویی داده روشن است</translation> <translation id="4797039098279997504">برای برگشتن به <ph name="URL_OF_THE_CURRENT_TAB" />، لمس کنید</translation> <translation id="4807098396393229769">نام روی کارت</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">گذرواژهها، سابقه و موارد دیگر در همه دستگاهها</translation> <translation id="4961700429721424617">هماکنون از حسابی که توسط <ph name="MANAGED_DOMAIN" /> مدیریت میشود، خارج میشوید. با این کار دادههای Chrome شما از این دستگاه حذف میشود اما همچنان در حساب Google شما باقی میماند.</translation> <translation id="497421865427891073">جلو رفتن</translation> +<translation id="4988210275050210843">درحال بارگیری فایل (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">صفحات</translation> <translation id="4996978546172906250">اشتراکگذاری از طریق</translation> <translation id="5004339818306944878">تا ۶۰٪ کمتر داده مصرف کنید و به وب سرعت ببخشید. سرورهای Google صفحاتی را که بازدید میکنید بهینهسازی میکند.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">پاک کردن داده ذخیره شده</translation> <translation id="5152843274749979095">هیچ برنامه پشتیبانیشدهای نصب نشده است</translation> <translation id="5161254044473106830">عنوان مورد نیاز است</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{۱ بارگیری انجام نشد.}one{# بارگیری انجام نشد.}other{# بارگیری انجام نشد.}}</translation> <translation id="5168917394043976756">بازکردن کشوی پیمایش</translation> <translation id="5171365962177408781">برای بارگیری صفحه برگه جدید و مشاهده مقالههای پیشنهادی ضربه بزنید</translation> <translation id="5184329579814168207">باز کردن در Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">صفحاتی که بیشترین بازدید را از آنها داشتهاید در اینجا نمایان میشوند</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> گیگابایت در دسترس</translation> <translation id="5433691172869980887">نام کاربری کپی شد</translation> +<translation id="543509235395288790">درحال بارگیری <ph name="COUNT" /> فایل (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">رفتن به نوار نشانی</translation> <translation id="5447201525962359567">همه فضای ذخیره سایتها، ازجمله کوکیها و سایر دادههای ذخیرهشده در دستگاه</translation> <translation id="5447765697759493033">این سایت ترجمه نخواهد شد</translation> +<translation id="545042621069398927">درحال سرعت بخشیدن به بارگیری.</translation> <translation id="5456381639095306749">بارگیری صفحه</translation> <translation id="548278423535722844">باز کردن در برنامه Maps</translation> <translation id="5487521232677179737">پاک کردن دادهها</translation> @@ -558,6 +567,7 @@ <translation id="5854790677617711513">قدیمیتر از ۳۰ روز</translation> <translation id="5858741533101922242">Chrome قادر به روشن کردن آداپتور بلوتوث نیست</translation> <translation id="5860033963881614850">خاموش</translation> +<translation id="5864174910718532887">جزئیات: مرتبشده براساس نام سایت</translation> <translation id="5864419784173784555">در انتظار بارگیری موردی دیگر…</translation> <translation id="5869522115854928033">گذرواژههای ذخیرهشده</translation> <translation id="5878455346526065919">مسدود کردن آگهیها از سایتهایی که تمایل دارند آگهیهای مزاحم نشان دهند</translation> @@ -604,13 +614,16 @@ <translation id="6255999984061454636">پیشنهادهای محتوا</translation> <translation id="6277522088822131679">در چاپ صفحه مشکلی پیش آمد. لطفاً دوباره امتحان کنید.</translation> <translation id="6295158916970320988">همه سایتها</translation> +<translation id="629730747756840877">حساب</translation> <translation id="6320088164292336938">لرزش</translation> <translation id="6324034347079777476">همگامسازی سیستم Android غیرفعال شد</translation> <translation id="6333140779060797560">اشتراکگذاری از طریق <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">رمزگذاری</translation> +<translation id="6341580099087024258">مکان ذخیره شدن فایلها پرسیده شود</translation> <translation id="6343192674172527289">هیچ بارگیریای پیدا نشد</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 و <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> نشانی دیگر}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 و <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> نشانی دیگر}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 و <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> نشانی دیگر}}</translation> <translation id="6364438453358674297">پیشنهاد از سابقه حذف شود؟</translation> +<translation id="6378173571450987352">جزئیات: مرتبشده براساس مقدار داده استفادهشده</translation> <translation id="6383961787135158834">پاک کردن فضای ذخیرهسازی سایت…</translation> <translation id="6388207532828177975">پاک کردن و بازنشانی</translation> <translation id="6393863479814692971">Chrome برای این سایت به مجوز دسترسی به دوربین و میکروفون نیاز دارد.</translation> @@ -722,12 +735,14 @@ <translation id="7253272406652746122">از صفحه «حسابها» در برنامه «تنظیمات» دستگاه، یک حساب Google اضافه کنید.</translation> <translation id="7274013316676448362">سایت مسدودشده</translation> <translation id="729975465115245577">دستگاه شما برنامهای برای ذخیره فایل گذرواژهها ندارد.</translation> +<translation id="7302081693174882195">جزئیات: مرتبشده براساس مقدار داده صرفهجوییشده</translation> <translation id="7333031090786104871">همچنان درحال افزودن سایت قبلی</translation> <translation id="7352939065658542140">ویدیو</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{اشتراکگذاری ۱ مورد انتخابشده}one{اشتراکگذاری # مورد انتخابشده}other{اشتراکگذاری # مورد انتخابشده}}</translation> <translation id="7359002509206457351">دسترسی به روشهای پرداخت</translation> <translation id="7366340029385295517">درحال فرستادن به <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">نوع:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">نشانی وب</translation> <translation id="7403691278183511381">اولین تجربه اجرا Chrome</translation> <translation id="741204030948306876">بله، موافقم</translation> @@ -735,6 +750,7 @@ <translation id="7423098979219808738">ابتدا سؤال شود</translation> <translation id="7423538860840206698">خواندن محتوای بریدهدان مسدود شد</translation> <translation id="7437998757836447326">خروج از سیستم Chrome</translation> +<translation id="7444811645081526538">دستههای بیشتر</translation> <translation id="7445411102860286510">اجازه به سایتها برای پخش خودکار ویدیوهای صامتشده (توصیه میشود)</translation> <translation id="7453467225369441013">شما را از سیستم اکثر سایتها خارج میکند. از سیستم حساب Google خارج نمیشوید.</translation> <translation id="7454641608352164238">فضای کافی وجود ندارد</translation> @@ -789,6 +805,7 @@ <translation id="7876243839304621966">حذف همه</translation> <translation id="7882131421121961860">هیچ سابقهای پیدا نشد</translation> <translation id="7882806643839505685">پخش صدا برای سایتی خاص مجاز شود.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{درحال بارگیری فایل.}one{درحال بارگیری # فایل.}other{درحال بارگیری # فایل.}}</translation> <translation id="7929962904089429003">باز کردن منو</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> قدیمی است.</translation> <translation id="7947953824732555851">پذیرش و ورود به سیستم</translation> @@ -884,6 +901,7 @@ <translation id="8812260976093120287">در بعضی از وبسایتها، میتوانید با برنامههای پرداخت پشتیبانیشده بالا در دستگاهتان پرداخت کنید.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> در Chrome باز خواهد شد. درصورت ادامه دادن، با <ph name="BEGIN_LINK1" />شرایط خدمات<ph name="END_LINK1" /> و <ph name="BEGIN_LINK2" />اعلان حریم خصوصی<ph name="END_LINK2" /> Chrome و <ph name="BEGIN_LINK3" />اعلان حریم خصوصی برای حسابهای Google مدیریتشده با Family<ph name="END_LINK3" /> موافقت میکنید.</translation> <translation id="8820817407110198400">نشانکها</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">هنگام بارگیری محتوا خطایی روی داد.</translation> <translation id="8840953339110955557">ممکن است این صفحه با نسخه آنلاین متفاوت باشد.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb index f363773..a4667c7c 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Sisältöehdotukset</translation> <translation id="6277522088822131679">Sivua tulostettaessa tapahtui virhe. Yritä uudelleen.</translation> <translation id="6295158916970320988">Kaikki sivustot</translation> +<translation id="629730747756840877">Tili</translation> <translation id="6320088164292336938">Värinä</translation> <translation id="6324034347079777476">Android-järjestelmän synkronointi poistettu käytöstä</translation> <translation id="6333140779060797560">Jaa sovelluksella <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb index ef9e236..584c3229 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Mga ulat sa paggamit at pag-crash</translation> <translation id="11221688409173367">I-tap ang button ng home para tingnan ang mga artikulong partikular na pinili para sa iyo</translation> <translation id="1129510026454351943">Mga Detalye: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{Nakabinbin ang 1 pag-download.}one{Nakabinbin ang # pag-download.}other{Nakabinbin ang # na pag-download.}}</translation> <translation id="1145536944570833626">I-delete ang kasalukuyang data.</translation> <translation id="1146678959555564648">Pumasok sa VR</translation> <translation id="114721135501989771">Magkaroon ng mga smart na feature ng Google sa Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Paki-update ang iyong mga detalye sa pag-sign in.</translation> <translation id="1974060860693918893">Advanced</translation> <translation id="1984937141057606926">Pinapayagan, maliban ang third-party</translation> +<translation id="1987739130650180037">Button ng <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Mag-browse</translation> <translation id="1993768208584545658">Gustong makipagpares ng <ph name="SITE" /></translation> <translation id="1994173015038366702">URL ng site</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">Storage ng hindi mahalaga</translation> <translation id="4002066346123236978">Pamagat</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# oras}one{# oras}other{# na oras}}</translation> <translation id="4042870126885713738">Magpakita ng mga suhestyon kapag hindi ma-resolve ang isang website o kung hindi makakonekta</translation> <translation id="4046123991198612571">Susunod na track</translation> <translation id="4048707525896921369">Matuto tungkol sa mga paksa sa mga website nang hindi umaalis sa page. Ipinapadala sa Google Search ng I-tap para Maghanap ang salita at ang konteksto nito, na nagbibigay ng mga kahulugan, larawan, resulta ng paghahanap, at iba pang detalye. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Naging incognito ka.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# minuto ang nakalipas}one{# minuto ang nakalipas}other{# na minuto ang nakalipas}}</translation> <translation id="4587589328781138893">Mga Site</translation> +<translation id="4594952190837476234">Naka-offline ang page na ito mula noong <ph name="CREATION_TIME" /> at maaaring iba ito sa online na bersyon.</translation> <translation id="4605958867780575332">Naalis na item: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Buksan ang <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Pinamamahalaan ng iyong magulang</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Magbukas ng bagong tab</translation> <translation id="4751476147751820511">Mga motion o light sensor</translation> <translation id="4759238208242260848">Mga Download </translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{Tapos na ang 1 pag-download.}one{Tapos na ang # pag-download.}other{Tapos na ang # na pag-download.}}</translation> <translation id="4766369052440583386">Naka-on ang Data Saver</translation> <translation id="4797039098279997504">Pindutin upang bumalik sa <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Pangalang makikita sa card</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Ang iyong mga password, history, at higit pa sa lahat ng device</translation> <translation id="4961700429721424617">Nagsa-sign out ka sa account na pinamamahalaan ng <ph name="MANAGED_DOMAIN" />. Ide-delete nito ang data mo sa Chrome mula sa device na ito, ngunit mananatili ang data mo sa iyong Google account.</translation> <translation id="497421865427891073">Sumulong</translation> +<translation id="4988210275050210843">Nagda-download ng file (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Mga Page</translation> <translation id="4996978546172906250">Ibahagi gamit ang</translation> <translation id="5004339818306944878">Makatipid ng hanggang 60% ng data at pabilisin ang web. Io-optimize ng mga server ng Google ang mga page na binibisita mo.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">I-clear ang nakaimbak na data</translation> <translation id="5152843274749979095">Walang naka-install na sinusuportahang app</translation> <translation id="5161254044473106830">Kailangan ng pamagat</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 ang hindi na-download.}one{# ang hindi na-download.}other{# ang hindi na-download.}}</translation> <translation id="5168917394043976756">Buksan ang navigation drawer</translation> <translation id="5171365962177408781">Mag-tap para ma-load ang page ng bagong tab at tingnan ang mga iminumungkahing artikulo</translation> <translation id="5184329579814168207">Buksan sa Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Lalabas dito ang mga page na madalas mong bisitahin</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB ang available</translation> <translation id="5433691172869980887">Nakopya ang username</translation> +<translation id="543509235395288790">Nagda-download ng <ph name="COUNT" /> (na) file (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Pumunta sa address bar</translation> <translation id="5447201525962359567">Lahat ng storage ng site, kabilang ang cookies at iba pang lokal na nakaimbak na data</translation> <translation id="5447765697759493033">Hindi isasalin ang site na ito</translation> +<translation id="545042621069398927">Pinapabilis ang iyong pag-download.</translation> <translation id="5456381639095306749">I-download ang page</translation> <translation id="548278423535722844">Buksan sa app na mga mapa</translation> <translation id="5487521232677179737">I-clear ang data</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Mas matagal sa 30 araw</translation> <translation id="5858741533101922242">Hindi ma-on ng Chrome ang Bluetooth adapter</translation> <translation id="5860033963881614850">Naka-off</translation> +<translation id="5864174910718532887">Mga detalye: Pinagbukud-bukod ayon sa pangalan ng site</translation> <translation id="5864419784173784555">Naghihintay ng isa pang download…</translation> <translation id="5869522115854928033">Mga naka-save na password</translation> <translation id="5878455346526065919">I-block ang mga ad mula sa mga site na malamang na magpakita ng mga nakakasagabal na ad</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Mga suhestyong content</translation> <translation id="6277522088822131679">Nagkaproblema sa pag-print sa pahina. Pakisubukang muli.</translation> <translation id="6295158916970320988">Lahat ng site</translation> +<translation id="629730747756840877">Account</translation> <translation id="6320088164292336938">Mag-vibrate</translation> <translation id="6324034347079777476">Naka-disable ang pag-sync ng Android system</translation> <translation id="6333140779060797560">Ibahagi sa pamamagitan ng <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Pag-encrypt</translation> +<translation id="6341580099087024258">Itanong kung saan magse-save ng mga file</translation> <translation id="6343192674172527289">Walang nakitang download</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 at <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> iba pa}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 at <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> iba pa}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 at <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> na iba pa}}</translation> <translation id="6364438453358674297">Alisin ang suhestyon mula sa history?</translation> +<translation id="6378173571450987352">Mga detalye: Pinagbukud-bukod ayon sa laki ng nagamit na data</translation> <translation id="6383961787135158834">I-clear ang Storage ng Site…</translation> <translation id="6388207532828177975">I-clear at i-reset</translation> <translation id="6393863479814692971">Kailangan ng Chrome ng pahintulot na i-access ang iyong camera at mikropono para sa site na ito.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Magdagdag ng Google Account mula sa page na Mga Account sa app na Mga Setting ng iyong device.</translation> <translation id="7274013316676448362">Naka-block na site</translation> <translation id="729975465115245577">Walang app sa iyong device upang ma-store ang file ng mga password.</translation> +<translation id="7302081693174882195">Mga detalye: Pinagbukud-bukod ayon sa laki ng natipid na data</translation> <translation id="7333031090786104871">Nagdaragdag pa rin ng nakaraang site</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Ibahagi ang 1 piniling item}one{Ibahagi ang # piniling item}other{Ibahagi ang # na piniling item}}</translation> <translation id="7359002509206457351">I-access ang mga paraan ng pagbabayad</translation> <translation id="7366340029385295517">Nagka-cast sa <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Uri:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Unang Karanasan sa Pagtakbo ng Chrome</translation> <translation id="741204030948306876">Oo, sali ako</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Magtanong muna</translation> <translation id="7423538860840206698">Na-block sa pag-read ng clipboard</translation> <translation id="7437998757836447326">Mag-sign out sa Chrome</translation> +<translation id="7444811645081526538">Higit pang kategorya</translation> <translation id="7445411102860286510">Payagan ang mga site na awtomatikong mag-play ng mga naka-mute na video (inirerekomenda)</translation> <translation id="7453467225369441013">Isa-sign out ka sa karamihan ng mga site. Hindi ka masa-sign out sa iyong Google Account.</translation> <translation id="7454641608352164238">Walang sapat na espasyo</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Alisin lahat</translation> <translation id="7882131421121961860">Walang nakitang history</translation> <translation id="7882806643839505685">Payagan ang tunog para sa isang partikular na site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Nagda-download ng file.}one{Nagda-download ng # file.}other{Nagda-download ng # na file.}}</translation> <translation id="7929962904089429003">Buksan ang menu</translation> <translation id="7942131818088350342">Luma na ang <ph name="PRODUCT_NAME" />.</translation> <translation id="7947953824732555851">I-accept, mag-sign in</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Sa ilang website, maaari kang magbayad sa iyong device gamit ang mga sinusuportahang app sa pagbabayad sa itaas.</translation> <translation id="8816439037877937734">Bubukas ang <ph name="APP_NAME" /> sa Chrome. Sa pamamagitan ng pagpapatuloy, sumasang-ayon ka sa <ph name="BEGIN_LINK1" />Mga Tuntunin ng Serbisyo<ph name="END_LINK1" /> at <ph name="BEGIN_LINK2" />Notification ng Privacy<ph name="END_LINK2" /> ng Chrome, at sa <ph name="BEGIN_LINK3" />Notification ng Privacy para sa Mga Google Account na Pinamamahalaan gamit ang Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Mga Bookmark</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Nagka-error habang dina-download ang content.</translation> <translation id="8840953339110955557">Maaaring iba ang page na ito sa online na bersyon.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb index d81e210..caf53aa 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Statistiques d'utilisation et rapports d'erreur</translation> <translation id="11221688409173367">Appuyez sur le bouton d'accueil pour afficher les articles sélectionnés spécialement pour vous</translation> <translation id="1129510026454351943">Détails°: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 téléchargement en attente.}one{# téléchargement en attente.}other{# téléchargements en attente.}}</translation> <translation id="1145536944570833626">Supprimer les données existantes.</translation> <translation id="1146678959555564648">Activer la réalité virtuelle</translation> <translation id="114721135501989771">Fonct. Google dans Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Veuillez mettre à jour vos informations de connexion.</translation> <translation id="1974060860693918893">Paramètres avancés</translation> <translation id="1984937141057606926">Autorisés, sauf cookies tiers</translation> +<translation id="1987739130650180037">Bouton <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Parcourir</translation> <translation id="1993768208584545658"><ph name="SITE" /> tente de s'associer</translation> <translation id="1994173015038366702">URL du site</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/ ?</translation> <translation id="3997476611815694295">Stockage non important</translation> <translation id="4002066346123236978">Titre</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}other{# h}}</translation> <translation id="4042870126885713738">Afficher d'autres solutions lorsqu'une adresse Web ne peut pas être résolue ou qu'une connexion ne peut pas être établie</translation> <translation id="4046123991198612571">Piste suivante</translation> <translation id="4048707525896921369">Découvrez les thèmes abordés sur les sites Web sans quitter la page. La fonctionnalité "Appuyer pour rechercher" transmet un mot et son contexte à la recherche Google, qui renvoie à son tour des définitions, des images, des résultats de recherche et d'autres informations. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Vous êtes passé en mode navigation privée</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Il y a # minute}one{Il y a # minute}other{Il y a # minutes}}</translation> <translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">Cette page hors connexion date du <ph name="CREATION_TIME" /> et peut différer de la version en ligne.</translation> <translation id="4605958867780575332">Élément supprimé : <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Ouvrir <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Géré par ton papa/ta maman</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Ouvrir un nouvel onglet</translation> <translation id="4751476147751820511">Capteurs de mouvement ou de lumière</translation> <translation id="4759238208242260848">Téléchargements</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 téléchargement terminé.}one{# téléchargement terminé.}other{# téléchargements terminés.}}</translation> <translation id="4766369052440583386">L'économiseur de données est activé</translation> <translation id="4797039098279997504">Appuyer ici pour revenir à l'adresse <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Titulaire de la carte</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Vos mots de passe, votre historique et plus encore sur tous les appareils</translation> <translation id="4961700429721424617">Vous vous déconnectez d'un compte géré par <ph name="MANAGED_DOMAIN" />. Cette opération entraînera la suppression de vos données Chrome de cet appareil, mais celles-ci seront conservées dans votre compte Google.</translation> <translation id="497421865427891073">Avancer</translation> +<translation id="4988210275050210843">Téléchargement du fichier (<ph name="MEGABYTES" />)…</translation> <translation id="4988526792673242964">Pages</translation> <translation id="4996978546172906250">Partager via</translation> <translation id="5004339818306944878">Utilisez jusqu'à 60 % de données en moins et naviguez plus rapidement sur le Web. Grâce aux serveurs Google, les pages que vous consultez sont optimisées.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Effacer les données stockées</translation> <translation id="5152843274749979095">Aucune application compatible n'est installée</translation> <translation id="5161254044473106830">Veuillez saisir un titre.</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{Échec de 1 téléchargement.}one{Échec de # téléchargement.}other{Échec de # téléchargements.}}</translation> <translation id="5168917394043976756">Ouvrir le panneau de navigation</translation> <translation id="5171365962177408781">Appuyez ici pour charger la page "Nouvel onglet" et afficher les articles suggérés</translation> <translation id="5184329579814168207">Ouvrir dans Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Les pages les plus consultées s'affichent ici.</translation> <translation id="5424588387303617268">Espace disponible : <ph name="GIGABYTES" /> Go</translation> <translation id="5433691172869980887">Nom d'utilisateur copié</translation> +<translation id="543509235395288790">Téléchargement de <ph name="COUNT" /> fichiers (<ph name="MEGABYTES" />)…</translation> <translation id="5441522332038954058">Accéder à la barre d'adresse</translation> <translation id="5447201525962359567">Toutes les données de site stockées, y compris les cookies et d'autres données stockées en local</translation> <translation id="5447765697759493033">Ce site ne sera pas traduit</translation> +<translation id="545042621069398927">Accélération du téléchargement…</translation> <translation id="5456381639095306749">Télécharger la page</translation> <translation id="548278423535722844">Ouvrir dans une application de plans</translation> <translation id="5487521232677179737">Effacer les données</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Datant de plus de 30 jours</translation> <translation id="5858741533101922242">Impossible d'activer l'adaptateur Bluetooth dans Chrome</translation> <translation id="5860033963881614850">Désactivé</translation> +<translation id="5864174910718532887">Détails : tri effectué par nom de site</translation> <translation id="5864419784173784555">En attente d'un autre téléchargement…</translation> <translation id="5869522115854928033">Mots de passe enregistrés</translation> <translation id="5878455346526065919">Bloquer les annonces des sites qui ont tendance à afficher des annonces intrusives</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Recommandations de contenus</translation> <translation id="6277522088822131679">Un problème est survenu lors de l'impression de la page. Veuillez réessayer.</translation> <translation id="6295158916970320988">Tous les sites</translation> +<translation id="629730747756840877">Compte</translation> <translation id="6320088164292336938">Vibreur</translation> <translation id="6324034347079777476">La synchronisation du système Android est désactivée.</translation> <translation id="6333140779060797560">Partager via <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Chiffrement</translation> +<translation id="6341580099087024258">Demander où enregistrer les fichiers</translation> <translation id="6343192674172527289">Aucun téléchargement trouvé</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 et <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> de plus}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 et <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> de plus}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 et <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> de plus}}</translation> <translation id="6364438453358674297">Supprimer la suggestion de l'historique ?</translation> +<translation id="6378173571450987352">Détails : tri effectué par volume de données utilisées</translation> <translation id="6383961787135158834">Suppr. données de site</translation> <translation id="6388207532828177975">Effacer et réinitialiser</translation> <translation id="6393863479814692971">Chrome a besoin de votre autorisation pour accéder à votre appareil photo et à votre micro pour ce site.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Ajoutez un compte Google depuis la page "Comptes" dans l'application "Paramètres" de votre appareil.</translation> <translation id="7274013316676448362">Site bloqué</translation> <translation id="729975465115245577">Aucune application n'est installée sur votre appareil pour stocker le fichier de mots de passe.</translation> +<translation id="7302081693174882195">Détails : tri effectué par volume de données enregistrées</translation> <translation id="7333031090786104871">L'ajout du site précédent est toujours en cours</translation> <translation id="7352939065658542140">VIDÉO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Partager 1 élément sélectionné}one{Partager # élément sélectionné}other{Partager # éléments sélectionnés}}</translation> <translation id="7359002509206457351">Accéder aux modes de paiement</translation> <translation id="7366340029385295517">Diffusion sur "<ph name="SCREEN_NAME" />" en cours…</translation> <translation id="7375125077091615385">Type :</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Expérience de première utilisation de Chrome</translation> <translation id="741204030948306876">J'accepte</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Demander d'abord</translation> <translation id="7423538860840206698">Accès en lecture au presse-papiers bloqué</translation> <translation id="7437998757836447326">Se déconnecter de Chrome</translation> +<translation id="7444811645081526538">Autres catégories</translation> <translation id="7445411102860286510">Autoriser les sites à lire automatiquement des vidéos dont le son est coupé (recommandé)</translation> <translation id="7453467225369441013">Vous déconnecte de la plupart des sites. Vous ne serez cependant pas déconnecté de votre compte Google.</translation> <translation id="7454641608352164238">Espace insuffisant</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Tout supprimer</translation> <translation id="7882131421121961860">Aucun historique trouvé</translation> <translation id="7882806643839505685">Autorise le son d'un site spécifique.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Téléchargement du fichier…}one{Téléchargement de # fichier…}other{Téléchargement de # fichiers…}}</translation> <translation id="7929962904089429003">Ouvrir le menu</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> est obsolète.</translation> <translation id="7947953824732555851">Accepter/Se connecter</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Sur certains sites Web, vous pouvez payer depuis votre appareil avec les applications de paiement compatibles indiquées ci-dessus.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> va s'ouvrir dans Chrome. En continuant, vous acceptez les <ph name="BEGIN_LINK1" />Conditions d'utilisation<ph name="END_LINK1" /> et l'<ph name="BEGIN_LINK2" />Avis de confidentialité<ph name="END_LINK2" /> de Chrome, ainsi que l'<ph name="BEGIN_LINK3" />Avis de confidentialité relatif aux comptes Google gérés dans Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Favoris</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Une erreur s'est produite lors du téléchargement du contenu.</translation> <translation id="8840953339110955557">Cette page peut différer de la version en ligne.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb b/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb index ea27d57..21e75d0 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">उपयोग और क्रैश रिपोर्ट</translation> <translation id="11221688409173367">खास तौर पर आपके लिए चुने गए लेख देखने के लिए 'होम' बटन पर टैप करें</translation> <translation id="1129510026454351943">विवरण: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 डाउनलोड बाकी है.}one{# डाउनलोड बाकी हैं.}other{# डाउनलोड बाकी हैं.}}</translation> <translation id="1145536944570833626">मौजूदा डेटा हटाएं.</translation> <translation id="1146678959555564648">VR डालें</translation> <translation id="114721135501989771">Chrome में Google स्मार्ट पाएं</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">कृपया अपने प्रवेश विवरण अपडेट करें.</translation> <translation id="1974060860693918893">उन्नत</translation> <translation id="1984937141057606926">तृतीय-पक्ष को छोड़कर अनुमति है</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> बटन</translation> <translation id="1989112275319619282">ब्राउज़ करें</translation> <translation id="1993768208584545658"><ph name="SITE" /> युग्मित करना चाहता है</translation> <translation id="1994173015038366702">साइट URL</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">महत्वहीन मेमोरी</translation> <translation id="4002066346123236978">शीर्षक</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# घंटा}one{# घंटे}other{# घंटे}}</translation> <translation id="4042870126885713738">किसी वेब पते का समाधान ना होने या कनेक्शन ना हो सकने पर सुझाव दिखाएं</translation> <translation id="4046123991198612571">अगला ट्रैक</translation> <translation id="4048707525896921369">पेज को छोड़े बिना वेबसाइटों पर मौजूद विषयों के बारे में जानें. 'खोजने के लिए टैप करें' सुविधा, 'Google सर्च' को कोई शब्द और उससे जुड़ी जानकारी भेजती है. इससे परिभाषाएं, तस्वीर, खोज नतीजे और दूसरी जानकारियां हासिल होती हैं. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">आप गुप्त मोड में चले गए हैं.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# मिनट पहले}one{# मिनट पहले}other{# मिनट पहले}}</translation> <translation id="4587589328781138893">साइटें</translation> +<translation id="4594952190837476234">यह पेज <ph name="CREATION_TIME" /> का है और यह ऑनलाइन वर्शन से अलग हो सकता है.</translation> <translation id="4605958867780575332">आइटम निकाला गया: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> को खोलें</translation> <translation id="4645575059429386691">आपके अभिभावक द्वारा प्रबंधित</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">नया टैब खोलें</translation> <translation id="4751476147751820511">गति या लाइट सेंसर</translation> <translation id="4759238208242260848">डाउनलोड</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 डाउनलोड पूरा हुआ.}one{# डाउनलोड पूरे हुए.}other{# डाउनलोड पूरे हुए.}}</translation> <translation id="4766369052440583386">डेटा बचाने का साधन चालू है</translation> <translation id="4797039098279997504"><ph name="URL_OF_THE_CURRENT_TAB" /> पर वापस लौटने के लिए स्पर्श करें</translation> <translation id="4807098396393229769">कार्ड पर नाम</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">सभी डिवाइस पर आपके पासवर्ड, इतिहास वगैरह</translation> <translation id="4961700429721424617">आप <ph name="MANAGED_DOMAIN" /> द्वारा प्रबंधित खाते से प्रस्थान कर रहे हैं. इससे आपका Chrome डेटा इस डिवाइस से हट जाएगा, लेकिन आपका डेटा आपके Google खाते में बना रहेगा.</translation> <translation id="497421865427891073">आगे जाएं</translation> +<translation id="4988210275050210843">फ़ाइल डाउनलोड हो रही है (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">पेज</translation> <translation id="4996978546172906250">इसके द्वारा शेयर करें</translation> <translation id="5004339818306944878">60% कम डेटा का उपयोग करके वेब में तेज़ी लाएं. Google सर्वर उन पेजों को ऑप्टिमाइज़ करेगा जिन पर आप विज़िट करते हैं.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">संग्रहित डेटा साफ़ करें</translation> <translation id="5152843274749979095">कोई समर्थित ऐप्लिकेशन इंस्टॉल नहीं है</translation> <translation id="5161254044473106830">शीर्षक आवश्यक</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 डाउनलोड नहीं हो सका.}one{# डाउनलोड नहीं हो सके.}other{# डाउनलोड नहीं हो सके.}}</translation> <translation id="5168917394043976756">मार्गदर्शक ड्रॉवर खोलें</translation> <translation id="5171365962177408781">नया टैब पेज लोड करने और सुझाए लेख देखने के लिए टैप करें</translation> <translation id="5184329579814168207">Chrome में खोलें</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">आपके द्वारा सबसे अधिक देखे गए पेज यहां दिखाई देंगे</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> जीबी उपलब्ध है</translation> <translation id="5433691172869980887">उपयोगकर्ता नाम कॉपी किया गया</translation> +<translation id="543509235395288790"><ph name="COUNT" /> फ़ाइलें डाउनलोड हो रही हैं (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">सीधे पता बार पर जाएं</translation> <translation id="5447201525962359567">सभी साइट मेमोरी, जिसमें कुकी और स्थानीय रूप से संग्रहित अन्य डेटा शामिल है</translation> <translation id="5447765697759493033">इस साइट का अनुवाद नहीं किया जाएगा</translation> +<translation id="545042621069398927">आपके डाउनलोड की गति बढ़ाई जा रही है.</translation> <translation id="5456381639095306749">पेज डाउनलोड करें</translation> <translation id="548278423535722844">मैप ऐप्लिकेशन में खोलें</translation> <translation id="5487521232677179737">डेटा साफ़ करें</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">30 दिनों से ज़्यादा पुराना</translation> <translation id="5858741533101922242">Chrome, ब्लूटूथ एडाप्टर को चालू नहीं कर सका</translation> <translation id="5860033963881614850">बंद</translation> +<translation id="5864174910718532887">जानकारी: साइट नाम के अनुसार क्रम से लगाया गया</translation> <translation id="5864419784173784555">दूसरे डाउनलोड का इंतज़ार किया जा रहा है…</translation> <translation id="5869522115854928033">सहेजे गए पासवर्ड</translation> <translation id="5878455346526065919">ऐसी साइटों के विज्ञापन ब्लॉक करें जो तंग करने वाले विज्ञापन दिखाने के लिए जानी जाती हैं</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">सामग्री के सुझाव</translation> <translation id="6277522088822131679">पेज को प्रिंट करने में समस्या थी. कृपया फिर से प्रयास करें.</translation> <translation id="6295158916970320988">सभी साइटें</translation> +<translation id="629730747756840877">खाता</translation> <translation id="6320088164292336938">कंपन</translation> <translation id="6324034347079777476">Android सिस्टम समन्वयन अक्षम है</translation> <translation id="6333140779060797560"><ph name="APPLICATION" /> के द्वारा शेयर करें</translation> <translation id="6337234675334993532">सुरक्षित तरीका</translation> +<translation id="6341580099087024258">फ़ाइलें सेव करने की जगह पूछें</translation> <translation id="6343192674172527289">कोई डाउनलोड नहीं मिला</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 और <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> अन्य}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 और <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> अन्य}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 और <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> अन्य}}</translation> <translation id="6364438453358674297">सुझाव को इतिहास से निकालें?</translation> +<translation id="6378173571450987352">जानकारी: इस्तेमाल किए गए डेटा की मात्रा के अनुसार क्रम से लगाया गया</translation> <translation id="6383961787135158834">साइट की जगह साफ़ करें…</translation> <translation id="6388207532828177975">साफ़ करें और रीसेट करें</translation> <translation id="6393863479814692971">Chrome को इस साइट के लिए आपका कैमरा और माइक्रोफ़ोन एक्सेस करने की अनुमति चाहिए.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">अपने डिवाइस के सेटिंग ऐप्लिकेशन में खाते पेज से कोई Google खाता जोड़ें.</translation> <translation id="7274013316676448362">अवरोधित साइट</translation> <translation id="729975465115245577">आपके डिवाइस में पासवर्ड फ़ाइल को संग्रहित करने वाला कोई ऐप्लिकेशन नहीं है.</translation> +<translation id="7302081693174882195">जानकारी: बचाए गए डेटा की मात्रा के अनुसार क्रम से लगाया गया</translation> <translation id="7333031090786104871">पिछली साइट अभी भी जोड़ी जा रही है</translation> <translation id="7352939065658542140">वीडियो</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{1 चयनित आइटम शेयर करें}one{# चयनित आइटम शेयर करें}other{# चयनित आइटम शेयर करें}}</translation> <translation id="7359002509206457351">भुगतान के तरीकों को एक्सेस करें</translation> <translation id="7366340029385295517"><ph name="SCREEN_NAME" /> पर कास्ट किया जा रहा है</translation> <translation id="7375125077091615385">प्रकार:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Chrome पहली बार चलाने का अनुभव</translation> <translation id="741204030948306876">हां मैं सहमत हूं</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">पहले पूछें</translation> <translation id="7423538860840206698">क्लिपबोर्ड पढ़ने से ब्लॉक किया गया है</translation> <translation id="7437998757836447326">Chrome से प्रस्थान करें</translation> +<translation id="7444811645081526538">ज़्यादा श्रेणियां</translation> <translation id="7445411102860286510">साइटों को म्यूट किए गए वीडियो अपने आप चलाने की अनुमति दें (अनुशंसित)</translation> <translation id="7453467225369441013">आपको ज़्यादातर साइटों से साइन आउट कर देता है. आप अपने Google खाते से साइन आउट नहीं होंगे.</translation> <translation id="7454641608352164238">जगह काफ़ी नहीं है</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">सभी को निकालें</translation> <translation id="7882131421121961860">कोई इतिहास नहीं मिला</translation> <translation id="7882806643839505685">किसी खास साइट के लिए आवाज़ की अनुमति दें.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{फ़ाइल डाउनलोड की जा रही है.}one{# फ़ाइलें डाउनलोड की जा रही हैं.}other{# फ़ाइलें डाउनलोड की जा रही हैं.}}</translation> <translation id="7929962904089429003">मेनू खोलें</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> पुराना है.</translation> <translation id="7947953824732555851">स्वीकार करें और प्रवेश करें</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">कुछ वेबसाइटों पर, आप ऊपर समर्थित भुगतान ऐप्लिकेशन के ज़रिए अपने डिवाइस पर भुगतान कर सकते हैं.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> Chrome में खुलेगा. जारी रखकर, आप Chrome की <ph name="BEGIN_LINK1" />सेवा की शर्तों<ph name="END_LINK1" /> और <ph name="BEGIN_LINK2" />निजता सूचना<ph name="END_LINK2" /> और <ph name="BEGIN_LINK3" />Family Link से प्रबंधित होने वाले Google खातों के लिए निजता सूचना<ph name="END_LINK3" /> से सहमत होते हैं.</translation> <translation id="8820817407110198400">बुकमार्क</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">सामग्री डाउनलोड करते समय कोई गड़बड़ी हुई.</translation> <translation id="8840953339110955557">यह पेज ऑनलाइन वर्शन से अलग हो सकता है.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb index 1e3ea75..fea39e2 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Prijedlozi sadržaja</translation> <translation id="6277522088822131679">Pojavio se problem prilikom ispisivanja stranice. Pokušajte ponovo.</translation> <translation id="6295158916970320988">Sve web-lokacije</translation> +<translation id="629730747756840877">Račun</translation> <translation id="6320088164292336938">Omogući vibraciju</translation> <translation id="6324034347079777476">Sinkronizacija sustava Android onemogućena</translation> <translation id="6333140779060797560">Dijeljenje putem aplikacije <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb b/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb index cd70974..b119829 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Használati és hibajelentések</translation> <translation id="11221688409173367">Koppintson a Kezdőképernyő gombra a kifejezetten Önnek kiválasztott cikkek megtekintéséhez</translation> <translation id="1129510026454351943">Részletek: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 letöltés függőben.}other{# letöltés függőben.}}</translation> <translation id="1145536944570833626">Meglévő adatok törlése.</translation> <translation id="1146678959555564648">Virtuális valóság – belépés</translation> <translation id="114721135501989771">Google-funkciók a Chrome-ban</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Kérjük, frissítse bejelentkezési adatait.</translation> <translation id="1974060860693918893">Speciális</translation> <translation id="1984937141057606926">Engedélyezve, kivéve a harmadik felektől származó cookie-kat</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> gomb</translation> <translation id="1989112275319619282">Böngészés</translation> <translation id="1993768208584545658">A(z) <ph name="SITE" /> párosítást szeretne végrehajtani</translation> <translation id="1994173015038366702">Webhely URL-je</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475">? / <ph name="BYTES_DOWNLOADED_WITH_UNITS" /></translation> <translation id="3997476611815694295">Nem fontos tárhely</translation> <translation id="4002066346123236978">Cím</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# órája}other{# órája}}</translation> <translation id="4042870126885713738">Javaslatok megjelenítése, ha egy internetcímet nem lehet feloldani, vagy nem lehet kapcsolódni</translation> <translation id="4046123991198612571">Következő szám</translation> <translation id="4048707525896921369">Megtudhatja a webhelyek témaköreit anélkül, hogy elhagyná az oldalt. A Keresés koppintással funkció elküld egy szót és annak kontextusát a Google Keresés számára, majd meghatározásokat, képeket, keresési eredményeket és egyéb részleteket ad vissza. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Ön inkognitómódra váltott.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# perce}other{# perce}}</translation> <translation id="4587589328781138893">Webhelyek</translation> +<translation id="4594952190837476234">Az offline oldal létrehozási ideje: <ph name="CREATION_TIME" />. Az oldal eltérhet az online változattól.</translation> <translation id="4605958867780575332">A következő elem eltávolítva: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> megnyitása</translation> <translation id="4645575059429386691">A szülő kezeli</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Új lap megnyitása</translation> <translation id="4751476147751820511">Mozgás- és fényérzékelők</translation> <translation id="4759238208242260848">Letöltések</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 letöltés befejeződött.}other{# letöltés befejeződött.}}</translation> <translation id="4766369052440583386">Az Adatforgalom-csökkentő aktív</translation> <translation id="4797039098279997504">Érintse meg, hogy visszatérjen ide: <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">A kártyán feltüntetett név</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Jelszavai, előzményei (és még sok más) valamennyi eszközén</translation> <translation id="4961700429721424617">Kijelentkezik egy <ph name="MANAGED_DOMAIN" /> által felügyelt fiókból. Ezzel törli az eszközön található Chrome-adatokat, amelyek azonban Google-fiókjában megmaradnak.</translation> <translation id="497421865427891073">Előrelépés</translation> +<translation id="4988210275050210843">Fájl letöltése folyamatban (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Oldal</translation> <translation id="4996978546172906250">Megosztás itt:</translation> <translation id="5004339818306944878">Akár 60%-kal kevesebb adatot használhat, és ezzel gyorsabbá válik az internet. A Google szerverei optimalizálni fogják az Ön által felkeresett oldalakat.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Tárolt adatok törlése</translation> <translation id="5152843274749979095">Nincs telepítve támogatott alkalmazás</translation> <translation id="5161254044473106830">Cím megadása kötelező</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 letöltés nem sikerült.}other{# letöltés nem sikerült.}}</translation> <translation id="5168917394043976756">Navigációs fiók megnyitása</translation> <translation id="5171365962177408781">Koppintson az új lap oldal betöltéséhez és a javasolt cikkek megtekintéséhez</translation> <translation id="5184329579814168207">Megnyitás Chrome-ban</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">A leggyakrabban látogatott oldalak fognak itt megjelenni</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB szabad</translation> <translation id="5433691172869980887">Felhasználónév vágólapra másolva</translation> +<translation id="543509235395288790"><ph name="COUNT" /> fájl letöltése folyamatban (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Ugrás a címsávba</translation> <translation id="5447201525962359567">Összes webhelytárhely, beleértve a cookie-kat és más helyben tárolt adatokat</translation> <translation id="5447765697759493033">Nem fordítjuk le ezt a webhelyet</translation> +<translation id="545042621069398927">Letöltés felgyorsítása…</translation> <translation id="5456381639095306749">Oldal letöltése</translation> <translation id="548278423535722844">Megnyitás térképalkalmazásban</translation> <translation id="5487521232677179737">Adatok törlése</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">30 napnál régebbi</translation> <translation id="5858741533101922242">A Chrome nem tudja bekapcsolni a Bluetooth-adaptert</translation> <translation id="5860033963881614850">Kikapcsolva</translation> +<translation id="5864174910718532887">Részletek: Webhelynév szerinti rendezés</translation> <translation id="5864419784173784555">Várakozás a másik letöltésre…</translation> <translation id="5869522115854928033">Mentett jelszavak</translation> <translation id="5878455346526065919">Hirdetések letiltása azokon a webhelyeken, amelyek jellemzően tolakodó hirdetéseket jelenítenek meg</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Javasolt tartalmak</translation> <translation id="6277522088822131679">Hiba történt az oldal nyomtatásakor. Próbálja újra.</translation> <translation id="6295158916970320988">Az összes webhely</translation> +<translation id="629730747756840877">Fiók</translation> <translation id="6320088164292336938">Rezgés</translation> <translation id="6324034347079777476">Az Android rendszer szinkronizálása letiltva</translation> <translation id="6333140779060797560">Megosztás a következőn keresztül: <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Titkosítás</translation> +<translation id="6341580099087024258">Rákérdezés a fájlok mentésének helyére</translation> <translation id="6343192674172527289">Nem található letöltés</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 és további <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 és további <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Eltávolítja a javaslatot az előzményekből?</translation> +<translation id="6378173571450987352">Részletek: Felhasznált adatmennyiség szerinti rendezés</translation> <translation id="6383961787135158834">Webhelytárhely törlése…</translation> <translation id="6388207532828177975">Törlés és visszaállítás</translation> <translation id="6393863479814692971">A Chrome számára engedély szükséges, hogy hozzáférjen a kamerához és a mikrofonhoz ennél a webhelynél.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Adjon hozzá Google-fiókot az eszköz Beállítások alkalmazásának Fiókok oldalán.</translation> <translation id="7274013316676448362">Letiltott oldal</translation> <translation id="729975465115245577">Az eszközön nincs olyan alkalmazás, amely tárolni tudja a jelszavakat tartalmazó fájlt.</translation> +<translation id="7302081693174882195">Részletek: Megtakarított adatmennyiség szerinti rendezés</translation> <translation id="7333031090786104871">Az előző webhely hozzáadása még folyamatban van</translation> <translation id="7352939065658542140">VIDEÓ</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{1 kijelölt elem megosztása}other{# kijelölt elem megosztása}}</translation> <translation id="7359002509206457351">Hozzáférés a fizetési módokhoz</translation> <translation id="7366340029385295517">Átküldés a következőre: <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Típus:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Chrome – Első futtatási élmény</translation> <translation id="741204030948306876">Igen, folytatom</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Kérdezzen rá</translation> <translation id="7423538860840206698">Le van tiltva a vágólap megtekintése</translation> <translation id="7437998757836447326">Kijelentkezés a Chrome-ból</translation> +<translation id="7444811645081526538">További kategóriák</translation> <translation id="7445411102860286510">Lehetővé teszi a webhelyek számára a némított videók automatikus lejátszását (ajánlott)</translation> <translation id="7453467225369441013">A rendszer a legtöbb webhelyről kijelentkezteti Önt, de Google-fiókjából nem.</translation> <translation id="7454641608352164238">Nincs elég tárhely</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Összes eltávolítása</translation> <translation id="7882131421121961860">Nincsenek előzmények</translation> <translation id="7882806643839505685">Egy adott webhely hangjának engedélyezése.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Fájl letöltése…}other{# fájl letöltése…}}</translation> <translation id="7929962904089429003">A menü megnyitása</translation> <translation id="7942131818088350342">A(z) <ph name="PRODUCT_NAME" /> elavult.</translation> <translation id="7947953824732555851">Elfogadás és bejelentkezés</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Bizonyos webhelyeken fizethet eszközén a fenti támogatott fizetési alkalmazásokkal.</translation> <translation id="8816439037877937734">A(z) <ph name="APP_NAME" /> a Chrome-ban nyílik meg. A folytatással elfogadja a Chrome <ph name="BEGIN_LINK1" />Általános Szerződési Feltételeit<ph name="END_LINK1" /> és <ph name="BEGIN_LINK2" />Adatvédelmi közleményét<ph name="END_LINK2" />, valamint <ph name="BEGIN_LINK3" />A Family Link szolgáltatással kezelt Google-fiókokra vonatkozó Adatvédelmi közleményt<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Könyvjelzők</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Hiba történt a tartalom letöltésekor.</translation> <translation id="8840953339110955557">Az oldal eltérhet az online változattól.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_id.xtb b/chrome/android/java/strings/translations/android_chrome_strings_id.xtb index 29da9f25..cd5ed1e 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_id.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_id.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Saran konten</translation> <translation id="6277522088822131679">Terjadi masalah saat mencetak halaman. Coba lagi.</translation> <translation id="6295158916970320988">Semua situs</translation> +<translation id="629730747756840877">Akun</translation> <translation id="6320088164292336938">Getar</translation> <translation id="6324034347079777476">Sinkronisasi sistem Android dinonaktifkan</translation> <translation id="6333140779060797560">Bagikan dengan <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_it.xtb b/chrome/android/java/strings/translations/android_chrome_strings_it.xtb index 4c6b015c..0747c9a 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_it.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_it.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Rapporti sull'utilizzo e sugli arresti anomali</translation> <translation id="11221688409173367">Tocca il pulsante Home per visualizzare gli articoli selezionati appositamente per te</translation> <translation id="1129510026454351943">Dettagli: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download in attesa.}other{# download in attesa.}}</translation> <translation id="1145536944570833626">Elimina dati esistenti.</translation> <translation id="1146678959555564648">Entra nella VR</translation> <translation id="114721135501989771">Tutta l'intelligenza Google in Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Aggiorna i dati di accesso.</translation> <translation id="1974060860693918893">Avanzate</translation> <translation id="1984937141057606926">Consentiti, tranne i cookie di terze parti</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> pulsante <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Esplora</translation> <translation id="1993768208584545658">Il sito <ph name="SITE" /> desidera accoppiarsi</translation> <translation id="1994173015038366702">URL sito</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> di ?</translation> <translation id="3997476611815694295">Memoria dati non importanti</translation> <translation id="4002066346123236978">Titolo</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# ora}other{# ore}}</translation> <translation id="4042870126885713738">Mostra suggerimenti quando un indirizzo web non viene risolto o non è possibile stabilire una connessione</translation> <translation id="4046123991198612571">Traccia successiva</translation> <translation id="4048707525896921369">Scopri gli argomenti dei siti web senza lasciare la pagina. La funzione Tocca per cercare consente di inviare una parola e il relativo contesto alla Ricerca Google; vengono restituiti risultati di ricerca, immagini, definizioni e altri dettagli. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Sei passato alla navigazione in incognito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# minuto fa}other{# minuti fa}}</translation> <translation id="4587589328781138893">Siti</translation> +<translation id="4594952190837476234">Questa pagina offline risale al giorno <ph name="CREATION_TIME" /> e potrebbe essere diversa dalla versione online.</translation> <translation id="4605958867780575332">Elemento rimosso: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Apri <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Gestito da un genitore</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Apri una nuova scheda</translation> <translation id="4751476147751820511">Sensori di movimento o della luce</translation> <translation id="4759238208242260848">Download</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download completato.}other{# download completati.}}</translation> <translation id="4766369052440583386">Risparmio dati attivato</translation> <translation id="4797039098279997504">Tocca per tornare a <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Nome sulla carta di credito</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Le tue password, la tua cronologia e altro su tutti i tuoi dispositivi</translation> <translation id="4961700429721424617">Stai per uscire da un account gestito da <ph name="MANAGED_DOMAIN" />. I dati di Chrome verranno eliminati da questo dispositivo, ma rimarranno memorizzati nel tuo account Google.</translation> <translation id="497421865427891073">Avanti</translation> +<translation id="4988210275050210843">Download del file (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Pagine</translation> <translation id="4996978546172906250">Condividi tramite</translation> <translation id="5004339818306944878">Utilizza fino al 60% di dati in meno e velocizza il Web. I server Google ottimizzeranno le pagine che visiti.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Cancella dati memorizzati</translation> <translation id="5152843274749979095">Nessuna app supportata installata</translation> <translation id="5161254044473106830">Titolo obbligatorio</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download non riuscito.}other{# download non riusciti.}}</translation> <translation id="5168917394043976756">Apri riquadro di navigazione a scomparsa</translation> <translation id="5171365962177408781">Tocca per caricare la pagina Nuova scheda e visualizzare gli articoli suggeriti</translation> <translation id="5184329579814168207">Apri in Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Le pagine che visiti più spesso verranno visualizzate qui</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB disponibili</translation> <translation id="5433691172869980887">Nome utente copiato</translation> +<translation id="543509235395288790">Download di <ph name="COUNT" /> file (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Vai alla barra degli indirizzi</translation> <translation id="5447201525962359567">Tutta la memoria utilizzata da siti, tra cui cookie e altri dati memorizzati in locale</translation> <translation id="5447765697759493033">Questo sito non verrà tradotto</translation> +<translation id="545042621069398927">Accelerazione del download.</translation> <translation id="5456381639095306749">Scarica la pagina</translation> <translation id="548278423535722844">Apri nell'app di mappe</translation> <translation id="5487521232677179737">Cancella dati</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Oltre 30 giorni fa</translation> <translation id="5858741533101922242">Chrome non riesce ad attivare l'adattatore Bluetooth</translation> <translation id="5860033963881614850">Off</translation> +<translation id="5864174910718532887">Dettagli: ordinati per nome del sito</translation> <translation id="5864419784173784555">In attesa di un altro download…</translation> <translation id="5869522115854928033">Password salvate</translation> <translation id="5878455346526065919">Blocca gli annunci dei siti che tendono a mostrare annunci invasivi</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Contenuti suggeriti</translation> <translation id="6277522088822131679">Si è verificato un problema durante la stampa della pagina. Riprova.</translation> <translation id="6295158916970320988">Tutti i siti</translation> +<translation id="629730747756840877">Account</translation> <translation id="6320088164292336938">Vibrazione</translation> <translation id="6324034347079777476">Sincronizzazione del sistema Android non attiva</translation> <translation id="6333140779060797560">Condividi tramite <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Crittografia</translation> +<translation id="6341580099087024258">Chiedi dove salvare i file</translation> <translation id="6343192674172527289">Nessun download trovato</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 e altri <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 e altri <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Rimuovere il suggerimento dalla cronologia?</translation> +<translation id="6378173571450987352">Dettagli: ordinati per quantità di dati utilizzati</translation> <translation id="6383961787135158834">Elimina memoria siti…</translation> <translation id="6388207532828177975">Cancella e reimposta</translation> <translation id="6393863479814692971">Per questo sito Chrome ha bisogno dell'autorizzazione ad accedere alla fotocamera e al microfono.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Aggiungi un account Google dalla pagina Account nell'app Impostazioni del dispositivo.</translation> <translation id="7274013316676448362">Sito bloccato</translation> <translation id="729975465115245577">Il tuo dispositivo non ha un'app per archiviare il file di password.</translation> +<translation id="7302081693174882195">Dettagli: ordinati per quantità di dati salvati</translation> <translation id="7333031090786104871">Aggiunta del sito precedente ancora in corso</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Condividi 1 elemento selezionato}other{Condividi # elementi selezionati}}</translation> <translation id="7359002509206457351">Accedi ai metodi di pagamento</translation> <translation id="7366340029385295517">Trasmissione su <ph name="SCREEN_NAME" /> in corso</translation> <translation id="7375125077091615385">Tipo:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Esperienza prima esecuzione di Chrome</translation> <translation id="741204030948306876">Sì, accetto</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Chiedi prima</translation> <translation id="7423538860840206698">Lettura degli appunti non consentita</translation> <translation id="7437998757836447326">Esci da Chrome</translation> +<translation id="7444811645081526538">Altre categorie</translation> <translation id="7445411102860286510">Consenti ai siti di riprodurre automaticamente i video con audio disattivato (opzione consigliata)</translation> <translation id="7453467225369441013">Verrai scollegato dalla maggior parte dei siti, ma non dal tuo account Google.</translation> <translation id="7454641608352164238">Spazio insufficiente</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Rimuovi tutto</translation> <translation id="7882131421121961860">Nessuna cronologia trovata</translation> <translation id="7882806643839505685">Consenti l'audio per un sito specifico.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Download del file.}other{Download di # file.}}</translation> <translation id="7929962904089429003">Apri il menu</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> è obsoleto.</translation> <translation id="7947953824732555851">Accetta e accedi</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">In alcuni siti web puoi pagare con le suddette app di pagamento supportate sul tuo dispositivo.</translation> <translation id="8816439037877937734">L'app <ph name="APP_NAME" /> verrà aperta in Chrome. Se continui, accetti i <ph name="BEGIN_LINK1" />Termini di servizio<ph name="END_LINK1" /> e l'<ph name="BEGIN_LINK2" />Informativa sulla privacy<ph name="END_LINK2" /> di Chrome, nonché l'<ph name="BEGIN_LINK3" />Informatica sulla privacy per gli account Google gestiti tramite Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Preferiti</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Si è verificato un errore durante il download dei contenuti.</translation> <translation id="8840953339110955557">Questa pagina potrebbe essere diversa dalla versione online.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb b/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb index 6e74ee6..7a49e49 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">דוחות קריסה ושימוש</translation> <translation id="11221688409173367">הקשה על לחצן הבית תציג מאמרים שנבחרו במיוחד בשבילך</translation> <translation id="1129510026454351943">פרטים: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{הורדה אחת בהמתנה.}two{# הורדות בהמתנה.}many{# הורדות בהמתנה.}other{# הורדות בהמתנה.}}</translation> <translation id="1145536944570833626">מחק נתונים קיימים.</translation> <translation id="1146678959555564648">כניסה למצב VR</translation> <translation id="114721135501989771">תכונות חכמות של Google</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">עדכן את פרטי הכניסה שלך.</translation> <translation id="1974060860693918893">מתקדם</translation> <translation id="1984937141057606926">מותר, מלבד צד שלישי</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> לחצן <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">דפדף</translation> <translation id="1993768208584545658"><ph name="SITE" /> רוצה לבצע התאמה עם</translation> <translation id="1994173015038366702">כתובת אתר</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">נתונים מאוחסנים לא חשובים</translation> <translation id="4002066346123236978">כותרת</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{שעה אחת}two{שעתיים}many{# שעות}other{# שעות}}</translation> <translation id="4042870126885713738">הצג הצעות כאשר כתובת אינטרנט אינה מזוהה או כשלא ניתן ליצור חיבור</translation> <translation id="4046123991198612571">הרצועה הבאה</translation> <translation id="4048707525896921369">ניתן לקבל מידע על נושאים באתרים מבלי לצאת מהדף. התכונה 'הקשה כדי לחפש' שולחת מילה ואת ההקשר שלה אל חיפוש Google, המחזיר הגדרות, תמונות, תוצאות חיפוש ופרטים אחרים. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">עברת למצב גלישה בסתר</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{לפני דקה}two{לפני # דקות}many{לפני # דקות}other{לפני # דקות}}</translation> <translation id="4587589328781138893">אתרים</translation> +<translation id="4594952190837476234">הדף הלא מקוון הזה נוצר ב-<ph name="CREATION_TIME" /> ויכול להיות שהגירסה המקוונת שלו שונה.</translation> <translation id="4605958867780575332">פריטים שהוסרו: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">פתיחה של <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">מנוהל על-ידי ההורה שלך</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">פתח כרטיסייה חדשה</translation> <translation id="4751476147751820511">חיישני תנועה או אור</translation> <translation id="4759238208242260848">הורדות</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{הורדה אחת הושלמה.}two{# הורדות הושלמו.}many{# הורדות הושלמו.}other{# הורדות הושלמו.}}</translation> <translation id="4766369052440583386">חוסך הנתונים (Data Saver) פועל</translation> <translation id="4797039098279997504">גע כדי לחזור אל <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">שם על הכרטיס</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">גישה אל הסיסמאות, ההיסטוריה ונתונים נוספים בכל המכשירים</translation> <translation id="4961700429721424617">אתה יוצא מחשבון המנוהל על-ידי <ph name="MANAGED_DOMAIN" />. פעולה זו תמחק את הנתונים שלך ב-Chrome מהמכשיר הזה, אבל הם יישארו בחשבון Google שלך.</translation> <translation id="497421865427891073">המשך קדימה</translation> +<translation id="4988210275050210843">מתבצעת הורדה של קובץ (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">דפים</translation> <translation id="4996978546172906250">שתף באמצעות</translation> <translation id="5004339818306944878">צמצום של צריכת הנתונים בשיעור של עד 60% והאצת הגלישה. השרתים של Google ימטבו את הדפים שאליהם אתה נכנס.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">נקה נתונים מאוחסנים</translation> <translation id="5152843274749979095">לא מותקנות אפליקציות נתמכות</translation> <translation id="5161254044473106830">יש להזין כותרת</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{הורדה אחת נכשלה.}two{# הורדות נכשלו.}many{# הורדות נכשלו.}other{# הורדות נכשלו.}}</translation> <translation id="5168917394043976756">פתח את חלונית ההזזה לניווט</translation> <translation id="5171365962177408781">הקשה תטען את דף הכרטיסייה החדשה ותציג הצעות למאמרים</translation> <translation id="5184329579814168207">פתח ב-Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">הדפים שבהם אתה מבקר בתדירות הגבוהה ביותר יופיעו כאן</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB זמינים</translation> <translation id="5433691172869980887">שם המשתמש הועתק</translation> +<translation id="543509235395288790">מתבצעת הורדה של <ph name="COUNT" /> קבצים (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">עבור לסרגל הכתובות</translation> <translation id="5447201525962359567">כל נתוני האתר המאוחסנים, כולל קובצי Cookie ונתונים אחרים המאוחסנים באופן מקומי</translation> <translation id="5447765697759493033">האתר הזה לא יתורגם</translation> +<translation id="545042621069398927">הדפדפן מאיץ את ההורדה.</translation> <translation id="5456381639095306749">הורד דף זה</translation> <translation id="548278423535722844">פתח יישום מפות</translation> <translation id="5487521232677179737">נקה נתונים</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">לפני יותר מ-30 ימים</translation> <translation id="5858741533101922242">לא ניתן להפעיל ב-Chrome את מתאם Bluetooth</translation> <translation id="5860033963881614850">כבוי</translation> +<translation id="5864174910718532887">פרטים: ממוינות לפי שם האתר</translation> <translation id="5864419784173784555">ממתין להורדה נוספת…</translation> <translation id="5869522115854928033">סיסמאות שמורות</translation> <translation id="5878455346526065919">חסום מודעות מאתרים שנוטים להציג מודעות שמפריעות</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">הצעות לתוכן</translation> <translation id="6277522088822131679">אירעה בעיה בעת הדפסת הדף. נסה שוב.</translation> <translation id="6295158916970320988">כל האתרים</translation> +<translation id="629730747756840877">חשבון</translation> <translation id="6320088164292336938">רטט</translation> <translation id="6324034347079777476">סנכרון מערכת Android מושבת</translation> <translation id="6333140779060797560">שתף באמצעות <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">הצפנה</translation> +<translation id="6341580099087024258">הצגת אפשרות לבחור את מיקום שמירת הקבצים</translation> <translation id="6343192674172527289">לא נמצאו הורדות</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספת}two{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספות}many{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספות}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספות}}</translation> <translation id="6364438453358674297">האם להסיר את ההצעה מההיסטוריה?</translation> +<translation id="6378173571450987352">פרטים: ממוינות לפי נפח הנתונים שבהם נעשה שימוש</translation> <translation id="6383961787135158834">מחיקת נתוני אתר מהאחסון...</translation> <translation id="6388207532828177975">נקה ואפס</translation> <translation id="6393863479814692971">Chrome זקוק להרשאת גישה אל המצלמה והמיקרופון בשביל האתר הזה.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">הוסף חשבון Google מהדף 'חשבונות' שבאפליקציית ההגדרות של המכשיר.</translation> <translation id="7274013316676448362">אתר חסום</translation> <translation id="729975465115245577">אין במכשיר אפליקציה לאחסון קובץ הסיסמאות.</translation> +<translation id="7302081693174882195">פרטים: ממוינות לפי נפח הנתונים שנחסכו</translation> <translation id="7333031090786104871">עדיין מוסיף את האתר הקודם</translation> <translation id="7352939065658542140">סרטון</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{שתף פריט אחד שנבחר}two{שתף # פריטים שנבחרו}many{שתף # פריטים שנבחרו}other{שתף # פריטים שנבחרו}}</translation> <translation id="7359002509206457351">גישה לאמצעי תשלום</translation> <translation id="7366340029385295517">מעביר אל <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">סוג:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">כתובת אתר</translation> <translation id="7403691278183511381">חוויית ההפעלה הראשונה של Chrome</translation> <translation id="741204030948306876">כן, אני רוצה</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">בקש אישור</translation> <translation id="7423538860840206698">הגישה לקריאה מלוח העריכה נחסמה</translation> <translation id="7437998757836447326">יציאה מ-Chrome</translation> +<translation id="7444811645081526538">קטגוריות נוספות</translation> <translation id="7445411102860286510">התר לאתרים להפעיל באופן אוטומטי סרטונים מושתקים (מומלץ)</translation> <translation id="7453467225369441013">תבוצע יציאה שלך מרוב האתרים. לא תבוצע יציאה מחשבון Google שלך.</translation> <translation id="7454641608352164238">אין מספיק מקום</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">הסר הכל</translation> <translation id="7882131421121961860">לא נמצאה היסטוריה</translation> <translation id="7882806643839505685">מתן הרשאה להשמעת צלילים באתר ספציפי.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{מתבצעת הורדה של הקובץ.}two{מתבצעת הורדה של # קבצים.}many{מתבצעת הורדה של # קבצים.}other{מתבצעת הורדה של # קבצים.}}</translation> <translation id="7929962904089429003">פתח את התפריט</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> אינו מעודכן.</translation> <translation id="7947953824732555851">קבל והיכנס</translation> @@ -883,6 +900,7 @@ <translation id="8812260976093120287">באתרים מסוימים ניתן לשלם דרך המכשיר באמצעות אפליקציות התשלום הנתמכות שמופיעות למעלה.</translation> <translation id="8816439037877937734">האפליקציה <ph name="APP_NAME" /> תיפתח ב-Chrome. המשך השימוש מבטא את הסכמתך ל<ph name="BEGIN_LINK1" />תנאים ולהגבלות<ph name="END_LINK1" /> ול<ph name="BEGIN_LINK2" />הודעת הפרטיות<ph name="END_LINK2" /> של Chrome, וכן ל<ph name="BEGIN_LINK3" />הודעת הפרטיות לחשבונות Google שמנוהלים ב-Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">סימניות</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">אירעה שגיאה בזמן הורדת התוכן.</translation> <translation id="8840953339110955557">ייתכן שהדף הזה שונה מהגירסה המקוונת.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb index 5da0bb70..c59e97c 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">利用状況と障害レポート</translation> <translation id="11221688409173367">おすすめの記事を表示するにはホームボタンをタップします</translation> <translation id="1129510026454351943">詳細: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 件のダウンロードが保留中です。}other{# 件のダウンロードが保留中です。}}</translation> <translation id="1145536944570833626">既存のデータを削除します。</translation> <translation id="1146678959555564648">VR を入力</translation> <translation id="114721135501989771">Chrome で Google の最先端技術を活用</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">ログイン情報を更新してください。</translation> <translation id="1974060860693918893">詳細設定</translation> <translation id="1984937141057606926">サードパーティを除いて許可する</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> ボタン</translation> <translation id="1989112275319619282">閲覧</translation> <translation id="1993768208584545658"><ph name="SITE" /> がペア設定を要求しています</translation> <translation id="1994173015038366702">サイトの URL</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">重要度の低いストレージ</translation> <translation id="4002066346123236978">タイトル</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# 時間}other{# 時間}}</translation> <translation id="4042870126885713738">ウェブアドレスが解決されない場合や接続を確立できない場合にアドバイスを表示します</translation> <translation id="4046123991198612571">次のトラック</translation> <translation id="4048707525896921369">ウェブサイト上のトピックについてページを移動せずに調べられます。「タップして検索」では、単語とその周囲のコンテキストが Google 検索に送信され、定義、画像、検索結果などの情報が返されます。 @@ -402,6 +405,7 @@ <translation id="4581964774250883625">シークレット モードです。</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# 分前}other{# 分前}}</translation> <translation id="4587589328781138893">サイト</translation> +<translation id="4594952190837476234">このオフライン ページは <ph name="CREATION_TIME" /> 時点のものであり、オンライン版とは異なる可能性があります。</translation> <translation id="4605958867780575332">削除したアイテム: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> を起動</translation> <translation id="4645575059429386691">保護者により管理されています</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">新しいタブを開く</translation> <translation id="4751476147751820511">モーション センサーまたは光センサー</translation> <translation id="4759238208242260848">ダウンロード</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 件のダウンロードが完了しました。}other{# 件のダウンロードが完了しました。}}</translation> <translation id="4766369052440583386">データセーバー ON</translation> <translation id="4797039098279997504">タップすると <ph name="URL_OF_THE_CURRENT_TAB" /> に戻ります</translation> <translation id="4807098396393229769">名義人名</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">すべての端末で同じパスワード、履歴、その他の設定を使用できます</translation> <translation id="4961700429721424617"><ph name="MANAGED_DOMAIN" /> で管理されているアカウントからログアウトしようとしています。この操作を行うと、Chrome データはこの端末から削除されますが、Google アカウントには残ります。</translation> <translation id="497421865427891073">次に進む</translation> +<translation id="4988210275050210843">ファイルをダウンロードしています(<ph name="MEGABYTES" />)。</translation> <translation id="4988526792673242964">ページ</translation> <translation id="4996978546172906250">共有方法</translation> <translation id="5004339818306944878">データセーバーを使用すると、データ使用量を最大 60% 節約でき、ウェブを高速にブラウジングできます。Google のサーバーにより、アクセスするページが最適化されます。</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">保存したデータの消去</translation> <translation id="5152843274749979095">サポートされているアプリがインストールされていません</translation> <translation id="5161254044473106830">タイトルが必要です</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 件のダウンロードが失敗しました。}other{# 件のダウンロードが失敗しました。}}</translation> <translation id="5168917394043976756">操作パネルを開く</translation> <translation id="5171365962177408781">タップすると新しいタブの画面が読み込まれ、おすすめの記事が表示されます</translation> <translation id="5184329579814168207">Chromeで開く</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">最もアクセスの多かったページがここに表示されます</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB 使用可能</translation> <translation id="5433691172869980887">ユーザー名がコピーされました</translation> +<translation id="543509235395288790"><ph name="COUNT" /> 件のファイルをダウンロードしています(<ph name="MEGABYTES" />)。</translation> <translation id="5441522332038954058">アドレスバーに移動する</translation> <translation id="5447201525962359567">すべてのサイトのストレージ(Cookie やローカルに保存した他のデータを含む)</translation> <translation id="5447765697759493033">このサイトは翻訳されません</translation> +<translation id="545042621069398927">ダウンロード速度が向上しました。</translation> <translation id="5456381639095306749">ページをダウンロード</translation> <translation id="548278423535722844">マップアプリで開く</translation> <translation id="5487521232677179737">データを消去</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">30 日以上経過</translation> <translation id="5858741533101922242">Chrome から Bluetooth アダプタをオンにできません</translation> <translation id="5860033963881614850">オフ</translation> +<translation id="5864174910718532887">詳細: サイト名の順</translation> <translation id="5864419784173784555">別のダウンロードの完了待ちです…</translation> <translation id="5869522115854928033">保存したパスワード</translation> <translation id="5878455346526065919">煩わしい広告がよく表示されるサイトで広告をブロックします</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">おすすめのコンテンツ</translation> <translation id="6277522088822131679">ページの印刷中に問題が発生しました。もう一度お試しください。</translation> <translation id="6295158916970320988">すべてのサイト</translation> +<translation id="629730747756840877">アカウント</translation> <translation id="6320088164292336938">バイブレーション</translation> <translation id="6324034347079777476">Android システムの同期が無効です</translation> <translation id="6333140779060797560"><ph name="APPLICATION" /> で共有します</translation> <translation id="6337234675334993532">暗号化</translation> +<translation id="6341580099087024258">ファイルの保存場所を確認する</translation> <translation id="6343192674172527289">ダウンロードしたアイテムは見つかりませんでした</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 他 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 件}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 他 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 件}}</translation> <translation id="6364438453358674297">履歴から候補を削除しますか?</translation> +<translation id="6378173571450987352">詳細: データ使用量の順</translation> <translation id="6383961787135158834">サイトのストレージ消去...</translation> <translation id="6388207532828177975">消去してリセット</translation> <translation id="6393863479814692971">このサイトを利用するには、Chrome でカメラとマイクの使用を許可する必要があります。</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">端末の設定アプリのアカウント ページで Google アカウントを追加してください。</translation> <translation id="7274013316676448362">ブロック中のサイト</translation> <translation id="729975465115245577">お使いの端末にはパスワード ファイルを保存するためのアプリがインストールされていません。</translation> +<translation id="7302081693174882195">詳細: データ節約量の順</translation> <translation id="7333031090786104871">前のサイトを追加中です</translation> <translation id="7352939065658542140">動画</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{1 件の選択されたアイテムを共有します}other{# 件の選択されたアイテムを共有します}}</translation> <translation id="7359002509206457351">お支払い方法へのアクセス</translation> <translation id="7366340029385295517"><ph name="SCREEN_NAME" />にキャストしています</translation> <translation id="7375125077091615385">タイプ:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />。</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Chrome 初回起動時の操作</translation> <translation id="741204030948306876">有効にする</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">最初に確認する</translation> <translation id="7423538860840206698">クリップボードの読み取りがブロックされています</translation> <translation id="7437998757836447326">Chromeからログアウト</translation> +<translation id="7444811645081526538">その他のカテゴリ</translation> <translation id="7445411102860286510">ミュートされた動画の自動再生をサイトに許可する(推奨)</translation> <translation id="7453467225369441013">ほとんどのサイトからログアウトします。Google アカウントへのログイン状態は維持されます。</translation> <translation id="7454641608352164238">空き容量が不足しています</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">すべて削除</translation> <translation id="7882131421121961860">履歴が見つかりません</translation> <translation id="7882806643839505685">特定のサイトに対して音声の再生を許可します。</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{ファイルをダウンロードしています。}other{# 件のファイルをダウンロードしています。}}</translation> <translation id="7929962904089429003">メニューを開く</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> は最新ではありません。</translation> <translation id="7947953824732555851">同意してログイン</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">一部のウェブサイトでは、端末でサポートされている上記のお支払いアプリを使って支払いができます。</translation> <translation id="8816439037877937734">Chrome で <ph name="APP_NAME" /> を開きます。続行すると、Chrome の<ph name="BEGIN_LINK1" />利用規約<ph name="END_LINK1" />と<ph name="BEGIN_LINK2" />プライバシーに関するお知らせ<ph name="END_LINK2" />、および <ph name="BEGIN_LINK3" />ファミリー リンクで作成された Google アカウントのプライバシーに関するお知らせ<ph name="END_LINK3" />に同意したことになります。</translation> <translation id="8820817407110198400">ブックマーク</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">コンテンツのダウンロード中にエラーが発生しました。</translation> <translation id="8840953339110955557">このページはオンライン版とは異なる可能性があります。</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb index 816c9dc..39150225 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">사용 및 비정상 종료 보고서</translation> <translation id="11221688409173367">홈 버튼을 탭하여 나를 위해 맞춤 선정된 기사를 확인하세요.</translation> <translation id="1129510026454351943">세부정보: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{다운로드 1개 대기 중}other{다운로드 #개 대기 중}}</translation> <translation id="1145536944570833626">기존 데이터 삭제</translation> <translation id="1146678959555564648">VR 시작</translation> <translation id="114721135501989771">Chrome에서 스마트한 Google 사용</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">로그인 세부정보를 업데이트하세요.</translation> <translation id="1974060860693918893">고급</translation> <translation id="1984937141057606926">타사 쿠키만 제외하고 허용</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> 버튼</translation> <translation id="1989112275319619282">찾아보기</translation> <translation id="1993768208584545658"><ph name="SITE" />에서 페어링하려고 함</translation> <translation id="1994173015038366702">사이트 URL</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">중요하지 않은 저장공간</translation> <translation id="4002066346123236978">제목</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{#시간}other{#시간}}</translation> <translation id="4042870126885713738">웹 주소가 확인되지 않거나 연결되지 않는 경우 추천 주소 표시</translation> <translation id="4046123991198612571">다음 트랙</translation> <translation id="4048707525896921369">페이지에서 나가지 않고도 웹사이트에 언급된 주제에 관해 자세히 알아보세요. 탭하여 검색 기능은 단어와 관련 맥락을 Google 검색으로 전송하여 정의, 사진, 검색결과 및 기타 세부정보를 제공합니다. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">시크릿 모드로 전환됨</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{#분 전}other{#분 전}}</translation> <translation id="4587589328781138893">사이트</translation> +<translation id="4594952190837476234">이 페이지는 <ph name="CREATION_TIME" />에 생성되었으며 온라인 버전과 다를 수 있습니다.</translation> <translation id="4605958867780575332"><ph name="ITEM_TITLE" /> 삭제됨</translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> 열기</translation> <translation id="4645575059429386691">부모님이 관리합니다.</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">새 탭 열기</translation> <translation id="4751476147751820511">모션 또는 조도 센서</translation> <translation id="4759238208242260848">다운로드</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{다운로드 1개 완료}other{다운로드 #개 완료}}</translation> <translation id="4766369052440583386">데이터 절약 모드 사용</translation> <translation id="4797039098279997504">터치하여 <ph name="URL_OF_THE_CURRENT_TAB" />(으)로 돌아가기</translation> <translation id="4807098396393229769">카드 명의</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">모든 기기의 비밀번호, 방문 기록 등</translation> <translation id="4961700429721424617"><ph name="MANAGED_DOMAIN" />에서 관리하는 계정에서 로그아웃합니다. 이렇게 하면 내 Chrome 데이터가 이 기기에서 삭제되지만 Google 계정에는 그대로 유지됩니다.</translation> <translation id="497421865427891073">앞으로 이동</translation> +<translation id="4988210275050210843">파일 다운로드 중(<ph name="MEGABYTES" />MB)</translation> <translation id="4988526792673242964">페이지</translation> <translation id="4996978546172906250">공유 방법</translation> <translation id="5004339818306944878">데이터 사용량을 최대 60%까지 절약하고 웹 속도를 높이세요. Google 서버에서 내가 방문하는 페이지를 최적화합니다.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">저장된 데이터 삭제</translation> <translation id="5152843274749979095">지원되는 앱이 설치되어 있지 않음</translation> <translation id="5161254044473106830">제목이 필요합니다.</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{다운로드 1개 실패}other{다운로드 #개 실패}}</translation> <translation id="5168917394043976756">탐색 창 열기</translation> <translation id="5171365962177408781">탭하여 새 탭 페이지를 로드하고 추천 기사를 확인하세요.</translation> <translation id="5184329579814168207">Chrome에서 열기</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">자주 방문한 페이지가 여기에 표시됩니다.</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB 사용 가능</translation> <translation id="5433691172869980887">사용자 이름 복사됨</translation> +<translation id="543509235395288790">파일 <ph name="COUNT" />개(<ph name="MEGABYTES" />MB) 다운로드 중</translation> <translation id="5441522332038954058">검색주소창으로 이동</translation> <translation id="5447201525962359567">쿠키 및 기타 로컬에 저장된 데이터 등 모든 사이트 저장공간</translation> <translation id="5447765697759493033">이 사이트는 번역되지 않습니다.</translation> +<translation id="545042621069398927">다운로드 속도 향상</translation> <translation id="5456381639095306749">다운로드 페이지</translation> <translation id="548278423535722844">지도 앱에서 열기</translation> <translation id="5487521232677179737">인터넷 사용 기록 삭제</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">30일 이상 전</translation> <translation id="5858741533101922242">Chrome에서 블루투스 어댑터를 사용 설정할 수 없습니다.</translation> <translation id="5860033963881614850">사용 안함</translation> +<translation id="5864174910718532887">세부정보: 사이트 이름별로 정렬</translation> <translation id="5864419784173784555">다른 다운로드 대기 중…</translation> <translation id="5869522115854928033">저장된 비밀번호</translation> <translation id="5878455346526065919">방해가 되는 광고를 표시하는 경향이 있는 사이트의 광고 차단</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">콘텐츠 추천</translation> <translation id="6277522088822131679">페이지를 인쇄하는 중에 문제가 발생했습니다. 다시 시도해 주세요.</translation> <translation id="6295158916970320988">모든 사이트</translation> +<translation id="629730747756840877">계정</translation> <translation id="6320088164292336938">진동</translation> <translation id="6324034347079777476">Android 시스템 동기화 사용 안함</translation> <translation id="6333140779060797560">공유 방법: <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">암호화</translation> +<translation id="6341580099087024258">파일 저장 위치 묻기</translation> <translation id="6343192674172527289">다운로드 항목을 찾을 수 없음</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />개}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />개}}</translation> <translation id="6364438453358674297">기록에서 제안을 삭제하시겠습니까?</translation> +<translation id="6378173571450987352">세부정보: 사용된 데이터 양에 따라 정렬</translation> <translation id="6383961787135158834">사이트 저장공간 삭제...</translation> <translation id="6388207532828177975">삭제 및 재설정</translation> <translation id="6393863479814692971">Chrome이 이 사이트에서 카메라와 마이크에 액세스하려면 권한이 필요합니다.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">기기 설정 앱의 계정 페이지에서 Google 계정을 추가하세요.</translation> <translation id="7274013316676448362">차단된 사이트</translation> <translation id="729975465115245577">기기에 비밀번호 파일을 저장할 수 있는 앱이 없습니다.</translation> +<translation id="7302081693174882195">세부정보: 저장된 데이터 양에 따라 정렬</translation> <translation id="7333031090786104871">아직 이전 사이트 추가 중</translation> <translation id="7352939065658542140">동영상</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{선택한 1개 항목 공유}other{선택한 #개 항목 공유}}</translation> <translation id="7359002509206457351">결제 수단 액세스</translation> <translation id="7366340029385295517"><ph name="SCREEN_NAME" />(으)로 전송 중</translation> <translation id="7375125077091615385">유형:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />(이)가 다운로드되었습니다.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Chrome 첫 실행</translation> <translation id="741204030948306876">사용</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">우선 확인</translation> <translation id="7423538860840206698">클립보드 액세스가 차단됨</translation> <translation id="7437998757836447326">Chrome에서 로그아웃</translation> +<translation id="7444811645081526538">카테고리 더보기</translation> <translation id="7445411102860286510">사이트에서 음소거된 동영상을 자동재생하도록 허용(권장)</translation> <translation id="7453467225369441013">대부분의 사이트에서 로그아웃됩니다. Google 계정에서는 로그아웃되지 않습니다.</translation> <translation id="7454641608352164238">저장공간 부족</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">모두 삭제</translation> <translation id="7882131421121961860">방문 기록이 없습니다.</translation> <translation id="7882806643839505685">특정 사이트가 소리를 재생하도록 허용합니다.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{파일 다운로드 중}other{파일 #개 다운로드 중}}</translation> <translation id="7929962904089429003">메뉴 열기</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" />이(가) 이전 버전입니다.</translation> <translation id="7947953824732555851">수락 및 로그인</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">일부 웹사이트에서는 위의 결제 앱을 사용하여 내 기기에서 결제할 수 있습니다.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" />이(가) Chrome에서 열립니다. 계속하면 Chrome의 <ph name="BEGIN_LINK1" />서비스 약관<ph name="END_LINK1" />, <ph name="BEGIN_LINK2" />개인정보처리방침<ph name="END_LINK2" /> 및 <ph name="BEGIN_LINK3" />Family Link로 관리되는 Google 계정용 개인정보처리방침<ph name="END_LINK3" />에 동의하는 것으로 간주됩니다.</translation> <translation id="8820817407110198400">북마크</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">콘텐츠를 다운로드하는 중에 오류가 발생했습니다.</translation> <translation id="8840953339110955557">이 페이지는 온라인 버전과 다를 수 있습니다.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb b/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb index fad22e85..c40b6cf1 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Turinio pasiūlymai</translation> <translation id="6277522088822131679">Spausdinant puslapį kilo problema. Bandykite dar kartą.</translation> <translation id="6295158916970320988">Visos svetainės</translation> +<translation id="629730747756840877">Paskyra</translation> <translation id="6320088164292336938">Vibruoti</translation> <translation id="6324034347079777476">„Android“ sistemos sinchronizavimas išjungtas</translation> <translation id="6333140779060797560">Bendrinti per „<ph name="APPLICATION" />“</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb b/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb index 6db2a7f..b0a3c94f 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Lietojuma un avāriju pārskati</translation> <translation id="11221688409173367">Lai skatītu tieši jums atlasītos rakstus, pieskarieties pogai Sākums.</translation> <translation id="1129510026454351943">Informācija: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 neapstiprināta lejupielāde.}zero{# neapstiprinātu lejupielāžu.}one{# neapstiprināta lejupielāde.}other{# neapstiprinātas lejupielādes.}}</translation> <translation id="1145536944570833626">Dzēst esošos datus.</translation> <translation id="1146678959555564648">Ieiet virtuālajā realitātē</translation> <translation id="114721135501989771">Google viedās tehnoloģijas pārlūkā Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Lūdzu, atjauniniet pierakstīšanās informāciju.</translation> <translation id="1974060860693918893">Papildu</translation> <translation id="1984937141057606926">Atļauti, izņemot trešo pušu sīkfailus</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> poga</translation> <translation id="1989112275319619282">Pārlūkot</translation> <translation id="1993768208584545658"><ph name="SITE" /> vēlas savienot pārī</translation> <translation id="1994173015038366702">Vietnes URL</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> no ?</translation> <translation id="3997476611815694295">Nesvarīga krātuve</translation> <translation id="4002066346123236978">Nosaukums</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# h}zero{# h}one{# h}other{# h}}</translation> <translation id="4042870126885713738">Rādīt ieteikumus, ja nedarbojas tīmekļa adrese vai nevar izveidot savienojumu.</translation> <translation id="4046123991198612571">Nākamais ieraksts</translation> <translation id="4048707525896921369">Uzziniet par vietņu tēmām, neizejot no lapas. Izmantojot funkciju “Pieskarties, lai meklētu”, vārds un tā konteksts tiek nosūtīts pakalpojumam Google meklēšana, un tiek parādītas definīcijas, attēli, meklēšanas rezultāti un cita informācija. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Jūs esat atvēris inkognito režīmu.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{pirms # minūtes}zero{pirms # minūtēm}one{pirms # minūtes}other{pirms # minūtēm}}</translation> <translation id="4587589328781138893">Vietnes</translation> +<translation id="4594952190837476234">Šī lapas bezsaistes versija (izveidota: <ph name="CREATION_TIME" />) var atšķirties no tiešsaistes versijas.</translation> <translation id="4605958867780575332">Vienums noņemts: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Atvērt <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Pārvalda viens no jūsu vecākiem</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Atvērt jaunu cilni</translation> <translation id="4751476147751820511">Kustību vai gaismas sensori</translation> <translation id="4759238208242260848">Lejupielādes</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 lejupielāde ir pabeigta.}zero{# lejupielādes ir pabeigtas.}one{# lejupielāde ir pabeigta.}other{# lejupielādes ir pabeigtas.}}</translation> <translation id="4766369052440583386">Datu lietojuma samazinātājs ir ieslēgts.</translation> <translation id="4797039098279997504">Pieskarieties, lai atgrieztos cilnē <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Vārds uz kartes</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Jūsu paroles, vēstures un cita informācijas sinhronizēšana visās jūsu ierīcēs</translation> <translation id="4961700429721424617">Jūs izrakstāties no konta, kas tiek pārvaldīts domēnā <ph name="MANAGED_DOMAIN" />. Izrakstoties jūsu Chrome dati tiks dzēsti no šīs ierīces, taču tie paliks jūsu Google kontā.</translation> <translation id="497421865427891073">Doties uz priekšu</translation> +<translation id="4988210275050210843">Notiek faila lejupielāde (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Lapas</translation> <translation id="4996978546172906250">Kopīgošanas veids:</translation> <translation id="5004339818306944878">Izmantojiet pat par 60% mazāk datu un paātriniet tīmekļa pārlūkošanu. Google serveri optimizēs jūsu apmeklētās lapas.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Saglabāto datu notīrīšana</translation> <translation id="5152843274749979095">Nav instalēta neviena atbalstīta lietotne</translation> <translation id="5161254044473106830">Jānorāda nosaukums</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 lejupielāde neizdevās.}zero{# lejupielādes neizdevās.}one{# lejupielāde neizdevās.}other{# lejupielādes neizdevās.}}</translation> <translation id="5168917394043976756">Atvērt navigācijas atvilktni</translation> <translation id="5171365962177408781">Pieskarieties, lai ielādētu jaunas cilnes lapu un skatītu ieteiktos rakstus.</translation> <translation id="5184329579814168207">Atvērt pārlūkā Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Šeit tiks parādītas jūsu visvairāk apmeklētās lapas.</translation> <translation id="5424588387303617268">Pieejami <ph name="GIGABYTES" /> GB</translation> <translation id="5433691172869980887">Lietotājvārds ir nokopēts.</translation> +<translation id="543509235395288790">Notiek <ph name="COUNT" /> faila(-u) lejupielāde (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Pāriet uz adreses joslu</translation> <translation id="5447201525962359567">Visa vietnes krātuve, tostarp sīkfaili un citi lokāli saglabāti dati</translation> <translation id="5447765697759493033">Šī vietne netiks tulkota</translation> +<translation id="545042621069398927">Lejupielāde tiek paātrināta.</translation> <translation id="5456381639095306749">Lejupielādēt lapu</translation> <translation id="548278423535722844">Atvērt karšu lietotnē</translation> <translation id="5487521232677179737">Notīrīt datus</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Vecāki par 30 dienām</translation> <translation id="5858741533101922242">Chrome nevar ieslēgt Bluetooth adapteri.</translation> <translation id="5860033963881614850">Izsl.</translation> +<translation id="5864174910718532887">Detalizēta informācija: kārtota pēc vietnes nosaukuma</translation> <translation id="5864419784173784555">Tiek gaidīta cita lejupielāde…</translation> <translation id="5869522115854928033">Saglabātās paroles</translation> <translation id="5878455346526065919">Tiek bloķētas reklāmas vietnēs, kurās tiek rādītas traucējošas reklāmas.</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Satura ieteikumi</translation> <translation id="6277522088822131679">Drukājot lapu, radās problēma. Lūdzu, mēģiniet vēlreiz.</translation> <translation id="6295158916970320988">Visas vietnes</translation> +<translation id="629730747756840877">Konts</translation> <translation id="6320088164292336938">Vibrācija</translation> <translation id="6324034347079777476">Android sistēmas sinhronizācija atspējota</translation> <translation id="6333140779060797560">Kopīgot, izmantojot <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Šifrēšana</translation> +<translation id="6341580099087024258">Vaicāt, kur saglabāt failus</translation> <translation id="6343192674172527289">Netika atrasta neviena lejupielāde</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />… un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}zero{<ph name="SHIPPING_ADDRESS_PREVIEW" />… un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />… un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />… un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Vai noņemt ieteikumu no vēstures?</translation> +<translation id="6378173571450987352">Detalizēta informācija: kārtota pēc izmantoto datu apjoma</translation> <translation id="6383961787135158834">Notīrīt vietnes krātuvi…</translation> <translation id="6388207532828177975">Notīrīt un atiestatīt</translation> <translation id="6393863479814692971">Pārlūkam Chrome ir nepieciešama atļauja piekļūt jūsu kamerai un mikrofonam šajā vietnē.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Pievienojiet Google kontu no lapas Konti savas ierīces lietotnē Iestatījumi.</translation> <translation id="7274013316676448362">Bloķēta vietne</translation> <translation id="729975465115245577">Ierīcē nav lietotnes, kurā uzglabāt paroļu failu.</translation> +<translation id="7302081693174882195">Detalizēta informācija: kārtota pēc ietaupīto datu apjoma</translation> <translation id="7333031090786104871">Joprojām notiek iepriekšējās vietnes pievienošana</translation> <translation id="7352939065658542140">VIDEOKLIPS</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Kopīgot 1 atlasīto vienumu}zero{Kopīgot # atlasītos vienumus}one{Kopīgot # atlasīto vienumu}other{Kopīgot # atlasītos vienumus}}</translation> <translation id="7359002509206457351">Piekļuve maksājumu veidiem</translation> <translation id="7366340029385295517">Notiek apraide uz ekrānu “<ph name="SCREEN_NAME" />”</translation> <translation id="7375125077091615385">Veids:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Chrome pirmās palaišanas pieredze</translation> <translation id="741204030948306876">Jā, piekrītu</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Vispirms jautāt</translation> <translation id="7423538860840206698">Bloķēta starpliktuves satura lasīšana</translation> <translation id="7437998757836447326">Izrakstīšanās no pārlūka Chrome</translation> +<translation id="7444811645081526538">Vairāk kategoriju</translation> <translation id="7445411102860286510">Atļaut vietnēm automātiski atskaņot videoklipus ar izslēgtu skaņu (ieteicams)</translation> <translation id="7453467225369441013">Jūs tiksiet izrakstīts no lielākās daļas vietņu. Jūs netiksiet izrakstīts no Google konta.</translation> <translation id="7454641608352164238">Nepietiek vietas</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Noņemt visu</translation> <translation id="7882131421121961860">Vēsture nav atrasta</translation> <translation id="7882806643839505685">Atļaut skaņu konkrētai vietnei</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Notiek faila lejupielāde.}zero{Notiek # failu lejupielāde.}one{Notiek # faila lejupielāde.}other{Notiek # failu lejupielāde.}}</translation> <translation id="7929962904089429003">Atvērt izvēlni</translation> <translation id="7942131818088350342">Spraudnis <ph name="PRODUCT_NAME" /> ir novecojis.</translation> <translation id="7947953824732555851">Pieņemt un pierakst.</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Dažās vietnēs var norēķināties, ierīcē izmantojot iepriekš norādītās atbalstītās maksājumu lietotnes.</translation> <translation id="8816439037877937734">Lietotne <ph name="APP_NAME" /> tiks atvērta pārlūkā Chrome. Turpinot jūs piekrītat Chrome <ph name="BEGIN_LINK1" />pakalpojumu sniegšanas noteikumiem<ph name="END_LINK1" /> un <ph name="BEGIN_LINK2" />konfidencialitātes paziņojumam<ph name="END_LINK2" />, kā arī <ph name="BEGIN_LINK3" />konfidencialitātes paziņojumam Google kontiem, kas tiek pārvaldīti lietotnē Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Grāmatzīmes</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> — <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Lejupielādējot saturu, radās kļūda.</translation> <translation id="8840953339110955557">Šī lapas versija var atšķirties no tiešsaises versijas.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb b/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb index 079d49c..4fd09c8 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Gebruiks- en crashrapporten</translation> <translation id="11221688409173367">Tik op de startknop om de speciaal voor jou geselecteerde artikelen te bekijken</translation> <translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download in behandeling.}other{# downloads in behandeling.}}</translation> <translation id="1145536944570833626">Bestaande gegevens verwijderen.</translation> <translation id="1146678959555564648">VR activeren</translation> <translation id="114721135501989771">Google-functies in Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Update je inloggegevens.</translation> <translation id="1974060860693918893">Geavanceerd</translation> <translation id="1984937141057606926">Toegestaan, behalve van derden</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />-knop</translation> <translation id="1989112275319619282">Browsen</translation> <translation id="1993768208584545658"><ph name="SITE" /> wil koppelen</translation> <translation id="1994173015038366702">Site-URL</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> van ?</translation> <translation id="3997476611815694295">Onbelangrijke opslag</translation> <translation id="4002066346123236978">Titel</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# uur}other{# uur}}</translation> <translation id="4042870126885713738">Suggesties weergeven wanneer een webadres onjuist is of er geen verbinding kan worden gemaakt</translation> <translation id="4046123991198612571">Volgend nummer</translation> <translation id="4048707525896921369">Meer informatie over onderwerpen op websites zonder dat je de pagina hoeft te verlaten. 'Tikken om te zoeken' stuurt een woord en contextuele informatie voor het woord naar Google Zoeken, waarna er definities, afbeeldingen, zoekresultaten en andere gegevens worden geretourneerd. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Je bent incognito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# minuut geleden}other{# minuten geleden}}</translation> <translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">Deze offline pagina is van <ph name="CREATION_TIME" /> en kan afwijken van de online versie.</translation> <translation id="4605958867780575332">Item verwijderd: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> openen</translation> <translation id="4645575059429386691">Beheerd door je ouder</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Een nieuw tabblad openen</translation> <translation id="4751476147751820511">Bewegings- of lichtsensoren</translation> <translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download voltooid.}other{# downloads voltooid.}}</translation> <translation id="4766369052440583386">Databesparing is ingeschakeld</translation> <translation id="4797039098279997504">Tik om terug te gaan naar <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Naam op kaart</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Je wachtwoorden, geschiedenis en meer op al je apparaten</translation> <translation id="4961700429721424617">Je logt uit van een account dat wordt beheerd door <ph name="MANAGED_DOMAIN" />. Hierdoor worden je Chrome-gegevens verwijderd van dit apparaat. Je gegevens blijven echter opgeslagen in je Google-account.</translation> <translation id="497421865427891073">Naar voren gaan</translation> +<translation id="4988210275050210843">Bestand downloaden (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Pagina's</translation> <translation id="4996978546172906250">Delen via</translation> <translation id="5004339818306944878">Gebruik tot 60% minder data en maak internet sneller. De servers van Google optimaliseren de pagina's die je bezoekt.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Opgeslagen gegevens wissen</translation> <translation id="5152843274749979095">Geen ondersteunde apps geïnstalleerd</translation> <translation id="5161254044473106830">Titel is vereist</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download mislukt.}other{# downloads mislukt.}}</translation> <translation id="5168917394043976756">Zijmenu openen</translation> <translation id="5171365962177408781">Tik om de nieuwe tabbladpagina te laden en voorgestelde artikelen te bekijken</translation> <translation id="5184329579814168207">Openen in Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Je meest bezochte pagina's worden hier weergegeven</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB beschikbaar</translation> <translation id="5433691172869980887">Gebruikersnaam gekopieerd</translation> +<translation id="543509235395288790"><ph name="COUNT" /> bestanden downloaden (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Naar de adresbalk gaan</translation> <translation id="5447201525962359567">Alle site-opslag, inclusief cookies en andere lokaal opgeslagen gegevens</translation> <translation id="5447765697759493033">Deze site wordt niet vertaald</translation> +<translation id="545042621069398927">Je download wordt versneld.</translation> <translation id="5456381639095306749">Pagina downloaden</translation> <translation id="548278423535722844">Openen in app voor kaarten</translation> <translation id="5487521232677179737">Gegevens wissen</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Ouder dan 30 dagen</translation> <translation id="5858741533101922242">Chrome kan de Bluetooth-adapter niet inschakelen</translation> <translation id="5860033963881614850">Uit</translation> +<translation id="5864174910718532887">Details: gesorteerd op sitenaam</translation> <translation id="5864419784173784555">Wachten op andere download…</translation> <translation id="5869522115854928033">Opgeslagen wachtwoorden</translation> <translation id="5878455346526065919">Advertenties blokkeren van sites die opdringerige advertenties weergeven</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Contentsuggesties</translation> <translation id="6277522088822131679">Er is een fout opgetreden bij het afdrukken van de pagina. Probeer het opnieuw.</translation> <translation id="6295158916970320988">Alle sites</translation> +<translation id="629730747756840877">Account</translation> <translation id="6320088164292336938">Trillen</translation> <translation id="6324034347079777476">Systeemsynchronisatie van Android uitgeschakeld</translation> <translation id="6333140779060797560">Delen via <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Codering</translation> +<translation id="6341580099087024258">Vragen waar bestanden moeten worden opgeslagen</translation> <translation id="6343192674172527289">Geen downloads gevonden</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 en nog <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> andere}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 en nog <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> andere}}</translation> <translation id="6364438453358674297">Suggestie verwijderen uit geschiedenis?</translation> +<translation id="6378173571450987352">Details: gesorteerd op hoeveelheid gebruikte data</translation> <translation id="6383961787135158834">Site-opslag wissen…</translation> <translation id="6388207532828177975">Wissen en opnieuw instellen</translation> <translation id="6393863479814692971">Chrome heeft toegangsrechten voor je camera en microfoon nodig voor deze site.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Voeg een Google-account toe via de pagina Accounts in de app Instellingen van je apparaat.</translation> <translation id="7274013316676448362">Geblokkeerde site</translation> <translation id="729975465115245577">Je apparaat bevat geen app om het wachtwoordbestand in op te slaan.</translation> +<translation id="7302081693174882195">Details: gesorteerd op de hoeveelheid bespaarde data</translation> <translation id="7333031090786104871">Nog steeds bezig met toevoegen van vorige site</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{1 geselecteerd item delen}other{# geselecteerde items delen}}</translation> <translation id="7359002509206457351">Toegang tot betaalmethoden</translation> <translation id="7366340029385295517">Casten naar <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">Functionaliteit bij eerste uitvoering van Chrome</translation> <translation id="741204030948306876">Ja, inschakelen</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Eerst vragen</translation> <translation id="7423538860840206698">Lezen van het klembord geblokkeerd</translation> <translation id="7437998757836447326">Uitloggen bij Chrome</translation> +<translation id="7444811645081526538">Meer categorieën</translation> <translation id="7445411102860286510">Sites toestaan gedempte video's automatisch af te spelen (aanbevolen)</translation> <translation id="7453467225369441013">Hiermee word je uitgelogd van de meeste sites. Je wordt niet uitgelogd van je Google-account.</translation> <translation id="7454641608352164238">Onvoldoende ruimte</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Alles verwijderen</translation> <translation id="7882131421121961860">Geen geschiedenis gevonden</translation> <translation id="7882806643839505685">Geluid toestaan voor een specifieke site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Bestand downloaden.}other{# bestanden downloaden.}}</translation> <translation id="7929962904089429003">Het menu openen</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is verouderd.</translation> <translation id="7947953824732555851">Accepteren en inloggen</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Op sommige websites kun je betalen met de bovenstaande ondersteunde betaal-apps op je apparaat.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> wordt geopend in Chrome. Als je doorgaat, ga je akkoord met de <ph name="BEGIN_LINK1" />Servicevoorwaarden<ph name="END_LINK1" /> en het <ph name="BEGIN_LINK2" />Privacybeleid<ph name="END_LINK2" /> van Chrome en het <ph name="BEGIN_LINK3" />Privacybeleid voor Google-accounts die worden beheerd met Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Bladwijzers</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Er is een fout opgetreden tijdens het downloaden van de content.</translation> <translation id="8840953339110955557">Deze pagina kan afwijken van de online versie.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_no.xtb b/chrome/android/java/strings/translations/android_chrome_strings_no.xtb index 4970789a..c43cb6e 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_no.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_no.xtb
@@ -605,6 +605,7 @@ <translation id="6255999984061454636">Innholdsforslag</translation> <translation id="6277522088822131679">Det oppsto et problem med å skrive ut siden. Prøv på nytt.</translation> <translation id="6295158916970320988">Alle nettsteder</translation> +<translation id="629730747756840877">Konto</translation> <translation id="6320088164292336938">Vibrering</translation> <translation id="6324034347079777476">Synkronisering for Android-systemet er slått av</translation> <translation id="6333140779060797560">Del via <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb b/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb index b9e151e..dc6e22c 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Raporty o użytkowaniu i awariach</translation> <translation id="11221688409173367">Dotknij przycisku ekranu głównego, by wyświetlić artykuły wybrane specjalnie dla Ciebie</translation> <translation id="1129510026454351943">Szczegóły: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 plik oczekuje na pobranie.}few{# pliki oczekują na pobranie.}many{# plików oczekuje na pobranie.}other{# pliku oczekuje na pobranie.}}</translation> <translation id="1145536944570833626">Usuń istniejące dane.</translation> <translation id="1146678959555564648">Włącz tryb VR</translation> <translation id="114721135501989771">Inteligentne rozwiązania Google w Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Zaktualizuj swoje dane logowania.</translation> <translation id="1974060860693918893">Zaawansowane</translation> <translation id="1984937141057606926">Dozwolone, z wyjątkiem witryn innych firm</translation> +<translation id="1987739130650180037">Przycisk <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Przeglądaj</translation> <translation id="1993768208584545658"><ph name="SITE" /> chce się sparować</translation> <translation id="1994173015038366702">URL strony</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">Nieistotne dane</translation> <translation id="4002066346123236978">Tytuł</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# godzina}few{# godziny}many{# godzin}other{# godziny}}</translation> <translation id="4042870126885713738">Pokazuj podpowiedzi, gdy nie można znaleźć adresu internetowego lub nawiązać połączenia</translation> <translation id="4046123991198612571">Następny utwór</translation> <translation id="4048707525896921369">Poznaj tematy w witrynach bez opuszczania strony. Funkcja Kliknij, by wyszukać kopiuje słowo wraz z kontekstem i wkleja je w wyszukiwarce Google. Dzięki temu otrzymujesz definicje, grafiki, wyniki wyszukiwania i inne informacje. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Jesteś w trybie incognito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# minutę temu}few{# minuty temu}many{# minut temu}other{# minuty temu}}</translation> <translation id="4587589328781138893">Witryny</translation> +<translation id="4594952190837476234">Ta strona offline jest z <ph name="CREATION_TIME" /> i może różnić się od wersji online.</translation> <translation id="4605958867780575332">Usunięto element: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Otwórz <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Zarządzany przez Twojego rodzica</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Otwórz nową kartę</translation> <translation id="4751476147751820511">Czujniki ruchu lub światła</translation> <translation id="4759238208242260848">Pobrane pliki</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{Ukończono pobieranie 1 pliku.}few{Ukończono pobieranie # plików.}many{Ukończono pobieranie # plików.}other{Ukończono pobieranie # pliku.}}</translation> <translation id="4766369052440583386">Oszczędzanie danych jest włączone</translation> <translation id="4797039098279997504">Kliknij, by wrócić na <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Imię i nazwisko na karcie</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Twoje hasła, historia i inne dane na wszystkich Twoich urządzeniach</translation> <translation id="4961700429721424617">Wylogowujesz się z konta, którym zarządza <ph name="MANAGED_DOMAIN" />. Spowoduje to usunięcie danych Chrome z tego urządzenia, ale pozostaną one na Twoim koncie Google.</translation> <translation id="497421865427891073">Dalej</translation> +<translation id="4988210275050210843">Pobieram plik (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Strony</translation> <translation id="4996978546172906250">Udostępnij przez</translation> <translation id="5004339818306944878">Przesyłaj nawet o 60% mniej danych i przyspiesz działanie sieci: serwery Google optymalizują strony, które odwiedzasz.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Wyczyść zapisane dane</translation> <translation id="5152843274749979095">Nie zainstalowano obsługiwanych aplikacji</translation> <translation id="5161254044473106830">Tytuł jest wymagany</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{Nie udało się pobrać 1 pliku.}few{Nie udało się pobrać # plików.}many{Nie udało się pobrać # plików.}other{Nie udało się pobrać # pliku.}}</translation> <translation id="5168917394043976756">Otwórz panel nawigacji</translation> <translation id="5171365962177408781">Dotknij, by załadować stronę nowej karty i wyświetlić sugerowane artykuły</translation> <translation id="5184329579814168207">Otwórz w Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Tu pojawią się strony, na które najczęściej wchodzisz</translation> <translation id="5424588387303617268">Dostępne <ph name="GIGABYTES" /> GB</translation> <translation id="5433691172869980887">Nazwa użytkownika została skopiowana</translation> +<translation id="543509235395288790">Pobieram pliki: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Przejdź do paska adresu</translation> <translation id="5447201525962359567">Wszystkie dane witryn, w tym pliki cookie i inne dane lokalne</translation> <translation id="5447765697759493033">Ta strona nie zostanie przetłumaczona</translation> +<translation id="545042621069398927">Przyspieszam pobieranie.</translation> <translation id="5456381639095306749">Pobierz stronę</translation> <translation id="548278423535722844">Otwórz w aplikacji z mapami</translation> <translation id="5487521232677179737">Wyczyść dane</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Sprzed ponad 30 dni</translation> <translation id="5858741533101922242">Chrome nie może włączyć adaptera Bluetooth</translation> <translation id="5860033963881614850">Wyłączone</translation> +<translation id="5864174910718532887">Szczegóły: posortowane według nazwy witryny</translation> <translation id="5864419784173784555">Czekam na inny plik do pobrania…</translation> <translation id="5869522115854928033">Zapisane hasła</translation> <translation id="5878455346526065919">Blokowanie reklam na stronach, które wyświetlają uciążliwe reklamy</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Polecane treści</translation> <translation id="6277522088822131679">Podczas drukowania strony wystąpił problem. Spróbuj ponownie.</translation> <translation id="6295158916970320988">Wszystkie witryny</translation> +<translation id="629730747756840877">Konto</translation> <translation id="6320088164292336938">Wibracje</translation> <translation id="6324034347079777476">Synchronizacja systemu Android jest wyłączona</translation> <translation id="6333140779060797560">Udostępnij przez: <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Szyfrowanie</translation> +<translation id="6341580099087024258">Pytaj, gdzie zapisać pliki</translation> <translation id="6343192674172527289">Brak pobranych plików</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}many{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Usunąć sugestię z historii?</translation> +<translation id="6378173571450987352">Szczegóły: posortowane według wykorzystanych danych</translation> <translation id="6383961787135158834">Wyczyść dane witryn…</translation> <translation id="6388207532828177975">Wyczyść i zresetuj</translation> <translation id="6393863479814692971">Chrome potrzebuje uprawnień dostępu do aparatu i mikrofonu na tej stronie.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Otwórz aplikację Ustawienia na urządzeniu, przejdź na stronę Konta i dodaj konto Google.</translation> <translation id="7274013316676448362">Zablokowana witryna</translation> <translation id="729975465115245577">Na urządzeniu nie ma aplikacji umożliwiającej zapisanie pliku z hasłami.</translation> +<translation id="7302081693174882195">Szczegóły: posortowane według zaoszczędzonych danych</translation> <translation id="7333031090786104871">Nadal dodaję poprzednią stronę</translation> <translation id="7352939065658542140">FILM</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Udostępnij 1 wybrany element}few{Udostępnij # wybrane elementy}many{Udostępnij # wybranych elementów}other{Udostępnij # wybranego elementu}}</translation> <translation id="7359002509206457351">Dostęp do form płatności</translation> <translation id="7366340029385295517">Przesyłam na ekran <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Typ:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">Adres URL</translation> <translation id="7403691278183511381">Pierwsze uruchomienie Chrome</translation> <translation id="741204030948306876">Tak</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Najpierw zapytaj</translation> <translation id="7423538860840206698">Zablokowano odczytywanie schowka</translation> <translation id="7437998757836447326">Wyloguj się z Chrome</translation> +<translation id="7444811645081526538">Więcej kategorii</translation> <translation id="7445411102860286510">Zezwalaj witrynom na automatyczne odtwarzanie wyciszonych filmów (zalecane)</translation> <translation id="7453467225369441013">Wylogowuje z większości stron internetowych. Nie wyloguje Cię z konta Google.</translation> <translation id="7454641608352164238">Za mało miejsca</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Usuń wszystkie</translation> <translation id="7882131421121961860">Brak historii</translation> <translation id="7882806643839505685">Zezwalaj na dźwięk na określonej stronie.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Pobieram plik.}few{Pobieram # pliki.}many{Pobieram # plików.}other{Pobieram # pliku.}}</translation> <translation id="7929962904089429003">Otwórz menu</translation> <translation id="7942131818088350342">Przeglądarka <ph name="PRODUCT_NAME" /> jest nieaktualna.</translation> <translation id="7947953824732555851">Zaakceptuj i zaloguj się</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Używając swojego urządzenia, na niektórych stronach możesz płacić za pomocą powyższych obsługiwanych aplikacji do płatności.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> otworzy się w Chrome. Przechodząc dalej, akceptujesz <ph name="BEGIN_LINK1" />Warunki korzystania z usługi<ph name="END_LINK1" /> Chrome, <ph name="BEGIN_LINK2" />Informacje na temat ochrony prywatności<ph name="END_LINK2" /> i <ph name="BEGIN_LINK3" />Informacje na temat ochrony prywatności dotyczące kont Google zarządzanych przez Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Zakładki</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Podczas pobierania treści wystąpił błąd.</translation> <translation id="8840953339110955557">Ta strona może różnić się od wersji online.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb b/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb index 9f2e169..5aeae95 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Sugestões de conteúdo</translation> <translation id="6277522088822131679">Ocorreu um problema ao imprimir a página. Tente novamente.</translation> <translation id="6295158916970320988">Todos os sites</translation> +<translation id="629730747756840877">Conta</translation> <translation id="6320088164292336938">Vibrar</translation> <translation id="6324034347079777476">Sincronização do sistema Android desativada</translation> <translation id="6333140779060797560">Compartilhar via <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb b/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb index bfb592a1..5939acc 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Relatórios de utilização e falhas</translation> <translation id="11221688409173367">Toque no botão página inicial para ver artigos selecionados especificamente para si.</translation> <translation id="1129510026454351943">Detalhes: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 transferência pendente.}other{# transferências pendentes.}}</translation> <translation id="1145536944570833626">Eliminar dados existentes.</translation> <translation id="1146678959555564648">Entrar na RV</translation> <translation id="114721135501989771">Inteligên. Google no Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Atualize os detalhes de início de sessão.</translation> <translation id="1974060860693918893">Avançadas</translation> <translation id="1984937141057606926">Permitidos, exceto de terceiros</translation> +<translation id="1987739130650180037">Botão <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Procurar</translation> <translation id="1993768208584545658"><ph name="SITE" /> pretende sincronizar</translation> <translation id="1994173015038366702">URL do site</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Armazenamento desnecessário</translation> <translation id="4002066346123236978">Título</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4042870126885713738">Mostrar sugestões quando um endereço Web não responder ou não for possível estabelecer ligação</translation> <translation id="4046123991198612571">Faixa seguinte</translation> <translation id="4048707525896921369">Saiba mais acerca dos tópicos nos Websites sem sair da página. A funcionalidade Tocar para pesquisar envia uma palavra e o contexto circundante para a Pesquisa Google, que devolve definições, imagens, resultados da pesquisa e outros detalhes. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Entrou no modo de navegação anónima.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Há # minuto}other{Há # minutos}}</translation> <translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">Esta página foi criada a <ph name="CREATION_TIME" /> e pode ser diferente da versão online.</translation> <translation id="4605958867780575332">Item removido: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Abrir <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Gerido pelos teus pais</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Abrir um novo separador</translation> <translation id="4751476147751820511">Sensores de movimento ou de luz</translation> <translation id="4759238208242260848">Transferências</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 transferência concluída.}other{# transferências concluídas.}}</translation> <translation id="4766369052440583386">Poupança de dados ativada</translation> <translation id="4797039098279997504">Toque para voltar a <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Nome no cartão</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">As suas palavras-passe, histórico e muito mais em todos os dispositivos.</translation> <translation id="4961700429721424617">Está a terminar sessão numa conta gerida por <ph name="MANAGED_DOMAIN" />. Esta ação elimina os seus dados do Chrome deste dispositivo, embora permaneçam na Conta Google.</translation> <translation id="497421865427891073">Avançar</translation> +<translation id="4988210275050210843">A transferir ficheiro (<ph name="MEGABYTES" />)…</translation> <translation id="4988526792673242964">Páginas </translation> <translation id="4996978546172906250">Partilhar através de</translation> <translation id="5004339818306944878">Utilize até menos 60% de dados e acelere a Web. Os servidores da Google otimizam as páginas que visita.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Limpar dados armazenados</translation> <translation id="5152843274749979095">Nenhuma aplicação compatível instalada</translation> <translation id="5161254044473106830">Título obrigatório</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 transferência com falha.}other{# transferências com falha.}}</translation> <translation id="5168917394043976756">Abrir a gaveta de navegação</translation> <translation id="5171365962177408781">Toque para carregar o novo separador e ver artigos sugeridos.</translation> <translation id="5184329579814168207">Abrir no Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">As páginas mais visitadas aparecem aqui</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB disponíveis</translation> <translation id="5433691172869980887">Nome de utilizador copiado</translation> +<translation id="543509235395288790">A transferir <ph name="COUNT" /> ficheiros (<ph name="MEGABYTES" />)…</translation> <translation id="5441522332038954058">Ir para a barra de endereço</translation> <translation id="5447201525962359567">Todo o armazenamento de sites, incluindo cookies e outros dados armazenados localmente</translation> <translation id="5447765697759493033">Este site não será traduzido.</translation> +<translation id="545042621069398927">A acelerar a transferência…</translation> <translation id="5456381639095306749">Transferir página</translation> <translation id="548278423535722844">Abrir na aplicação de mapas</translation> <translation id="5487521232677179737">Limpar dados</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Com mais de 30 dias</translation> <translation id="5858741533101922242">O Chrome não consegue ativar o adaptador Bluetooth</translation> <translation id="5860033963881614850">Desativado</translation> +<translation id="5864174910718532887">Detalhes: ordenado por nome do site</translation> <translation id="5864419784173784555">A aguardar por outra transferência…</translation> <translation id="5869522115854928033">Palavras-passe guardadas</translation> <translation id="5878455346526065919">Bloquear anúncios de sites que têm tendência para mostrar anúncios intrusivos</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Sugestões de conteúdo</translation> <translation id="6277522088822131679">Ocorreu um problema ao imprimir a página. Tente novamente.</translation> <translation id="6295158916970320988">Todos os sites</translation> +<translation id="629730747756840877">Conta</translation> <translation id="6320088164292336938">Vibrar</translation> <translation id="6324034347079777476">Sincronização do sistema Android desativada</translation> <translation id="6333140779060797560">Partilhar através de <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Encriptação</translation> +<translation id="6341580099087024258">Perguntar onde guardar os ficheiros</translation> <translation id="6343192674172527289">Nenhuma transferência encontrada</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Pretende remover a sugestão do histórico?</translation> +<translation id="6378173571450987352">Detalhes: ordenado por quantidade de dados utilizados</translation> <translation id="6383961787135158834">Limpar armazen. do site…</translation> <translation id="6388207532828177975">Limpar e repor</translation> <translation id="6393863479814692971">O Chrome necessita de autorização de acesso à câmara e ao microfone para este site.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Adicione uma Conta Google na página Contas na aplicação Definições do dispositivo.</translation> <translation id="7274013316676448362">Site bloqueado</translation> <translation id="729975465115245577">O dispositivo não tem uma aplicação para armazenar o ficheiro de palavras-passe.</translation> +<translation id="7302081693174882195">Detalhes: ordenado por quantidade de dados guardados</translation> <translation id="7333031090786104871">Ainda a adicionar o site anterior…</translation> <translation id="7352939065658542140">VÍDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Partilhar 1 item selecionado}other{Partilhar # itens selecionados}}</translation> <translation id="7359002509206457351">Aceder aos métodos de pagamento</translation> <translation id="7366340029385295517">A transmitir para <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Tipo:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Experiência de primeira execução do Chrome</translation> <translation id="741204030948306876">Sim, aceito</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Perguntar primeiro</translation> <translation id="7423538860840206698">Leitura da área de transferência bloqueada</translation> <translation id="7437998757836447326">Terminar sessão no Chrome</translation> +<translation id="7444811645081526538">Mais categorias</translation> <translation id="7445411102860286510">Permitir que os sites reproduzam automaticamente vídeos com o som desativado (recomendado)</translation> <translation id="7453467225369441013">A sua sessão é terminada na maioria dos sites. A sessão na sua Conta Google não é terminada.</translation> <translation id="7454641608352164238">Espaço insuficiente</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Remover tudo</translation> <translation id="7882131421121961860">Nenhum histórico encontrado</translation> <translation id="7882806643839505685">Permita a reprodução de som de um site específico.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{A transferir o ficheiro…}other{A transferir # ficheiros…}}</translation> <translation id="7929962904089429003">Abrir o menu</translation> <translation id="7942131818088350342">O <ph name="PRODUCT_NAME" /> está desatualizado.</translation> <translation id="7947953824732555851">Aceitar e in. sessão</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Nalguns Sites, é possível pagar com as aplicações de pagamento compatíveis acima no dispositivo.</translation> <translation id="8816439037877937734">A aplicação <ph name="APP_NAME" /> será aberta no Chrome. Ao continuar, aceita os <ph name="BEGIN_LINK1" />Termos de Utilização<ph name="END_LINK1" /> e o <ph name="BEGIN_LINK2" />Aviso de Privacidade<ph name="END_LINK2" /> do Chrome, bem como o <ph name="BEGIN_LINK3" />Aviso de Privacidade para Contas Google Geridas com o Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Marcadores</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Ocorreu um erro ao transferir o conteúdo.</translation> <translation id="8840953339110955557">Esta página pode ser diferente da versão online.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb index 7808a283b..aafac6c 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Statistici de utilizare și rapoarte de blocare</translation> <translation id="11221688409173367">Atinge butonul Pagina principală pentru a vedea articolele selectate special pentru tine</translation> <translation id="1129510026454351943">Detalii: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{O descărcare în așteptare.}few{# descărcări în așteptare.}other{# de descărcări în așteptare.}}</translation> <translation id="1145536944570833626">Șterge datele existente.</translation> <translation id="1146678959555564648">Intră în RV</translation> <translation id="114721135501989771">Profită de ingeniozitatea Google în Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Actualizați detaliile de conectare.</translation> <translation id="1974060860693918893">Avansate</translation> <translation id="1984937141057606926">Permise, cu excepția celor terță parte</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> Butonul <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Răsfoiește</translation> <translation id="1993768208584545658"><ph name="SITE" /> dorește să se asocieze</translation> <translation id="1994173015038366702">Adresa URL a site-ului</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">Stocare neimportantă</translation> <translation id="4002066346123236978">Titlu</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{O oră}few{# ore}other{# de ore}}</translation> <translation id="4042870126885713738">Afișează sugestii atunci când o adresă web nu se rezolvă sau nu poate fi stabilită o conexiune</translation> <translation id="4046123991198612571">Melodia următoare</translation> <translation id="4048707525896921369">Află despre subiectele de pe site-uri fără să părăsești pagina. Funcția Atinge pentru a căuta trimite un cuvânt și contextul aferent către Căutarea Google și returnează definiții, imagini, rezultate ale căutării și alte detalii. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Ai trecut în modul incognito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Acum # minut}few{Acum # minute}other{Acum # de minute}}</translation> <translation id="4587589328781138893">Site-uri</translation> +<translation id="4594952190837476234">Această pagină offline este din data de <ph name="CREATION_TIME" /> și poate fi diferită de versiunea online.</translation> <translation id="4605958867780575332">Element eliminat: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Deschide <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Gestionat de părintele tău</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Deschide o filă nouă</translation> <translation id="4751476147751820511">Senzori de mișcare sau de lumină</translation> <translation id="4759238208242260848">Descărcări</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{O descărcare finalizată.}few{# descărcări finalizate.}other{# de descărcări finalizate.}}</translation> <translation id="4766369052440583386">Economizorul de date este activat</translation> <translation id="4797039098279997504">Atinge pentru a reveni la <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Numele de pe card</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Parolele, istoricul și alte date, pe toate dispozitivele</translation> <translation id="4961700429721424617">Te deconectezi de la un cont gestionat de <ph name="MANAGED_DOMAIN" />. Astfel, se vor șterge datele Chrome de pe acest dispozitiv, dar datele vor rămâne în Contul Google.</translation> <translation id="497421865427891073">Înainte</translation> +<translation id="4988210275050210843">Fișierul se descarcă (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Pagini</translation> <translation id="4996978546172906250">Trimiteți prin</translation> <translation id="5004339818306944878">Folosește cu până la 60% mai puține date și navighează mai rapid pe web. Serverele Google vor optimiza paginile pe care le accesezi.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Șterge datele stocate</translation> <translation id="5152843274749979095">Nu sunt instalate aplicații acceptate</translation> <translation id="5161254044473106830">Titlul este obligatoriu</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{O descărcare nu a reușit.}few{# descărcări nu au reușit.}other{# de descărcări nu au reușit.}}</translation> <translation id="5168917394043976756">Deschide panoul de navigare</translation> <translation id="5171365962177408781">Atinge pentru a încărca pagina Filă nouă și a vedea articolele sugerate</translation> <translation id="5184329579814168207">Deschide în Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Cele mai accesate pagini vor apărea aici</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB disponibili</translation> <translation id="5433691172869980887">Numele de utilizator a fost copiat</translation> +<translation id="543509235395288790">Se descarcă <ph name="COUNT" /> fișiere (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Accesează bara de adrese</translation> <translation id="5447201525962359567">Toată stocarea site-urilor, inclusiv cookie-urile și alte date stocate local</translation> <translation id="5447765697759493033">Acest site nu va fi tradus</translation> +<translation id="545042621069398927">Se accelerează descărcarea.</translation> <translation id="5456381639095306749">Descarcă pagina</translation> <translation id="548278423535722844">Deschide în aplicația Maps</translation> <translation id="5487521232677179737">Șterge datele</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Mai vechi de 30 de zile</translation> <translation id="5858741533101922242">Chrome nu poate activa adaptorul Bluetooth</translation> <translation id="5860033963881614850">Dezactivat</translation> +<translation id="5864174910718532887">Detalii: sortate după numele site-ului</translation> <translation id="5864419784173784555">Se așteaptă altă descărcare…</translation> <translation id="5869522115854928033">Parole salvate</translation> <translation id="5878455346526065919">Blochează anunțurile de la site-urile care tind să afișeze anunțuri deranjante</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Sugestii de conținut</translation> <translation id="6277522088822131679">A apărut o problemă la printarea paginii. Încercați din nou.</translation> <translation id="6295158916970320988">Toate site-urile</translation> +<translation id="629730747756840877">Cont</translation> <translation id="6320088164292336938">Vibrații</translation> <translation id="6324034347079777476">Sincronizarea de sistem Android este dezactivată</translation> <translation id="6333140779060797560">Trimiteți prin <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Criptare</translation> +<translation id="6341580099087024258">Întreabă unde să fie salvate fișierele</translation> <translation id="6343192674172527289">Nu s-a găsit nicio descărcare</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 și încă <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 și încă <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 și încă <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Elimini sugestia din istoric?</translation> +<translation id="6378173571450987352">Detalii: sortate după volumul de date folosite</translation> <translation id="6383961787135158834">Șterge stocare site-uri…</translation> <translation id="6388207532828177975">Șterge și resetează</translation> <translation id="6393863479814692971">Chrome are nevoie de permisiune ca să acceseze camera foto și microfonul pentru acest site.</translation> @@ -723,11 +736,14 @@ <translation id="7253272406652746122">Adaugă un Cont Google din pagina Conturi din aplicația Setări a dispozitivului.</translation> <translation id="7274013316676448362">Site blocat</translation> <translation id="729975465115245577">Dispozitivul nu are o aplicație pentru stocarea fișierului parolelor.</translation> +<translation id="7302081693174882195">Detalii: sortate după volumul de date salvate</translation> <translation id="7333031090786104871">Încă se adaugă site-ul anterior</translation> <translation id="7352939065658542140">VIDEOCLIP</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Trimite un element selectat}few{Trimite # elemente selectate}other{Trimite # de elemente selectate}}</translation> +<translation id="7359002509206457351">Acces la metodele de plată</translation> <translation id="7366340029385295517">Se proiectează pe <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Tip:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">Adresă URL</translation> <translation id="7403691278183511381">Experiența primei rulări Chrome</translation> <translation id="741204030948306876">Da, accept</translation> @@ -735,6 +751,7 @@ <translation id="7423098979219808738">Mai întâi întreabă</translation> <translation id="7423538860840206698">Citirea clipboardului este blocată</translation> <translation id="7437998757836447326">Deconectează-te de la Chrome</translation> +<translation id="7444811645081526538">Mai multe categorii</translation> <translation id="7445411102860286510">Permite site-urilor să redea automat videoclipuri cu sunetul dezactivat (recomandat)</translation> <translation id="7453467225369441013">Te deconectează de pe majoritatea site-urilor. Nu te va deconecta de la Contul Google.</translation> <translation id="7454641608352164238">Spațiu insuficient</translation> @@ -789,6 +806,7 @@ <translation id="7876243839304621966">Elimină tot</translation> <translation id="7882131421121961860">Nu s-a găsit niciun istoric</translation> <translation id="7882806643839505685">Permite sunetul pentru un anumit site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Fișierul se descarcă.}few{Se descarcă # fișiere.}other{Se descarcă # de fișiere.}}</translation> <translation id="7929962904089429003">Deschide meniul</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> este învechit.</translation> <translation id="7947953824732555851">Accept și conectare</translation> @@ -884,6 +902,7 @@ <translation id="8812260976093120287">Pe unele site-uri, poți plăti folosind aplicațiile acceptate pentru plăți de mai sus de pe dispozitiv.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> se va deschide în Chrome. Continuând, ești de acord cu <ph name="BEGIN_LINK1" />Termenii și condițiile<ph name="END_LINK1" /> și <ph name="BEGIN_LINK2" />Notificarea privind confidențialitatea<ph name="END_LINK2" /> Chrome și cu <ph name="BEGIN_LINK3" />Notificarea privind confidențialitatea pentru Conturile Google gestionate cu Family<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Marcaje</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">A apărut o eroare la descărcarea conținutului.</translation> <translation id="8840953339110955557">Această pagină poate fi diferită de versiunea online.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb index 95a5978..d6d1e818 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Предлагаемый контент</translation> <translation id="6277522088822131679">Не удалось распечатать страницу. Повторите попытку.</translation> <translation id="6295158916970320988">Все сайты</translation> +<translation id="629730747756840877">Аккаунт</translation> <translation id="6320088164292336938">Вибросигнал</translation> <translation id="6324034347079777476">Синхронизация системы Android отключена</translation> <translation id="6333140779060797560">Отправить с помощью <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb index ce15c56..5ae135ac 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb
@@ -615,6 +615,7 @@ <translation id="6255999984061454636">Návrhy obsahu</translation> <translation id="6277522088822131679">Pri tlačení stránky sa vyskytol problém. Skúste to znova.</translation> <translation id="6295158916970320988">Všetky stránky</translation> +<translation id="629730747756840877">Účet</translation> <translation id="6320088164292336938">Vibrovanie</translation> <translation id="6324034347079777476">Synchronizácia systému Android je zakázaná</translation> <translation id="6333140779060797560">Zdieľať prostredníctvom aplikácie <ph name="APPLICATION" /></translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb index f4e15c3..c2492bea 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Poročila o uporabi in zrušitvah</translation> <translation id="11221688409173367">Dotaknite se gumba za začetni zaslon, če si želite ogledati članke, izbrane za vas</translation> <translation id="1129510026454351943">Podrobnosti: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 prenos na čakanju}one{# prenos na čakanju}two{# prenosa na čakanju}few{# prenosi na čakanju}other{# prenosov na čakanju}}</translation> <translation id="1145536944570833626">Izbris obstoječih podatkov.</translation> <translation id="1146678959555564648">V navidezno resničnost</translation> <translation id="114721135501989771">Prejmite Googlove pametne rešitve v Chromu</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Posodobite podrobnosti prijave.</translation> <translation id="1974060860693918893">Dodatno</translation> <translation id="1984937141057606926">Dovoljeno, razen za druga spletna mesta</translation> +<translation id="1987739130650180037">Gumb <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Brskanje</translation> <translation id="1993768208584545658"><ph name="SITE" /> želi opraviti seznanitev</translation> <translation id="1994173015038366702">URL spletnega mesta</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Nepomembni shranjeni podatki</translation> <translation id="4002066346123236978">Naslov</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}two{# h}few{# h}other{# h}}</translation> <translation id="4042870126885713738">Pokaži predloge, ko spletnega naslova ni mogoče razrešiti ali povezave ni mogoče vzpostaviti</translation> <translation id="4046123991198612571">Naslednja skladba</translation> <translation id="4048707525896921369">Več informacij o temah na spletnih mestih, ne da bi zapustili stran. Funkcija »Iskanje z dotikom« pošlje besedo in njeno sobesedilo Iskanju Google in vrne definicije, slike, rezultate iskanja in druge podrobnosti. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Zdaj se vaše brskanje ne shranjuje v zgodovino.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Pred # minuto}one{Pred # minuto}two{Pred # minutama}few{Pred # minutami}other{Pred # minutami}}</translation> <translation id="4587589328781138893">Spletna mesta</translation> +<translation id="4594952190837476234">Ta stran brez povezave je bila ustvarjena <ph name="CREATION_TIME" /> in se morda razlikuje od spletne različice.</translation> <translation id="4605958867780575332">Odstranjen element: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Odpri <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Upravlja starš</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Odpiranje novega zavihka</translation> <translation id="4751476147751820511">Tipala za gibanje in svetlobo</translation> <translation id="4759238208242260848">Prenosi</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 prenos končan.}one{# prenos končan.}two{# prenosa končana.}few{# prenosi končani.}other{# prenosov končanih.}}</translation> <translation id="4766369052440583386">Varčevanje s podatki je vklopljeno</translation> <translation id="4797039098279997504">Dotaknite se, če se želite vrniti na <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Ime na kartici</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Gesla, zgodovina in drugi podatki v vseh vaših napravah</translation> <translation id="4961700429721424617">Odjavili se boste iz računa, ki ga upravlja <ph name="MANAGED_DOMAIN" />. S tem boste iz te naprave izbrisali podatke v Chromu, vendar bodo vaši podatki še vedno na voljo v Google Računu.</translation> <translation id="497421865427891073">Pojdi naprej</translation> +<translation id="4988210275050210843">Prenos datoteke (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Strani</translation> <translation id="4996978546172906250">Skupna raba prek</translation> <translation id="5004339818306944878">Prenesite do 60 % manj podatkov in zagotovite hitrejše delovanje spleta. Googlovi strežniki optimizirajo strani, ki jih obiščete.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Izbris shranjenih podatkov</translation> <translation id="5152843274749979095">Nameščena ni nobena podprta aplikacija</translation> <translation id="5161254044473106830">Naslov je obvezen</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 prenos ni uspel.}one{# prenos ni uspel.}two{# prenosa nista uspela.}few{# prenosi niso uspeli.}other{# prenosov ni uspelo.}}</translation> <translation id="5168917394043976756">Odpri predal za krmarjenje</translation> <translation id="5171365962177408781">Dotaknite se, če želite naložiti nov zavihek s povezavami in si ogledati predlagane članke</translation> <translation id="5184329579814168207">Odpri v Chromu</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Tu bodo prikazane strani, ki jih obiskujete najpogosteje</translation> <translation id="5424588387303617268">Na voljo: <ph name="GIGABYTES" /> GB</translation> <translation id="5433691172869980887">Uporabniško ime kopirano</translation> +<translation id="543509235395288790">Prenašanje toliko datotek: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Premik na naslovno vrstico</translation> <translation id="5447201525962359567">Vsi shranjeni podatki spletnega mesta, vključno s piškotki in drugimi lokalno shranjenimi podatki</translation> <translation id="5447765697759493033">To spletno mesto ne bo prevedeno</translation> +<translation id="545042621069398927">Pospeševanje prenosa.</translation> <translation id="5456381639095306749">Prenos strani</translation> <translation id="548278423535722844">Odpiranje v aplikaciji z zemljevidi</translation> <translation id="5487521232677179737">Izbriši podatke</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Starejše od 30 dni</translation> <translation id="5858741533101922242">Chrome ne more vklopiti vmesnika za Bluetooth</translation> <translation id="5860033963881614850">Izklopljeno</translation> +<translation id="5864174910718532887">Podrobnosti: razvrščeno po imenu spletnega mesta</translation> <translation id="5864419784173784555">Čakanje na drug prenos …</translation> <translation id="5869522115854928033">Shranjena gesla</translation> <translation id="5878455346526065919">Blokiraj oglase spletnih mest, ki prikazujejo vsiljive oglase</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Predlogi za vsebino</translation> <translation id="6277522088822131679">Pri tiskanju strani je prišlo do težave. Poskusite znova.</translation> <translation id="6295158916970320988">Vsa spletna mesta</translation> +<translation id="629730747756840877">Račun</translation> <translation id="6320088164292336938">Vibriranje</translation> <translation id="6324034347079777476">Sinhronizacija sistema Android je onemogočena.</translation> <translation id="6333140779060797560">Skupna raba prek: <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Šifriranje</translation> +<translation id="6341580099087024258">Vprašaj, kje shraniti datoteke</translation> <translation id="6343192674172527289">Ni prenosov</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> \u2026 in še <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> \u2026 in še <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}two{<ph name="SHIPPING_ADDRESS_PREVIEW" /> \u2026 in še <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> \u2026 in še <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> \u2026 in še <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Ali želite odstraniti predlog iz zgodovine?</translation> +<translation id="6378173571450987352">Podrobnosti: razvrščeno po količini prenesenih podatkov</translation> <translation id="6383961787135158834">Izbris shrambe mesta …</translation> <translation id="6388207532828177975">Izbriši in ponastavi</translation> <translation id="6393863479814692971">Chrome potrebuje dovoljenje za dostop do fotoaparata in mikrofona za to spletno mesto.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Na strani za račune v aplikaciji Nastavitve dodajte Google Račun.</translation> <translation id="7274013316676448362">Blokirano spletno mesto</translation> <translation id="729975465115245577">V napravi ni aplikacije za shranjevanje datoteke z gesli.</translation> +<translation id="7302081693174882195">Podrobnosti: razvrščeno po količini prihranjenih podatkov</translation> <translation id="7333031090786104871">Dodajanje prejšnjega spletnega mesta še vedno poteka</translation> <translation id="7352939065658542140">VIDEOPOSNETEK</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Delitev 1 izbranega elementa z drugimi}one{Delitev # izbranega elementa z drugimi}two{Delitev # izbranih elementov z drugimi}few{Delitev # izbranih elementov z drugimi}other{Delitev # izbranih elementov z drugimi}}</translation> <translation id="7359002509206457351">Dostop do plačilnih sredstev</translation> <translation id="7366340029385295517">Predvajanje na zaslonu <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Vrsta:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Izkušnje ob prvem izvajanju Chroma</translation> <translation id="741204030948306876">Da, sem za</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Najprej vprašaj</translation> <translation id="7423538860840206698">Blokirano branje vsebine odložišča</translation> <translation id="7437998757836447326">Odjava iz Google Chroma</translation> +<translation id="7444811645081526538">Več kategorij</translation> <translation id="7445411102860286510">Dovoli spletnim mestom samodejno predvajanje videoposnetkov z izklopljenim zvokom (priporočljivo)</translation> <translation id="7453467225369441013">Odjavi vas iz večine spletnih mest, vendar ne iz Google Računa.</translation> <translation id="7454641608352164238">Ni dovolj prostora</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Odstrani vse</translation> <translation id="7882131421121961860">Ni zgodovine</translation> <translation id="7882806643839505685">Dovolitev zvoka za določeno spletno mesto.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Prenos datoteke.}one{Prenos # datoteke.}two{Prenos # datotek.}few{Prenos # datotek.}other{Prenos # datotek.}}</translation> <translation id="7929962904089429003">Odpiranje menija</translation> <translation id="7942131818088350342">Izdelek <ph name="PRODUCT_NAME" /> je zastarel.</translation> <translation id="7947953824732555851">Sprejem in prijava</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Na nekaterih spletnih mestih je mogoče plačevati z zgoraj navedenimi podprtimi aplikacijami v napravi.</translation> <translation id="8816439037877937734">Aplikacija <ph name="APP_NAME" /> se bo odprla v Chromu. Če nadaljujete, se strinjate s Chromovimi <ph name="BEGIN_LINK1" />pogoji storitve<ph name="END_LINK1" /> in <ph name="BEGIN_LINK2" />pravilnikom o zasebnosti<ph name="END_LINK2" /> ter <ph name="BEGIN_LINK3" />obvestilom o zasebnosti za Google Račune, upravljane s Family Linkom<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Zaznamki</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Pri prenosu vsebine je prišlo do napake.</translation> <translation id="8840953339110955557">Ta stran se morda razlikuje od spletne različice.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb index 4a59df1..18c3347a 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Извештаји о коришћењу и отказивању</translation> <translation id="11221688409173367">Додирните дугме Почетак да бисте прегледали чланке изабране само за вас</translation> <translation id="1129510026454351943">Детаљи: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 преузимање на чекању.}one{# преузимање на чекању.}few{# преузимања на чекању.}other{# преузимања на чекању.}}</translation> <translation id="1145536944570833626">Избришите постојеће податке</translation> <translation id="1146678959555564648">Уђи у ВР</translation> <translation id="114721135501989771">Паметне Google функције</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Ажурирајте податке за пријављивање.</translation> <translation id="1974060860693918893">Напредне опције</translation> <translation id="1984937141057606926">Дозвољени, осим треће стране</translation> +<translation id="1987739130650180037">Дугме <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Прегледај</translation> <translation id="1993768208584545658"><ph name="SITE" /> жели да се упари</translation> <translation id="1994173015038366702">URL сајта</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Неважан меморијски простор</translation> <translation id="4002066346123236978">Наслов</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# ч}one{# ч}few{# ч}other{# ч}}</translation> <translation id="4042870126885713738">Приказивање предлога када се веб-адреса не разреши или када није могуће успоставити везу</translation> <translation id="4046123991198612571">Следећа песма</translation> <translation id="4048707525896921369">Сазнајте више о темама на веб-сајтовима без напуштања странице. Функција „Додирните за претрагу“ шаље реч и њен контекст у Google претрагу и приказује дефиниције, слике, резултате претраге и друге детаље. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Прешли сте у режим без архивирања.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Пре # минута}one{Пре # минута}few{Пре # минута}other{Пре # минута}}</translation> <translation id="4587589328781138893">Сајтови</translation> +<translation id="4594952190837476234">Ова офлајн страница је од <ph name="CREATION_TIME" /> и може да се разликује од онлајн верзије.</translation> <translation id="4605958867780575332">Ставка је уклоњена: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Отвори <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Овим управља твој родитељ</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Отворите нову картицу</translation> <translation id="4751476147751820511">Сензори за покрет или светло</translation> <translation id="4759238208242260848">Преузимања</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 преузимање је довршено.}one{# преузимање је довршено.}few{# преузимања су довршена.}other{# преузимања је довршено.}}</translation> <translation id="4766369052440583386">Уштеда података је укључена</translation> <translation id="4797039098279997504">Додирните да бисте се вратили на <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Име и презиме на картици</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Лозинке, историја и други садржај са свих уређаја</translation> <translation id="4961700429721424617">Одјављујете се са налога којим управља <ph name="MANAGED_DOMAIN" />. Тако бришете Chrome податке са овог уређаја, али ће подаци остати на Google налогу.</translation> <translation id="497421865427891073">Кретање унапред</translation> +<translation id="4988210275050210843">Преузима се датотека (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Странице</translation> <translation id="4996978546172906250">Дељење преко</translation> <translation id="5004339818306944878">Користите и до 60% мање података и убрзајте веб. Google сервери оптимизују странице које посећујете.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Обришите сачуване податке</translation> <translation id="5152843274749979095">Није инсталирана ниједна подржана апликација</translation> <translation id="5161254044473106830">Наслов је обавезан</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 преузимање није успело.}one{# преузимање није успело.}few{# преузимања нису успела.}other{# преузимања није успело.}}</translation> <translation id="5168917394043976756">Отвори фиоку за навигацију</translation> <translation id="5171365962177408781">Додирните да бисте учитали страницу нове картице и прегледали предложене чланке</translation> <translation id="5184329579814168207">Отвори у Chrome-у</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Најчешће посећиване странице ће се појавити овде</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB је доступно</translation> <translation id="5433691172869980887">Корисничко име је копирано</translation> +<translation id="543509235395288790">Преузимају се датотеке (<ph name="COUNT" />: <ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Прелазак на траку за адресу</translation> <translation id="5447201525962359567">Целокупан меморијски простор за сајт, укључујући колачиће и друге локално сачуване податке</translation> <translation id="5447765697759493033">Овај сајт се неће преводити</translation> +<translation id="545042621069398927">Преузимање се убрзава.</translation> <translation id="5456381639095306749">Преузми страницу</translation> <translation id="548278423535722844">Отворите у апликацији за мапе</translation> <translation id="5487521232677179737">Обриши податке</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Старије од 30 дана</translation> <translation id="5858741533101922242">Chrome не може да укључи Bluetooth адаптер</translation> <translation id="5860033963881614850">Искључено</translation> +<translation id="5864174910718532887">Детаљи: сортирано према називу сајта</translation> <translation id="5864419784173784555">Чека се друго преузимање...</translation> <translation id="5869522115854928033">Сачуване лозинке</translation> <translation id="5878455346526065919">Блокирај огласе са сајтова који приказују огласе који ометају</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Предлози за садржај</translation> <translation id="6277522088822131679">Дошло је до проблема при штампању странице. Пробајте поново.</translation> <translation id="6295158916970320988">Сви сајтови</translation> +<translation id="629730747756840877">Налог</translation> <translation id="6320088164292336938">Вибрација</translation> <translation id="6324034347079777476">Синхронизација Android система је онемогућена</translation> <translation id="6333140779060797560">Дељење преко <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Шифровање</translation> +<translation id="6341580099087024258">Питај где да сачуваш датотеке</translation> <translation id="6343192674172527289">Нису пронађена преузимања</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Желите ли да уклоните предлог из историје?</translation> +<translation id="6378173571450987352">Детаљи: сортирано према количини искоришћених података</translation> <translation id="6383961787135158834">Обриши меморију сајта…</translation> <translation id="6388207532828177975">Обриши и ресетуј</translation> <translation id="6393863479814692971">Chrome тражи дозволу да приступи камери и микрофону за овај сајт.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Додајте Google налог са странице Налози у апликацији Подешавања на уређају.</translation> <translation id="7274013316676448362">Сајт је блокиран</translation> <translation id="729975465115245577">Уређај нема апликацију за чување датотеке са лозинкама.</translation> +<translation id="7302081693174882195">Детаљи: сортирано према количини уштеђених података</translation> <translation id="7333031090786104871">Још увек додајемо претходни сајт</translation> <translation id="7352939065658542140">ВИДЕО</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Дели 1 изабрану ставку}one{Дели # изабрану ставку}few{Дели # изабране ставке}other{Дели # изабраних ставки}}</translation> <translation id="7359002509206457351">Приступ начинима плаћања</translation> <translation id="7366340029385295517">Пребацивање на <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Тип:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL адреса</translation> <translation id="7403691278183511381">Chrome доживљај првог покретања</translation> <translation id="741204030948306876">Да, омогући</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Прво питај</translation> <translation id="7423538860840206698">Читање привремене меморије је блокирано</translation> <translation id="7437998757836447326">Одјављивање из Chrome-а</translation> +<translation id="7444811645081526538">Још категорија</translation> <translation id="7445411102860286510">Дозволи сајтовима да аутоматски пуштају видео снимке са искљученим звуком (препоручено)</translation> <translation id="7453467225369441013">Одјавиће вас са већине сајтова. Неће вас одјавити са Google налога.</translation> <translation id="7454641608352164238">Нема довољно простора</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Уклони све</translation> <translation id="7882131421121961860">Историја није пронађена</translation> <translation id="7882806643839505685">Дозволи звук за одређени сајт.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Преузима се датотека.}one{Преузима се # датотека.}few{Преузимају се # датотеке.}other{Преузима се # датотека.}}</translation> <translation id="7929962904089429003">Отворите мени</translation> <translation id="7942131818088350342">Производ <ph name="PRODUCT_NAME" /> је застарео.</translation> <translation id="7947953824732555851">Прихвати и пријави ме</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">На неким веб-сајтовима можете да плаћате помоћу претходно наведених подржаних апликација за плаћање на уређају.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> ће се отворити у Chrome-у. Ако наставите, прихватате Chrome <ph name="BEGIN_LINK1" />услове коришћења услуге<ph name="END_LINK1" /> и <ph name="BEGIN_LINK2" />обавештење о приватности<ph name="END_LINK2" />, као и <ph name="BEGIN_LINK3" />обавештење о приватности за Google налоге којима се управља помоћу Family Link-а<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Обележивачи</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Дошло је до грешке при преузимању садржаја.</translation> <translation id="8840953339110955557">Ова страница може да се разликује од онлајн верзије.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb index 37af3c6..3b9e1be 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Användning och felrapporter</translation> <translation id="11221688409173367">Tryck på hemknappen om du vill se artiklar som valts ut för dig</translation> <translation id="1129510026454351943">Mer information: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 nedladdning väntar.}other{# nedladdningar väntar.}}</translation> <translation id="1145536944570833626">Radera befintlig data.</translation> <translation id="1146678959555564648">Kliv in i VR</translation> <translation id="114721135501989771">Få Google-teknik i Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Uppdatera dina inloggningsuppgifter.</translation> <translation id="1974060860693918893">Avancerat</translation> <translation id="1984937141057606926">Tillåts, men inte från tredje part</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> – knapp för <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Bläddra</translation> <translation id="1993768208584545658"><ph name="SITE" /> vill kopplas</translation> <translation id="1994173015038366702">Webbadress</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Oviktig lagring</translation> <translation id="4002066346123236978">Titel</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# tim}other{# tim}}</translation> <translation id="4042870126885713738">Visa förslag när det inte går att öppna en webbadress eller upprätta en anslutning</translation> <translation id="4046123991198612571">Nästa spår</translation> <translation id="4048707525896921369">Läs om olika ämnen på webbplatser utan att lämna sidan. Med funktionen Tryck för att söka skickas ett ord och dess kontext till Google Sök. Sedan visas definitioner, bilder, sökresultat och annan information. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Du surfar inkognito.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{för # minut sedan}other{för # minuter sedan}}</translation> <translation id="4587589328781138893">Webbplatser</translation> +<translation id="4594952190837476234">Den här offlinesidan sparades <ph name="CREATION_TIME" /> och kan skilja sig från onlineversionen.</translation> <translation id="4605958867780575332">Borttaget objekt: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Öppna <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Hanteras av din förälder</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Öppna en ny flik</translation> <translation id="4751476147751820511">Rörelse- eller ljussensorer</translation> <translation id="4759238208242260848">Nedladdningar</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 nedladdning har slutförts.}other{# nedladdningar har slutförts.}}</translation> <translation id="4766369052440583386">Databesparing är aktiverat</translation> <translation id="4797039098279997504">Tryck här om du vill återgå till <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Namn på kort</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Samma lösenord, historik med mera på alla dina enheter</translation> <translation id="4961700429721424617">Du håller på att logga ut från ett konto som hanteras av <ph name="MANAGED_DOMAIN" />. Åtgärden raderar din data i Chrome från den här enheten, men den finns kvar i Google-kontot.</translation> <translation id="497421865427891073">Fortsätt</translation> +<translation id="4988210275050210843">En fil laddas ned (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Sidor</translation> <translation id="4996978546172906250">Dela via</translation> <translation id="5004339818306944878">Använd upp till 60 procent mindre data och gör webben snabbare. Googles servrar optimerar de sidor du besöker.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Ta bort sparad data</translation> <translation id="5152843274749979095">Inga appar som stöds finns installerade</translation> <translation id="5161254044473106830">Titel krävs</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 nedladdning misslyckades.}other{# nedladdningar misslyckades.}}</translation> <translation id="5168917394043976756">Öppna navigeringspanelen</translation> <translation id="5171365962177408781">Tryck här om du vill läsa in sidan Ny flik och se artikelförslag</translation> <translation id="5184329579814168207">Öppna i Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Dina mest besökta sidor visas här</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB tillgängligt</translation> <translation id="5433691172869980887">Användarnamnet har kopierats</translation> +<translation id="543509235395288790"><ph name="COUNT" /> filer (<ph name="MEGABYTES" />) laddas ned.</translation> <translation id="5441522332038954058">Hoppa till adressfältet</translation> <translation id="5447201525962359567">All webbplatslagring, inklusive cookies och annan lokalt sparad data</translation> <translation id="5447765697759493033">Den här webbplatsen översätts inte</translation> +<translation id="545042621069398927">Nedladdningen görs snabbare.</translation> <translation id="5456381639095306749">Ladda ned sida</translation> <translation id="548278423535722844">Öppna i kartapp</translation> <translation id="5487521232677179737">Rensa data</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Äldre än 30 dagar</translation> <translation id="5858741533101922242">Det gick inte att aktivera Bluetooth-adaptern i Chrome</translation> <translation id="5860033963881614850">Av</translation> +<translation id="5864174910718532887">Mer information: Sorterad efter webbplatsnamn</translation> <translation id="5864419784173784555">Väntar på nästa nedladdning …</translation> <translation id="5869522115854928033">Sparade lösenord</translation> <translation id="5878455346526065919">Blockera annonser från webbplatser som brukar visa påträngande annonser</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Förslag på innehåll</translation> <translation id="6277522088822131679">Det gick inte att skriva ut sidan. Försök igen.</translation> <translation id="6295158916970320988">Alla webbplatser</translation> +<translation id="629730747756840877">Konto</translation> <translation id="6320088164292336938">Vibration</translation> <translation id="6324034347079777476">Synkronisering av Android-system har inaktiverats</translation> <translation id="6333140779060797560">Dela via <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Kryptering</translation> +<translation id="6341580099087024258">Fråga var filerna ska sparas</translation> <translation id="6343192674172527289">Inga nedladdningar hittades</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 och <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> till}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 och <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> till}}</translation> <translation id="6364438453358674297">Vill du ta bort förslaget från historiken?</translation> +<translation id="6378173571450987352">Mer information: Sorterad efter dataförbrukning</translation> <translation id="6383961787135158834">Rensa webbplatslagring …</translation> <translation id="6388207532828177975">Ta bort och återställ</translation> <translation id="6393863479814692971">Du behöver ge Chrome behörighet att använda kameran och mikrofonen på den här webbplatsen.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Lägg till ett Google-konto från kontosidan i appen Inställningar på enheten.</translation> <translation id="7274013316676448362">Blockerad webbplats</translation> <translation id="729975465115245577">Det finns ingen app som kan spara lösenordsfilen på enheten.</translation> +<translation id="7302081693174882195">Mer information: Sorterad efter databesparing</translation> <translation id="7333031090786104871">Processen pågår fortfarande för den förra webbplatsen</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Dela 1 markerat objekt}other{Dela # markerade objekt}}</translation> <translation id="7359002509206457351">Åtkomst till betalningsmetoder</translation> <translation id="7366340029385295517">Castar till <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Typ:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">Webbadress</translation> <translation id="7403691278183511381">Första körningen av Chrome</translation> <translation id="741204030948306876">Ja</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Fråga först</translation> <translation id="7423538860840206698">Läsbehörighet till Urklipp har nekats</translation> <translation id="7437998757836447326">Logga ut från Chrome</translation> +<translation id="7444811645081526538">Fler kategorier</translation> <translation id="7445411102860286510">Tillåt att webbplatser automatiskt spelar upp videor utan ljud (rekommenderas)</translation> <translation id="7453467225369441013">Du loggas ut från de flesta webbplatser. Du loggas inte ut från Google-kontot.</translation> <translation id="7454641608352164238">Utrymmet räcker inte</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Ta bort alla</translation> <translation id="7882131421121961860">Ingen historik hittades</translation> <translation id="7882806643839505685">Tillåt ljud för en webbplats.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{En fil laddas ned.}other{# filer laddas ned.}}</translation> <translation id="7929962904089429003">Öppna menyn</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> är inaktuell.</translation> <translation id="7947953824732555851">Godkänn och logga in</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">På vissa webbplatser kan du betala med ovanstående betalningsappar som stöds på enheten.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> öppnas i Chrome. Genom att fortsätta godkänner du Chromes <ph name="BEGIN_LINK1" />användarvillkor<ph name="END_LINK1" /> och <ph name="BEGIN_LINK2" />sekretesspolicy<ph name="END_LINK2" /> samt <ph name="BEGIN_LINK3" />sekretessmeddelandet för Google-konton som hanteras via Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Bokmärken</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Ett fel uppstod när innehållet skulle laddas ned.</translation> <translation id="8840953339110955557">Sidan kan skilja sig från onlineversionen.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb index 3635425..d7b813e8 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Ripoti za matumizi na za kuacha kufanya kazi</translation> <translation id="11221688409173367">Gusa kitufe cha ukurasa wa mwanzo ili uone makala yaliyochaguliwa mahususi kwa ajili yako</translation> <translation id="1129510026454351943">Maelezo: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{Inasubiri kupakua faili 1.}other{Inasubiri kupakua faili #.}}</translation> <translation id="1145536944570833626">Futa data iliyopo.</translation> <translation id="1146678959555564648">Tumia hali ya VR</translation> <translation id="114721135501989771">Pata Google mahiri kwenye Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Tafadhali sasisha maelezo yako ya kuingia katika akaunti.</translation> <translation id="1974060860693918893">Mipangilio ya kina</translation> <translation id="1984937141057606926">Inaruhusiwa, isipokuwa vidakuzi vingine</translation> +<translation id="1987739130650180037">Kitufe cha <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Vinjari</translation> <translation id="1993768208584545658"><ph name="SITE" /> inataka kuoanisha</translation> <translation id="1994173015038366702">URL ya Tovuti</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">Hifadhi ambayo si muhimu</translation> <translation id="4002066346123236978">Kichwa</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{Saa #}other{Saa #}}</translation> <translation id="4042870126885713738">Onyesha mapendekezo wakati anwani ya wavuti inaposhindwa kutatuliwa au muunganisho ukiwa hauwezi kufanyika</translation> <translation id="4046123991198612571">Wimbo unaofuata</translation> <translation id="4048707525896921369">Pata maelezo kuhusu mada kwenye tovuti bila kuondoka kwenye ukurasa. Kipengele cha Gusa ili Utafute hutuma neno na muktadha wake kwenye huduma ya Tafuta na Google na kuonyesha ufafanuzi, picha, matokeo ya utafutaji na maelezo mengine. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Unavinjari katika hali fiche.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{Dakika # iliyopita}other{Dakika # zilizopita}}</translation> <translation id="4587589328781138893">Tovuti</translation> +<translation id="4594952190837476234">Ukurasa huu wa nje ya mtandao umetoka <ph name="CREATION_TIME" /> na huenda ukatofautiana na toleo la mtandaoni.</translation> <translation id="4605958867780575332">Kipengee kilichoondolewa: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Fungua <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Inadhibitiwa na wazazi wako</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Fungua kichupo kipya</translation> <translation id="4751476147751820511">Vitambuzi vya mwendo au mwangaza</translation> <translation id="4759238208242260848">Vipakuliwa</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{Imemaliza kupakua faili 1.}other{Imemaliza kupakua faili #.}}</translation> <translation id="4766369052440583386">Kiokoa Data kimewashwa</translation> <translation id="4797039098279997504">Gusa ili urudi kwenye <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Jina kwenye kadi</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Manenosiri yako, historia na zaidi katika vifaa vyote</translation> <translation id="4961700429721424617">Unaondoka kwenye akaunti inayodhibitiwa na <ph name="MANAGED_DOMAIN" />. Hatua hii itafuta data yako ya Chrome kwenye kifaa hiki, lakini data yako itasalia katika akaunti yako ya Google.</translation> <translation id="497421865427891073">Nenda mbele</translation> +<translation id="4988210275050210843">Inapakua faili (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Kurasa</translation> <translation id="4996978546172906250">Shiriki kupitia</translation> <translation id="5004339818306944878">Tumia data chache zaidi kwa hadi asilimia 60 na uongeze kasi ya wavuti. Seva za Google zitaboresha kurasa unazotembelea.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Futa data iliyohifadhiwa</translation> <translation id="5152843274749979095">Hakuna programu zinazotumika zimesakinishwa</translation> <translation id="5161254044473106830">Kichwa kinahitajika</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{Imeshindwa kupakua 1.}other{Imeshindwa kupakua faili #.}}</translation> <translation id="5168917394043976756">Fungua droo ya kusogeza</translation> <translation id="5171365962177408781">Gusa ili upakie ukurasa wa kichupo kipya na uone makala yanayopendekezwa</translation> <translation id="5184329579814168207">Fungulia katika Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Kurasa zako zilizotembelewa sana zitaonekana hapa</translation> <translation id="5424588387303617268">GB <ph name="GIGABYTES" /> zinapatikana</translation> <translation id="5433691172869980887">Jina la mtumiaji limenakiliwa</translation> +<translation id="543509235395288790">Inapakua faili <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Rudi kwenye sehemu ya anwani</translation> <translation id="5447201525962359567">Hifadhi yote ya tovuti, ikiwa ni pamoja na vidakuzi na data nyingine iliyohifadhiwa ndani</translation> <translation id="5447765697759493033">Tovuti hii haitatafsiriwa</translation> +<translation id="545042621069398927">Inaongeza kasi ya kupakua faili yako.</translation> <translation id="5456381639095306749">Pakua ukurasa</translation> <translation id="548278423535722844">Fungua katika programu ya ramani</translation> <translation id="5487521232677179737">Futa data</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Iliyohifadhiwa kwa zaidi ya siku 30</translation> <translation id="5858741533101922242">Chrome imeshindwa kuwasha adapta ya Bluetooth</translation> <translation id="5860033963881614850">Kimezimwa</translation> +<translation id="5864174910718532887">Maelezo: Imepangwa kulingana na jina la tovuti</translation> <translation id="5864419784173784555">Inasubiri kipakuliwa kingine…</translation> <translation id="5869522115854928033">Manenosiri yaliyohifadhiwa</translation> <translation id="5878455346526065919">Zuia matangazo kutoka kwenye tovuti zinazoonyesha matangazo yanayokatiza matumizi</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Mapendekezo ya maudhui</translation> <translation id="6277522088822131679">Kulikuwa na tatizo katika kuchapisha ukurasa. Tafadhali jaribu tena.</translation> <translation id="6295158916970320988">Tovuti zote</translation> +<translation id="629730747756840877">Akaunti</translation> <translation id="6320088164292336938">Tetema</translation> <translation id="6324034347079777476">Kipengele cha usawazishaji wa mfumo wa Android kimezimwa</translation> <translation id="6333140779060797560">Shiriki kupitia <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Usimbaji fiche</translation> +<translation id="6341580099087024258">Iulize ambapo itahifadhi faili</translation> <translation id="6343192674172527289">Hakuna vipakuliwa vilivyopatikana</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 na <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> zaidi}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 na <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> zaidi}}</translation> <translation id="6364438453358674297">Je, ungependa kuondoa pendekezo kwenye historia?</translation> +<translation id="6378173571450987352">Maelezo: Imepangwa kulingana na kiasi cha data inayotumiwa</translation> <translation id="6383961787135158834">Futa Hifadhi ya Tovuti...</translation> <translation id="6388207532828177975">Futa na uweke upya</translation> <translation id="6393863479814692971">Chrome inahitaji ruhusa ya kufikia kamera yako kwa ajili ya tovuti hii.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Ongeza Akaunti ya Google kutoka kwenye ukurasa wa Akaunti katika programu ya Mipangilio ya kifaa chako.</translation> <translation id="7274013316676448362">Tovuti imezuiwa</translation> <translation id="729975465115245577">Kifaa chako hakina programu ya kuhifadhi faili ya manenosiri.</translation> +<translation id="7302081693174882195">Maelezo: Imepangwa kulingana na data iliyohifadhiwa</translation> <translation id="7333031090786104871">Bado inaongeza tovuti ya awali</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Shiriki kipengee 1 kilichochaguliwa}other{Shiriki vipengee # vilivyochaguliwa}}</translation> <translation id="7359002509206457351">Ufikiaji wa njia za kulipa</translation> <translation id="7366340029385295517">Inatuma kwenye <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Aina:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Hali ya Utekelezaji wa Kwanza wa Chrome</translation> <translation id="741204030948306876">Ndiyo, ninakubali</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Uliza kwanza</translation> <translation id="7423538860840206698">Imezuiwa kusoma ubao wa kunakili</translation> <translation id="7437998757836447326">Ondoka kwenye Chrome</translation> +<translation id="7444811645081526538">Aina zingine</translation> <translation id="7445411102860286510">Ruhusu tovuti zicheze video kiotomatiki bila sauti (inapendekezwa)</translation> <translation id="7453467225369441013">Hukuondoa kwenye akaunti za tovuti nyingi. Hutaondolewa kwenye Akaunti ya Google.</translation> <translation id="7454641608352164238">Nafasi haitoshi</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Ondoa yote</translation> <translation id="7882131421121961860">Hakuna historia iliyopatikana</translation> <translation id="7882806643839505685">Ruhusu sauti katika tovuti mahususi.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Inapakua faili.}other{Inapakua faili #.}}</translation> <translation id="7929962904089429003">Fungua menyu</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> imepitwa na wakati.</translation> <translation id="7947953824732555851">Kubali na uingie</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Kwenye baadhi ya tovuti, unaweza kulipa kwa programu za malipo zinazotumika zilizo hapo juu kwenye kifaa chako.</translation> <translation id="8816439037877937734">Itafungua <ph name="APP_NAME" /> katika Chrome. Kwa kuendelea, unakubali <ph name="BEGIN_LINK1" />Sheria na Masharti<ph name="END_LINK1" /> na <ph name="BEGIN_LINK2" />Ilani ya Faragha<ph name="END_LINK2" />, na <ph name="BEGIN_LINK3" />Ilani ya Faragha ya Akaunti za Google Zinazodhibitiwa na Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Alamisho</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Hitilafu imetokea wakati wa kupakua maudhui.</translation> <translation id="8840953339110955557">Ukurasa huu huenda ukatofautiana na toleo la mtandaoni.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_th.xtb b/chrome/android/java/strings/translations/android_chrome_strings_th.xtb index bec3f75..1e6ec6e 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_th.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_th.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">รายงานการใช้งานและข้อขัดข้อง</translation> <translation id="11221688409173367">แตะปุ่มหน้าแรกเพื่อดูบทความที่เลือกไว้ให้คุณโดยเฉพาะ</translation> <translation id="1129510026454351943">รายละเอียด: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{การดาวน์โหลดที่รอดำเนินการ 1 รายการ}other{การดาวน์โหลดที่รอดำเนินการ # รายการ}}</translation> <translation id="1145536944570833626">ลบข้อมูลที่มีอยู่</translation> <translation id="1146678959555564648">เข้าสู่ VR</translation> <translation id="114721135501989771">ใช้ฟีเจอร์เจ๋งๆ จาก Google ใน Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">โปรดอัปเดตรายละเอียดการลงชื่อเข้าใช้ของคุณ</translation> <translation id="1974060860693918893">ขั้นสูง</translation> <translation id="1984937141057606926">อนุญาต ยกเว้นบุคคลที่สาม</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> ปุ่ม<ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">เล่นเน็ต</translation> <translation id="1993768208584545658"><ph name="SITE" /> ต้องการจับคู่</translation> <translation id="1994173015038366702">URL ของเว็บไซต์</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">พื้นที่เก็บข้อมูลที่ไม่สำคัญ</translation> <translation id="4002066346123236978">ชื่อ</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# ชม.}other{# ชม.}}</translation> <translation id="4042870126885713738">แสดงคำแนะนำเมื่อไม่สามารถระบุที่อยู่เว็บหรือไม่สามารถเชื่อมต่อได้</translation> <translation id="4046123991198612571">แทร็กถัดไป</translation> <translation id="4048707525896921369">ดูข้อมูลเกี่ยวกับหัวข้อในเว็บไซต์โดยไม่ต้องออกจากหน้า แตะเพื่อค้นหาจะส่งคำและบริบทที่อยู่ข้างเคียงไปยัง Google Search เพื่อแสดงคำจำกัดความ รูปภาพ ผลการค้นหา และรายละเอียดอื่นๆ @@ -402,6 +405,7 @@ <translation id="4581964774250883625">คุณเข้าสู่โหมดไม่ระบุตัวตนแล้ว</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# นาทีที่ผ่านมา}other{# นาทีที่ผ่านมา}}</translation> <translation id="4587589328781138893">เว็บไซต์</translation> +<translation id="4594952190837476234">หน้าเว็บออฟไลน์นี้สร้างเมื่อวันที่ <ph name="CREATION_TIME" /> และอาจแตกต่างไปจากเวอร์ชันออนไลน์</translation> <translation id="4605958867780575332">รายการที่นำออก: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">เปิด <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">มีการจัดการโดยผู้ปกครอง</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">เปิดแท็บใหม่</translation> <translation id="4751476147751820511">เซ็นเซอร์จับความเคลื่อนไหวหรือเซ็นเซอร์แสง</translation> <translation id="4759238208242260848">ดาวน์โหลด</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{การดาวน์โหลด 1 รายการเสร็จสมบูรณ์}other{การดาวน์โหลด # รายการเสร็จสมบูรณ์}}</translation> <translation id="4766369052440583386">โปรแกรมประหยัดอินเทอร์เน็ตเปิดอยู่</translation> <translation id="4797039098279997504">แตะเพื่อกลับไปยัง <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">ชื่อบนบัตร</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">รหัสผ่าน ประวัติการเข้าชม และอื่นๆ ในอุปกรณ์ทุกเครื่อง</translation> <translation id="4961700429721424617">คุณกำลังออกจากระบบบัญชีที่จัดการโดย <ph name="MANAGED_DOMAIN" /> การออกจากระบบจะลบข้อมูล Chrome ออกจากอุปกรณ์เครื่องนี้ แต่ข้อมูลจะยังคงอยู่ในบัญชี Google</translation> <translation id="497421865427891073">ไปข้างหน้า</translation> +<translation id="4988210275050210843">กำลังดาวน์โหลดไฟล์ (<ph name="MEGABYTES" />)</translation> <translation id="4988526792673242964">หน้า</translation> <translation id="4996978546172906250">แชร์ผ่าน</translation> <translation id="5004339818306944878">ใช้เน็ตมือถือน้อยลงถึง 60% และท่องเว็บได้เร็วขึ้น เซิร์ฟเวอร์ Google จะเพิ่มประสิทธิภาพหน้าที่คุณเข้าชม</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">ล้างข้อมูลที่เก็บไว้</translation> <translation id="5152843274749979095">ไม่มีแอปที่รองรับติดตั้งอยู่</translation> <translation id="5161254044473106830">ต้องระบุชื่อ</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{การดาวน์โหลดล้มเหลว 1 รายการ}other{การดาวน์โหลดล้มเหลว # รายการ}}</translation> <translation id="5168917394043976756">เปิดลิ้นชักการนำทาง</translation> <translation id="5171365962177408781">แตะเพื่อโหลดหน้าแท็บใหม่และดูบทความที่แนะนำ</translation> <translation id="5184329579814168207">เปิดใน Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">หน้าที่มีการเข้าชมมากที่สุดของคุณจะปรากฏที่นี่</translation> <translation id="5424588387303617268">ว่าง <ph name="GIGABYTES" /> GB</translation> <translation id="5433691172869980887">คัดลอกชื่อผู้ใช้แล้ว</translation> +<translation id="543509235395288790">กำลังดาวน์โหลด <ph name="COUNT" /> ไฟล์ (<ph name="MEGABYTES" />)</translation> <translation id="5441522332038954058">ข้ามไปยังแถบที่อยู่เว็บ</translation> <translation id="5447201525962359567">พื้นที่เก็บข้อมูลเว็บไซต์ทั้งหมด รวมถึงคุกกี้และข้อมูลอื่นๆ ที่เก็บไว้ในเครื่อง</translation> <translation id="5447765697759493033">ระบบจะไม่แปลไซต์นี้</translation> +<translation id="545042621069398927">กำลังเพิ่มความเร็วในการดาวน์โหลด</translation> <translation id="5456381639095306749">ดาวน์โหลดหน้า</translation> <translation id="548278423535722844">เปิดในแอปแผนที่</translation> <translation id="5487521232677179737">ล้างข้อมูล</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">เกิน 30 วัน</translation> <translation id="5858741533101922242">Chrome ไม่สามารถเปิดอะแดปเตอร์บลูทูธ</translation> <translation id="5860033963881614850">ปิด</translation> +<translation id="5864174910718532887">รายละเอียด: จัดเรียงตามชื่อเว็บไซต์</translation> <translation id="5864419784173784555">กำลังรอการดาวน์โหลดรายการอื่น…</translation> <translation id="5869522115854928033">รหัสผ่านที่บันทึกไว้</translation> <translation id="5878455346526065919">บล็อกโฆษณาจากไซต์ที่มักแสดงโฆษณาที่แทรก</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">การแนะนำเนื้อหา</translation> <translation id="6277522088822131679">เกิดปัญหาในการพิมพ์หน้านี้ โปรดลองอีกครั้ง</translation> <translation id="6295158916970320988">ไซต์ทั้งหมด</translation> +<translation id="629730747756840877">บัญชี</translation> <translation id="6320088164292336938">สั่น</translation> <translation id="6324034347079777476">ปิดใช้การซิงค์ระบบ Android อยู่</translation> <translation id="6333140779060797560">แชร์ผ่าน <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">การเข้ารหัส</translation> +<translation id="6341580099087024258">ถามว่าจะให้บันทึกไฟล์ไว้ที่ใด</translation> <translation id="6343192674172527289">ไม่พบการดาวน์โหลด</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 และอีก <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> แห่ง}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 และอีก <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> แห่ง}}</translation> <translation id="6364438453358674297">ต้องการนำคำแนะนำออกจากประวัติการเข้าชมใช่ไหม</translation> +<translation id="6378173571450987352">รายละเอียด: จัดเรียงตามปริมาณเน็ตมือถือที่ใช้</translation> <translation id="6383961787135158834">ล้างที่เก็บข้อมูลไซต์…</translation> <translation id="6388207532828177975">ล้างข้อมูลและรีเซ็ต</translation> <translation id="6393863479814692971">Chrome ต้องการสิทธิ์เข้าถึงไมโครโฟนและกล้องถ่ายรูปของคุณสำหรับไซต์นี้</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">เพิ่มบัญชี Google จากหน้า "บัญชี" ในแอปการตั้งค่าของอุปกรณ์</translation> <translation id="7274013316676448362">เว็บไซต์ที่ถูกบล็อก</translation> <translation id="729975465115245577">อุปกรณ์ของคุณไม่มีแอปไว้จัดเก็บไฟล์รหัสผ่าน</translation> +<translation id="7302081693174882195">รายละเอียด: จัดเรียงตามปริมาณเน็ตมือถือที่ประหยัดได้</translation> <translation id="7333031090786104871">ยังเพิ่มไซต์ก่อนหน้าอยู่</translation> <translation id="7352939065658542140">วิดีโอ</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{แชร์ 1 รายการที่เลือก}other{แชร์ # รายการที่เลือก}}</translation> <translation id="7359002509206457351">เข้าถึงวิธีการชำระเงิน</translation> <translation id="7366340029385295517">กำลังส่งไปยัง <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">ประเภท:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" /></translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">ประสบการณ์กับ First Run บน Chrome</translation> <translation id="741204030948306876">ได้สิ ตกลง</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">ถามก่อน</translation> <translation id="7423538860840206698">บล็อกไม่ให้อ่านคลิปบอร์ด</translation> <translation id="7437998757836447326">ออกจากระบบ Chrome</translation> +<translation id="7444811645081526538">หมวดหมู่อื่นๆ</translation> <translation id="7445411102860286510">อนุญาตให้เว็บไซต์เล่นวิดีโอที่ปิดเสียงโดยอัตโนมัติ (แนะนำ)</translation> <translation id="7453467225369441013">นำคุณออกจากระบบของเว็บไซต์ส่วนใหญ่ แต่คุณจะไม่ออกจากระบบบัญชี Google</translation> <translation id="7454641608352164238">พื้นที่ว่างไม่พอ</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">ลบทั้งหมด</translation> <translation id="7882131421121961860">ไม่พบประวัติ</translation> <translation id="7882806643839505685">อนุญาตให้ไซต์ที่ต้องการเล่นเสียงได้</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{กำลังดาวน์โหลดไฟล์}other{กำลังดาวน์โหลด # ไฟล์}}</translation> <translation id="7929962904089429003">เปิดเมนู</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> ล้าสมัย</translation> <translation id="7947953824732555851">ยอมรับและลงชื่อเข้าใช้</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">ในบางเว็บไซต์ คุณสามารถชำระเงินด้วยแอปชำระเงินที่รองรับด้านบนในอุปกรณ์ของคุณ</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> จะเปิดขึ้นใน Chrome การดำเนินการต่อแสดงว่าคุณยอมรับ<ph name="BEGIN_LINK1" />ข้อกำหนดในการให้บริการ<ph name="END_LINK1" />และ<ph name="BEGIN_LINK2" />ประกาศเกี่ยวกับนโยบายความเป็นส่วนตัว<ph name="END_LINK2" />ของ Chrome รวมถึง<ph name="BEGIN_LINK3" />ประกาศเกี่ยวกับนโยบายความเป็นส่วนตัวสำหรับบัญชี Google ที่จัดการด้วย Family Link<ph name="END_LINK3" /></translation> <translation id="8820817407110198400">บุ๊กมาร์ก</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">เกิดข้อผิดพลาดขณะดาวน์โหลดเนื้อหา</translation> <translation id="8840953339110955557">หน้าเว็บนี้อาจแตกต่างไปจากเวอร์ชันที่ออนไลน์</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb index 254cfb6..1788d506 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Kullanım ve kilitlenme raporları</translation> <translation id="11221688409173367">Özellikle size özel seçilen makaleleri görüntülemek için ana ekran düğmesine dokunun</translation> <translation id="1129510026454351943">Ayrıntılar: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 indirme işlemi beklemede.}other{# indirme işlemi beklemede.}}</translation> <translation id="1145536944570833626">Mevcut verileri silin.</translation> <translation id="1146678959555564648">VR'ye Gir</translation> <translation id="114721135501989771">Chrome'da Google'ın akıllı yaklaşımını elde edin</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Lütfen oturum açma ayrıntılarınızı güncelleyin.</translation> <translation id="1974060860693918893">Gelişmiş</translation> <translation id="1984937141057606926">Üçüncü taraf hariç izin verildi</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> düğmesi</translation> <translation id="1989112275319619282">Göz at</translation> <translation id="1993768208584545658"><ph name="SITE" /> eşlenmek istiyor</translation> <translation id="1994173015038366702">Site URL'si</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / ?</translation> <translation id="3997476611815694295">Önemli olmayan depolama alanı</translation> <translation id="4002066346123236978">Başlık</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# sa.}other{# sa.}}</translation> <translation id="4042870126885713738">Bir web adresi çözümlenemezse veya bağlantı yapılamazsa öneriler göster</translation> <translation id="4046123991198612571">Sonraki parça</translation> <translation id="4048707525896921369">Sayfadan ayrılmadan web siteleriyle ilgili konuları öğrenin. Dokun ve Ara özelliği seçilen kelimeyi, çevresindeki içerikle birlikte Google Arama'ya gönderir ve karşılığında ilgili tanımlar, resimler, arama sonuçları ve diğer ayrıntıları döndürür. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Gizli moda geçtiniz.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# dakika önce}other{# dakika önce}}</translation> <translation id="4587589328781138893">Siteler</translation> +<translation id="4594952190837476234">Bu çevrimdışı sayfa <ph name="CREATION_TIME" /> tarihli olup web'deki sürümden farklı olabilir.</translation> <translation id="4605958867780575332">Öğe kaldırıldı: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> APK'sını aç</translation> <translation id="4645575059429386691">Ebeveyniniz tarafından yönetiliyor</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Yeni sekme açar</translation> <translation id="4751476147751820511">Hareket veya ışık sensörleri</translation> <translation id="4759238208242260848">İndirilenler</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 indirme işlemi tamamlandı.}other{# indirme işlemi tamamlandı.}}</translation> <translation id="4766369052440583386">Veri Tasarrufu açık</translation> <translation id="4797039098279997504"><ph name="URL_OF_THE_CURRENT_TAB" /> adresine dönmek için dokunun</translation> <translation id="4807098396393229769">Kartın üzerindeki ad</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Tüm cihazlardaki şifreleriniz, geçmişiniz ve diğer öğeler</translation> <translation id="4961700429721424617"><ph name="MANAGED_DOMAIN" /> tarafından yönetilen bir hesabın oturumunu kapatıyorsunuz. Bu işlemle Chrome verileriniz bu cihazdan silinir, ancak Google Hesabınızda kalmaya devam eder.</translation> <translation id="497421865427891073">İlerle</translation> +<translation id="4988210275050210843">Dosya indiriliyor (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Sayfalar</translation> <translation id="4996978546172906250">Paylaşım yöntemi:</translation> <translation id="5004339818306944878">%60'a kadar daha az veri kullanın ve web'i hızlandırın. Google sunucuları, ziyaret ettiğiniz sayfaları optimize eder.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Depolanmış verileri sil</translation> <translation id="5152843274749979095">Desteklenen yüklü uygulama yok</translation> <translation id="5161254044473106830">Başlık gerekiyor</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 indirme işlemi başarısız oldu.}other{# indirme işlemi başarısız oldu.}}</translation> <translation id="5168917394043976756">Gezinme çekmecesini aç</translation> <translation id="5171365962177408781">Yeni sekme sayfasını yüklemek ve önerilen makaleleri görüntülemek için dokunun</translation> <translation id="5184329579814168207">Chrome'da aç</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">En çok ziyaret ettiğiniz sayfalar burada görünecektir</translation> <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB kullanılabilir</translation> <translation id="5433691172869980887">Kullanıcı adı kopyalandı</translation> +<translation id="543509235395288790"><ph name="COUNT" /> dosya indiriliyor (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Adres çubuğuna gider</translation> <translation id="5447201525962359567">Çerezler ve yerel olarak depolanmış diğer veriler de dahil olmak üzere tüm site depolama alanı</translation> <translation id="5447765697759493033">Bu site çevrilmeyecek</translation> +<translation id="545042621069398927">İndirme işleminiz hızlandırılıyor.</translation> <translation id="5456381639095306749">Sayfayı indir</translation> <translation id="548278423535722844">Haritalar uygulamasında aç</translation> <translation id="5487521232677179737">Verileri temizle</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">30 günden daha eski</translation> <translation id="5858741533101922242">Chrome, Bluetooth adaptörünü açamıyor</translation> <translation id="5860033963881614850">Kapalı</translation> +<translation id="5864174910718532887">Ayrıntılar: Site adına göre sıralı</translation> <translation id="5864419784173784555">Başka bir indirme işlemi bekleniyor…</translation> <translation id="5869522115854928033">Kayıtlı şifreler</translation> <translation id="5878455346526065919">Araya giren reklamlar gösterme eğiliminde olan sitelerden reklamları engelle</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">İçerik önerileri</translation> <translation id="6277522088822131679">Sayfa yazdırılırken bir sorun oluştu. Lütfen tekrar deneyin.</translation> <translation id="6295158916970320988">Tüm siteler</translation> +<translation id="629730747756840877">Hesap</translation> <translation id="6320088164292336938">Titreşim</translation> <translation id="6324034347079777476">Android sistem senkronizasyonu devre dışı</translation> <translation id="6333140779060797560">Paylaşım yöntemi: <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Şifreleme</translation> +<translation id="6341580099087024258">Dosyaların kaydedileceği yeri sor</translation> <translation id="6343192674172527289">İndirilen herhangi bir şey bulunmadı</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 ve <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> adres daha}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 ve <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> adres daha}}</translation> <translation id="6364438453358674297">Öneri geçmişten kaldırılsın mı?</translation> +<translation id="6378173571450987352">Ayrıntılar: Kullanılan veri miktarına göre sıralı</translation> <translation id="6383961787135158834">Site Depolama Alanını Sil…</translation> <translation id="6388207532828177975">Temizle ve sıfırla</translation> <translation id="6393863479814692971">Chrome'un bu sitede kameranıza ve mikrofonunuza erişmesi için izin gerekiyor.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Cihazınızın Ayarlar uygulamasındaki Hesaplar sayfasından bir Google Hesabı ekleyin.</translation> <translation id="7274013316676448362">Engellenmiş site</translation> <translation id="729975465115245577">Cihazınızda şifreler dosyasını depolayacak bir uygulama yok.</translation> +<translation id="7302081693174882195">Ayrıntılar: Tasarruf edilen veri miktarına göre sıralı</translation> <translation id="7333031090786104871">Önceki siteyi ekleme işlemi devam ediyor.</translation> <translation id="7352939065658542140">VİDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{1 seçili öğeyi paylaş}other{# seçili öğeyi paylaş}}</translation> <translation id="7359002509206457351">Ödeme yöntemlerine erişme</translation> <translation id="7366340029385295517"><ph name="SCREEN_NAME" /> ekranına yayınlanıyor</translation> <translation id="7375125077091615385">Tür:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Chrome İlk Çalıştırma Deneyimi</translation> <translation id="741204030948306876">Evet, istiyorum</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Önce sor</translation> <translation id="7423538860840206698">Pano okuma engellendi</translation> <translation id="7437998757836447326">Chrome oturumunu kapatma</translation> +<translation id="7444811645081526538">Diğer kategoriler</translation> <translation id="7445411102860286510">Sitelerin, sesi kapatılmış videoları otomatik olarak oynatmasına izin ver (önerilen)</translation> <translation id="7453467225369441013">Çoğu sitedeki oturumunuz kapatılır. Google Hesabınızdaki oturumunuz kapatılmaz.</translation> <translation id="7454641608352164238">Yeterli alan yok</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Tümünü kaldır</translation> <translation id="7882131421121961860">Geçmiş bulunamadı</translation> <translation id="7882806643839505685">Belirli bir site için sese izin verin.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Dosya indiriliyor.}other{# dosya indiriliyor.}}</translation> <translation id="7929962904089429003">Menüyü açar</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> güncel değil.</translation> <translation id="7947953824732555851">Kabul et ve oturum aç</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Bazı web sitelerinde, yukarıdaki desteklenen ödeme uygulamalarıyla cihazınızdan ödeme yapabilirsiniz.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> Chrome'da açılacak. Devam ederek Chrome'un <ph name="BEGIN_LINK1" />Hizmet Şartları<ph name="END_LINK1" />'nı, <ph name="BEGIN_LINK2" />Gizlilik Uyarısı<ph name="END_LINK2" />'nı ve <ph name="BEGIN_LINK3" />Family Link ile Yönetilen Google Hesapları için Gizlilik Uyarısı<ph name="END_LINK3" />'nı kabul etmiş olursunuz.</translation> <translation id="8820817407110198400">Favoriler</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">İçerik indirilirken bir hata oluştu.</translation> <translation id="8840953339110955557">Bu sayfa, web'deki sürümden farklı olabilir.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb b/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb index 38cec1e..49f07688 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Звіти про використання й аварійне завершення роботи</translation> <translation id="11221688409173367">Торкніться кнопки головного екрана, щоб переглянути статті, підібрані спеціально для вас</translation> <translation id="1129510026454351943">Деталі. <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{Очікується 1 завантаження.}one{Очікується # завантаження.}few{Очікується # завантаження.}many{Очікується # завантажень.}other{Очікується # завантаження.}}</translation> <translation id="1145536944570833626">Видалити наявні дані.</translation> <translation id="1146678959555564648">Увійти у VR-режим</translation> <translation id="114721135501989771">Розумні функції в Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Оновіть свої дані для входу.</translation> <translation id="1974060860693918893">Розширені</translation> <translation id="1984937141057606926">Заборонено лише сторонні файли cookie</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" />, кнопка <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Переглянути</translation> <translation id="1993768208584545658">Сайт <ph name="SITE" /> хоче підключитися до пристрою</translation> <translation id="1994173015038366702">URL-адреса сайту</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Неважливі дані</translation> <translation id="4002066346123236978">Назва</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# год}one{# год}few{# год}many{# год}other{# год}}</translation> <translation id="4042870126885713738">Показувати пропозиції, коли неможливо перейти за веб-адресою чи не вдається встановити з’єднання</translation> <translation id="4046123991198612571">Наступна композиція</translation> <translation id="4048707525896921369">Дізнавайтеся більше про теми на веб-сайтах, не залишаючи сторінку. Функція "Торкніться, щоб шукати" надсилає слово та його контекст у Пошук Google і повертає визначення, зображення, результати пошуку й інші дані. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Ви перейшли в режим анонімного перегляду.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# хвилину тому}one{# хвилину тому}few{# хвилини тому}many{# хвилин тому}other{# хвилини тому}}</translation> <translation id="4587589328781138893">Сайти</translation> +<translation id="4594952190837476234">Цю сторінку створено <ph name="CREATION_TIME" />. Вона може відрізнятися від онлайн-версії.</translation> <translation id="4605958867780575332">Елемент "<ph name="ITEM_TITLE" />" вилучено</translation> <translation id="4616150815774728855">Відкрити файл <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Керується одним із батьків</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Відкрити нову вкладку</translation> <translation id="4751476147751820511">Датчики руху та світла</translation> <translation id="4759238208242260848">Завантаження</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 файл завантажено.}one{# файл завантажено.}few{# файли завантажено.}many{# файлів завантажено.}other{# файлу завантажено.}}</translation> <translation id="4766369052440583386">Заощадження трафіку ввімкнено</translation> <translation id="4797039098279997504">Торкніться, щоб повернутися на сторінку <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Ім'я на картці</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Ваші паролі, історія тощо на всіх пристроях</translation> <translation id="4961700429721424617">Ви виходите з облікового запису, зареєстрованого в домені <ph name="MANAGED_DOMAIN" />. Дані Chrome буде видалено з цього пристрою, але вони залишаться у вашому обліковому записі Google.</translation> <translation id="497421865427891073">Перейти вперед</translation> +<translation id="4988210275050210843">Завантажується файл (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Сторінки</translation> <translation id="4996978546172906250">Надіслати через</translation> <translation id="5004339818306944878">Заощаджуйте до 60% трафіку та пришвидшіть завантаження веб-сторінок. Сервери Google оптимізують сторінки, які ви відвідуєте.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Очистити збережені дані</translation> <translation id="5152843274749979095">Немає підтримуваних додатків</translation> <translation id="5161254044473106830">Введіть назву</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{Не вдалося завантажити 1 файл.}one{Не вдалося завантажити # файл.}few{Не вдалося завантажити # файли.}many{Не вдалося завантажити # файлів.}other{Не вдалося завантажити # файлу.}}</translation> <translation id="5168917394043976756">Відкрити панель навігації</translation> <translation id="5171365962177408781">Торкніться, щоб завантажити сторінку нової вкладки та переглянути пропоновані статті</translation> <translation id="5184329579814168207">Відкрити в Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Тут відображатимуться найчастіше відвідувані сторінки</translation> <translation id="5424588387303617268">Доступно <ph name="GIGABYTES" /> ГБ</translation> <translation id="5433691172869980887">Ім’я користувача скопійовано</translation> +<translation id="543509235395288790">Завантажується файлів: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Перейти до адресного рядка</translation> <translation id="5447201525962359567">Усі дані сайтів, зокрема файли cookie й інші локально збережені дані</translation> <translation id="5447765697759493033">Цей сайт не буде перекладено</translation> +<translation id="545042621069398927">Прискорюється завантаження.</translation> <translation id="5456381639095306749">Завантажити сторінку</translation> <translation id="548278423535722844">Відкрити в додатку Карти</translation> <translation id="5487521232677179737">Видалити дані</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Понад 30 днів тому</translation> <translation id="5858741533101922242">Chrome не може ввімкнути адаптер Bluetooth</translation> <translation id="5860033963881614850">Вимк.</translation> +<translation id="5864174910718532887">Деталі: відсортовано за назвою сайту</translation> <translation id="5864419784173784555">Очікується інше завантаження…</translation> <translation id="5869522115854928033">Збережені паролі</translation> <translation id="5878455346526065919">Блокувати рекламу на сайтах, які часто показують нав’язливі оголошення</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Пропозиції вмісту</translation> <translation id="6277522088822131679">Виникла проблема з друком цієї сторінки. Повторіть спробу.</translation> <translation id="6295158916970320988">Усі сайти</translation> +<translation id="629730747756840877">Обліковий запис</translation> <translation id="6320088164292336938">Вібросигнал</translation> <translation id="6324034347079777476">Синхронізацію системи Android вимкнено</translation> <translation id="6333140779060797560">Надіслати через <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Шифрування</translation> +<translation id="6341580099087024258">Запитувати, де зберігати файли</translation> <translation id="6343192674172527289">Завантаження не знайдено</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}many{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation> <translation id="6364438453358674297">Вилучити пропозицію з історії?</translation> +<translation id="6378173571450987352">Деталі: відсортовано за кількістю використаного трафіку</translation> <translation id="6383961787135158834">Видалити дані сайтів…</translation> <translation id="6388207532828177975">Очистити та скинути</translation> <translation id="6393863479814692971">Chrome потрібні дозволи, щоб використовувати камеру та мікрофон на цьому сайті.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Додайте обліковий запис Google зі сторінки "Облікові записи" в додатку Налаштування на пристрої.</translation> <translation id="7274013316676448362">Заблокований сайт</translation> <translation id="729975465115245577">На пристрої немає додатка для зберігання файлу з паролями.</translation> +<translation id="7302081693174882195">Деталі: відсортовано за кількістю заощадженого трафіку</translation> <translation id="7333031090786104871">Попередній сайт ще додається</translation> <translation id="7352939065658542140">ВІДЕО</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Поділитись 1 вибраним елементом}one{Поділитися # вибраним елементом}few{Поділитися # вибраними елементами}many{Поділитися # вибраними елементами}other{Поділитися # вибраного елемента}}</translation> <translation id="7359002509206457351">Отримати доступ до способів оплати</translation> <translation id="7366340029385295517">Трансляція на екран "<ph name="SCREEN_NAME" />"</translation> <translation id="7375125077091615385">Тип:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL-адреса</translation> <translation id="7403691278183511381">Перший запуск Chrome</translation> <translation id="741204030948306876">Увімкнути</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Спершу запитувати</translation> <translation id="7423538860840206698">Заборонено переглядати буфер обміну</translation> <translation id="7437998757836447326">Вихід із Chrome</translation> +<translation id="7444811645081526538">Інші категорії</translation> <translation id="7445411102860286510">Дозволити сайтам автоматично відтворювати відео з вимкненим звуком (рекомендується)</translation> <translation id="7453467225369441013">Ви вийдете з більшості сайтів, але не вийдете з облікового запису Google.</translation> <translation id="7454641608352164238">Замало місця</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Видалити все</translation> <translation id="7882131421121961860">Історії не знайдено</translation> <translation id="7882806643839505685">Увімкнути звук для певного сайту.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Завантажується файл.}one{Завантажується # файл.}few{Завантажується # файли.}many{Завантажується # файлів.}other{Завантажується # файлу.}}</translation> <translation id="7929962904089429003">Відкрити меню</translation> <translation id="7942131818088350342">Застаріла версія <ph name="PRODUCT_NAME" />.</translation> <translation id="7947953824732555851">Прийняти й увійти</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">На деяких веб-сайтах ви можна оплачувати за допомогою перелічених вище підтримуваних додатків для платежів на вашому пристрої.</translation> <translation id="8816439037877937734">Додаток <ph name="APP_NAME" /> відкриватиметься в Chrome. Продовжуючи, ви приймаєте <ph name="BEGIN_LINK1" />Умови використання<ph name="END_LINK1" /> та <ph name="BEGIN_LINK2" />Примітку про конфіденційність<ph name="END_LINK2" /> Chrome, а також <ph name="BEGIN_LINK3" />Примітку про конфіденційність для облікових записів Google, якими можна керувати у Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Закладки</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Не вдалося завантажити вміст.</translation> <translation id="8840953339110955557">Ця сторінка може відрізнятися від онлайн-версії.</translation> <translation id="8847988622838149491">Сповіщення щодо USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb b/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb index 0a78c69..feab950 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">Báo cáo sử dụng và sự cố</translation> <translation id="11221688409173367">Chạm vào nút màn hình chính để xem các bài viết chọn lọc dành riêng cho bạn</translation> <translation id="1129510026454351943">Chi tiết: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 tệp đang chờ tải xuống.}other{# tệp đang chờ tải xuống.}}</translation> <translation id="1145536944570833626">Xóa dữ liệu hiện có.</translation> <translation id="1146678959555564648">Nhập VR</translation> <translation id="114721135501989771">Dùng các tính năng thông minh của Google trong Chrome</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">Vui lòng cập nhật chi tiết đăng nhập của bạn.</translation> <translation id="1974060860693918893">Nâng cao</translation> <translation id="1984937141057606926">Được cho phép, ngoại trừ cookie của bên thứ ba</translation> +<translation id="1987739130650180037">Nút <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation> <translation id="1989112275319619282">Duyệt qua</translation> <translation id="1993768208584545658"><ph name="SITE" /> muốn ghép nối</translation> <translation id="1994173015038366702">URL trang web</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> <translation id="3997476611815694295">Bộ nhớ không quan trọng</translation> <translation id="4002066346123236978">Tiêu đề</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# giờ}other{# giờ}}</translation> <translation id="4042870126885713738">Hiển thị các đề xuất khi địa chỉ web không khắc phục được hoặc kết nối không thể được thực hiện</translation> <translation id="4046123991198612571">Bản nhạc tiếp theo</translation> <translation id="4048707525896921369">Tìm hiểu về các chủ đề trên trang web mà không cần rời khỏi trang. Tính năng Nhấn để tìm kiếm sẽ gửi một từ và ngữ cảnh xung quanh từ đó tới Google Tìm kiếm, trả về định nghĩa, hình ảnh, kết quả tìm kiếm và các chi tiết khác. @@ -402,6 +405,7 @@ <translation id="4581964774250883625">Bạn đã chuyển sang chế độ ẩn danh.</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# phút trước}other{# phút trước}}</translation> <translation id="4587589328781138893">Trang web</translation> +<translation id="4594952190837476234">Trang ngoại tuyến này được tạo từ lúc <ph name="CREATION_TIME" /> và có thể khác với phiên bản trực tuyến.</translation> <translation id="4605958867780575332">Đã xóa mục: <ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">Mở <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">Do cha mẹ của bạn quản lý</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">Mở tab mới</translation> <translation id="4751476147751820511">Cảm biến chuyển động hoặc ánh sáng</translation> <translation id="4759238208242260848">Tải xuống</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{Đã tải xong 1 tệp xuống.}other{Đã tải xong # tệp xuống.}}</translation> <translation id="4766369052440583386">Trình tiết kiệm dữ liệu bật</translation> <translation id="4797039098279997504">Chạm để quay lại <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">Tên trên thẻ</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">Mật khẩu, lịch sử và nhiều nội dung khác của bạn trên tất cả các thiết bị</translation> <translation id="4961700429721424617">Bạn đang đăng xuất khỏi tài khoản do <ph name="MANAGED_DOMAIN" /> quản lý. Thao tác này sẽ xóa dữ liệu Chrome khỏi thiết bị này nhưng dữ liệu sẽ vẫn còn trong Tài khoản Google của bạn.</translation> <translation id="497421865427891073">Đi về phía trước</translation> +<translation id="4988210275050210843">Đang tải tệp xuống (<ph name="MEGABYTES" />).</translation> <translation id="4988526792673242964">Trang</translation> <translation id="4996978546172906250">Chia sẻ qua</translation> <translation id="5004339818306944878">Sử dụng ít dữ liệu hơn tối đa 60% và tăng tốc web. Máy chủ của Google sẽ tối ưu hóa các trang bạn truy cập.</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">Xóa dữ liệu đã lưu trữ</translation> <translation id="5152843274749979095">Chưa cài đặt ứng dụng được hỗ trợ nào</translation> <translation id="5161254044473106830">Cần có tiêu đề</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{Không tải được 1 tệp xuống.}other{Không tải được # tệp xuống.}}</translation> <translation id="5168917394043976756">Mở ngăn điều hướng</translation> <translation id="5171365962177408781">Chạm để tải trang tab mới và xem các bài viết đề xuất</translation> <translation id="5184329579814168207">Mở trong Chrome</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">Trang bạn truy cập nhiều nhất sẽ xuất hiện ở đây</translation> <translation id="5424588387303617268">Còn trống <ph name="GIGABYTES" /> GB</translation> <translation id="5433691172869980887">Đã sao chép tên người dùng</translation> +<translation id="543509235395288790">Đang tải <ph name="COUNT" /> tệp (<ph name="MEGABYTES" />) xuống.</translation> <translation id="5441522332038954058">Chuyển đến thanh địa chỉ</translation> <translation id="5447201525962359567">Tất cả bộ nhớ trang web, bao gồm cookie và các dữ liệu được lưu trữ cục bộ khác</translation> <translation id="5447765697759493033">Trang web này sẽ không được dịch</translation> +<translation id="545042621069398927">Đang tăng tốc độ tải xuống.</translation> <translation id="5456381639095306749">Tải trang xuống</translation> <translation id="548278423535722844">Mở trong ứng dụng bản đồ</translation> <translation id="5487521232677179737">Xóa dữ liệu</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">Đã tồn tại hơn 30 ngày</translation> <translation id="5858741533101922242">Chrome không thể bật bộ điều hợp Bluetooth</translation> <translation id="5860033963881614850">Tắt</translation> +<translation id="5864174910718532887">Thông tin chi tiết: Sắp xếp theo tên trang web</translation> <translation id="5864419784173784555">Đang chờ đến lần tải xuống tiếp theo…</translation> <translation id="5869522115854928033">Mật khẩu đã lưu</translation> <translation id="5878455346526065919">Chặn quảng cáo từ các trang web thường hiển thị quảng cáo xâm nhập</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">Đề xuất nội dung</translation> <translation id="6277522088822131679">Đã xảy ra sự cố khi in trang này. Vui lòng thử lại.</translation> <translation id="6295158916970320988">Tất cả các trang web</translation> +<translation id="629730747756840877">Tài khoản</translation> <translation id="6320088164292336938">Rung</translation> <translation id="6324034347079777476">Đồng bộ hóa hệ thống Android đã bị tắt</translation> <translation id="6333140779060797560">Chia sẻ qua <ph name="APPLICATION" /></translation> <translation id="6337234675334993532">Mã hóa</translation> +<translation id="6341580099087024258">Hỏi vị trí lưu tệp</translation> <translation id="6343192674172527289">Không tìm thấy tài nguyên đã tải xuống nào</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 và <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> tùy chọn khác}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 và <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> tùy chọn khác}}</translation> <translation id="6364438453358674297">Xóa đề xuất khỏi lịch sử?</translation> +<translation id="6378173571450987352">Thông tin chi tiết: Sắp xếp theo lượng dữ liệu đã sử dụng</translation> <translation id="6383961787135158834">Xóa bộ nhớ trang web...</translation> <translation id="6388207532828177975">Xóa và đặt lại</translation> <translation id="6393863479814692971">Chrome cần có quyền truy cập máy ảnh và micrô của bạn cho trang web này.</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">Thêm Tài khoản Google từ trang Tài khoản trong ứng dụng Cài đặt trên thiết bị của bạn.</translation> <translation id="7274013316676448362">Trang web bị chặn</translation> <translation id="729975465115245577">Thiết bị của bạn không có ứng dụng để lưu trữ tệp mật khẩu.</translation> +<translation id="7302081693174882195">Thông tin chi tiết: Sắp xếp theo lượng dữ liệu đã tiết kiệm được</translation> <translation id="7333031090786104871">Vẫn đang thêm trang web trước</translation> <translation id="7352939065658542140">VIDEO</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Chia sẻ 1 mục đã chọn}other{Chia sẻ # mục đã chọn}}</translation> <translation id="7359002509206457351">Truy cập vào phương thức thanh toán</translation> <translation id="7366340029385295517">Đang truyền tới <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">Loại:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> <translation id="7400418766976504921">URL</translation> <translation id="7403691278183511381">Trải nghiệm lần chạy đầu tiên của Chrome</translation> <translation id="741204030948306876">Có, tôi đồng ý</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">Hỏi trước</translation> <translation id="7423538860840206698">Đã chặn quyền đọc khay nhớ tạm</translation> <translation id="7437998757836447326">Đăng xuất khỏi Chrome</translation> +<translation id="7444811645081526538">Danh mục khác</translation> <translation id="7445411102860286510">Cho phép trang web tự động phát video tắt tiếng (được đề xuất)</translation> <translation id="7453467225369441013">Đăng xuất bạn khỏi hầu hết các trang web. Bạn sẽ không bị đăng xuất khỏi Tài khoản Google của mình.</translation> <translation id="7454641608352164238">Không đủ dung lượng</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">Xóa tất cả</translation> <translation id="7882131421121961860">Không tìm thấy lịch sử nào</translation> <translation id="7882806643839505685">Cho phép phát âm thanh trên một trang web cụ thể.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Đang tải tệp xuống.}other{Đang tải # tệp xuống.}}</translation> <translation id="7929962904089429003">Mở menu</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> đã lỗi thời.</translation> <translation id="7947953824732555851">Chấp nhận & đăng nhập</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">Trên một số trang web, bạn có thể thanh toán bằng các ứng dụng thanh toán được hỗ trợ bên trên trên thiết bị của bạn.</translation> <translation id="8816439037877937734"><ph name="APP_NAME" /> sẽ mở trong Chrome. Bằng việc tiếp tục, bạn đồng ý với <ph name="BEGIN_LINK1" />Điều khoản dịch vụ<ph name="END_LINK1" /> và <ph name="BEGIN_LINK2" />Thông báo bảo mật<ph name="END_LINK2" /> của Chrome, cũng như <ph name="BEGIN_LINK3" />Thông báo bảo mật cho Tài khoản Google được quản lý bằng Family Link<ph name="END_LINK3" />.</translation> <translation id="8820817407110198400">Dấu trang</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">Đã xảy ra lỗi khi tải nội dung xuống.</translation> <translation id="8840953339110955557">Trang này có thể khác với phiên bản trực tuyến.</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb b/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb index 6275071..5727641 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">使用情况统计信息和崩溃报告</translation> <translation id="11221688409173367">点按主页按钮即可查看系统专门为您挑选的文章</translation> <translation id="1129510026454351943">错误详情:<ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{有 1 项下载尚待处理。}other{有 # 项下载尚待处理。}}</translation> <translation id="1145536944570833626">删除现有数据。</translation> <translation id="1146678959555564648">进入 VR</translation> <translation id="114721135501989771">在 Chrome 中畅享 Google 的智能技术</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">请更新您的登录详细信息。</translation> <translation id="1974060860693918893">高级</translation> <translation id="1984937141057606926">允许(第三方除外)</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />按钮</translation> <translation id="1989112275319619282">浏览</translation> <translation id="1993768208584545658"><ph name="SITE" /> 希望与以下所选设备配对:</translation> <translation id="1994173015038366702">网站网址</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475">已下载 <ph name="BYTES_DOWNLOADED_WITH_UNITS" />,总大小不明</translation> <translation id="3997476611815694295">不重要网站的存储数据</translation> <translation id="4002066346123236978">标题</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# 小时}other{# 小时}}</translation> <translation id="4042870126885713738">无法解析网址或无法建立连接时显示建议</translation> <translation id="4046123991198612571">下一曲</translation> <translation id="4048707525896921369">无需离开所在页面,便可了解网站上的主题。“点按搜索”功能会将所选字词及上下文一起发送给 Google 搜索,后者即会据此返回相应的定义、图片、搜索结果及其他详情。 @@ -402,6 +405,7 @@ <translation id="4581964774250883625">您已进入无痕模式。</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# 分钟前}other{# 分钟前}}</translation> <translation id="4587589328781138893">网站</translation> +<translation id="4594952190837476234">此离线网页是在 <ph name="CREATION_TIME" />创建的,可能与在线版本有所不同。</translation> <translation id="4605958867780575332">以下项已移除:<ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">打开<ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">由您父母管理</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">打开新标签页</translation> <translation id="4751476147751820511">动态传感器或光传感器</translation> <translation id="4759238208242260848">下载内容</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{已完成 1 项下载。}other{已完成 # 项下载。}}</translation> <translation id="4766369052440583386">流量节省程序已开启</translation> <translation id="4797039098279997504">触摸即可返回到 <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">持卡人姓名</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">您所有设备上的密码、历史记录等信息</translation> <translation id="4961700429721424617">您正要退出由 <ph name="MANAGED_DOMAIN" /> 管理的帐号。退出后,您的 Chrome 数据将从这台设备上删除,但仍会保留在您的 Google 帐号中。</translation> <translation id="497421865427891073">前进</translation> +<translation id="4988210275050210843">正在下载文件(<ph name="MEGABYTES" /> MB)。</translation> <translation id="4988526792673242964">页码</translation> <translation id="4996978546172906250">分享方式</translation> <translation id="5004339818306944878">最多可减少 60% 的数据用量,并加快网页加载速度。Google 服务器会对您访问的网页进行优化。</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">清除存储的数据</translation> <translation id="5152843274749979095">尚未安装任何受支持的应用</translation> <translation id="5161254044473106830">必须提供标题</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 项下载失败。}other{# 项下载失败。}}</translation> <translation id="5168917394043976756">打开抽屉式导航栏</translation> <translation id="5171365962177408781">点按即可加载新标签页并查看推荐文章</translation> <translation id="5184329579814168207">在 Chrome 中打开</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">您最常访问的网页将列在此处</translation> <translation id="5424588387303617268">可用存储空间:<ph name="GIGABYTES" /> GB</translation> <translation id="5433691172869980887">已复制用户名</translation> +<translation id="543509235395288790">正在下载 <ph name="COUNT" /> 个文件(<ph name="MEGABYTES" /> MB)。</translation> <translation id="5441522332038954058">跳转到地址栏</translation> <translation id="5447201525962359567">所有网站存储数据,包括 Cookie 及其他本地存储的数据</translation> <translation id="5447765697759493033">系统不会翻译此网站</translation> +<translation id="545042621069398927">正在加快您的下载速度。</translation> <translation id="5456381639095306749">下载网页</translation> <translation id="548278423535722844">在地图应用中打开</translation> <translation id="5487521232677179737">清除数据</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">30 天之前的</translation> <translation id="5858741533101922242">Chrome 无法开启蓝牙适配器</translation> <translation id="5860033963881614850">关闭</translation> +<translation id="5864174910718532887">详细信息:按网站名称排序</translation> <translation id="5864419784173784555">正在等待完成另一项下载…</translation> <translation id="5869522115854928033">已保存的密码</translation> <translation id="5878455346526065919">阻止常常会展示侵扰性广告的网站显示广告</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">内容建议</translation> <translation id="6277522088822131679">打印该页面时出现问题,请重试。</translation> <translation id="6295158916970320988">所有网站</translation> +<translation id="629730747756840877">帐号</translation> <translation id="6320088164292336938">振动</translation> <translation id="6324034347079777476">Android 系统同步功能已停用</translation> <translation id="6333140779060797560">通过<ph name="APPLICATION" />分享</translation> <translation id="6337234675334993532">加密</translation> +<translation id="6341580099087024258">询问文件保存位置</translation> <translation id="6343192674172527289">未找到任何下载内容</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026以及另外 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 个地址}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026以及另外 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 个地址}}</translation> <translation id="6364438453358674297">要从历史记录中移除建议吗?</translation> +<translation id="6378173571450987352">详细信息:按已使用的数据流量排序</translation> <translation id="6383961787135158834">清除网站存储数据…</translation> <translation id="6388207532828177975">清除并重置</translation> <translation id="6393863479814692971">Chrome 需要获得相应权限,才能允许此网站使用您的摄像头和麦克风。</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">请在设备的“设置”应用中,通过“帐号”页面添加 Google 帐号。</translation> <translation id="7274013316676448362">禁止访问的网站</translation> <translation id="729975465115245577">您的设备上没有可以存储密码文件的应用。</translation> +<translation id="7302081693174882195">详细信息:按已节省的数据流量排序</translation> <translation id="7333031090786104871">仍在添加先前的网站</translation> <translation id="7352939065658542140">视频</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{分享 1 个所选项}other{分享 # 个所选项}}</translation> <translation id="7359002509206457351">查询付款方式</translation> <translation id="7366340029385295517">正在投射至<ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">类型:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />。</translation> <translation id="7400418766976504921">网址</translation> <translation id="7403691278183511381">Chrome 首次运行体验</translation> <translation id="741204030948306876">确认</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">先询问</translation> <translation id="7423538860840206698">已阻止读取剪贴板中的内容</translation> <translation id="7437998757836447326">退出 Chrome</translation> +<translation id="7444811645081526538">更多类别</translation> <translation id="7445411102860286510">允许网站自动播放静音的视频(推荐)</translation> <translation id="7453467225369441013">您会从大多数网站退出,但不会退出自己的 Google 帐号。</translation> <translation id="7454641608352164238">空间不足</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">全部删除</translation> <translation id="7882131421121961860">未找到任何记录</translation> <translation id="7882806643839505685">允许特定网站播放声音。</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{正在下载 1 个文件。}other{正在下载 # 个文件。}}</translation> <translation id="7929962904089429003">打开菜单</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> 不是最新版本。</translation> <translation id="7947953824732555851">接受并登录</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">在某些网站上,您可以使用自己的设备通过上述支持的付款应用付款。</translation> <translation id="8816439037877937734"><ph name="APP_NAME" />将在 Chrome 中打开。继续操作即表示您同意 Chrome 的<ph name="BEGIN_LINK1" />服务条款<ph name="END_LINK1" />和<ph name="BEGIN_LINK2" />隐私权声明<ph name="END_LINK2" />,以及<ph name="BEGIN_LINK3" />针对通过 Family Link 管理的 Google 帐号的隐私权声明<ph name="END_LINK3" />。</translation> <translation id="8820817407110198400">书签</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">下载此内容时出错。</translation> <translation id="8840953339110955557">此网页可能与在线版本有所不同。</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb b/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb index 928b159..cb0198d 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb
@@ -15,6 +15,7 @@ <translation id="1121094540300013208">使用資料和當機報告</translation> <translation id="11221688409173367">輕觸主螢幕按鈕即可查看精選文章</translation> <translation id="1129510026454351943">詳細資料:<ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 項下載作業仍待處理。}other{# 項下載作業仍待處理。}}</translation> <translation id="1145536944570833626">刪除現有資料。</translation> <translation id="1146678959555564648">進入 VR</translation> <translation id="114721135501989771">在 Chrome 中體驗 Google 智慧功能</translation> @@ -118,6 +119,7 @@ <translation id="1966710179511230534">請更新你的登入詳細資料。</translation> <translation id="1974060860693918893">進階</translation> <translation id="1984937141057606926">允許 (第三方網站除外)</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />按鈕</translation> <translation id="1989112275319619282">瀏覽</translation> <translation id="1993768208584545658"><ph name="SITE" /> 要求配對</translation> <translation id="1994173015038366702">網站網址</translation> @@ -336,6 +338,7 @@ <translation id="3991845972263764475">已下載:<ph name="BYTES_DOWNLOADED_WITH_UNITS" />,總大小:不明</translation> <translation id="3997476611815694295">不重要網站的儲存資料量</translation> <translation id="4002066346123236978">標題</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# 小時}other{# 小時}}</translation> <translation id="4042870126885713738">在無法解析網址或建立連線時顯示建議</translation> <translation id="4046123991198612571">下一首曲目</translation> <translation id="4048707525896921369">不需離開網頁即可瞭解網站上的主題。「輕觸搜尋」可將特定字詞及其上下文內容傳送給 Google 搜尋,並傳回定義、圖片、搜尋結果和其他詳細資料。 @@ -402,6 +405,7 @@ <translation id="4581964774250883625">你已啟用無痕模式。</translation> <translation id="4583164079174244168">{MINUTES,plural, =1{# 分鐘前}other{# 分鐘前}}</translation> <translation id="4587589328781138893">網站</translation> +<translation id="4594952190837476234">這個離線版網頁是於 <ph name="CREATION_TIME" />建立,可能會和線上版本有所不同。</translation> <translation id="4605958867780575332">已移除項目:<ph name="ITEM_TITLE" /></translation> <translation id="4616150815774728855">開啟 <ph name="WEBAPK_NAME" /></translation> <translation id="4645575059429386691">你的家長已停用這項功能</translation> @@ -422,6 +426,7 @@ <translation id="4749960740855309258">開啟新分頁</translation> <translation id="4751476147751820511">動作或光源感應器</translation> <translation id="4759238208242260848">下載</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{已完成 1 項下載作業。}other{已完成 # 項下載作業。}}</translation> <translation id="4766369052440583386">Data Saver 已開啟</translation> <translation id="4797039098279997504">輕觸即可返回 <ph name="URL_OF_THE_CURRENT_TAB" /></translation> <translation id="4807098396393229769">持卡人姓名</translation> @@ -448,6 +453,7 @@ <translation id="4961334780091921942">你所有裝置上的密碼、歷史記錄和其他設定</translation> <translation id="4961700429721424617">您即將登出由 <ph name="MANAGED_DOMAIN" /> 所管理的帳戶。系統會將您的 Chrome 資料從這個裝置上刪除,但繼續保留在您的 Google 帳戶中。</translation> <translation id="497421865427891073">往前</translation> +<translation id="4988210275050210843">正在下載檔案 (<ph name="MEGABYTES" /> MB)。</translation> <translation id="4988526792673242964">頁數</translation> <translation id="4996978546172906250">分享方式:</translation> <translation id="5004339818306944878">Google 伺服器會對你造訪的網頁進行最佳化處理,最多可減少 60% 的數據用量,並加快網頁載入速度。</translation> @@ -467,6 +473,7 @@ <translation id="515227803646670480">清除儲存的資料</translation> <translation id="5152843274749979095">尚未安裝系統支援的應用程式</translation> <translation id="5161254044473106830">請輸入標題</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{無法完成 1 項下載作業。}other{無法完成 # 項下載作業。}}</translation> <translation id="5168917394043976756">開啟導覽匣</translation> <translation id="5171365962177408781">輕觸即可載入新分頁頁面並查看推薦文章</translation> <translation id="5184329579814168207">在 Chrome 中開啟</translation> @@ -496,9 +503,11 @@ <translation id="5423934151118863508">這裡會顯示您最常造訪的網頁</translation> <translation id="5424588387303617268">可用空間:<ph name="GIGABYTES" /> GB</translation> <translation id="5433691172869980887">已複製使用者名稱</translation> +<translation id="543509235395288790">正在下載 <ph name="COUNT" /> 個檔案 (共 <ph name="MEGABYTES" /> MB)。</translation> <translation id="5441522332038954058">切換到網址列</translation> <translation id="5447201525962359567">所有網站儲存的資料,包括 Cookie 和其他儲存在本機上的資料</translation> <translation id="5447765697759493033">系統不會翻譯這個網站</translation> +<translation id="545042621069398927">正在加快下載速度。</translation> <translation id="5456381639095306749">下載網頁</translation> <translation id="548278423535722844">在地圖應用程式中開啟</translation> <translation id="5487521232677179737">清除資料</translation> @@ -559,6 +568,7 @@ <translation id="5854790677617711513">超過 30 天前</translation> <translation id="5858741533101922242">Chrome 無法開啟藍牙轉接器</translation> <translation id="5860033963881614850">關閉</translation> +<translation id="5864174910718532887">詳細資料:依網站名稱排序</translation> <translation id="5864419784173784555">正在等待其他下載程序完成…</translation> <translation id="5869522115854928033">已儲存的密碼</translation> <translation id="5878455346526065919">如果網站經常顯示侵入式廣告,就封鎖廣告</translation> @@ -605,13 +615,16 @@ <translation id="6255999984061454636">內容建議</translation> <translation id="6277522088822131679">列印網頁時發生問題,請再試一次。</translation> <translation id="6295158916970320988">所有網站</translation> +<translation id="629730747756840877">帳戶</translation> <translation id="6320088164292336938">震動</translation> <translation id="6324034347079777476">Android 系統同步處理功能已停用</translation> <translation id="6333140779060797560">透過 <ph name="APPLICATION" /> 分享</translation> <translation id="6337234675334993532">加密</translation> +<translation id="6341580099087024258">詢問檔案儲存位置</translation> <translation id="6343192674172527289">找不到下載內容</translation> <translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 和另外 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 個地址}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 和另外 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 個地址}}</translation> <translation id="6364438453358674297">從歷史記錄中移除建議項目?</translation> +<translation id="6378173571450987352">詳細資料:依使用資料量排序</translation> <translation id="6383961787135158834">清除網站儲存的資料…</translation> <translation id="6388207532828177975">清除並重設</translation> <translation id="6393863479814692971">Chrome 需要相關權限,才能讓這個網站使用你的攝影機和麥克風。</translation> @@ -723,12 +736,14 @@ <translation id="7253272406652746122">在裝置的「設定」應用程式中,透過「帳戶」頁面新增 Google 帳戶。</translation> <translation id="7274013316676448362">已封鎖網站</translation> <translation id="729975465115245577">你的裝置沒有可儲存密碼檔案的應用程式。</translation> +<translation id="7302081693174882195">詳細資料:依儲存資料量排序</translation> <translation id="7333031090786104871">仍在新增先前的網站</translation> <translation id="7352939065658542140">影片</translation> <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{分享 1 個選取的項目}other{分享 # 個選取的項目}}</translation> <translation id="7359002509206457351">存取付款方式</translation> <translation id="7366340029385295517">正在投放到 <ph name="SCREEN_NAME" /></translation> <translation id="7375125077091615385">類型:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />。</translation> <translation id="7400418766976504921">網址</translation> <translation id="7403691278183511381">Chrome 初次使用體驗</translation> <translation id="741204030948306876">是,我要啟用</translation> @@ -736,6 +751,7 @@ <translation id="7423098979219808738">先詢問我</translation> <translation id="7423538860840206698">禁止讀取剪貼簿</translation> <translation id="7437998757836447326">登出 Chrome</translation> +<translation id="7444811645081526538">更多類別</translation> <translation id="7445411102860286510">允許網站自動播放靜音的影片 (建議)</translation> <translation id="7453467225369441013">你會從大多數網站登出,但不會因此登出 Google 帳戶。</translation> <translation id="7454641608352164238">空間不足</translation> @@ -790,6 +806,7 @@ <translation id="7876243839304621966">全部移除</translation> <translation id="7882131421121961860">找不到瀏覽記錄</translation> <translation id="7882806643839505685">允許特定網站播放音訊。</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{正在下載檔案。}other{正在下載 # 個檔案。}}</translation> <translation id="7929962904089429003">開啟選單</translation> <translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> 版本過舊。</translation> <translation id="7947953824732555851">接受並登入</translation> @@ -885,6 +902,7 @@ <translation id="8812260976093120287">在部分網站上,你可以在你的裝置上使用上述支援的付款應用程式付款。</translation> <translation id="8816439037877937734">「<ph name="APP_NAME" />」將在 Chrome 中開啟。繼續操作即表示您同意接受 Chrome 的《<ph name="BEGIN_LINK1" />服務條款<ph name="END_LINK1" />》和《<ph name="BEGIN_LINK2" />隱私權聲明<ph name="END_LINK2" />》,以及《<ph name="BEGIN_LINK3" />透過 Family Link 管理的 Google 帳戶所適用的隱私權聲明<ph name="END_LINK3" />》。</translation> <translation id="8820817407110198400">書籤</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> - <ph name="FILE_SIZE" /></translation> <translation id="883806473910249246">下載這項內容時發生錯誤。</translation> <translation id="8840953339110955557">這個網頁可能會和線上版本有所不同。</translation> <translation id="8847988622838149491">USB</translation>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 3ddab65..dab545c 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -116,7 +116,6 @@ "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetCoordinator.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewBinder.java", - "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewAdapter.java", "java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java", "java/src/org/chromium/chrome/browser/banners/AppBannerManager.java", "java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java", @@ -454,8 +453,9 @@ "java/src/org/chromium/chrome/browser/download/home/filter/chips/Chip.java", "java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsCoordinator.java", "java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsProvider.java", - "java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewBinder.java", + "java/src/org/chromium/chrome/browser/download/home/filter/chips/ChipsViewHolder.java", "java/src/org/chromium/chrome/browser/download/home/glue/DownloadGlue.java", + "java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java", "java/src/org/chromium/chrome/browser/download/home/glue/OfflineContentProviderGlue.java", "java/src/org/chromium/chrome/browser/download/home/glue/ThumbnailRequestGlue.java", "java/src/org/chromium/chrome/browser/download/home/list/CalendarFactory.java", @@ -466,8 +466,8 @@ "java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutator.java", "java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java", "java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java", - "java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java", "java/src/org/chromium/chrome/browser/download/home/list/DecoratedListItemModel.java", + "java/src/org/chromium/chrome/browser/download/home/list/ItemUtils.java", "java/src/org/chromium/chrome/browser/download/home/list/ListItem.java", "java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.java", "java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java", @@ -475,6 +475,8 @@ "java/src/org/chromium/chrome/browser/download/home/list/ListPropertyViewBinder.java", "java/src/org/chromium/chrome/browser/download/home/list/ListUtils.java", "java/src/org/chromium/chrome/browser/download/home/list/UiUtils.java", + "java/src/org/chromium/chrome/browser/download/home/snackbars/DeleteUndoCoordinator.java", + "java/src/org/chromium/chrome/browser/download/home/snackbars/UndoUiUtils.java", "java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java", "java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java", "java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiFactory.java", @@ -681,6 +683,7 @@ "java/src/org/chromium/chrome/browser/locale/SogouPromoDialog.java", "java/src/org/chromium/chrome/browser/locale/LocaleTemplateUrlLoader.java", "java/src/org/chromium/chrome/browser/media/MediaCaptureNotificationService.java", + "java/src/org/chromium/chrome/browser/media/MediaLauncherActivity.java", "java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java", "java/src/org/chromium/chrome/browser/media/PictureInPicture.java", "java/src/org/chromium/chrome/browser/media/PictureInPictureController.java", @@ -701,6 +704,7 @@ "java/src/org/chromium/chrome/browser/media/remote/RemoteVideoInfo.java", "java/src/org/chromium/chrome/browser/media/remote/PositionExtrapolator.java", "java/src/org/chromium/chrome/browser/media/router/BaseMediaRouteDialogManager.java", + "java/src/org/chromium/chrome/browser/media/router/ClientRecord.java", "java/src/org/chromium/chrome/browser/media/router/ChromeMediaRouter.java", "java/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterDialogController.java", "java/src/org/chromium/chrome/browser/media/router/DiscoveryCallback.java", @@ -716,7 +720,11 @@ "java/src/org/chromium/chrome/browser/media/router/MediaRouteProvider.java", "java/src/org/chromium/chrome/browser/media/router/MediaSource.java", "java/src/org/chromium/chrome/browser/media/router/MediaSink.java", + "java/src/org/chromium/chrome/browser/media/router/caf/CastOptionsProvider.java", + "java/src/org/chromium/chrome/browser/media/router/caf/CastSessionController.java", + "java/src/org/chromium/chrome/browser/media/router/caf/CastUtils.java", "java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java", + "java/src/org/chromium/chrome/browser/media/router/caf/CastMessageHandler.java", "java/src/org/chromium/chrome/browser/media/router/cast/BaseMediaRouteProvider.java", "java/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProvider.java", "java/src/org/chromium/chrome/browser/media/router/cast/CastMediaSource.java", @@ -727,7 +735,6 @@ "java/src/org/chromium/chrome/browser/media/router/cast/CastSessionInfo.java", "java/src/org/chromium/chrome/browser/media/router/cast/CastSessionUtil.java", "java/src/org/chromium/chrome/browser/media/router/cast/ChromeCastSessionManager.java", - "java/src/org/chromium/chrome/browser/media/router/cast/ClientRecord.java", "java/src/org/chromium/chrome/browser/media/router/cast/CreateRouteRequest.java", "java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingCastSession.java", "java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingMediaRouteProvider.java", @@ -760,6 +767,7 @@ "java/src/org/chromium/chrome/browser/modaldialog/ModalDialogView.java", "java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java", "java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java", + "java/src/org/chromium/chrome/browser/modelutil/ForwardingListObservable.java", "java/src/org/chromium/chrome/browser/modelutil/LazyViewBinderAdapter.java", "java/src/org/chromium/chrome/browser/modelutil/ListModelChangeProcessor.java", "java/src/org/chromium/chrome/browser/modelutil/ListObservable.java", @@ -767,9 +775,10 @@ "java/src/org/chromium/chrome/browser/modelutil/PropertyModel.java", "java/src/org/chromium/chrome/browser/modelutil/PropertyModelChangeProcessor.java", "java/src/org/chromium/chrome/browser/modelutil/PropertyObservable.java", - "java/src/org/chromium/chrome/browser/modelutil/RecyclerViewModelChangeProcessor.java", "java/src/org/chromium/chrome/browser/modelutil/RecyclerViewAdapter.java", + "java/src/org/chromium/chrome/browser/modelutil/SimpleList.java", "java/src/org/chromium/chrome/browser/modelutil/SimpleListObservable.java", + "java/src/org/chromium/chrome/browser/modelutil/SimpleRecyclerViewMcp.java", "java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java", "java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceChromeTabbedActivity.java", "java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java", @@ -1064,6 +1073,7 @@ "java/src/org/chromium/chrome/browser/preferences/SeekBarPreference.java", "java/src/org/chromium/chrome/browser/preferences/SignInPreference.java", "java/src/org/chromium/chrome/browser/preferences/SpinnerPreference.java", + "java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java", "java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java", "java/src/org/chromium/chrome/browser/preferences/SyncPreference.java", "java/src/org/chromium/chrome/browser/preferences/SyncedAccountPreference.java", @@ -2084,7 +2094,9 @@ "junit/src/org/chromium/chrome/browser/download/home/filter/OffTheRecordOfflineItemFilterTest.java", "junit/src/org/chromium/chrome/browser/download/home/filter/SearchOfflineItemFilterTest.java", "junit/src/org/chromium/chrome/browser/download/home/filter/TypeOfflineItemFilterTest.java", + "junit/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueueTest.java", "junit/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java", + "junit/src/org/chromium/chrome/browser/download/home/list/ItemUtilsTest.java", "junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiTest.java", "junit/src/org/chromium/chrome/browser/download/DownloadResumptionSchedulerTest.java", "junit/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtilsTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java index 2148fe6..39f4f98 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ContentViewFocusTest.java
@@ -112,7 +112,7 @@ // Start the swipe addFocusChangedListener(view); final EdgeSwipeHandler edgeSwipeHandler = - mActivityTestRule.getActivity().getLayoutManager().getTopSwipeHandler(); + mActivityTestRule.getActivity().getLayoutManager().getToolbarSwipeHandler(); ThreadUtils.runOnUiThread(() -> { edgeSwipeHandler.swipeStarted(ScrollDirection.RIGHT, 0, 0); edgeSwipeHandler.swipeUpdated(100, 0, 100, 0, 100, 0);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 6f43015..40646100 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -1672,7 +1672,7 @@ public void testOSKIsNotShownDuringSwipe() throws InterruptedException { final View urlBar = mActivityTestRule.getActivity().findViewById(R.id.url_bar); final LayoutManagerChrome layoutManager = updateTabsViewSize(); - final EdgeSwipeHandler edgeSwipeHandler = layoutManager.getTopSwipeHandler(); + final EdgeSwipeHandler edgeSwipeHandler = layoutManager.getToolbarSwipeHandler(); UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation()); InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> urlBar.requestFocus());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewTest.java index 8038b252..d0b5e91 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewTest.java
@@ -77,10 +77,9 @@ mActivityTestRule.startMainActivityOnBlankPage(); openLayoutInAccessorySheet(R.layout.password_accessory_sheet, view -> { mView.set((RecyclerView) view); - final PasswordAccessorySheetViewBinder binder = new PasswordAccessorySheetViewBinder(); // Reuse coordinator code to create and wire the adapter. No mediator involved. - binder.initializeView( - mView.get(), PasswordAccessorySheetCoordinator.createAdapter(mModel, binder)); + PasswordAccessorySheetViewBinder.initializeView( + mView.get(), PasswordAccessorySheetCoordinator.createAdapter(mModel)); }); CriteriaHelper.pollUiThread(Criteria.equals(true, () -> mView.get() != null)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index 480b0610..42d3f4c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -537,9 +537,9 @@ direction == ScrollDirection.LEFT || direction == ScrollDirection.RIGHT); final Layout layout = mManager.getActiveLayout(); - final EdgeSwipeHandler eventHandler = mManager.getTopSwipeHandler(); + final EdgeSwipeHandler eventHandler = mManager.getToolbarSwipeHandler(); - Assert.assertNotNull("LayoutManager#getTopSwipeHandler() returned null", eventHandler); + Assert.assertNotNull("LayoutManager#getToolbarSwipeHandler() returned null", eventHandler); Assert.assertNotNull("LayoutManager#getActiveLayout() returned null", layout); final float layoutWidth = layout.getWidth();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS index 2b5bfcd..94b86d4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/document/OWNERS
@@ -1,2 +1 @@ -mariakhomenko@chromium.org yusufo@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 342b86d..04b05cca 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -70,6 +70,7 @@ import org.chromium.chrome.test.util.OmniboxTestUtils; import org.chromium.chrome.test.util.RenderTestRule; import org.chromium.chrome.test.util.browser.ChromeModernDesign; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils; @@ -129,6 +130,15 @@ } } + /** Parameter provider for enabling/disabling "Interest Feed Content Suggestions". */ + public static class InterestFeedParams implements ParameterProvider { + @Override + public Iterable<ParameterSet> getParameters() { + return Arrays.asList(new ParameterSet().value(false).name("DisableInterestFeed"), + new ParameterSet().value(true).name("EnableInterestFeed")); + } + } + private static final String TEST_PAGE = "/chrome/test/data/android/navigate/simple.html"; private Tab mTab; @@ -151,6 +161,15 @@ mChromeModernProcessor.clearTestState(); } + @ParameterAnnotations.UseMethodParameterBefore(InterestFeedParams.class) + public void setupInterestFeed(boolean interestFeedEnabled) { + if (interestFeedEnabled) { + Features.getInstance().enable(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS); + } else { + Features.getInstance().disable(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS); + } + } + @Before public void setUp() throws Exception { mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); @@ -231,10 +250,11 @@ @Test @MediumTest - @Feature({"NewTabPage"}) + @Feature({"NewTabPage", "FeedNewTabPage"}) @EnableFeatures({ChromeFeatureList.SIMPLIFIED_NTP}) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - public void testSimplifiedNtp_BookmarksShortcuts() { + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testSimplifiedNtp_BookmarksShortcuts(boolean interestFeedEnabled) { ActivityMonitor activityMonitor = InstrumentationRegistry.getInstrumentation().addMonitor( BookmarkActivity.class.getName(), new Instrumentation.ActivityResult(Activity.RESULT_OK, null), true); @@ -249,10 +269,11 @@ @Test @MediumTest - @Feature({"NewTabPage"}) + @Feature({"NewTabPage", "FeedNewTabPage"}) @EnableFeatures({ChromeFeatureList.SIMPLIFIED_NTP}) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - public void testSimplifiedNtp_DownloadsShortcuts() { + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testSimplifiedNtp_DownloadsShortcuts(boolean interestFeedEnabled) { ActivityMonitor activityMonitor = InstrumentationRegistry.getInstrumentation().addMonitor( DownloadActivity.class.getName(), new Instrumentation.ActivityResult(Activity.RESULT_OK, null), true); @@ -267,10 +288,12 @@ @Test @MediumTest - @Feature({"NewTabPage"}) + @Feature({"NewTabPage", "FeedNewTabPage"}) @EnableFeatures({ChromeFeatureList.SIMPLIFIED_NTP}) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - public void testSimplifiedNtp_DefaultSearchEngineChange() throws Exception { + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testSimplifiedNtp_DefaultSearchEngineChange(boolean interestFeedEnabled) + throws Exception { View logo = mNtp.getView().findViewById(R.id.search_provider_logo); View shortcuts = mNtp.getView().findViewById(R.id.shortcuts); Assert.assertEquals(View.VISIBLE, logo.getVisibility()); @@ -380,8 +403,9 @@ */ @Test @SmallTest - @Feature({"NewTabPage"}) - public void testClickMostVisitedItem() throws InterruptedException { + @Feature({"NewTabPage", "FeedNewTabPage"}) + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testClickMostVisitedItem(boolean interestFeedEnabled) throws InterruptedException { ChromeTabUtils.waitForTabPageLoaded(mTab, new Runnable() { @Override public void run() { @@ -410,8 +434,9 @@ */ @Test @SmallTest - @Feature({"NewTabPage"}) - public void testOpenMostVisitedItemInIncognitoTab() + @Feature({"NewTabPage", "FeedNewTabPage"}) + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testOpenMostVisitedItemInIncognitoTab(boolean interestFeedEnabled) throws InterruptedException, ExecutionException { ChromeTabUtils.invokeContextMenuAndOpenInANewTab(mActivityTestRule, mTileGridLayout.getChildAt(0), ContextMenuManager.ID_OPEN_IN_INCOGNITO_TAB, true, @@ -423,8 +448,9 @@ */ @Test @SmallTest - @Feature({"NewTabPage"}) - public void testRemoveMostVisitedItem() throws ExecutionException { + @Feature({"NewTabPage", "FeedNewTabPage"}) + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testRemoveMostVisitedItem(boolean interestFeedEnabled) throws ExecutionException { SiteSuggestion testSite = mSiteSuggestions.get(0); View mostVisitedItem = mTileGridLayout.getChildAt(0); ArrayList<View> views = new ArrayList<>(); @@ -441,8 +467,10 @@ @Test @MediumTest - @Feature({"NewTabPage"}) - public void testUrlFocusAnimationsDisabledOnLoad() throws InterruptedException { + @Feature({"NewTabPage", "FeedNewTabPage"}) + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testUrlFocusAnimationsDisabledOnLoad(boolean interestFeedEnabled) + throws InterruptedException { Assert.assertFalse(getUrlFocusAnimationsDisabled()); ChromeTabUtils.waitForTabPageLoaded(mTab, new Runnable() { @Override @@ -466,7 +494,7 @@ @Test @LargeTest - @Feature({"NewTabPage"}) + @Feature({"NewTabPage", "FeedNewTabPage"}) public void testUrlFocusAnimationsEnabledOnFailedLoad() throws Exception { // TODO(jbudorick): switch this to EmbeddedTestServer. TestWebServer webServer = TestWebServer.start(); @@ -533,38 +561,18 @@ */ @Test @SmallTest - @Feature({"NewTabPage"}) - public void testSetSearchProviderInfo() throws Throwable { + @Feature({"NewTabPage", "FeedNewTabPage"}) + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testSetSearchProviderInfo(boolean interestFeedEnabled) throws Throwable { mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { - NewTabPageView ntpView = mNtp.getNewTabPageView(); - View logoView = ntpView.findViewById(R.id.search_provider_logo); + NewTabPageLayout ntpLayout = mNtp.getNewTabPageLayout(); + View logoView = ntpLayout.findViewById(R.id.search_provider_logo); Assert.assertEquals(View.VISIBLE, logoView.getVisibility()); - ntpView.setSearchProviderInfo(/* hasLogo = */ false, /* isGoogle */ true); + ntpLayout.setSearchProviderInfo(/* hasLogo = */ false, /* isGoogle */ true); Assert.assertEquals(View.GONE, logoView.getVisibility()); - ntpView.setSearchProviderInfo(/* hasLogo = */ true, /* isGoogle */ true); - Assert.assertEquals(View.VISIBLE, logoView.getVisibility()); - } - }); - } - - /** - * Tests setting whether the search provider has a logo when the condensed UI is enabled. - */ - @Test - @SmallTest - @Feature({"NewTabPage"}) - public void testSetSearchProviderInfoCondensedUi() throws Throwable { - mActivityTestRule.runOnUiThread(new Runnable() { - @Override - public void run() { - NewTabPageView ntpView = mNtp.getNewTabPageView(); - View logoView = ntpView.findViewById(R.id.search_provider_logo); - Assert.assertEquals(View.VISIBLE, logoView.getVisibility()); - ntpView.setSearchProviderInfo(/* hasLogo = */ false, /* isGoogle */ true); - Assert.assertEquals(View.GONE, logoView.getVisibility()); - ntpView.setSearchProviderInfo(/* hasLogo = */ true, /* isGoogle */ true); + ntpLayout.setSearchProviderInfo(/* hasLogo = */ true, /* isGoogle */ true); Assert.assertEquals(View.VISIBLE, logoView.getVisibility()); } }); @@ -576,31 +584,32 @@ */ @Test @SmallTest - @Feature({"NewTabPage"}) - public void testPlaceholder() { - final NewTabPageView ntpView = mNtp.getNewTabPageView(); - final View logoView = ntpView.findViewById(R.id.search_provider_logo); - final View searchBoxView = ntpView.findViewById(R.id.search_box); + @Feature({"NewTabPage", "FeedNewTabPage"}) + @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) + public void testPlaceholder(boolean interestFeedEnabled) { + final NewTabPageLayout ntpLayout = mNtp.getNewTabPageLayout(); + final View logoView = ntpLayout.findViewById(R.id.search_provider_logo); + final View searchBoxView = ntpLayout.findViewById(R.id.search_box); // Initially, the logo is visible, the search box is visible, there is one tile suggestion, // and the placeholder has not been inflated yet. Assert.assertEquals(View.VISIBLE, logoView.getVisibility()); Assert.assertEquals(View.VISIBLE, searchBoxView.getVisibility()); Assert.assertEquals(8, mTileGridLayout.getChildCount()); - Assert.assertNull(ntpView.getPlaceholder()); + Assert.assertNull(ntpLayout.getPlaceholder()); // When the search provider has no logo and there are no tile suggestions, the placeholder // is shown. ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - ntpView.setSearchProviderInfo(/* hasLogo = */ false, /* isGoogle */ true); + ntpLayout.setSearchProviderInfo(/* hasLogo = */ false, /* isGoogle */ true); Assert.assertEquals(View.GONE, logoView.getVisibility()); Assert.assertEquals(View.GONE, searchBoxView.getVisibility()); mMostVisitedSites.setTileSuggestions(new String[] {}); - ntpView.getTileGroup().onSwitchToForeground(false); // Force tile refresh. + ntpLayout.getTileGroup().onSwitchToForeground(false); // Force tile refresh. } }); CriteriaHelper.pollUiThread(new Criteria("The tile grid was not updated.") { @@ -609,18 +618,18 @@ return mTileGridLayout.getChildCount() == 0; } }); - Assert.assertNotNull(ntpView.getPlaceholder()); - Assert.assertEquals(View.VISIBLE, ntpView.getPlaceholder().getVisibility()); + Assert.assertNotNull(ntpLayout.getPlaceholder()); + Assert.assertEquals(View.VISIBLE, ntpLayout.getPlaceholder().getVisibility()); // Once the search provider has a logo again, the logo and search box are shown again and // the placeholder is hidden. ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - ntpView.setSearchProviderInfo(/* hasLogo = */ true, /* isGoogle */ true); + ntpLayout.setSearchProviderInfo(/* hasLogo = */ true, /* isGoogle */ true); Assert.assertEquals(View.VISIBLE, logoView.getVisibility()); Assert.assertEquals(View.VISIBLE, searchBoxView.getVisibility()); - Assert.assertEquals(View.GONE, ntpView.getPlaceholder().getVisibility()); + Assert.assertEquals(View.GONE, ntpLayout.getPlaceholder().getVisibility()); } }); } @@ -739,7 +748,7 @@ return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() { @Override public Boolean call() throws Exception { - return mNtp.getNewTabPageView().urlFocusAnimationsDisabled(); + return mNtp.getNewTabPageLayout().urlFocusAnimationsDisabled(); } }); } @@ -770,7 +779,7 @@ CriteriaHelper.pollUiThread(Criteria.equals(percent, new Callable<Float>() { @Override public Float call() { - return ntp.getNewTabPageView().getUrlFocusChangeAnimationPercent(); + return ntp.getNewTabPageLayout().getUrlFocusChangeAnimationPercent(); } })); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java index 99161ce..5fb6dbc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerViewTest.java
@@ -344,8 +344,7 @@ private int getSnapPosition(int scrollPosition) { NewTabPageView ntpView = getNtpView(); - return getRecyclerView().calculateSnapPosition( - scrollPosition, ntpView.findViewById(R.id.search_box), ntpView.getHeight()); + return getRecyclerView().calculateSnapPosition(scrollPosition, ntpView.getHeight()); } private NewTabPageView getNtpView() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OWNERS index 915949f..b45eb40 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OWNERS +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/OWNERS
@@ -1,4 +1,3 @@ -mariakhomenko@chromium.org tedchoc@chromium.org # COMPONENT: UI>Browser>Omnibox
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webauth/AuthenticatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webauth/AuthenticatorTest.java index 24da6652..c08af9ef 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webauth/AuthenticatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webauth/AuthenticatorTest.java
@@ -23,9 +23,13 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.common.ContentSwitches; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.net.test.ServerCertificate; +import org.chromium.webauth.mojom.AuthenticatorStatus; +import org.chromium.webauth.mojom.PublicKeyCredentialCreationOptions; +import org.chromium.webauth.mojom.PublicKeyCredentialRequestOptions; /** Test suite for navigator.credentials functionality. */ @RunWith(ChromeJUnit4ClassRunner.class) @@ -43,6 +47,21 @@ private String mUrl; private Tab mTab; private AuthenticatorUpdateWaiter mUpdateWaiter; + private MockFido2ApiHandler mMockHandler; + + private class MockFido2ApiHandler extends Fido2ApiHandler { + @Override + protected void makeCredential(PublicKeyCredentialCreationOptions options, + RenderFrameHost frameHost, HandlerResponseCallback callback) { + callback.onError(AuthenticatorStatus.NOT_IMPLEMENTED); + } + + @Override + protected void getAssertion(PublicKeyCredentialRequestOptions options, + RenderFrameHost frameHost, HandlerResponseCallback callback) { + callback.onError(AuthenticatorStatus.NOT_IMPLEMENTED); + } + } /** Waits until the JavaScript code supplies a result. */ private class AuthenticatorUpdateWaiter extends EmptyTabObserver { @@ -79,6 +98,7 @@ mTab = mActivityTestRule.getActivity().getActivityTab(); mUpdateWaiter = new AuthenticatorUpdateWaiter(); mTab.addObserver(mUpdateWaiter); + mMockHandler = new MockFido2ApiHandler(); } @After @@ -98,6 +118,7 @@ @Feature({"WebAuth"}) public void testCreatePublicKeyCredential() throws Exception { mActivityTestRule.loadUrl(mUrl); + Fido2ApiHandler.overrideInstanceForTesting(mMockHandler); mActivityTestRule.runJavaScriptCodeInCurrentTab("doCreatePublicKeyCredential()"); Assert.assertEquals("Success", mUpdateWaiter.waitForUpdate()); } @@ -113,6 +134,7 @@ @Feature({"WebAuth"}) public void testGetPublicKeyCredential() throws Exception { mActivityTestRule.loadUrl(mUrl); + Fido2ApiHandler.overrideInstanceForTesting(mMockHandler); mActivityTestRule.runJavaScriptCodeInCurrentTab("doGetPublicKeyCredential()"); Assert.assertEquals("Success", mUpdateWaiter.waitForUpdate()); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetControllerTest.java index 34f0587..7ae1ccb 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/AccessorySheetControllerTest.java
@@ -92,10 +92,10 @@ mModel.addObserver(mMockPropertyObserver); mModel.getTabList().addObserver(mTabListObserver); - assertThat(mModel.getTabList().getItemCount(), is(0)); + assertThat(mModel.getTabList().size(), is(0)); mCoordinator.addTab(mTabs[0]); verify(mTabListObserver).onItemRangeInserted(mModel.getTabList(), 0, 1); - assertThat(mModel.getTabList().getItemCount(), is(1)); + assertThat(mModel.getTabList().size(), is(1)); } @Test @@ -103,20 +103,20 @@ mModel.addObserver(mMockPropertyObserver); // Initially, there is no active Tab. - assertThat(mModel.getTabList().getItemCount(), is(0)); + assertThat(mModel.getTabList().size(), is(0)); assertThat(mCoordinator.getTab(), is(nullValue())); // The first tab becomes the active Tab. mCoordinator.addTab(mTabs[0]); verify(mMockPropertyObserver).onPropertyChanged(mModel, PropertyKey.ACTIVE_TAB_INDEX); - assertThat(mModel.getTabList().getItemCount(), is(1)); + assertThat(mModel.getTabList().size(), is(1)); assertThat(mModel.getActiveTabIndex(), is(0)); assertThat(mCoordinator.getTab(), is(mTabs[0])); // A second tab is added but doesn't become automatically active. mCoordinator.addTab(mTabs[1]); verify(mMockPropertyObserver).onPropertyChanged(mModel, PropertyKey.ACTIVE_TAB_INDEX); - assertThat(mModel.getTabList().getItemCount(), is(2)); + assertThat(mModel.getTabList().size(), is(2)); assertThat(mModel.getActiveTabIndex(), is(0)); } @@ -126,12 +126,12 @@ mCoordinator.addTab(mTabs[1]); mCoordinator.addTab(mTabs[2]); mCoordinator.addTab(mTabs[3]); - assertThat(mModel.getTabList().getItemCount(), is(4)); + assertThat(mModel.getTabList().size(), is(4)); assertThat(mModel.getActiveTabIndex(), is(0)); mCoordinator.removeTab(mTabs[0]); - assertThat(mModel.getTabList().getItemCount(), is(3)); + assertThat(mModel.getTabList().size(), is(3)); assertThat(mModel.getActiveTabIndex(), is(0)); } @@ -140,7 +140,7 @@ mCoordinator.addTab(mTabs[0]); mCoordinator.removeTab(mTabs[0]); - assertThat(mModel.getTabList().getItemCount(), is(0)); + assertThat(mModel.getTabList().size(), is(0)); assertThat(mModel.getActiveTabIndex(), is(AccessorySheetModel.NO_ACTIVE_TAB)); } @@ -156,7 +156,7 @@ mCoordinator.removeTab(mTabs[2]); verify(mMockPropertyObserver).onPropertyChanged(mModel, PropertyKey.ACTIVE_TAB_INDEX); - assertThat(mModel.getTabList().getItemCount(), is(3)); + assertThat(mModel.getTabList().size(), is(3)); assertThat(mModel.getActiveTabIndex(), is(1)); } @@ -172,7 +172,7 @@ mCoordinator.removeTab(mTabs[1]); verify(mMockPropertyObserver).onPropertyChanged(mModel, PropertyKey.ACTIVE_TAB_INDEX); - assertThat(mModel.getTabList().getItemCount(), is(3)); + assertThat(mModel.getTabList().size(), is(3)); assertThat(mModel.getActiveTabIndex(), is(1)); } @@ -186,7 +186,7 @@ mCoordinator.removeTab(mTabs[3]); - assertThat(mModel.getTabList().getItemCount(), is(3)); + assertThat(mModel.getTabList().size(), is(3)); assertThat(mModel.getActiveTabIndex(), is(2)); } } \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java index b0d1dc13..5e10985 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java
@@ -102,13 +102,13 @@ // Calling addTab on the coordinator should make model propagate that it has a new tab. mCoordinator.addTab(mTestTab); verify(mMockTabListObserver).onItemRangeInserted(mModel.getTabList(), 0, 1); - assertThat(mModel.getTabList().getItemCount(), is(1)); + assertThat(mModel.getTabList().size(), is(1)); assertThat(mModel.getTabList().get(0), is(mTestTab)); // Calling hide on the coordinator should make model propagate that it's invisible. mCoordinator.removeTab(mTestTab); verify(mMockTabListObserver).onItemRangeRemoved(mModel.getTabList(), 0, 1); - assertThat(mModel.getTabList().getItemCount(), is(0)); + assertThat(mModel.getTabList().size(), is(0)); } @Test @@ -122,19 +122,19 @@ // If the coordinator receives an initial actions, the model should report an insertion. testProvider.notifyObservers(new Action[] {testAction}); verify(mMockActionListObserver).onItemRangeInserted(mModel.getActionList(), 0, 1); - assertThat(mModel.getActionList().getItemCount(), is(1)); + assertThat(mModel.getActionList().size(), is(1)); assertThat(mModel.getActionList().get(0), is(equalTo(testAction))); // If the coordinator receives a new set of actions, the model should report a change. testProvider.notifyObservers(new Action[] {testAction}); verify(mMockActionListObserver).onItemRangeChanged(mModel.getActionList(), 0, 1, null); - assertThat(mModel.getActionList().getItemCount(), is(1)); + assertThat(mModel.getActionList().size(), is(1)); assertThat(mModel.getActionList().get(0), is(equalTo(testAction))); // If the coordinator receives an empty set of actions, the model should report a deletion. testProvider.notifyObservers(new Action[] {}); verify(mMockActionListObserver).onItemRangeRemoved(mModel.getActionList(), 0, 1); - assertThat(mModel.getActionList().getItemCount(), is(0)); + assertThat(mModel.getActionList().size(), is(0)); // There should be no notification if no actions are reported repeatedly. testProvider.notifyObservers(new Action[] {}); @@ -194,7 +194,7 @@ @Test public void testIsVisibleWithActions() { // Without any actions, the accessory should remain invisible. - assertThat(mModel.getActionList().getItemCount(), is(0)); + assertThat(mModel.getActionList().size(), is(0)); mMediator.keyboardVisibilityChanged(true); assertThat(mModel.isVisible(), is(false)); @@ -206,7 +206,7 @@ @Test public void testIsVisibleWithTabs() { // Without any actions, the accessory should remain invisible. - assertThat(mModel.getActionList().getItemCount(), is(0)); + assertThat(mModel.getActionList().size(), is(0)); mMediator.keyboardVisibilityChanged(true); assertThat(mModel.isVisible(), is(false));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingControllerTest.java index 2e8f276..40c5228 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingControllerTest.java
@@ -111,14 +111,14 @@ .getModelForTesting(); accessorySheetModel.getTabList().addObserver(mMockTabListObserver); - assertThat(keyboardAccessoryModel.getTabList().getItemCount(), is(0)); + assertThat(keyboardAccessoryModel.getTabList().size(), is(0)); mController.getMediatorForTesting().addTab( new KeyboardAccessoryData.Tab(null, null, 0, null)); verify(mMockTabListObserver).onItemRangeInserted(keyboardAccessoryModel.getTabList(), 0, 1); verify(mMockTabListObserver).onItemRangeInserted(accessorySheetModel.getTabList(), 0, 1); - assertThat(keyboardAccessoryModel.getTabList().getItemCount(), is(1)); - assertThat(accessorySheetModel.getTabList().getItemCount(), is(1)); + assertThat(keyboardAccessoryModel.getTabList().size(), is(1)); + assertThat(accessorySheetModel.getTabList().size(), is(1)); } @Test @@ -196,7 +196,7 @@ mController.registerActionProvider(secondTabProvider); secondTabProvider.notifyObservers(new Action[] {}); mMockItemListObserver.onItemRangeRemoved(keyboardActions, 0, 1); - assertThat(keyboardActions.getItemCount(), is(0)); // No actions on this tab. + assertThat(keyboardActions.size(), is(0)); // No actions on this tab. // Simulate switching back to the first tab: switchTab(mediator, /*from=*/secondTab, /*to=*/firstTab); @@ -206,7 +206,7 @@ // And back to the second: switchTab(mediator, /*from=*/firstTab, /*to=*/secondTab); mMockItemListObserver.onItemRangeRemoved(keyboardActions, 0, 1); - assertThat(keyboardActions.getItemCount(), is(0)); // Still no actions on this tab. + assertThat(keyboardActions.size(), is(0)); // Still no actions on this tab. } @Test @@ -217,33 +217,33 @@ AccessorySheetModel accessorySheetModel = mediator.getAccessorySheet().getMediatorForTesting().getModelForTesting(); - assertThat(keyboardAccessoryModel.getTabList().getItemCount(), is(0)); - assertThat(accessorySheetModel.getTabList().getItemCount(), is(0)); + assertThat(keyboardAccessoryModel.getTabList().size(), is(0)); + assertThat(accessorySheetModel.getTabList().size(), is(0)); // Create a new tab with a passwords tab: Tab firstTab = addTab(mediator, 1111, null); mController.registerPasswordProvider(new PropertyProvider<>()); // There should be a tab in accessory and sheet: - assertThat(keyboardAccessoryModel.getTabList().getItemCount(), is(1)); - assertThat(accessorySheetModel.getTabList().getItemCount(), is(1)); + assertThat(keyboardAccessoryModel.getTabList().size(), is(1)); + assertThat(accessorySheetModel.getTabList().size(), is(1)); // Simulate creating a second tab without any tabs: Tab secondTab = addTab(mediator, 2222, firstTab); // There should be no tab in accessory and sheet: - assertThat(keyboardAccessoryModel.getTabList().getItemCount(), is(0)); - assertThat(accessorySheetModel.getTabList().getItemCount(), is(0)); + assertThat(keyboardAccessoryModel.getTabList().size(), is(0)); + assertThat(accessorySheetModel.getTabList().size(), is(0)); // Simulate switching back to the first tab: switchTab(mediator, /*from=*/secondTab, /*to=*/firstTab); // There should be a tab in accessory and sheet: - assertThat(keyboardAccessoryModel.getTabList().getItemCount(), is(1)); - assertThat(accessorySheetModel.getTabList().getItemCount(), is(1)); + assertThat(keyboardAccessoryModel.getTabList().size(), is(1)); + assertThat(accessorySheetModel.getTabList().size(), is(1)); // And back to the second: switchTab(mediator, /*from=*/firstTab, /*to=*/secondTab); // Still no tab in accessory and sheet: - assertThat(keyboardAccessoryModel.getTabList().getItemCount(), is(0)); - assertThat(accessorySheetModel.getTabList().getItemCount(), is(0)); + assertThat(keyboardAccessoryModel.getTabList().size(), is(0)); + assertThat(accessorySheetModel.getTabList().size(), is(0)); } // TODO(fhorschig): Test that updating tab1 works if tab2 is active.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetControllerTest.java index cbba5bb..c21db21 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetControllerTest.java
@@ -78,19 +78,19 @@ // If the coordinator receives an initial items, the model should report an insertion. testProvider.notifyObservers(new KeyboardAccessoryData.Item[] {testItem}); verify(mMockItemListObserver).onItemRangeInserted(mModel, 0, 1); - assertThat(mModel.getItemCount(), is(1)); + assertThat(mModel.size(), is(1)); assertThat(mModel.get(0), is(equalTo(testItem))); // If the coordinator receives a new set of items, the model should report a change. testProvider.notifyObservers(new KeyboardAccessoryData.Item[] {testItem}); verify(mMockItemListObserver).onItemRangeChanged(mModel, 0, 1, null); - assertThat(mModel.getItemCount(), is(1)); + assertThat(mModel.size(), is(1)); assertThat(mModel.get(0), is(equalTo(testItem))); // If the coordinator receives an empty set of items, the model should report a deletion. testProvider.notifyObservers(new KeyboardAccessoryData.Item[] {}); verify(mMockItemListObserver).onItemRangeRemoved(mModel, 0, 1); - assertThat(mModel.getItemCount(), is(0)); + assertThat(mModel.size(), is(0)); // There should be no notification if no item are reported repeatedly. testProvider.notifyObservers(new KeyboardAccessoryData.Item[] {});
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueueTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueueTest.java new file mode 100644 index 0000000..229b8ad --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueueTest.java
@@ -0,0 +1,130 @@ +// 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.download.home.glue; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; + +import org.chromium.base.Callback; +import org.chromium.base.CollectionUtil; +import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseRobolectricTestRunner; + +import java.io.File; +import java.util.concurrent.Semaphore; + +/** Unit tests for the FileDeletionQueue class. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class FileDeletionQueueTest { + @Mock + public Callback<File> mDeleter; + + @Rule + public MockitoRule mMockitoRule = MockitoJUnit.rule(); + + private CallbackWrapper mWrappedDeleter; + + @Before + public void setUp() { + mWrappedDeleter = new CallbackWrapper(mDeleter); + } + + @After + public void tearDown() { + mWrappedDeleter = null; + } + + @Test + public void testSingleDeletion() { + FileDeletionQueue queue = new FileDeletionQueue(mWrappedDeleter); + queue.delete(new File("test")); + + mWrappedDeleter.waitFor(1); + verify(mDeleter, times(1)).onResult(new File("test")); + } + + @Test + public void testMultipleDeletion() { + FileDeletionQueue queue = new FileDeletionQueue(mWrappedDeleter); + queue.delete(new File("test1")); + queue.delete(new File("test2")); + queue.delete(new File("test3")); + + mWrappedDeleter.waitFor(3); + verify(mDeleter, times(1)).onResult(new File("test1")); + verify(mDeleter, times(1)).onResult(new File("test2")); + verify(mDeleter, times(1)).onResult(new File("test3")); + } + + @Test + public void testMultipleDeletionsAPI() { + FileDeletionQueue queue = new FileDeletionQueue(mWrappedDeleter); + queue.delete(CollectionUtil.newArrayList( + new File("test1"), new File("test2"), new File("test3"))); + + mWrappedDeleter.waitFor(3); + verify(mDeleter, times(1)).onResult(new File("test1")); + verify(mDeleter, times(1)).onResult(new File("test2")); + verify(mDeleter, times(1)).onResult(new File("test3")); + } + + @Test + public void testOneDeletionHappensAtATime() { + FileDeletionQueue queue = new FileDeletionQueue(mWrappedDeleter); + queue.delete(CollectionUtil.newArrayList( + new File("test1"), new File("test2"), new File("test3"))); + + mWrappedDeleter.waitFor(1); + verify(mDeleter, times(1)).onResult(new File("test1")); + + mWrappedDeleter.waitFor(1); + verify(mDeleter, times(1)).onResult(new File("test2")); + + mWrappedDeleter.waitFor(1); + verify(mDeleter, times(1)).onResult(new File("test3")); + } + + private static class CallbackWrapper implements Callback<File> { + private final Callback<File> mWrappedCallback; + private final Semaphore mDeletedSemaphore = new Semaphore(0); + + public CallbackWrapper(Callback<File> wrappedCallback) { + mWrappedCallback = wrappedCallback; + } + + public void waitFor(int calls) { + long time = System.currentTimeMillis(); + + while (!mDeletedSemaphore.tryAcquire(calls)) { + if (time - System.currentTimeMillis() > 3000) Assert.fail(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); + Robolectric.flushBackgroundThreadScheduler(); + } + } + + // Callback<File> implementation. + @Override + public void onResult(File result) { + System.out.println("dtrainor: Releasing sempahore!"); + ThreadUtils.assertOnBackgroundThread(); + mWrappedCallback.onResult(result); + mDeletedSemaphore.release(); + } + } +} \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java index 3486a957..b008d49 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java
@@ -65,7 +65,7 @@ DateOrderedListMutator list = new DateOrderedListMutator(mSource, mModel); verify(mSource, times(1)).addObserver(list); - Assert.assertEquals(0, mModel.getItemCount()); + Assert.assertEquals(0, mModel.size()); } /** @@ -79,9 +79,9 @@ when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item1)); DateOrderedListMutator list = new DateOrderedListMutator(mSource, mModel); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 1, 1), item1); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 1, 1), item1); } /** @@ -97,10 +97,10 @@ when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item1, item2)); DateOrderedListMutator list = new DateOrderedListMutator(mSource, mModel); - Assert.assertEquals(3, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 1, 2), item1); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 1, 1), item2); + Assert.assertEquals(3, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 1, 2), item1); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 1, 1), item2); } /** @@ -117,11 +117,11 @@ when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item1, item2)); DateOrderedListMutator list = new DateOrderedListMutator(mSource, mModel); - Assert.assertEquals(4, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 0), item1); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(3), buildCalendar(2018, 1, 1, 0), item2); + Assert.assertEquals(4, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 0), item1); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(3), buildCalendar(2018, 1, 1, 0), item2); } /** @@ -137,10 +137,10 @@ when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item1, item2)); DateOrderedListMutator list = new DateOrderedListMutator(mSource, mModel); - Assert.assertEquals(3, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 1, 5), item2); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 1, 4), item1); + Assert.assertEquals(3, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 1, 5), item2); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 1, 4), item1); } /** @@ -157,11 +157,11 @@ when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item1, item2)); DateOrderedListMutator list = new DateOrderedListMutator(mSource, mModel); - Assert.assertEquals(4, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 4), item1); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(3), buildCalendar(2018, 1, 1, 5), item2); + Assert.assertEquals(4, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 4), item1); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(3), buildCalendar(2018, 1, 1, 5), item2); } /** @@ -178,11 +178,11 @@ when(mSource.getItems()).thenReturn(CollectionUtil.newArrayList(item1, item2)); DateOrderedListMutator list = new DateOrderedListMutator(mSource, mModel); - Assert.assertEquals(4, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 3), item2); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(3), buildCalendar(2018, 1, 1, 4), item1); + Assert.assertEquals(4, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 3), item2); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(3), buildCalendar(2018, 1, 1, 4), item1); } /** @@ -203,9 +203,9 @@ list.onItemsAdded(CollectionUtil.newArrayList(item1)); verify(mObserver, times(1)).onItemRangeInserted(mModel, 0, 2); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 1, 4), item1); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 1, 4), item1); } /** @@ -236,10 +236,10 @@ list.onItemsAdded(CollectionUtil.newArrayList(item2)); verify(mObserver, times(1)).onItemRangeInserted(mModel, 1, 1); - Assert.assertEquals(3, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 2), item2); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 2, 1), item1); + Assert.assertEquals(3, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 2), item2); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 2, 1), item1); // Add an item on an earlier day that will be placed first. OfflineItem item3 = buildItem("3", buildCalendar(2018, 1, 3, 2)); @@ -247,12 +247,12 @@ list.onItemsAdded(CollectionUtil.newArrayList(item3)); verify(mObserver, times(1)).onItemRangeInserted(mModel, 0, 2); - Assert.assertEquals(5, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 3, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 3, 2), item3); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(3), buildCalendar(2018, 1, 2, 2), item2); - assertListItemEquals(mModel.getItemAt(4), buildCalendar(2018, 1, 2, 1), item1); + Assert.assertEquals(5, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 3, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 3, 2), item3); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(3), buildCalendar(2018, 1, 2, 2), item2); + assertListItemEquals(mModel.get(4), buildCalendar(2018, 1, 2, 1), item1); } /** @@ -283,10 +283,10 @@ list.onItemsAdded(CollectionUtil.newArrayList(item2)); verify(mObserver, times(1)).onItemRangeInserted(mModel, 2, 1); - Assert.assertEquals(3, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 4), item1); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 2, 3), item2); + Assert.assertEquals(3, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 4), item1); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 2, 3), item2); // Add an item on a later day that will be placed last. OfflineItem item3 = buildItem("3", buildCalendar(2018, 1, 1, 4)); @@ -294,12 +294,12 @@ list.onItemsAdded(CollectionUtil.newArrayList(item3)); verify(mObserver, times(1)).onItemRangeInserted(mModel, 3, 2); - Assert.assertEquals(5, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 4), item1); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 2, 3), item2); - assertListItemEquals(mModel.getItemAt(3), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(4), buildCalendar(2018, 1, 1, 4), item3); + Assert.assertEquals(5, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 4), item1); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 2, 3), item2); + assertListItemEquals(mModel.get(3), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(4), buildCalendar(2018, 1, 1, 4), item3); } /** @@ -320,7 +320,7 @@ list.onItemsRemoved(CollectionUtil.newArrayList(item1)); verify(mObserver, times(1)).onItemRangeRemoved(mModel, 0, 2); - Assert.assertEquals(0, mModel.getItemCount()); + Assert.assertEquals(0, mModel.size()); } /** @@ -344,9 +344,9 @@ list.onItemsRemoved(CollectionUtil.newArrayList(item1)); verify(mObserver, times(1)).onItemRangeRemoved(mModel, 1, 1); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 2), item2); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 2), item2); } /** @@ -370,9 +370,9 @@ list.onItemsRemoved(CollectionUtil.newArrayList(item2)); verify(mObserver, times(1)).onItemRangeRemoved(mModel, 2, 1); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 3), item1); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 3), item1); } /** @@ -397,9 +397,9 @@ list.onItemsRemoved(CollectionUtil.newArrayList(item2)); verify(mObserver, times(1)).onItemRangeRemoved(mModel, 2, 2); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 3, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 3, 3), item1); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 3, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 3, 3), item1); } /** @@ -429,13 +429,13 @@ list.onItemsAdded(CollectionUtil.newArrayList(item1, item2, item3, item4)); verify(mObserver, times(1)).onItemRangeInserted(mModel, 0, 6); - Assert.assertEquals(6, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 12), item4); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 2, 10), item3); - assertListItemEquals(mModel.getItemAt(3), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(4), buildCalendar(2018, 1, 1, 6), item1); - assertListItemEquals(mModel.getItemAt(5), buildCalendar(2018, 1, 1, 4), item2); + Assert.assertEquals(6, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 12), item4); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 2, 10), item3); + assertListItemEquals(mModel.get(3), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(4), buildCalendar(2018, 1, 1, 6), item1); + assertListItemEquals(mModel.get(5), buildCalendar(2018, 1, 1, 4), item2); } /** @@ -468,9 +468,9 @@ verify(mObserver, times(1)).onItemRangeRemoved(mModel, 5, 1); verify(mObserver, times(1)).onItemRangeRemoved(mModel, 0, 3); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 1, 6), item1); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 1, 6), item1); } /** @@ -496,9 +496,9 @@ list.onItemUpdated(item1, newItem1); verify(mObserver, times(1)).onItemRangeChanged(mModel, 1, 1, null); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 1, 4), newItem1); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 1, 4), newItem1); } /** @@ -527,10 +527,10 @@ verify(mObserver, times(1)).onItemRangeRemoved(mModel, 1, 1); verify(mObserver, times(1)).onItemRangeInserted(mModel, 2, 1); - Assert.assertEquals(3, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 1, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 1, 4), item2); - assertListItemEquals(mModel.getItemAt(2), buildCalendar(2018, 1, 1, 3), newItem1); + Assert.assertEquals(3, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 1, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 1, 4), item2); + assertListItemEquals(mModel.get(2), buildCalendar(2018, 1, 1, 3), newItem1); } /** @@ -557,9 +557,9 @@ verify(mObserver, times(1)).onItemRangeRemoved(mModel, 0, 2); verify(mObserver, times(1)).onItemRangeInserted(mModel, 0, 2); - Assert.assertEquals(2, mModel.getItemCount()); - assertListItemEquals(mModel.getItemAt(0), buildCalendar(2018, 1, 2, 0), null); - assertListItemEquals(mModel.getItemAt(1), buildCalendar(2018, 1, 2, 6), newItem1); + Assert.assertEquals(2, mModel.size()); + assertListItemEquals(mModel.get(0), buildCalendar(2018, 1, 2, 0), null); + assertListItemEquals(mModel.get(1), buildCalendar(2018, 1, 2, 6), newItem1); } private static Calendar buildCalendar(int year, int month, int dayOfMonth, int hourOfDay) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/download/home/list/ItemUtilsTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/download/home/list/ItemUtilsTest.java new file mode 100644 index 0000000..7f842f3 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/download/home/list/ItemUtilsTest.java
@@ -0,0 +1,63 @@ +// 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.download.home.list; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.CollectionUtil; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.components.offline_items_collection.OfflineItem; + +import java.util.Collection; + +/** Unit tests for the ItemUtils class. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class ItemUtilsTest { + /** + * Test scenarios with which we might call + * {@link ItemUtils#findItemsWithSameFilePath(Collection, Collection)}. + */ + @Test + public void testFindItemsWithSameFilePath() { + OfflineItem item1 = buildItem("1", ""); + OfflineItem item2 = buildItem("2", ""); + OfflineItem item3 = buildItem("3", null); + OfflineItem item4 = buildItem("4", null); + OfflineItem item5 = buildItem("5", "path1"); + OfflineItem item6 = buildItem("6", "path1"); + OfflineItem item7 = buildItem("7", "path2"); + OfflineItem item8 = buildItem("8", "path3"); + OfflineItem item9 = buildItem("9", "path4"); + OfflineItem item10 = buildItem("10", "path4"); + OfflineItem item11 = buildItem("11", "path4"); + OfflineItem item12 = buildItem("12", "path5"); + + Collection<OfflineItem> items = CollectionUtil.newHashSet( + item1 /* Empty path includes item but not other empty paths. */, + item3 /* Null path includes item but not other null paths. */, + item5 /* Pull in duplicate path item. */, + item7 /* Pull in item with no duplicate paths by itself. */, + item9 /* Pull in item with two other matching paths. */, + item12 /* Item is included even if it does not exist in all items. */); + Collection<OfflineItem> allItems = CollectionUtil.newHashSet(item1, item2, item3, item4, + item5, item6, item7, item8, item9, item10, item11, item12); + allItems.addAll(items); + + Collection<OfflineItem> expected = CollectionUtil.newHashSet( + item1, item3, item5, item6, item7, item9, item10, item11, item12); + Assert.assertEquals(expected, ItemUtils.findItemsWithSameFilePath(items, allItems)); + } + + private static OfflineItem buildItem(String id, String filePath) { + OfflineItem item = new OfflineItem(); + item.id.id = id; + item.filePath = filePath; + return item; + } +} \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java index 0a89394..b2f92d9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java
@@ -35,6 +35,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.media.router.ClientRecord; import org.chromium.chrome.browser.media.router.cast.CastMessageHandler.RequestRecord; import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONObjectLike; import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONStringLike;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/modelutil/SimpleListObservableTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/modelutil/SimpleListObservableTest.java index 736afe9..727c11af 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/modelutil/SimpleListObservableTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/modelutil/SimpleListObservableTest.java
@@ -45,16 +45,16 @@ @Test public void testNotifiesSuccessfulInsertions() { // Replacing an empty list with a non-empty one is always an insertion. - assertThat(mIntegerList.getItemCount(), is(0)); + assertThat(mIntegerList.size(), is(0)); mIntegerList.set(new Integer[] {333, 88888888, 22}); verify(mObserver).onItemRangeInserted(mIntegerList, 0, 3); - assertThat(mIntegerList.getItemCount(), is(3)); + assertThat(mIntegerList.size(), is(3)); assertThat(mIntegerList.get(1), is(88888888)); // Adding Items is always an insertion. mIntegerList.add(55555); verify(mObserver).onItemRangeInserted(mIntegerList, 3, 1); - assertThat(mIntegerList.getItemCount(), is(4)); + assertThat(mIntegerList.size(), is(4)); assertThat(mIntegerList.get(3), is(55555)); } @@ -62,7 +62,7 @@ public void testModelNotifiesSuccessfulRemoval() { Integer eightEights = 88888888; mIntegerList.set(new Integer[] {333, eightEights, 22}); - assertThat(mIntegerList.getItemCount(), is(3)); + assertThat(mIntegerList.size(), is(3)); // Removing any item by instance is always a removal. mIntegerList.remove(eightEights);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/InnerNodeTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/InnerNodeTest.java index b9d527d..4e15adc1 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/InnerNodeTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/InnerNodeTest.java
@@ -221,7 +221,7 @@ private void checkCount(ListObservable child) { if (mNextExpectedItemCount == null) fail("Unexpected call"); - assertThat(child.getItemCount(), is(mNextExpectedItemCount)); + assertThat(((ChildNode) child).getItemCount(), is(mNextExpectedItemCount)); mNextExpectedItemCount = null; } }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 07c2468..a4f56e7d 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1652,7 +1652,7 @@ <message name="IDS_HID_DETECTION_CONTINUE_BUTTON" desc="Text shown on continue button" meaning="Continue button label of HID detection screen."> Continue </message> - <message name="IDS_NETWORK_SELECTION_CONTINUE_BUTTON" desc="Text shown on continue button" meaning="Continue button label of network screen."> + <message name="IDS_NETWORK_SELECTION_CONTINUE_BUTTON" desc="Text shown on continue button" meaning="Continue button label of welcome screen."> Continue </message> <message name="IDS_NETWORK_ENABLE_DEV_FEATURES_LINK" desc="Text shown on continue button" meaning="Link shown on OOBE screens that opens enable debugging features dialog"> @@ -4156,21 +4156,45 @@ Device Location </message> <!-- Administrator facing strings for Active Directory screens. --> - <message name="IDS_AD_MACHINE_NAME_INPUT_LABEL" desc="Admin-facing. Label for device name input field on the AD domain join screen. User should tell us the name of his device."> + <message name="IDS_AD_DEVICE_NAME_INPUT_LABEL" desc="Admin-facing. Label for device name input field on the Active Directory domain join screen. User should tell us the name of their device."> Chromebook device name </message> - <message name="IDS_AD_DOMAIN_JOIN_WELCOME_MESSAGE" desc="Admin-facing. Welcome message on the AD domain join screen."> + <message name="IDS_AD_DEVICE_NAME_REGEX_INPUT_LABEL" desc="Admin-facing. Label for device name input field on the Active Directory domain join screen. User should tell us the name of their device."> + Chromebook device name (<ph name="REGEX">$1<ex>^DEVICE_\d+$</ex></ph>) + </message> + <message name="IDS_AD_DOMAIN_JOIN_WELCOME_MESSAGE" desc="Admin-facing. Welcome message on the Active Directory domain join screen."> Join device to domain </message> <message name="IDS_AD_MORE_OPTIONS_BUTTON" desc="Admin-facing. Text on the 'More options' button on the Active Directory domain join screen."> More options </message> + <message name="IDS_AD_UNLOCK_CONFIG" desc="Admin-facing. Text on the button which opens 'Enter unlocking password' dialog on the Active Directory domain join screen."> + Unlock configuration + </message> + <message name="IDS_AD_UNLOCK_CONFIG_UNLOCK_BUTTON" desc="Admin-facing. Text on the button to use entered password to unlock domain join configuration."> + Unlock + </message> + <message name="IDS_AD_UNLOCK_CONFIG_PASSWORD" desc="Admin-facing. Label for unlocking password input field on the Active Directory domain join screen."> + Unlocking password + </message> + <message name="IDS_AD_UNLOCK_INCORRECT_PASSWORD" desc="Admin-facing. Error that is shown when incorrect unlocking password was entered."> + Incorrect password + </message> + <message name="IDS_AD_UNLOCK_PASSWORD_SKIP" desc="Admin-facing. Text on the button which skips entering unlocking password step."> + Skip + </message> <message name="IDS_AD_ORG_UNIT_HINT" desc="Admin-facing. Hint for the Active Directory Organizational units input on the 'More options' dialog."> Device OU (e.g. OU=Chromebooks,DC=example,DC=com) </message> <message name="IDS_AD_ENCRYPTION_SELECTION_SELECT" desc="Admin-facing. Title for kerberos encryption types selection."> Select encryption types </message> + <message name="IDS_AD_CONFIG_SELECTION_SELECT" desc="Admin-facing. Title for configuration selection."> + Select configuration + </message> + <message name="IDS_AD_CONFIG_SELECTION_CUSTOM" desc="Admin-facing. Title for a custom option of domain join config."> + Custom + </message> <message name="IDS_AD_ENCRYPTION_STRONG_TITLE" desc="Admin-facing. Title for 'Strong' kerberos types option."> Strong </message> @@ -4192,13 +4216,16 @@ <message name="IDS_AD_DOMAIN_JOIN_UNKNOWN_ERROR" desc="Admin-facing. Default error text on the Active Directory join screen"> Oops! Something went wrong when trying to join the domain. Please try again. </message> - <message name="IDS_AD_MACHINENAME_INVALID" desc="Admin-facing alert message. Admin entered a bad device name."> + <message name="IDS_AD_DEVICE_NAME_INVALID" desc="Admin-facing alert message. Admin entered a bad device name."> The device name is invalid. Enter a valid device name to try again. </message> - <message name="IDS_AD_MACHINENAME_TOO_LONG" desc="Admin-facing alert message. Admin entered a device name that was too long."> + <message name="IDS_AD_DEVICE_NAME_TOO_LONG" desc="Admin-facing alert message. Admin entered a device name that was too long."> The device name is too long. Enter a shorter name to try again. </message> - <message name="IDS_AD_USER_DENIED_TO_JOIN_MACHINE" desc="Admin-facing alert message. Admin doesn’t have privileges to add devices to the domain. 'Devices' refers to Chromebook computers. 'Domain' is the Windows domain that accounts are registered to."> + <message name="IDS_AD_DEVICE_NAME_DOESNT_MATCH_REGEX" desc="Admin-facing. Alert message about device name does not match regular expression"> + The device name must match regular expression <ph name="REGEX">$1<ex>^DEVICE_\d+$</ex></ph>. + </message> + <message name="IDS_AD_USER_DENIED_TO_JOIN_DEVICE" desc="Admin-facing alert message. Admin doesn’t have privileges to add devices to the domain. 'Devices' refers to Chromebook computers. 'Domain' is the Windows domain that accounts are registered to."> Can't join the domain. Check your account to see if you have sufficient privileges to add devices. </message> <message name="IDS_AD_USER_HIT_JOIN_QUOTA" desc="Admin-facing alert message. Administrator has reached the limit of devices that can be added."> @@ -4220,16 +4247,16 @@ Chrome <ph name="MS_AD_NAME">Microsoft® Active Directory®</ph> integration is only supported on x86_64 platforms. Chromebooks built on top of an ARM or x86 platform do not support this functionality. </message> <!-- User facing strings for Active Directory screens. --> - <message name="IDS_AD_DOMAIN_AUTH_WELCOME_MESSAGE" desc="Welcome message on the AD Authentication user screen. Include the domain (realm) the device joined to."> + <message name="IDS_AD_DOMAIN_AUTH_WELCOME_MESSAGE" desc="Welcome message on the Active Directory Authentication user screen. Include the domain (realm) the device joined to."> Sign in to <ph name="REALM">$1<ex>example.com</ex></ph> </message> - <message name="IDS_AD_ENROLLMENT_LOGIN_USER" desc="Label for userPrincipalName input field on the AD domain join user screen. Looks like user@example.com where example.com is the realm."> + <message name="IDS_AD_ENROLLMENT_LOGIN_USER" desc="Label for userPrincipalName input field on the Active Directory domain join user screen. Looks like user@example.com where example.com is the realm."> Username (e.g. user@example.com) </message> - <message name="IDS_AD_AUTH_LOGIN_USER" desc="Label for userPrincipalName input field on the AD authentication user screen."> + <message name="IDS_AD_AUTH_LOGIN_USER" desc="Label for userPrincipalName input field on the Active Directory authentication user screen."> Username </message> - <message name="IDS_AD_LOGIN_PASSWORD" desc="Label for Password input field on both AD domain join and AD Authorization user screens."> + <message name="IDS_AD_LOGIN_PASSWORD" desc="Label for Password input field on both Active Directory domain join and Active Directory Authorization user screens."> Password </message> <message name="IDS_AD_PASSWORD_CHANGE_OLD_PASSWORD_HINT" desc="Old password field hint on the Active Directory password change dialog."> @@ -4274,6 +4301,9 @@ <message name="IDS_AD_AUTH_NETWORK_ERROR" desc="Error message to show when there is a problem contacting the logon server when authenticating for Active Directory enrollment."> Oops! There was a problem contacting the logon server. Please check your network connection and the domain name, then try again. </message> + <message name="IDS_AD_JOIN_CONFIG_NOT_PARSED" desc="Alert message to say unlocked configuration could not be parsed."> + Oops! Can't parse domain join configuration. Please contact your administrator. + </message> <message name="IDS_AD_AUTH_UNKNOWN_ERROR" desc="Error message to show that occurs something a user could not fix."> Oops! An unknown error occurred. Please try again later or contact your administrator if the issue persists. </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index daba763..69cccc3e 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -6919,6 +6919,15 @@ <message name="IDS_PROFILES_SIGNIN_PROMO" desc="Text describing the benefits of signing in."> Sign in to get your bookmarks, history, passwords, and other settings on all your devices. </message> + <message name="IDS_PROFILES_PASSWORDS_LINK" desc="Text of the menu item leading to the list of saved passwords."> + Passwords + </message> + <message name="IDS_PROFILES_CREDIT_CARDS_LINK" desc="Text of the menu item leading to the list of saved credit cards."> + Credit cards + </message> + <message name="IDS_PROFILES_ADDRESSES_LINK" desc="Text of the menu item leading to the list of autofill addresses."> + Addresses + </message> <if expr="not use_titlecase"> <message name="IDS_PROFILES_DICE_SIGNIN_WITH_ANOTHER_ACCOUNT_BUTTON" desc="Button to sign in and turn on Sync with another web account."> Sync to another account
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb index 493d536a..aee45785 100644 --- a/chrome/app/resources/generated_resources_am.xtb +++ b/chrome/app/resources/generated_resources_am.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">የእረፍት ጊዜ ሊደርስ ነው</translation> <translation id="1062407476771304334">ተካ</translation> -<translation id="1064835277883315402">የግል አውታረ መረብን ይቀላቀሉ</translation> <translation id="1064912851688322329">የGoogle መለያዎትን ግንኙነት ያቋርጡ</translation> <translation id="1067048845568873861">ተፈጥሯል</translation> <translation id="1067291318998134776">Linux (ቅድመ-ይሁንታ)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">በመፈለግ ላይ...</translation> <translation id="1316495628809031177">ስምረት ባለበት ቆሟል</translation> <translation id="1319979322914001937">ከChrome የድር መደብር የመጡ ቅጥያዎች የተጣራ ዝርዝርን የሚያሳይ መተግበሪያ። በዝርዝሩ ውስጥ ያሉ ቅጥያዎች ከመተግበሪያው በቀጥታ ሊጫኑ ይችላሉ።</translation> -<translation id="132090119144658135">የርዕሰ ጉዳይ ተዛማጅ፦</translation> <translation id="1326317727527857210">ትሮችዎን ከሌሎች መሣሪያዎችዎ ለማግኘት ወደ Chrome ይግቡ።</translation> <translation id="1327074568633507428">በGoogle ደመና ህትመት ላይ ያለ አታሚ</translation> <translation id="1327977588028644528">አግባቢ ፍኖት</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">የመተግበሪያ መስኮት</translation> <translation id="1534389735079119190">ስህተት፦ መያዣውን በቪኤም ውስጥ ማስጀመር አልተሳካም።</translation> <translation id="15373452373711364">ትልቅ የመዳፊት ጠቋሚ</translation> +<translation id="1540605929960647700">የማሳያ ሁነታውን ያንቁ</translation> <translation id="1543284117603151572">ከEdge ላይ የመጣ</translation> <translation id="1545177026077493356">ራስ-ሰር የኪዮስክ ሁነታ</translation> <translation id="1545775234664667895">የተጫነ ገጽታ '<ph name="THEME_NAME" />'</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">የአጠቃቀም ስታቲክሶችን እና የስንኩል ሪፖርቶችን ወደ Google በቀጥታ በመላክ <ph name="PRODUCT_NAME" />ን የተሻለ ለማድረግ እገዛ ያድርጉ።</translation> <translation id="1658424621194652532">ይህ ገጽ ማይክሮፎንዎን እየደረሰበት ነው።</translation> <translation id="1660204651932907780">ጣቢያዎች ድምጽን እንዲያጫውቱ ፍቀድ (የሚመከር)</translation> +<translation id="1660938185063657230">የእርስዎን የደህንነት ቁልፍ ያረጋግጡ</translation> <translation id="1661156625580498328">የAES ምሥጠራን ተግብር (የሚመከር)።</translation> <translation id="1661245713600520330">ይህ ገጽ ሁሉም በዋናው ሂደት ላይ የተጫኑ እና በኋላ የተወሰነ ጊዜ ላይ እንዲጫኑ የተመዘገቡ ሞዱሎችን ይዘረዝራል።</translation> <translation id="166179487779922818">የይለፍ ቃሉ በጣም አጭር ነው።</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">ጣቢያዎች ወደ ቅንጥብ ሰሌዳው የተቀዱ ጽሑፍን እና ምስሎችን እንዲመለከቱ አትፍቀድ</translation> <translation id="1682548588986054654">አዲስ ማንነትን የማያሳውቅ መስኮት</translation> <translation id="168715261339224929">የእርስዎን ዕልባቶች በሁሉም መሣሪያዎችዎ ላይ ለማግኘት ስምረትን ያብሩ።</translation> +<translation id="1688867105868176567">የጣቢያ ውሂብ ይጸዳ?</translation> <translation id="1688935057616748272">አንድ ፊደል ይተይቡ</translation> <translation id="168991973552362966">በአቅራቢያ ያለ አታሚን ያክሉ</translation> <translation id="1689945336726856614">&ዩአርኤል ቅዳ</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">ይህን ሰው አስወግድ</translation> <translation id="1706586824377653884">በእርስዎ አስተዳዳሪ ታክሏል</translation> <translation id="1706625117072057435">የማጉላት ደረጃዎች</translation> -<translation id="1707463636381878959">ይህን አውታረ መረብ ለሌሎች ተጠቃሚዎች ያጋሩ</translation> <translation id="1708338024780164500">(የቦዘነ)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (መታወቂያ፦ <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (ቤተኛ)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">ገጽታን አንቃ</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">በChrome የድር መደብር ውስጥ ይመልከቱ</translation> -<translation id="1758831820837444715">የኤተርኔት አውታረ መረብ ያዋቅሩ</translation> <translation id="1763046204212875858">የመተግበሪያ አቋራጮችን ፍጠር</translation> <translation id="1763108912552529023">ማሰሱን ቀጥል</translation> <translation id="1763808908432309942">በአዲስ ትር ውስጥ ይከፍታል</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">ይህ ፋይል እንዴት እንደሚጋራ ይቀይሩ</translation> <translation id="1841545962859478868">የመሣሪያው አስተዳዳሪ የሚከተሉትን ሊከታተል ይችላል፦</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> ተሰናክሏል</translation> +<translation id="1842766183094193446">እርግጠኛ ነዎት የቅንጭብ ማሳያ ሁነታን ማንቃት ይፈልጋሉ?</translation> <translation id="1844692022597038441">ይህ ፋይል ከመስመር ውጪ አይገኝም።</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" />ን ለማሄድ Control-ጠቅ ያድርጉ</translation> +<translation id="1847880352285315359">የተቀመጡ</translation> <translation id="1848219224579402567">ክዳኑ ሲዘጋ ዘግተህ ውጣ</translation> <translation id="184823282865851239">ጣቢያ ጣልቃ ገቢ ማስታወቂያዎችን የማሳየት አዝማሚያ ካለው አግድ</translation> <translation id="1849186935225320012">ይህ ገጽ የMIDI መሳሪያዎች ሙሉ ቁጥጥር አለው።</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">ይሄንን በኋላ ቅንብሮች ውስጥ ሊለውጡት ይችላሉ</translation> <translation id="2006638907958895361">አገናኝን በ<ph name="APP" /> ውስጥ ይክፈቱ</translation> <translation id="2007404777272201486">ችግር ሪፖርት አድርግ...</translation> +<translation id="2016237810978710652">የLinux ፋይሎችን በመክፈት ላይ...</translation> <translation id="2016430552235416146">ተለምዷዊ</translation> <translation id="2017334798163366053">የአፈጻጸም የውሂብ መሰብሰብን አሰናክል</translation> <translation id="2017836877785168846">በአድራሻ አሞሌው ውስጥ ታሪክን እና ራስ-ሰር ማጠናቀቆችን ያጸዳል።</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">ካርትን ያርትዑ</translation> <translation id="2154710561487035718">URL ቅዳ</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> ይመስላል</translation> +<translation id="2156283799932971644">አንዳንድ የሥርዓት መረጃ እና የገጽ ይዘትን ወደ Google በመላክ የጥንቃቄ አሰሳን ለማሻሻል እንዲቻል ማገዝ ይችላሉ።</translation> <translation id="215753907730220065">ከሙሉ ገጽ ዕይታ ውጣ</translation> <translation id="2157875535253991059">ይህ ገጽ አሁን ሙሉ ማያ ገጽ ነው።</translation> <translation id="216169395504480358">Wi-Fi ያክሉ...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">የማግኛ መታወቂያ ወደዚህ መሣሪያ ያክሉ</translation> <translation id="2175042898143291048">ሁልጊዜ ይህን አድርግ</translation> <translation id="2175607476662778685">የፈጣን አጀማመር አሞሌ</translation> +<translation id="2176087259161165020">ሌሎች ምንጮች</translation> <translation id="2177950615300672361">ማንነት የማያሳውቅ ትር፦ <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">በ<ph name="PEPPER_PLUGIN_DOMAIN" /> ላይ ያለው <ph name="PEPPER_PLUGIN_NAME" /> ኮምፒውተርዎን መድረስ ይፈልጋል</translation> <translation id="2178614541317717477">CA Compromise</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">ቀጣዩ ትር</translation> <translation id="2292848386125228270"><ph name="PRODUCT_NAME" /> እባክዎ እንደ መደበኛ ተጠቃሚ ያስጀምሩት። እንደ ለግንባታ ስርወ ሆኖ ማሄድ ካስፈለግዎት፣ ከ--no-sandbox ጠቁም ጋር እንደገና ያሂዱት።</translation> <translation id="2294358108254308676"><ph name="PRODUCT_NAME" />ን መጫን ይፈልጋሉ?</translation> -<translation id="2296019197782308739">EAP ስልት፦</translation> <translation id="2297705863329999812">አታሚዎችን ይፈልጉ</translation> <translation id="2300383962156589922"><ph name="APP_NAME" />ን ያብጁት እና ይቆጣጠሩት</translation> <translation id="2301382460326681002">የቅጥያ ስርወ ማውጫ ልክ አይደለም።</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">ስህተት፦ <ph name="APP_NAME" />ን ማራገፍ አልተቻለም።</translation> <translation id="2367199180085172140">ፋይል አጋራን ያክሉ</translation> <translation id="2367972762794486313">መተግበሪያዎችን አሳይ</translation> +<translation id="2369536625682139252">ከኩኪዎች በስተቀር ሁሉም በ<ph name="SITE" /> የተከማቸው ውሂብ ይሰረዛል።</translation> <translation id="2371076942591664043">&ሲጠናቀቅ ክፈት</translation> <translation id="2377319039870049694">ወደ የዝርዝር እይታ ቀይር</translation> <translation id="2377667304966270281">ከባድ ስህተቶች</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">የስርዓት መገናኛ ተጠቅመው ያትሙ... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">ከመላክ በፊት ጠይቅ (የሚመከር)</translation> <translation id="2384436799579181135">አንድ ስህተት ተከስቷል። እባክዎ የእርስዎን አታሚ ያረጋግጡና እንደገና ይሞክሩ።</translation> -<translation id="2385700042425247848">የአገልግሎት ስም፦</translation> <translation id="2387458720915042159">የተኪ ግንኙነት አይነት</translation> <translation id="2391419135980381625">መደበኛ ቅርጸ-ቁምፊ</translation> <translation id="2391762656119864333">ሻር</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">ኦዲዮ አጋራ</translation> <translation id="2480868415629598489">እርስዎ የሚቀዱትን እና የሚለጥፉትን ውሂብ መቀየር</translation> <translation id="2482878487686419369">ማስታወቂያዎች</translation> -<translation id="2485056306054380289">የአገልጋይ CA እውቅና ማረጋገጫ፦</translation> <translation id="2485422356828889247">አራግፍ</translation> <translation id="2487067538648443797">አዲስ ዕልባት ያክሉ</translation> <translation id="248861575772995840">የእርስዎን ስልክ ማግኘት አልተቻለም። የእርስዎ <ph name="DEVICE_TYPE" /> ብሉቱዝ መብራቱን ያረጋግጡ። <a>የበለጠ ለመረዳት</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">የ<ph name="IDS_SHORT_PRODUCT_NAME" /> መሣሪያዎ ልክ እንደ አዲስ እንዲሆን ዳግም ለማስጀመር Powerwash።</translation> <translation id="2567257616420533738">የይለፍ ቃል ተቀምጧል። <ph name="SAVED_PASSWORDS_LINK" /> ላይ የተቀመጡ የይለፍ ቃላትን ይመልከቱ እና ያቀናብሩ</translation> <translation id="2568774940984945469">መረጃ አሞሌ መያዣ</translation> +<translation id="2570454805927264159">ከእርስዎ ረዳት ሊገኝ የሚችለውን ነገር ሁሉ ያግኙ</translation> <translation id="257088987046510401">ገፅታዎች </translation> <translation id="2572032849266859634">ወደ <ph name="VOLUME_NAME" /> ተነባቢ-ብቻ መዳረሻ ተሰጥቷል።</translation> <translation id="2573269395582837871">ስዕል እና ስም ይምረጡ</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">አስገባ</translation> <translation id="265390580714150011">የመስክ እሴት</translation> <translation id="2654166010170466751">ጣቢያዎች የክፍያ ተቆጣጣሪይዎችን እንዲጭኑ ይፍቀዱ</translation> -<translation id="2655386581175833247">የተጠቃሚ እውቅና ማረጋገጫ፦</translation> <translation id="2660779039299703961">ክስተት</translation> <translation id="266079277508604648">ከአታሚ ጋር መገናኘት አልተቻለም። አታሚው መብራቱንና በWi-Fi ወይም በዩኤስቢ ከእርስዎ Chromebook ጋር መገናኘቱን ያረጋግጡ።</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">ምንም የአጠቃቀም ውሂብ የለም</translation> <translation id="3007214526293698309">ውሱን ውድር</translation> <translation id="3007771295016901659">የተባዛ ትር</translation> +<translation id="3008272652534848354">ፈቃዶችን ዳግም ያቀናብሩ</translation> <translation id="3009300415590184725">እርግጠኛ ነዎት የተንቀሳቃሽ ስልክ ውሂብ አገልግሎት የማዋቀር ሂደቱን ይቅር ማለት ይፈልጋሉ?</translation> <translation id="3009779501245596802">በመረጃ ጠቋሚ የተሰናዱ የውሂብ ጎታዎች</translation> <translation id="3010279545267083280">የይለፍ ቃል ተሰርዟል</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">ሞዱሎች (<ph name="TOTAL_COUNT" />) - የታወቁ ግጭቶች፦ <ph name="BAD_COUNT" />፣ የተጠረጠሩ፦ <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">ቀን እና ሰዓት</translation> <translation id="310671807099593501">ጣቢያ ብሉቱዝን እየተጠቀመ ነው</translation> -<translation id="3108967419958202225">ይምረጡ...</translation> <translation id="3115128645424181617">የእርስዎን ስልክ ማግኘት አልተቻለም። በቅርብ ርቀት ላይ የሚችል መሆኑንና ብሉቱዝ መብራቱን ያረጋግጡ።</translation> <translation id="3115147772012638511">መሸጎጫ በመጠበቅ ላይ…</translation> <translation id="3118319026408854581">የ<ph name="PRODUCT_NAME" /> እገዛ</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">አንዳንድ የአገልግሎት አቅራቢዎች ይህን ባህሪ ሊያግዱት ይችላሉ።</translation> <translation id="316854673539778496">ሁሉንም የእርስዎ ቅጥያዎች በሁሉም መሣሪያዎችዎ ላይ ለማግኘት በመለያ ይግቡና ስምረትን ያብሩ።</translation> <translation id="3170072451822350649">እንዲሁም መግባቱን ትተው <ph name="LINK_START" />እንደ እንግዳ ማሰስ<ph name="LINK_END" /> ይችላሉ።</translation> -<translation id="3177048931975664371">የይለፍ ቃልን ለመደበቅ ጠቅ ያድርጉ</translation> <translation id="3177909033752230686">የገጽ ቋንቋ፦</translation> <translation id="3181110748548073003">ወደፊት ለመሄድ |<ph name="SHORTCUT" />|ን ይጫኑ</translation> <translation id="3182749001423093222">ፊደል አራሚ</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">ባለቤትነትን ወደ <ph name="DESTINATION_DOMAIN" /> ይዛወራል።</translation> <translation id="323803881985677942">የቅጥያ አማራጮችን ይክፈቱ</translation> <translation id="3241680850019875542">ለመሸከፍ የቅጥያውን ስርወ ማውጫ ይምረጡ። ቅጥያውን ለማዘመን እንዲሁ የግል ቁልፍ ፋይልን እንደገና ለመጠቀም ይምረጡ።</translation> -<translation id="3242765319725186192">ቅድሚያ የተጋራ ቁልፍ፦</translation> <translation id="3244294424315804309">ድምጽን መዝጋቱ ቀጥል</translation> <translation id="3245321423178950146">ያልታወቀ አርቲስት</translation> <translation id="3246097286174000800">Smart Lockን ይሞክሩት</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">ለ<ph name="BOOKMARK_NAME" /> ተጨማሪ እርምጃዎች</translation> <translation id="3440761377721825626">አንድ ጣቢያ ኮምፒውተርዎን ለመድረስ አንድ ተሰኪን መጠቀም ሲፈልግ ጠይቅ</translation> <translation id="3441653493275994384">ማያ ገጽ</translation> -<translation id="3445830502289589282">የክፍል 2 ማረጋገጥ፦</translation> <translation id="344630545793878684">የእርስዎን ውሂብ በበርካታ የድር ጣቢያዎች ላይ ያንብቡ</translation> <translation id="3449839693241009168">ትዕዛዞችን ለ<ph name="EXTENSION_NAME" /> ለመላክ <ph name="SEARCH_KEY" />ን ይጫኑ</translation> <translation id="3450157232394774192">የስራ-ፈት ሁኔታ ያዥነት መቶኛ</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> ስህተቶች።</translation> <translation id="3495660573538963482">የGoogle ረዳት ቅንብሮች</translation> <translation id="3496213124478423963">አሳንስ</translation> -<translation id="3504135463003295723">የቡድን ስም፦</translation> <translation id="3505030558724226696">የመሣሪያ መዳረሻ ሻር</translation> <translation id="3507421388498836150">ለ«<ph name="EXTENSION_NAME" />» አሁን ያሉት ፈቃዶች</translation> <translation id="3507547268929739059">የLinux መተግበሪያዎችን ለChromebook ያስወግዱ</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">በመለያ መግቢያ የእውቅና ማረጋገጫ የሚሠራ አይደለም፣ መስኮት በ<ph name="MINUTES" /> : <ph name="SECONDS" /> ውስጥ ይዘጋል</translation> <translation id="3664511988987167893">የቅጥያ አዶ</translation> <translation id="3665589677786828986">Chrome አንዳንድ ቅንብሮችዎ በሌላ ፕሮግራም መበላሸቱን አስተውሏል፣ እና ወደ የመጀመሪያዎቹ ነባሪዎቻቸው መልሷቸዋል።</translation> -<translation id="3665842570601375360">ደህንነት፦</translation> <translation id="3668570675727296296">የቋንቋ ቅንብሮች</translation> <translation id="3668823961463113931">ተቆጣጣሪዎች</translation> <translation id="3670229581627177274">ብሉቱዝን አብራ</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">የዚህ መሣሪያ ስርዓተ ፋይል ስለማይደገፍ ስላልሆነ ሊከፈት አይችልም።</translation> <translation id="3727148787322499904">ይህን ቅንብር መቀየር በሁሉም የተጋሩ አውታረ መረቦች ላይ ተጽዕኖ አለው</translation> <translation id="3727187387656390258">ብቅባይ መርምር</translation> -<translation id="3728067901555601989">ኦቲፒ፦</translation> <translation id="3732078975418297900">በመስመር <ph name="ERROR_LINE" /> ላይ ስህተት</translation> <translation id="3733127536501031542">SSL አገልጋይ ከነ ማሳደጊያው</translation> <translation id="3737536731758327622">የእርስዎ ውርዶች እዚህ ይታያሉ</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">ሲከናወን Enterን ይጫኑ</translation> <translation id="3827774300009121996">&በሙሉ ገጽ ማያ አሳይ</translation> <translation id="3828029223314399057">ዕልባቶች ፈልግ</translation> -<translation id="3829932584934971895">የአቅራቢ አይነት፦</translation> <translation id="3830674330436234648">መልሶ ማጫወት አይገኝም</translation> <translation id="3831486154586836914">የአጠቃላይ እይታ ሁኔታ መስኮት ገብቷል</translation> <translation id="383161972796689579">የዚህ መሣሪያ ባለቤት አዲስ ተጠቃሚዎች እንዳይታከሉ አሰናክሏል</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">የውሂብ አጠቃቀምን መለካት ተጠናቅቋል</translation> <translation id="3857228364945137633">የእርስዎ ስልክ በአቅራቢያ በሚሆንበት ጊዜ የእርስዎን <ph name="DEVICE_TYPE" /> ያለ ይለፍ ቃል ለመክፈት Smart Lockን ይሞክሩት።</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />፦ ማሳመር ባለበት ቆሟል</translation> <translation id="3860381078714302691">እንኳን ወደ Hangouts Meet በደህና መጡ</translation> <translation id="3862134173397075045">እንኳን ወደ በChrome ውስጥ የCast ተሞክሮ በደህና መጡ!</translation> <translation id="3862788408946266506">የ«kiosk_only» ዝርዝር ሰነድ አይነታ ያለው መተግበሪያ በChrome OS ኪዮስክ ሁኔታ ላይ መጫን አለበት።</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">አውታረ መረቡን ማቀናበር አልቻም</translation> <translation id="3970114302595058915">መታወቂያ</translation> <translation id="397105322502079400">በማስላት ላይ...</translation> -<translation id="3974195870082915331">የይለፍ ቃል ለማሳየት ጠቅ ያድርጉ</translation> <translation id="3975222297214566386">የግቤት አማራጮች አረፋ</translation> <translation id="397703832102027365">በማጠናቀቅ ላይ...</translation> <translation id="3979395879372752341">አዲስ ቅጥያ ታክሏል (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">የእርስዎን የዕውቅና ማረጋገጫ ይለፍ ቃል ያስገቡ</translation> <translation id="404493185430269859">ነባሪ የፍለጋ ፕሮግራም</translation> <translation id="4047112090469382184">ይሄ እንዴት ደህንነቱ የተጠበቀ እንደሆነ</translation> +<translation id="4051049974203704184">በማያ ገጽ ላለው ነገር መረጃ ያግኙ</translation> <translation id="4052120076834320548">በጣም ትንሽ</translation> <translation id="4055023634561256217">መሣሪያዎ በPowerwash ዳግም ሊጀምር ከመቻሉ በፊት ዳግም ማስጀመር ያስፈልጋል።</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2037,6 +2033,7 @@ <translation id="4088095054444612037">ለቡድኑ ተቀበል</translation> <translation id="4089235344645910861">ቅንብሮች ተቀምጠዋል። ስምረት ጀምሯል።</translation> <translation id="4090103403438682346">የተረጋገጠ መዳረሻ ያንቁ</translation> +<translation id="4090947011087001172">ለ<ph name="SITE" /> የጣቢያ ፈቃዶች ዳግም ይቀናበሩ?</translation> <translation id="4091434297613116013">የወረቀት ሉሆች</translation> <translation id="4093955363990068916">አካባቢያዊ ፋይል፦</translation> <translation id="4095507791297118304">ዋና ማሳያ</translation> @@ -2213,7 +2210,6 @@ <translation id="4419556793104466535">ስምረትን፣ ግላዊነት ማላበስን እና ተጨማሪ ነገሮችን ይቆጣጠሩ</translation> <translation id="4421932782753506458">ለስላሳ</translation> <translation id="4422347585044846479">ለእዚህ ገጽ ዕልባት አርትዕ</translation> -<translation id="4423104065312875417">ተጨማሪ የንግግር ፕሮግራሞችን ጫን</translation> <translation id="4423376891418188461">ቅንብሮችን ወደነበሩበት መልስ</translation> <translation id="4423482519432579560">&ፊደል አራሚ</translation> <translation id="442397852638519243"><ph name="USER_NAME" />፣ የእርስዎ አስተዳዳሪ የይለፍ ቃልዎን እንዲቀይሩ ይፈልግብዎታል።</translation> @@ -2238,7 +2234,6 @@ <translation id="4449996769074858870">ይህ ትር ድምጽ እያጫወተ ነው።</translation> <translation id="4450974146388585462">መርምር</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> ላይ ይፈልጉ ወይም ዩአርኤል ይተይቡ</translation> -<translation id="445923051607553918">የWi-Fi አውታረ መረብ ይቀላቀሉ</translation> <translation id="4462159676511157176">የብጁ ስም አገልጋዮች</translation> <translation id="4467100756425880649">የChrome የድር መደብር የሥነ ጥበብ ማዕከል</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> ዘርጋ</translation> @@ -2374,6 +2369,7 @@ <translation id="4682551433947286597">የግድግዳ ወረቀቶች በመግቢያ ገጹ ላይ ይታያሉ።</translation> <translation id="4684427112815847243">ሁሉንም ያመሳስሉ</translation> <translation id="4689421377817139245">ይህን ዕልባት ከእርስዎ iPhone ጋር ያስምሩት</translation> +<translation id="4690091457710545971"><አራት ፋይሎች በIntel Wi-Fi ፈርምዌር መንጭተዋል፦ csr.lst፣ fh_regs.lst፣ radio_reg.lst፣ monitor.lst.sysmon። የመጀመሪያዎቹ ሦስት የመዝገብ ተወጋጆችን የያዙ የሁለትዮሽ ፋይሎች ናቸው፣ እና ምንም የግል ወይም መሣሪያን ለይቶ የሚያሳውቅ መረጃን እንዳልያዙ በIntel የተረጋገጡ ናቸው። የመጨረሻው ፋይል ከIntel ፈርምዌር የሥራ ማስፈጸሚያ ዱካ ነው፤ ማናቸውም የግል ወይም መሣሪያን ለይቶ የሚያሳውቅ መረጃው እንዲራገፍ ተደርጓል። እነዚህ ፋይሎች የመነጩት በቅርቡ በእርስዎ መሣሪያ ላይ ከWi-Fi ጋር ለነበሩ ችግሮች እንደ ምላሽ ነው፣ እና ለእነዚህ ችግሮች መላ ለመፈለግ ለIntel ይጋራሉ።></translation> <translation id="4692302215262324251">የእርስዎ <ph name="DEVICE_TYPE" /> በተሳካ ሁኔታ በ<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ለኢንተርፕራይዝ አስተዳደር ተመዝግቧል። <ph name="LINE_BREAK_AND_EMPTY_LINE" /> ይህ ያልተጠበቀ ነገር ከነበረ እባክዎ ድጋፍን ያነጋግሩ።</translation> @@ -2633,6 +2629,7 @@ <translation id="5074318175948309511">አዲሶቹ ቅንብሮች ከመተግበራቸው በፊት ይህ ገጽ ዳግም መጫን ሊኖርበት ይችላል።</translation> <translation id="5075131525758602494">የሲም ፒን ያስገቡ</translation> <translation id="5078638979202084724">ለሁሉም ትሮች ዕልባት ያብጁ</translation> +<translation id="5079950360618752063">የተጠቆመ የይለፍ ቃልን ይጠቀሙ</translation> <translation id="5084230410268011727">ጣቢያዎች የእንቅስቃሴ እና የብርሃን ዳሳሾችን እንዲጠቀሙ ፍቀድ</translation> <translation id="5085162214018721575">ዝማኔዎችን በመፈተሽ ላይ</translation> <translation id="5086082738160935172">HID</translation> @@ -2671,6 +2668,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">ይህን ንጥል ሰርዝ</translation> <translation id="5139955368427980650">&ክፈት</translation> +<translation id="5142961317498132443">ማረጋገጥ</translation> <translation id="5143374789336132547">ይህ «<ph name="EXTENSION_NAME" />» ቅጥያ የመነሻ አዝራሩን ጠቅ ሲያደርጉ የሚታየውን ገጽ ቀይሮታል።</translation> <translation id="5143712164865402236">ወደ ሙሉ ገጽ ዕይታ ግባ</translation> <translation id="5145331109270917438">የተቀየረበት ቀን</translation> @@ -2841,7 +2839,6 @@ <translation id="5380103295189760361">የእነዚህ መቀየሪያዎች የቁልፍ ሰሌዳ አቋራጮችን ለማየት Control፣ Alt፣ Shift፣ ወይም Searchን ይያዙ።</translation> <translation id="5382591305415226340">የሚደገፉ አገናኞችን ያስተዳድሩ</translation> <translation id="5384883051496921101">ይህ ጣቢያ ማንነት ከማያሳውቅ ሁነታ ውጭ ላለ መተግበሪያ መረጃ ሊያጋራ ነው።</translation> -<translation id="5388588172257446328">የተጠቃሚው ስም፦</translation> <translation id="5388885445722491159">ተጣምሯል</translation> <translation id="5389237414310520250">አዲሱ ተጠቃሚ ሊፈጠር አልቻለም። እባክዎ የደረቅ አንጻፊዎ ቦታ እና ፍቃዶችን ያረጋግጡና እንደገና ይሞክሩ።</translation> <translation id="5390100381392048184">ጣቢያዎች ድምጽ እንዲያጫውቱ ፍቀድ</translation> @@ -2966,7 +2963,6 @@ <translation id="5551573675707792127">የቁልፍ ሰሌዳ እና የጽሑፍ ግቤት</translation> <translation id="5553089923092577885">የሰርቲፊኬት መመሪያ ጉድኝቶች</translation> <translation id="5554489410841842733">ቅጥያው በአሁኑ ገጽ ላይ በሚተገበርብት ጊዜ ይህ አዶ የሚታይ ይሆናል።</translation> -<translation id="5554573843028719904">ሌላ የWi-Fi አውታረ መረብ...</translation> <translation id="5554720593229208774">የኢሜይል እውቅና ማረጋገጫ ባለስልጣን</translation> <translation id="5556206011531515970">ነባሪ አሳሽዎን ለመምረጥ ቀጣይን ጠቅ ያድርጉ።</translation> <translation id="5556459405103347317">ዳግም ጫን</translation> @@ -3007,7 +3003,6 @@ <translation id="5610038042047936818">ወደ ካሜራ ሁነታ ቀይር</translation> <translation id="5612720917913232150"><ph name="URL" /> የኮምፒውተርዎን አካባቢ መጠቀም ይፈልጋል</translation> <translation id="5612734644261457353">ይቅርታ፣ የይለፍ ቃልዎ አሁንም ሊረጋገጥ አልቻለም። ማሳሰቢያ፦ የይለፍ ቃልዎን በቅርብ ጊዜ ቀይረው ከሆነ አዲስ የይለፍ ቃልዎ የሚተገበረው ሲወጡ ነው፣ እባክዎ የድሮውን ይለፍ ቃል እዚህ ይጠቀሙ።</translation> -<translation id="5613695965848159202">ስም-አልባ መታወቂያ፦</translation> <translation id="5614190747811328134">የተጠቃሚ ማሳወቂያ</translation> <translation id="561698261642843490">Firefoxን ዝጋ</translation> <translation id="5618075537869101857">ኤዲያ፣ የኪዮስክ መተግበሪያውን ማስጀመር አልተቻለም።</translation> @@ -3224,7 +3219,6 @@ <translation id="5941343993301164315">እባክዎ ወደ <ph name="TOKEN_NAME" /> ይግቡ።</translation> <translation id="5941711191222866238">አሳንስ</translation> <translation id="5946591249682680882">የሪፖርት መታወቂያ <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">የግል አውታረ መረብ ያክሉ</translation> <translation id="5949544233750246342">ፋይልን መተንተን አልተቻለም</translation> <translation id="5955282598396714173">የእርስዎ የይለፍ ቃል ጊዜው አልፎበታል። ለመቀየር እባክዎ ዘግተው ይውጡና እንደገና ይግቡ።</translation> <translation id="5956585768868398362">የጠበቁት የፍለጋ ገጽ ይሄ ነው?</translation> @@ -3385,11 +3379,13 @@ <translation id="6198102561359457428">ዘግተው ይውጡና ከዚያ እንደገና ይግቡ...</translation> <translation id="6198252989419008588">ፒን ይቀይሩ</translation> <translation id="6199801702437275229">የቦታ መረጃን በመጠበቅ ላይ...</translation> +<translation id="6204015976622790023">በማያ ገጽዎ ላይ ካለው ነገር ጋር የሚዛመዱ ተገቢ የአስተያየት ጥቆማዎችን ከረዳትዎ ይመልከቱ።</translation> <translation id="6205710420833115353">አንዳንድ ክወናዎች ከሚጠበቀው በላይ ጊዜ እየወሰዱ ነው። ሊያቋርጧቸው ይፈልጋሉ?</translation> <translation id="6206311232642889873">ምስል ቅ&ዳ</translation> <translation id="6207200176136643843">ወደ ነባሪ የማጉላት ደረጃ ዳግም አስጀምር</translation> <translation id="620722923698527029">ሁልጊዜ እነዚህን የአገናኝ አይነቶች በተጓዳኙ መተግበሪያ ውስጥ ክፈት</translation> <translation id="6207937957461833379">አገር/ክልል</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />፦ ስምረት እየሠራ አይደለም</translation> <translation id="6212039847102026977">የላቁ የአውታረ መረብ ባህሪያትን አሳይ</translation> <translation id="6212168817037875041">ማሳያን አጥፋ</translation> <translation id="6212752530110374741">የኢሜይል አገናኝ</translation> @@ -3427,7 +3423,6 @@ <translation id="6263541650532042179">ማመሳሰልን ዳግም አስጀምር</translation> <translation id="6264365405983206840">&ሁሉንም ምረጥ</translation> <translation id="6264422956566238156">ስምረትን አብርተዋል</translation> -<translation id="6265930187414222160">ተከናውኗል! ጎጂ ሶፍትዌር ተወግዷል።</translation> <translation id="6267166720438879315">ራስዎን ለ<ph name="HOST_NAME" /> ለማረጋገጥ ሰርቲፊኬት ይምረጡ</translation> <translation id="6268252012308737255">በ<ph name="APP" /> ክፈት</translation> <translation id="6268747994388690914">ዕልባቶችን ከኤች ቲ ኤም ኤል ፋይል አስመጣ...</translation> @@ -3534,7 +3529,6 @@ ወደ የእርስዎ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> መለያ መግባቱን ለመቀጠል እባክዎ «ቀጣይ»ን ጠቅ ያድርጉ።</translation> <translation id="6419546358665792306">ጭነት ተፈትቷል</translation> <translation id="642282551015776456">ይህ ስም የፋይል ወይም አቃፊ ስም ሆኖ ሊያገለግል አይችልም።</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">የChromeVox ቅንብሮችን ክፈት</translation> <translation id="6429384232893414837">የማዘመን ስህተት</translation> <translation id="6430814529589430811">Base64-encoded ASCII፣ ነጠላ ሰርቲፊኬት</translation> @@ -3615,7 +3609,6 @@ <translation id="6544215763872433504">በGoogle የቀረበ የድር አሳሽ፣ ለእርስዎ</translation> <translation id="6545665334409411530">የድግግሞሽ ፍጥነት</translation> <translation id="6545834809683560467">በአድራሻ አሞሌ ወይም በመተግበሪያ ማስጀመሪያ ሳጥኑ ውስጥ የተተየቡ ፍለጋዎችን እና ዩአርኤሎችን ለማጠናቀቅ የመገመቻ አገልግሎት ይጠቀሙ።</translation> -<translation id="6546686722964485737">የWiMAX አውታረ መረብ ይቀላቀሉ</translation> <translation id="6547316139431024316">ለዚህ ቅጥያ ዳግም አታስጠንቅቅ</translation> <translation id="6547354035488017500">ቢያንስ 512 ሜባ ባዶ ቦታ ያስለቅቁ ወይም የእርስዎ መሣሪያ ምላሽ የማይሰጥ ይሆናል። ቦታ ለማስለቀቅ ፋይሎችን ከመሣሪያ ማከማቻው ይሰርዙ።</translation> <translation id="6549689063733911810">የቅርብ ጊዜ</translation> @@ -4034,7 +4027,6 @@ <translation id="7201014958346994077">የLinux ፋይሎችን መመልከት አልተቻለም</translation> <translation id="720110658997053098">ይህን መሣሪያ እስከመጨረሻው በኪዮስክ ሁነታ አቆየው</translation> <translation id="7201118060536064622">«<ph name="DELETED_ITEM_NAME" />» ተሰርዟል</translation> -<translation id="7205869271332034173">SSID፦</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" />ን በማውረድ ላይ...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{ከገጽ ውጣ}one{ከገጾች ውጣ}other{ከገጾች ውጣ}}</translation> <translation id="7216409898977639127">የተንቀሳቃሽ ስልክ አገልግሎት አቅራቢ</translation> @@ -4512,7 +4504,6 @@ <translation id="7909969815743704077">በIncognito ውስጥ የወረደ</translation> <translation id="7910768399700579500">&አዲስ አቃፊ</translation> <translation id="7912080627461681647">የእርስዎ የይለፍ ቃል በአገልጋዩ ላይ ተቀይሯል። እባክዎ ዘግተው ይውጡና እንደገና ይግቡ።</translation> -<translation id="7912883689016444961">የተንቀሳቃሽ ስልክ አውታረ መረብን አዋቅር</translation> <translation id="7915471803647590281">ግብረ መልሱን ከመላክዎ በፊት እባክዎ ምን እየተከሰተ እንደሆነ ይንገሩን።</translation> <translation id="7916556741383518510">ጠቅ ሲደረግ</translation> <translation id="792514962475806987">የተተከለ ማጉያ ደረጃ፦</translation> @@ -4566,7 +4557,6 @@ <translation id="7988355189918024273">የተደራሽነት ቅንብሮች ያንቁ</translation> <translation id="7994702968232966508">የEAP ስልት</translation> <translation id="799547531016638432">አቋራጭ ያስወግዱ</translation> -<translation id="7997479212858899587">ማንነት፦</translation> <translation id="7997826902155442747">የቅድሚያ ሂደት</translation> <translation id="7999229196265990314">'የሚከተሉትን ፋይሎች ፈጥሯል፦ nil @@ -4655,7 +4645,6 @@ <translation id="8105368624971345109">አጥፋ</translation> <translation id="8106045200081704138">ከእኔ ጋር የተጋሩ</translation> <translation id="8107015733319732394">የGoogle Play መደብርን በእርስዎ <ph name="DEVICE_TYPE" /> ላይ በመጫን ላይ። ይሄ ጥቂት ደቂቃዎችን ሊወስድ ይችላል።</translation> -<translation id="8109930990200908494">ለተጠቀሚ እውቅና ማረጋገጫ በመለያ መግባት ይስፈልጋል።</translation> <translation id="8111155949205007504">ይህን የይለፍ ቃል ለእርስዎ iPhone ያጋሩ</translation> <translation id="8113043281354018522">የፈቃድ አይነት ይምረጡ</translation> <translation id="8116190140324504026">ተጨማሪ መረጃ...</translation> @@ -4666,6 +4655,7 @@ <translation id="8118860139461251237">ማውረድዎችዎን ያስተዳድሩ</translation> <translation id="81238879832906896">ቢጫ እና ነጭ አበባ</translation> <translation id="8124313775439841391">የሚቀናበር ONC</translation> +<translation id="8125562866093998907">ጣቢያው የእርስዎን የደህንነት ቁልፍ ለእርስዎ መለያ ተጨማሪ ደህንነትን ለማከል ሊያረጋግጠው ይፈልጋል።</translation> <translation id="813082847718468539">የጣቢያ መረጃን ይመልከቱ</translation> <translation id="8131740175452115882">አረጋግጥ</translation> <translation id="8133676275609324831">&በአቃፊ ውስጥ አሳይ</translation> @@ -4776,7 +4766,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> የእርስዎ ካሜራ መድረስ የሚፈልግ ከሆነ ይጠይቅ</translation> <translation id="830868413617744215">ቅድመ-ይሁንታ</translation> <translation id="8309458809024885768">የእውቅና ማረጋገጫ አስቀድሞ አለ</translation> -<translation id="8309505303672555187">አውታረ መረብ ይምረጡ፦</translation> <translation id="8312871300878166382">ወደ አቃፊ ውስጥ ይለጥፉ</translation> <translation id="8317671367883557781">የአውታረ መረብ ግንኙነት ያክሉ</translation> <translation id="8319414634934645341">የተስፋፋ ቁልፍ አጠቃቀም</translation> @@ -4851,7 +4840,6 @@ <translation id="8451512073679317615">ረዳት</translation> <translation id="8452135315243592079">ሲም ካርድ ይጎድላል</translation> <translation id="8453482423012550001">$1 ንጥሎችን በመቅዳት ላይ...</translation> -<translation id="8454288007744638700">ወይም ደግሞ አዲስ አውታረ መረብ ይምረጡ፦</translation> <translation id="845627346958584683">ጊዜው የሚቃጠልበት ጊዜ</translation> <translation id="8456681095658380701">ልክ ያልሆነ ስም</translation> <translation id="8457451314607652708">ዕልባቶችን አስመጣ</translation> @@ -4915,6 +4903,7 @@ <translation id="855081842937141170">ትር አጣብቅ</translation> <translation id="8551388862522347954">ፍቃዶች</translation> <translation id="8553342806078037065">ሌሎች ሰዎችን አቀናብር</translation> +<translation id="8554899698005018844">ምንም ቋንቋ</translation> <translation id="855773602626431402">በማጠሪያ ያልተቀመጠ ተሰኪ በዚህ ገጽ ላይ እንዳይሄድ ታግዷል።</translation> <translation id="8557930019681227453">ዝርዝር ሰነድ</translation> <translation id="8559694214572302298">ምስል ከጽምጽ ጋር አዛምዶ አንባቢ</translation> @@ -4952,7 +4941,6 @@ <translation id="862727964348362408">ተንጠልጥሏል</translation> <translation id="862750493060684461">የCSS መሸጎጫ</translation> <translation id="8627795981664801467">ጥብቅ የሆኑ ግንኙነቶች ብቻ</translation> -<translation id="8628085465172583869">የአገልጋይ አስተናጋጅ ስም፦</translation> <translation id="8630903300770275248">ትክክል የሚደረግበት ተጠቃሚ አስመጣ</translation> <translation id="8631032106121706562">እንቡጥ አበቦች</translation> <translation id="8637542770513281060">የእርስዎ ኮምፒውተር ደህንነቱ የተጠበቀ ሞዱል አለው፣ ይህም በChrome OS ውስጥ ብዙ ወሳኝ የደህንነት ባህሪያትን ለመተግበር ሥራ ላይ የሚውል ነው። የበለጠ ለመረዳት የChromebook እገዛ ማዕከሉን ይጎብኙ፦ https://support.google.com/chromebook/?p=sm</translation> @@ -5208,7 +5196,6 @@ <translation id="899403249577094719">የNetscape ሰርቲፊኬት መሰረት</translation> <translation id="8995603266996330174">የተቀናበረው በ<ph name="DOMAIN" /></translation> <translation id="8996526648899750015">መለያ ያክሉ...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">የዲስክ ምስልን በመፍጠር ላይ።</translation> <translation id="9003647077635673607">በሁሉም ድር ጣቢያዎች ላይ ፍቀድ</translation> <translation id="9003677638446136377">እንደገና ፈትሽ</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb index 98c18be..d1c69154 100644 --- a/chrome/app/resources/generated_resources_ar.xtb +++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">سيتم قفل الجهاز بعد قليل</translation> <translation id="1062407476771304334">استبدال</translation> -<translation id="1064835277883315402">الانضمام إلى شبكة خاصة</translation> <translation id="1064912851688322329">قطع الاتصال بحساب Google</translation> <translation id="1067048845568873861">تم الإنشاء</translation> <translation id="1067291318998134776">نظام التشغيل Linux (نسخة تجريبية)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">جارِ البحث...</translation> <translation id="1316495628809031177">تم إيقاف المزامنة مؤقتًا</translation> <translation id="1319979322914001937">أحد التطبيقات التي تعرض قائمة مُفلترة بالإضافات من سوق Chrome الإلكتروني. يمكن تثبيت الإضافات الموجودة في القائمة من التطبيق مباشرةً.</translation> -<translation id="132090119144658135">مطابقة الموضوع:</translation> <translation id="1326317727527857210">للحصول على علامات التبويب من أجهزتك الأخرى، سجّل الدخول إلى Chrome.</translation> <translation id="1327074568633507428">طابعة مسجلة في الطباعة السحابية من Google</translation> <translation id="1327977588028644528">المدخل</translation> @@ -377,6 +375,7 @@ <translation id="1531004739673299060">نافذة التطبيق</translation> <translation id="1534389735079119190">خطأ: تعذّر بدء الحاوية داخل الجهاز الافتراضي (VM).</translation> <translation id="15373452373711364">مؤشر الماوس الكبير</translation> +<translation id="1540605929960647700">تفعيل الوضع التجريبي</translation> <translation id="1543284117603151572">تم الاستيراد من شبكة Edge</translation> <translation id="1545177026077493356">وضع الكشك التلقائي</translation> <translation id="1545775234664667895">تم تثبيت المظهر "<ph name="THEME_NAME" />".</translation> @@ -460,6 +459,7 @@ <translation id="1657406563541664238">المساعدة في تحسين <ph name="PRODUCT_NAME" /> بإرسال إحصاءات الاستخدام وتقارير الأعطال إلى Google تلقائيًا</translation> <translation id="1658424621194652532">هذه الصفحة تحاول الدخول إلى الميكروفون.</translation> <translation id="1660204651932907780">السماح للمواقع بتشغيل الصوت (مُقترح)</translation> +<translation id="1660938185063657230">التحقُّق من صحة مفتاح الأمان</translation> <translation id="1661156625580498328">فرض تشفير AES (مستحسن)</translation> <translation id="1661245713600520330">تدرج هذه الصفحة جميع الوحدات التي تم تحميلها في العملية الرئيسية والوحدات المسجلة للتحميل في وقت لاحق.</translation> <translation id="166179487779922818">كلمة المرور أقصر مما يجب.</translation> @@ -477,6 +477,7 @@ <translation id="16815041330799488">عدم السماح لمواقع الويب بالاطلاع على النصوص والصور التي تم نسخها إلى الحافظة</translation> <translation id="1682548588986054654">نافذة جديدة للتصفح المتخفي</translation> <translation id="168715261339224929">للحصول على الإشارات المرجعية على جميع أجهزتك، يُرجى تفعيل المزامنة.</translation> +<translation id="1688867105868176567">هل تريد محو بيانات موقع الويب؟</translation> <translation id="1688935057616748272">يرجى كتابة حرف.</translation> <translation id="168991973552362966">إضافة طابعة قريبة</translation> <translation id="1689945336726856614">نسخ &عنوان URL</translation> @@ -488,7 +489,6 @@ <translation id="1701062906490865540">إزالة هذا الشخص</translation> <translation id="1706586824377653884">تمت الإضافة من قبل المشرف</translation> <translation id="1706625117072057435">مستويات التكبير/التصغير</translation> -<translation id="1707463636381878959">مشاركة هذه الشبكة مع مستخدمين آخرين</translation> <translation id="1708338024780164500">(غير نشطة)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (رقم التعريف: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (الأصلي)</translation> @@ -524,7 +524,6 @@ <translation id="175772926354468439">تفعيل المظهر</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">العرض في سوق Chrome الإلكتروني</translation> -<translation id="1758831820837444715">تهيئة شبكة Ethernet</translation> <translation id="1763046204212875858">إنشاء اختصارات للتطبيق</translation> <translation id="1763108912552529023">متابعة الاستكشاف</translation> <translation id="1763808908432309942">تفتح الصفحة في علامة تبويب جديدة</translation> @@ -583,8 +582,10 @@ <translation id="1839704667838141620">تغيير كيفية مشاركة هذا الملف</translation> <translation id="1841545962859478868">قد يراقب مشرف الجهاز ما يلي:</translation> <translation id="1841705068325380214">تم إيقاف <ph name="EXTENSION_NAME" /></translation> +<translation id="1842766183094193446">هل تريد حقًا تفعيل الوضع التجريبي؟</translation> <translation id="1844692022597038441">هذا الملف غير متاح بلا إنترنت.</translation> <translation id="1846308012215045257">انقر بالماوس مع الضغط على مفتاح Ctrl لتشغيل <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">تم الحفظ</translation> <translation id="1848219224579402567">تسجيل الخروج عند إغلاق الغطاء</translation> <translation id="184823282865851239">الحظر إذا كان الموقع يميل إلى عرض إعلانات متداخلة</translation> <translation id="1849186935225320012">تتضمن هذه الصفحة إمكانية تحكم شامل في أجهزة MIDI.</translation> @@ -682,6 +683,7 @@ <translation id="200544492091181894">يمكنك تغيير هذا الخيار من الإعدادات متى شئت.</translation> <translation id="2006638907958895361">فتح الرابط في <ph name="APP" /></translation> <translation id="2007404777272201486">الإبلاغ عن مشكلة...</translation> +<translation id="2016237810978710652">جارٍ فتح ملفات نظام التشغيل Linux...</translation> <translation id="2016430552235416146">التقليدي</translation> <translation id="2017334798163366053">إيقاف جمع بيانات مستوى الأداء</translation> <translation id="2017836877785168846">مسح السجل وعمليات الإكمال التلقائي في شريط العناوين.</translation> @@ -776,6 +778,7 @@ <translation id="2154484045852737596">تعديل البطاقة</translation> <translation id="2154710561487035718">نسخ عنوان URL</translation> <translation id="2155772377859296191">تبدو كـ <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">يمكنك المساعدة في تحسين التصفُّح الآمن عن طريق إرسال بعض معلومات النظام ومحتوى الصفحة إلى Google.</translation> <translation id="215753907730220065">إنهاء وضع ملء الشاشة</translation> <translation id="2157875535253991059">هذه الصفحة في وضع ملء الشاشة الآن.</translation> <translation id="216169395504480358">إضافة Wi-Fi...</translation> @@ -785,6 +788,7 @@ <translation id="2173801458090845390">إضافة معرّف الطلبات إلى هذا الجهاز</translation> <translation id="2175042898143291048">أجرِ ذلك دائمًا</translation> <translation id="2175607476662778685">شريط التشغيل السريع</translation> +<translation id="2176087259161165020">مصادر أخرى</translation> <translation id="2177950615300672361">علامة تبويب التصفح المتخفي: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">يريد <ph name="PEPPER_PLUGIN_NAME" /> الموجود على <ph name="PEPPER_PLUGIN_DOMAIN" /> الوصول إلى جهاز الكمبيوتر.</translation> <translation id="2178614541317717477">اختراق المرجع المصدق (CA)</translation> @@ -868,7 +872,6 @@ <translation id="2291643155573394834">علامة التبويب التالية</translation> <translation id="2292848386125228270">يُرجى بدء تشغيل <ph name="PRODUCT_NAME" /> كمستخدم عادي. إذا كنت بحاجة إلى إجراء تشغيل كجذر لأغراض متعلقة بالتطوير، يمكنك إعادة التشغيل باستخدام العلامة التي لا تتضمن وضع الحماية.</translation> <translation id="2294358108254308676">هل تريد تثبيت <ph name="PRODUCT_NAME" />؟</translation> -<translation id="2296019197782308739">طريقة EAP:</translation> <translation id="2297705863329999812">البحث في الطابعات</translation> <translation id="2300383962156589922">تخصيص <ph name="APP_NAME" /> والتحكّم فيه</translation> <translation id="2301382460326681002">دليل الجذر للإضافة غير صالح.</translation> @@ -916,6 +919,7 @@ <translation id="2366463953911599217">خطأ: تعذّر إلغاء تثبيت <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">إضافة "مشاركة ملف"</translation> <translation id="2367972762794486313">إظهار التطبيقات</translation> +<translation id="2369536625682139252">سيتم حذف جميع البيانات المُخزَّنة بواسطة <ph name="SITE" /> باستثناء ملفات تعريف الارتباط.</translation> <translation id="2371076942591664043">فتح الملفّ عند &انتهاء التحميل</translation> <translation id="2377319039870049694">تبديل إلى عرض القائمة</translation> <translation id="2377667304966270281">الأخطاء الجسيمة</translation> @@ -925,7 +929,6 @@ <translation id="2379281330731083556">الطباعة باستخدام مربع حوار النظام... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">اسأل قبل الإرسال (موصى به)</translation> <translation id="2384436799579181135">حدث خطأ ما. يُرجى التحقق من الطابعة وإعادة المحاولة.</translation> -<translation id="2385700042425247848">اسم الخدمة:</translation> <translation id="2387458720915042159">نوع الاتصال بالخادم الوكيل</translation> <translation id="2391419135980381625">الخط القياسي</translation> <translation id="2391762656119864333">إبطال</translation> @@ -976,7 +979,6 @@ <translation id="247949520305900375">مشاركة الصوت</translation> <translation id="2480868415629598489">تعديل البيانات التي يتم نسخها ولصقها</translation> <translation id="2482878487686419369">الاشعارات</translation> -<translation id="2485056306054380289">شهادة المرجع المصدق (CA) للخادم:</translation> <translation id="2485422356828889247">إزالة التثبيت</translation> <translation id="2487067538648443797">إضافة إشارة مرجعية جديدة</translation> <translation id="248861575772995840">تعذّر العثور على هاتفك. تأكد من تشغيل البلوتوث لجهاز <ph name="DEVICE_TYPE" />. <a>مزيد من المعلومات</a></translation> @@ -1037,6 +1039,7 @@ <translation id="2566124945717127842">يمكنك إجراء Powerwash لإعادة تعيين جهاز <ph name="IDS_SHORT_PRODUCT_NAME" /> ليصبح كما لو كان جديدًا.</translation> <translation id="2567257616420533738">تم حفظ كلمة المرور. عرض كلمات المرور المحفوظة وإدارتها في <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">حاوية شريط المعلومات</translation> +<translation id="2570454805927264159">تحقيق أقصى استفادة من "المساعد"</translation> <translation id="257088987046510401">المظاهر</translation> <translation id="2572032849266859634">تم منح إذن دخول للقراءة فقط إلى <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">اختر صورة واسمًا</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">إرسال</translation> <translation id="265390580714150011">قيمة الحقل</translation> <translation id="2654166010170466751">السماح لمواقع الويب بتثبيت معالجات الدفع</translation> -<translation id="2655386581175833247">شهادة المستخدم:</translation> <translation id="2660779039299703961">حدث</translation> <translation id="266079277508604648">يتعذّر الاتصال بالطابعة. تحقق مما إذا كانت الطابعة مُفعّلة ومتصلة بجهاز Chromebook عن طريق Wi-Fi أو USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">لا تتوفر بيانات استخدام</translation> <translation id="3007214526293698309">إصلاح النسبة</translation> <translation id="3007771295016901659">تكرار علامة التبويب</translation> +<translation id="3008272652534848354">إعادة ضبط الأذونات</translation> <translation id="3009300415590184725">هل تريد فعلًا إلغاء عملية إعداد خدمة بيانات الجوال؟</translation> <translation id="3009779501245596802">قواعد بيانات مفهرسة</translation> <translation id="3010279545267083280">تم حذف كلمة المرور</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">الوحدات (<ph name="TOTAL_COUNT" />) - عدد التعارضات المعروفة: <ph name="BAD_COUNT" />، المشتبه بها: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">التاريخ والوقت</translation> <translation id="310671807099593501">يستخدم موقع الويب البلوتوث.</translation> -<translation id="3108967419958202225">اختيار...</translation> <translation id="3115128645424181617">تعذّر العثور على هاتفك. تأكد من أنه في متناول يديك وأنّ البلوتوث قيد التشغيل.</translation> <translation id="3115147772012638511">في انتظار ذاكرة التخزين المؤقت ...</translation> <translation id="3118319026408854581">مساعدة <ph name="PRODUCT_NAME" /></translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">قد يحظر بعض مشغلي شبكات الجوّال هذه الميزة.</translation> <translation id="316854673539778496">للحصول على كل الإضافات على جميع أجهزتك، يُرجى تسجيل الدخول وتفعيل المزامنة.</translation> <translation id="3170072451822350649">يمكنك أيضًا تخطي تسجيل الدخول و<ph name="LINK_START" />التصفح كضيف<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">انقر لإخفاء كلمة المرور</translation> <translation id="3177909033752230686">لغة الصفحة:</translation> <translation id="3181110748548073003">اضغط على |<ph name="SHORTCUT" />| للانتقال إلى الأمام</translation> <translation id="3182749001423093222">التدقيق الإملائي</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">سيتم نقل الملكية إلى <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">فتح خيارات الإضافة</translation> <translation id="3241680850019875542">حدد الدليل الجذر للإضافة المراد إنشاء حزمة لها، ولتحديث إضافة، حدد أيضًا ملف المفتاح الخاص لإعادة استخدامه.</translation> -<translation id="3242765319725186192">مفتاح مشترك مسبقًا:</translation> <translation id="3244294424315804309">استمرار كتم الصوت</translation> <translation id="3245321423178950146">فنان غير معروف</translation> <translation id="3246097286174000800">تجربة Smart Lock</translation> @@ -1606,7 +1606,6 @@ <translation id="3440663250074896476">مزيد من الإجراءات للإشارة المرجعية <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">السؤال عند محاولة أحد مواقع الويب استخدام مكون إضافي للوصول إلى جهاز الكمبيوتر</translation> <translation id="3441653493275994384">الشاشة</translation> -<translation id="3445830502289589282">مصادقة المرحلة الثانية</translation> <translation id="344630545793878684">قراءة بياناتك على عدد من مواقع الويب</translation> <translation id="3449839693241009168">اضغط على <ph name="SEARCH_KEY" /> لإرسال الأوامر إلى <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">نسبة الإشغال لحالة الخمول</translation> @@ -1647,7 +1646,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> من الأخطاء.</translation> <translation id="3495660573538963482">إعدادات مساعد Google</translation> <translation id="3496213124478423963">تصغير</translation> -<translation id="3504135463003295723">اسم المجموعة:</translation> <translation id="3505030558724226696">إبطال الوصول إلى الجهاز</translation> <translation id="3507421388498836150">الأذونات الحالية لـ "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">إزالة تطبيقات Linux لـ Chromebook</translation> @@ -1756,7 +1754,6 @@ <translation id="3661054927247347545">شهادة تسجيل الدخول غير صالحة، وسيتم غلق النافذة خلال <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">رمز الإضافة</translation> <translation id="3665589677786828986">اكتشف Chrome أن بعض إعداداتك تم إتلافها من قبل برنامج آخر وإعادة تعيينها للحالة التلقائية الأصلية.</translation> -<translation id="3665842570601375360">الأمان:</translation> <translation id="3668570675727296296">إعدادات اللغة</translation> <translation id="3668823961463113931">المعالجات</translation> <translation id="3670229581627177274">تشغيل البلوتوث</translation> @@ -1795,7 +1792,6 @@ <translation id="3726463242007121105">لا يمكن فتح الجهاز لأن نظام الملفات غير متوافق.</translation> <translation id="3727148787322499904">سيؤثر تغيير هذا الإعداد في جميع الشبكات المشتركة</translation> <translation id="3727187387656390258">فحص النوافذ المنبثقة</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">خطأ في السطر رقم <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">خادم بروتوكول SSL (طبقة المقابس الآمنة) مع الترقية</translation> <translation id="3737536731758327622">تظهر تنزيلاتك هنا</translation> @@ -1870,7 +1866,6 @@ <translation id="38275787300541712">اضغط على Enter عند الانتهاء</translation> <translation id="3827774300009121996">&ملء الشاشة</translation> <translation id="3828029223314399057">بحث في الإشارات المرجعية</translation> -<translation id="3829932584934971895">نوع مقدم الخدمة:</translation> <translation id="3830674330436234648">لا تتوفر أي عملية تشغيل</translation> <translation id="3831486154586836914">تم الدخول إلى وضع النظرة العامة على النافذة</translation> <translation id="383161972796689579">أوقف مالك هذا الجهاز إمكانية إضافة مستخدمين جدد.</translation> @@ -1891,6 +1886,7 @@ <translation id="3856921555429624101">انتهى قياس استخدام البيانات</translation> <translation id="3857228364945137633">يمكنك تجربة Smart Lock لإلغاء قفل جهاز <ph name="DEVICE_TYPE" /> من دون كلمة المرور عندما يكون هاتفك قريبًا.</translation> <translation id="3857773447683694438">أبجد هوز حطي كلمن سعفص قرشت</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: تم إيقاف المزامنة مؤقتًا</translation> <translation id="3860381078714302691">مرحبًا بك في Hangouts Meet</translation> <translation id="3862134173397075045">مرحبًا بكم في تجربة الإرسال في Chrome!</translation> <translation id="3862788408946266506">يجب تثبيت التطبيق الذي يحمل سمة البيان "kiosk_only" في وضع الكشك على نظام تشغيل Chrome.</translation> @@ -1965,7 +1961,6 @@ <translation id="3968261067169026421">تعذَّر إعداد الشبكة</translation> <translation id="3970114302595058915">رقم التعريف</translation> <translation id="397105322502079400">جارٍ الحساب...</translation> -<translation id="3974195870082915331">انقر لإظهار كلمة المرور</translation> <translation id="3975222297214566386">فقاعة تفسيرية لخيارات الإدخال</translation> <translation id="397703832102027365">جارٍ الإنهاء...</translation> <translation id="3979395879372752341">تمت إضافة إحدى الإضافات الجديدة (<ph name="EXTENSION_NAME" />)</translation> @@ -2007,6 +2002,7 @@ <translation id="4044612648082411741">إدخال كلمة المرور للشهادة</translation> <translation id="404493185430269859">محرك البحث التلقائي</translation> <translation id="4047112090469382184">كم هذا آمن</translation> +<translation id="4051049974203704184">الحصول على معلومات حول العناصر المعروضة على الشاشة</translation> <translation id="4052120076834320548">دقيق</translation> <translation id="4055023634561256217">يُتطلب إعادة تشغيل الجهاز حتى يتسنى لك إعادة تعيينه باستخدام Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2035,6 +2031,7 @@ <translation id="4088095054444612037">الموافقة للمجموعة</translation> <translation id="4089235344645910861">تم حفظ الإعدادات، وبدأت عملية المزامنة.</translation> <translation id="4090103403438682346">تفعيل الدخول الذي تم التحقق منه</translation> +<translation id="4090947011087001172">هل تريد إعادة ضبط أذونات موقع الويب لـ <ph name="SITE" />؟</translation> <translation id="4091434297613116013">أوراق</translation> <translation id="4093955363990068916">الملف المحلي:</translation> <translation id="4095507791297118304">شاشة أساسية</translation> @@ -2211,7 +2208,6 @@ <translation id="4419556793104466535">التحكُّم في المزامنة والتخصيص والمزيد</translation> <translation id="4421932782753506458">الانتفاش</translation> <translation id="4422347585044846479">تعديل إشارة هذه الصفحة</translation> -<translation id="4423104065312875417">تثبيت محركات كلام إضافية</translation> <translation id="4423376891418188461">استعادة الإعدادات</translation> <translation id="4423482519432579560">ال&تدقيق الإملائي</translation> <translation id="442397852638519243">يا <ph name="USER_NAME" />، يطلب منك مشرفك تغيير كلمة المرور.</translation> @@ -2236,7 +2232,6 @@ <translation id="4449996769074858870">تشغّل علامة التبويب هذه صوتًا.</translation> <translation id="4450974146388585462">التشخيص</translation> <translation id="4453946976636652378">البحث في <ph name="SEARCH_ENGINE_NAME" /> أو كتابة عنوان URL</translation> -<translation id="445923051607553918">الانضمام إلى شبكة Wi-Fi</translation> <translation id="4462159676511157176">خوادم أسماء مخصصة</translation> <translation id="4467100756425880649">معرض سوق Chrome الإلكتروني</translation> <translation id="4467101674048705704">توسيع <ph name="FOLDER_NAME" /></translation> @@ -2372,6 +2367,7 @@ <translation id="4682551433947286597">تظهر الخلفيات على شاشة تسجيل الدخول.</translation> <translation id="4684427112815847243">مزامنة كل شيء</translation> <translation id="4689421377817139245">مزامنة هذه الإشارة المرجعة على جهاز iPhone</translation> +<translation id="4690091457710545971"><تم إنشاء أربعة ملفات من خلال برامج Intel Wi-Fi الثابتة وهي كما يلي: csr.lst وfh_regs.lst وradio_reg.lst وmonitor.lst.sysmon. والملفات الثلاثة الأولى هي ملفات ثنائية تحتوي على عمليات تفريغ التسجيل ويتم تقييمها من خلال Intel لعدم احتوائها على أي معلومات شخصية أو معلومات تحديد هوية الجهاز. الملف الأخير عبارة عن تتبُّع تنفيذ من البرامج الثابتة Intel، وتم تنقيحه من أي معلومات شخصية أو معلومات تحديد هوية الجهاز، ولكنه كبير الحجم للغاية لعرضه هنا. وتم إنشاء هذه الملفات استجابةً لمشاكل Wi-Fi الأخيرة مع جهازك، وستتم مشاركتها مع Intel للمساعدة في تحرّي هذه المشاكل وإصلاحها.></translation> <translation id="4692302215262324251">لقد تم تسجيل جهاز <ph name="DEVICE_TYPE" /> بنجاح لإدارة المؤسسة من قبل <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> إذا لم يكن ذلك متوقعًا، يُرجى الاتصال بالدعم.</translation> @@ -2630,6 +2626,7 @@ <translation id="5074318175948309511">قد تحتاج هذه الصفحة إلى إعادة التحميل قبل تنفيذ الإعدادات الجديدة.</translation> <translation id="5075131525758602494">أدخل رمز PIN لشريحة SIM</translation> <translation id="5078638979202084724">وضع إشارات على كل علامات التبويب</translation> +<translation id="5079950360618752063">استخدام كلمة مرور مُقترَحة</translation> <translation id="5084230410268011727">السماح للمواقع باستخدام أجهزة استشعار الإضاءة والحركة</translation> <translation id="5085162214018721575">جارٍ البحث عن تحديثات</translation> <translation id="5086082738160935172">جهاز واجهة بشرية (HID)</translation> @@ -2668,6 +2665,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">حذف هذا العنصر</translation> <translation id="5139955368427980650">ف&تح</translation> +<translation id="5142961317498132443">المصادقة</translation> <translation id="5143374789336132547">غيّرت الإضافة "<ph name="EXTENSION_NAME" />" الصفحة التي تظهر عند النقر على زر الصفحة الرئيسية.</translation> <translation id="5143712164865402236">دخول إلى وضع ملء الشاشة</translation> <translation id="5145331109270917438">تاريخ التعديل</translation> @@ -2838,7 +2836,6 @@ <translation id="5380103295189760361">اضغط مع الاستمرار على Control أو Alt أو Shift أو Search لمشاهدة اختصارات لوحة المفاتيح لتلك المعدّلات.</translation> <translation id="5382591305415226340">إدارة الروابط المدعومة</translation> <translation id="5384883051496921101">موقع الويب هذا على وشك مشاركة معلومات مع أحد التطبيقات خارج وضع التصفح المتخفي.</translation> -<translation id="5388588172257446328">اسم المستخدم:</translation> <translation id="5388885445722491159">مقترن</translation> <translation id="5389237414310520250">تعذّر إنشاء المستخدم الجديد. يُرجى التحقق من مساحة محرك الأقراص الثابتة والأذونات، وإعادة المحاولة.</translation> <translation id="5390100381392048184">السماح للمواقع بتشغيل الصوت</translation> @@ -2963,7 +2960,6 @@ <translation id="5551573675707792127">لوحة المفاتيح وإدخال النص</translation> <translation id="5553089923092577885">تعيينات سياسة الشهادة</translation> <translation id="5554489410841842733">سيظهر هذا الرمز عند عمل الإضافة في الصفحة الحالية.</translation> -<translation id="5554573843028719904">شبكة Wi-Fi أخرى...</translation> <translation id="5554720593229208774">المرجع المصدق للبريد الإلكتروني</translation> <translation id="5556206011531515970">انقر على "التالي" لاختيار المتصفح التلقائي.</translation> <translation id="5556459405103347317">إعادة تحميل</translation> @@ -3004,7 +3000,6 @@ <translation id="5610038042047936818">التبديل إلى وضع الكاميرا</translation> <translation id="5612720917913232150">يريد <ph name="URL" /> استخدام الموقع الجغرافي لجهاز الكمبيوتر.</translation> <translation id="5612734644261457353">عذرًا، لا يزال التحقق من كلمة المرور متعذرًا. ملاحظة: في حالة تغيير كلمة المرور مؤخرًا، فإنه سيتم تطبيق كلمة المرور بعد الخروج، يُرجى استخدام كلمة المرور القديمة هنا.</translation> -<translation id="5613695965848159202">هوية مجهولة:</translation> <translation id="5614190747811328134">إشعار المستخدم</translation> <translation id="561698261642843490">إغلاق Firefox</translation> <translation id="5618075537869101857">عذرًا، تعذر تشغيل تطبيق Kiosk.</translation> @@ -3222,7 +3217,6 @@ <translation id="5941343993301164315">يُرجى تسجيل الدخول إلى <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">تصغير</translation> <translation id="5946591249682680882">معرف التقرير: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">إضافة شبكة خاصة</translation> <translation id="5949544233750246342">تعذَّر تحليل الملف</translation> <translation id="5955282598396714173">انتهت صلاحية كلمة المرور. يُرجى الخروج ثم تسجيل الدخول مجددًا لتغييرها.</translation> <translation id="5956585768868398362">هل هذه هي صفحة البحث التي كنت تتوقع ظهورها؟</translation> @@ -3384,11 +3378,13 @@ <translation id="6198102561359457428">الخروج ثم إعادة تسجيل الدخول...</translation> <translation id="6198252989419008588">تغيير رقم التعريف الشخصي</translation> <translation id="6199801702437275229">في انتظار معلومات المساحة...</translation> +<translation id="6204015976622790023">يمكنك الاطِّلاع على اقتراحات ذات صلة من "المساعد" متعلِّقة بالمحتوى المعروض على شاشتك.</translation> <translation id="6205710420833115353">تستغرق بعض العمليات وقتًا أطول من المتوقع. هل تريد إيقافها؟</translation> <translation id="6206311232642889873">نس&خ صورة</translation> <translation id="6207200176136643843">إعادة الضبط على مستوى التكبير/التصغير التلقائي</translation> <translation id="620722923698527029">فتح هذه الأنواع من الروابط دائمًا في التطبيق المرتبط</translation> <translation id="6207937957461833379">البلد/المنطقة</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: المزامنة لا تعمل</translation> <translation id="6212039847102026977">عرض خصائص الشبكة المتقدمة</translation> <translation id="6212168817037875041">إيقاف تشغيل الشاشة</translation> <translation id="6212752530110374741">إرسال الرابط عبر البريد الإلكتروني</translation> @@ -3426,7 +3422,6 @@ <translation id="6263541650532042179">إعادة تعيين المزامنة</translation> <translation id="6264365405983206840">تحديد &الكل</translation> <translation id="6264422956566238156">تم تفعيل المزامنة</translation> -<translation id="6265930187414222160">تمت إزالة البرامج الضارة.</translation> <translation id="6267166720438879315">حدّد شهادة للمصادقة مع <ph name="HOST_NAME" />.</translation> <translation id="6268252012308737255">فتح باستخدام <ph name="APP" /></translation> <translation id="6268747994388690914">استيراد الإشارات المرجعية من ملف HTML...</translation> @@ -3533,7 +3528,6 @@ يُرجى النقر على "التالي" لمتابعة تسجيل الدخول إلى حسابك <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">تحميل إضافة تم فك حزمتها</translation> <translation id="642282551015776456">لا يمكن استخدام هذا الاسم كملف باسم مجلد</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">فتح إعدادات Chromevox</translation> <translation id="6429384232893414837">خطأ في التحديث</translation> <translation id="6430814529589430811">حفظ شهادة واحدة بتشفير ASCII المرمّز باستخدام Base64</translation> @@ -3614,7 +3608,6 @@ <translation id="6544215763872433504">متصفح الويب المقدم من Google، لك</translation> <translation id="6545665334409411530">معدل التكرار</translation> <translation id="6545834809683560467">يمكنك استخدام خدمة التوقع لمساعدتك في إكمال عبارات البحث وعناوين URL التي تكتبها في شريط العناوين أو في مربع بحث تطبيقات Launcher</translation> -<translation id="6546686722964485737">الانضمام إلى شبكة WiMAX</translation> <translation id="6547316139431024316">لا أريد التحذير مرة أخرى بشأن هذه الإضافة</translation> <translation id="6547354035488017500">احرص على تفريغ مساحة قدرها 512 ميغابايت على الأقل أو سيصبح جهازك غير مستجيب. لتفريغ مساحة، يمكنك حذف الملفات من سعة تخزين الجهاز.</translation> <translation id="6549689063733911810">الأحدث</translation> @@ -4033,7 +4026,6 @@ <translation id="7201014958346994077">تعذَّر عرض ملفات Linux</translation> <translation id="720110658997053098">تشغيل هذا الجهاز في وضع الكشك دائمًا</translation> <translation id="7201118060536064622">تم حذف "<ph name="DELETED_ITEM_NAME" />"</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">جارٍ تنزيل <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{الخروج من الصفجة}zero{الخروج من صفحة}two{الخروج من الصفحتين}few{الخروج من صفحات}many{الخروج من صفحة}other{الخروج من صفحة}}</translation> <translation id="7216409898977639127">موفر شبكة الجوّال</translation> @@ -4512,7 +4504,6 @@ <translation id="7909969815743704077">تم التحميل في وضع التصفح المتخفي</translation> <translation id="7910768399700579500">م&جلّد جديد</translation> <translation id="7912080627461681647">تم تغيير كلمة المرور على الخادم. يُرجى الخروج ثم تسجيل الدخول مجددًا.</translation> -<translation id="7912883689016444961">تهيئة شبكة الجوّال</translation> <translation id="7915471803647590281">يُرجى إخبارنا بما يحدث قبل إرسال التعليقات.</translation> <translation id="7916556741383518510">عند النقر</translation> <translation id="792514962475806987">مستوى التكبير الذي تم إرساؤه:</translation> @@ -4566,7 +4557,6 @@ <translation id="7988355189918024273">تفعيل ميزات إمكانية الدخول</translation> <translation id="7994702968232966508">طريقة EAP</translation> <translation id="799547531016638432">إزالة الاختصار</translation> -<translation id="7997479212858899587">الهوية:</translation> <translation id="7997826902155442747">أولوية المعالجة</translation> <translation id="7999229196265990314">تم إنشاء الملفات التالية: @@ -4650,7 +4640,6 @@ <translation id="8105368624971345109">إيقاف</translation> <translation id="8106045200081704138">تمت مشاركتها معي</translation> <translation id="8107015733319732394">تثبيت متجر Google Play على <ph name="DEVICE_TYPE" />. قد يستغرق ذلك بضع دقائق.</translation> -<translation id="8109930990200908494">تسجيل الدخول مطلوب لشهادة المستخدم.</translation> <translation id="8111155949205007504">مشاركة كلمة المرور هذه مع جهاز iPhone</translation> <translation id="8113043281354018522">اختيار نوع الترخيص</translation> <translation id="8116190140324504026">مزيد من المعلومات...</translation> @@ -4661,6 +4650,7 @@ <translation id="8118860139461251237">إدارة التنزيلات</translation> <translation id="81238879832906896">زهرة صفراء وبيضاء</translation> <translation id="8124313775439841391">ONC مُدار</translation> +<translation id="8125562866093998907">يحتاج موقع الويب إلى التحقُّق من مفتاح الأمان لزيادة مستوى الأمان لحسابك.</translation> <translation id="813082847718468539">عرض معلومات الموقع</translation> <translation id="8131740175452115882">التأكيد</translation> <translation id="8133676275609324831">&عرض في المجلد</translation> @@ -4771,7 +4761,6 @@ <translation id="8308179586020895837">الرجوع إليك عند رغبة <ph name="HOST" /> في الدخول إلى الكاميرا</translation> <translation id="830868413617744215">تجريبي</translation> <translation id="8309458809024885768">الشهادة موجودة من قَبل</translation> -<translation id="8309505303672555187">حدّد شبكة:</translation> <translation id="8312871300878166382">لصق في مجلد</translation> <translation id="8317671367883557781">إضافة اتصال شبكة</translation> <translation id="8319414634934645341">استخدام المفتاح الموسع</translation> @@ -4846,7 +4835,6 @@ <translation id="8451512073679317615">المساعد</translation> <translation id="8452135315243592079">شريحة SIM مفقودة</translation> <translation id="8453482423012550001">جارٍ نسخ $1 من العناصر...</translation> -<translation id="8454288007744638700">أو تحديد شبكة جديدة:</translation> <translation id="845627346958584683">وقت انتهاء الصلاحية:</translation> <translation id="8456681095658380701">اسم غير صالح</translation> <translation id="8457451314607652708">استيراد الإشارات المرجعية</translation> @@ -4910,6 +4898,7 @@ <translation id="855081842937141170">تثبيت علامة التبويب</translation> <translation id="8551388862522347954">التراخيص</translation> <translation id="8553342806078037065">إدارة الأشخاص الآخرين</translation> +<translation id="8554899698005018844">بدون لغة</translation> <translation id="855773602626431402">تم منع تشغيل مكون إضافي غير محمي على هذه الصفحة.</translation> <translation id="8557930019681227453">البيان</translation> <translation id="8559694214572302298">أداة فك تشفير الصور</translation> @@ -4947,7 +4936,6 @@ <translation id="862727964348362408">معلقة</translation> <translation id="862750493060684461">ذاكرة التخزين المؤقت للغة CSS</translation> <translation id="8627795981664801467">الاتصالات الآمنة فقط</translation> -<translation id="8628085465172583869">اسم المضيف للخادم:</translation> <translation id="8630903300770275248">استيراد مستخدم يخضع للإشراف</translation> <translation id="8631032106121706562">البتلات</translation> <translation id="8637542770513281060">يحتوي الكمبيوتر على وحدة آمنة، والتي يتم استخدامها لتنفيذ العديد من ميزات الأمان المهمة في نظام التشغيل Chrome. ويُمكنك الانتقال إلى مركز مساعدة Chromebook للتعرف على مزيد من المعلومات: https://support.google.com/chromebook/?p=sm</translation> @@ -5203,7 +5191,6 @@ <translation id="899403249577094719">عنوان URL الأساسي لشهادة Netscape</translation> <translation id="8995603266996330174">مدار بواسطة <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">إضافة حساب...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">جارٍ إنشاء صورة القرص</translation> <translation id="9003647077635673607">السماح على جميع مواقع الويب</translation> <translation id="9003677638446136377">التحقق مرة أخرى</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb index 7f89d91..1b712d1 100644 --- a/chrome/app/resources/generated_resources_bg.xtb +++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Скоро ще е време за почивка</translation> <translation id="1062407476771304334">Замяна</translation> -<translation id="1064835277883315402">Присъединяване към частна мрежа</translation> <translation id="1064912851688322329">Прекъсване на връзката с профила ви в Google...</translation> <translation id="1067048845568873861">Дата на създаване</translation> <translation id="1067291318998134776">Linux (бета)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Търси се...</translation> <translation id="1316495628809031177">Синхронизирането е на пауза</translation> <translation id="1319979322914001937">Приложение, което показва филтриран списък с разширения от уеб магазина на Chrome. Те могат да бъдат инсталирани направо от приложението.</translation> -<translation id="132090119144658135">Съвпадение на субекта:</translation> <translation id="1326317727527857210">Влезте в Chrome, за да получите разделите си от другите си устройства.</translation> <translation id="1327074568633507428">Принтер в Google Отпечатване в облак</translation> <translation id="1327977588028644528">Шлюз</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">Прозорец на приложението</translation> <translation id="1534389735079119190">ГРЕШКА: Стартирането на контейнера във виртуалната машина не бе успешно.</translation> <translation id="15373452373711364">Голям курсор на мишката</translation> +<translation id="1540605929960647700">Активиране на демонстрационния режим</translation> <translation id="1543284117603151572">Импортирани от Edge</translation> <translation id="1545177026077493356">Автоматичен павилионен режим</translation> <translation id="1545775234664667895">Инсталирана тема: <ph name="THEME_NAME" /></translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">Помогнете ни да подобрим <ph name="PRODUCT_NAME" /> като автоматично изпращате на Google статистически данни за използването му и сигнали за сривове</translation> <translation id="1658424621194652532">Тази страница осъществява достъп до микрофона ви.</translation> <translation id="1660204651932907780">Разрешаване на сайтовете да възпроизвеждат звук (препоръчително)</translation> +<translation id="1660938185063657230">Потвърждаване на ключа ви за сигурност</translation> <translation id="1661156625580498328">Задължително прилагане на AES шифроване (препоръчително).</translation> <translation id="1661245713600520330">Тази страница посочва всички модули, заредени в основния процес, и модулите, регистрирани за зареждане по-късно.</translation> <translation id="166179487779922818">Паролата е твърде кратка.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">Забраняване на сайтовете да преглеждат текста и изображенията, копирани в буферната памет</translation> <translation id="1682548588986054654">Нов прозорец инкогнито</translation> <translation id="168715261339224929">Включете синхронизирането, за да получите отметките си на всичките си устройства.</translation> +<translation id="1688867105868176567">Да се изчистят ли данните за сайта?</translation> <translation id="1688935057616748272">Въведете буква</translation> <translation id="168991973552362966">Добавяне на принтер в близост</translation> <translation id="1689945336726856614">Копиране на &URL адреса</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">Премахване на този човек</translation> <translation id="1706586824377653884">Добавено от администратора ви</translation> <translation id="1706625117072057435">Нива на мащаба</translation> -<translation id="1707463636381878959">Тази мрежа да се споделя с други потребители</translation> <translation id="1708338024780164500">(Неактивно)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (идент. №: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (стандартно)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">Активиране на темата</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Преглед в уеб магазина на Chrome</translation> -<translation id="1758831820837444715">Конфигуриране на Ethernet мрежа</translation> <translation id="1763046204212875858">Създаване на преки пътища към приложението</translation> <translation id="1763108912552529023">Продължаване на изследването</translation> <translation id="1763808908432309942">Отваря се в нов раздел</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">Промяна на начина на споделяне на този файл</translation> <translation id="1841545962859478868">Администраторът на устройството може да наблюдава следното:</translation> <translation id="1841705068325380214">Разширението <ph name="EXTENSION_NAME" /> е деактивирано</translation> +<translation id="1842766183094193446">Наистина ли искате да активирате демонстрационния режим?</translation> <translation id="1844692022597038441">Този файл не е налице офлайн.</translation> <translation id="1846308012215045257">Задръжте „Ctrl“ и кликнете, за да стартирате <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Запазено</translation> <translation id="1848219224579402567">Излизане от профила при затваряне на капака</translation> <translation id="184823282865851239">Блокиране, ако на сайта обикновено се показват натрапчиви реклами</translation> <translation id="1849186935225320012">Тази страница има пълен контрол над MIDI устройствата.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">Винаги можете да промените това по-късно от настройките</translation> <translation id="2006638907958895361">Отваряне на връзката чрез <ph name="APP" /></translation> <translation id="2007404777272201486">Подаване на сигнал за проблем...</translation> +<translation id="2016237810978710652">Файловете за Linux се отварят...</translation> <translation id="2016430552235416146">Традиционно</translation> <translation id="2017334798163366053">Деактивиране на събирането на данни за ефективността</translation> <translation id="2017836877785168846">Изчиства историята и автоматичните довършвания в адресната лента.</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">Редактиране на картата</translation> <translation id="2154710561487035718">Копиране на URL адреса</translation> <translation id="2155772377859296191">Разделителната способност е <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Можете да помогнете за подобряването на Безопасно сърфиране, като ни изпращате системна информация и част от съдържанието на страниците.</translation> <translation id="215753907730220065">Изход от цял екран</translation> <translation id="2157875535253991059">Тази страница сега е на цял екран.</translation> <translation id="216169395504480358">Добавяне на Wi-Fi...</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">Добавяне на идентификационен номер на заявка към това устройство</translation> <translation id="2175042898143291048">Превеждане винаги</translation> <translation id="2175607476662778685">Лента за бързо стартиране</translation> +<translation id="2176087259161165020">Други източници</translation> <translation id="2177950615300672361">Раздел в режим „инкогнито“: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> от <ph name="PEPPER_PLUGIN_DOMAIN" /> иска да осъществи достъп до компютъра ви</translation> <translation id="2178614541317717477">Компрометиране на сертифициращия орган</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">Следващият раздел</translation> <translation id="2292848386125228270">Моля, стартирайте <ph name="PRODUCT_NAME" /> като обикновен потребител. Ако имате нужда от права на потребител root, за да преминете в режим за програмиране, стартирайте отново браузъра с флага --no-sandbox.</translation> <translation id="2294358108254308676">Искате ли да инсталирате <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Метод от EAP:</translation> <translation id="2297705863329999812">Търсете принтери</translation> <translation id="2300383962156589922">Персонализиране и управление на <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Основната директория на разширението е невалидна.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">ГРЕШКА: Деинсталирането на <ph name="APP_NAME" /> не бе успешно.</translation> <translation id="2367199180085172140">Добавяне на споделяне на файл</translation> <translation id="2367972762794486313">Показване на приложенията</translation> +<translation id="2369536625682139252">Ще бъдат изтрити всички съхранявани от <ph name="SITE" /> данни освен „бисквитките“.</translation> <translation id="2371076942591664043">Отваряне &след изтегляне</translation> <translation id="2377319039870049694">Превключване към списъчен изглед</translation> <translation id="2377667304966270281">Съществени грешки</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">Печат чрез системния диалогов прозорец... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Извеждане на запитване преди изпращане (препоръчително)</translation> <translation id="2384436799579181135">Възникна грешка. Моля, проверете принтера си и опитайте отново.</translation> -<translation id="2385700042425247848">Име на услугата:</translation> <translation id="2387458720915042159">Тип на връзката през прокси сървър</translation> <translation id="2391419135980381625">Стандартен шрифт</translation> <translation id="2391762656119864333">Оттегляне</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">Споделяне на звука</translation> <translation id="2480868415629598489">Промяна на данните, които копирате и поставяте</translation> <translation id="2482878487686419369">Известия</translation> -<translation id="2485056306054380289">Сертификат на сертифициращ орган за сървъра:</translation> <translation id="2485422356828889247">Деинсталиране</translation> <translation id="2487067538648443797">Добавяне на нова отметка</translation> <translation id="248861575772995840">Телефонът ви не може да бъде намерен. Уверете се, че функцията за Bluetooth на вашия <ph name="DEVICE_TYPE" /> е включена. <a>Научете повече</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">Извършете Powerwash, за да възстановите устройството си с <ph name="IDS_SHORT_PRODUCT_NAME" />, така че да бъде като ново.</translation> <translation id="2567257616420533738">Паролата е запазена. Преглеждайте и управлявайте запазените пароли на адрес <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Контейнер на инфолента</translation> +<translation id="2570454805927264159">Възползвайте се максимално от Асистент</translation> <translation id="257088987046510401">Теми</translation> <translation id="2572032849266859634">Предоставен е достъп само за четене до „<ph name="VOLUME_NAME" />“.</translation> <translation id="2573269395582837871">Изберете снимка и име</translation> @@ -1096,7 +1099,6 @@ <translation id="2653659639078652383">Изпращане</translation> <translation id="265390580714150011">Стойност на полето</translation> <translation id="2654166010170466751">Разрешаване на сайтовете да инсталират приложения за обработване на плащания</translation> -<translation id="2655386581175833247">Потребителски сертификат:</translation> <translation id="2660779039299703961">Събитие</translation> <translation id="266079277508604648">Не може да се установи връзка с принтера. Уверете се, че е включен и е свързан с вашия Chromebook чрез Wi-Fi или USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1329,6 +1331,7 @@ <translation id="3006881078666935414">Няма данни за използването</translation> <translation id="3007214526293698309">Коригиране на съотношението</translation> <translation id="3007771295016901659">Дублиране на раздела</translation> +<translation id="3008272652534848354">Нулиране на разрешенията</translation> <translation id="3009300415590184725">Наистина ли искате да анулирате процеса на настройка на мобилната услуга за данни?</translation> <translation id="3009779501245596802">Индексирани бази от данни</translation> <translation id="3010279545267083280">Паролата е изтрита</translation> @@ -1395,7 +1398,6 @@ <translation id="3100609564180505575">Модули (<ph name="TOTAL_COUNT" />) – Известни конфликти: <ph name="BAD_COUNT" />, предполагаеми: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Дата и час</translation> <translation id="310671807099593501">Сайтът използва Bluetooth</translation> -<translation id="3108967419958202225">Изберете...</translation> <translation id="3115128645424181617">Телефонът ви не може да бъде намерен. Уверете се, че е подръка и че функцията за Bluetooth е включена.</translation> <translation id="3115147772012638511">Кешът се изчаква...</translation> <translation id="3118319026408854581">Помощ за <ph name="PRODUCT_NAME" /></translation> @@ -1440,7 +1442,6 @@ <translation id="3165390001037658081">Някои оператори може да блокират тази функция.</translation> <translation id="316854673539778496">Влезте в профила си и включете синхронизирането, за да получите разширенията си на всичките си устройства.</translation> <translation id="3170072451822350649">Може също да пропуснете влизането и <ph name="LINK_START" />да сърфирате като гост<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Кликнете, за да скриете паролата</translation> <translation id="3177909033752230686">Език на страницата:</translation> <translation id="3181110748548073003">Натиснете |<ph name="SHORTCUT" />|, за да преминете напред</translation> <translation id="3182749001423093222">Проверка на правописа</translation> @@ -1471,7 +1472,6 @@ <translation id="3236289833370040187">Собствеността ще бъде прехвърлена на <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Отваряне на опциите на разширението</translation> <translation id="3241680850019875542">Изберете основната директория на разширението, което ще се пакетира. За да актуализирате разширение, изберете и файла с личен ключ за повторно използване.</translation> -<translation id="3242765319725186192">Предварително споделен ключ:</translation> <translation id="3244294424315804309">Продължаване без звук</translation> <translation id="3245321423178950146">Неизвестен изпълнител</translation> <translation id="3246097286174000800">Изпробване на Smart Lock</translation> @@ -1604,7 +1604,6 @@ <translation id="3440663250074896476">Още действия за „<ph name="BOOKMARK_NAME" />“</translation> <translation id="3440761377721825626">Извеждане на запитване, когато сайт иска да използва приставка за достъп до компютъра ви</translation> <translation id="3441653493275994384">Екран</translation> -<translation id="3445830502289589282">Удостоверяване във фаза 2:</translation> <translation id="344630545793878684">Четене на данните ви от редица уебсайтове</translation> <translation id="3449839693241009168">Натиснете <ph name="SEARCH_KEY" /> за да изпратите командите до <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Процент на използване в състояние на неактивност</translation> @@ -1645,7 +1644,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> грешки.</translation> <translation id="3495660573538963482">Настройки на Google Асистент</translation> <translation id="3496213124478423963">Намаляване</translation> -<translation id="3504135463003295723">Име на групата:</translation> <translation id="3505030558724226696">Отмяна на достъпа до устройството</translation> <translation id="3507421388498836150">Текущи разрешения за <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Премахване на приложенията за Linux за Chromebook</translation> @@ -1755,7 +1753,6 @@ <translation id="3661054927247347545">Данните за вход не са валидни. Прозорецът ще се затвори след <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Икона на разширението</translation> <translation id="3665589677786828986">Chrome установи, че някои от настройките ви са повредени от друга програма, и възстанови първоначалните им стандартни стойности.</translation> -<translation id="3665842570601375360">Сигурност:</translation> <translation id="3668570675727296296">Езикови настройки</translation> <translation id="3668823961463113931">Манипулатори</translation> <translation id="3670229581627177274">Включване на Bluetooth</translation> @@ -1794,7 +1791,6 @@ <translation id="3726463242007121105">Това устройство не може да бъде отворено, защото файловата му система не се поддържа.</translation> <translation id="3727148787322499904">Промяната на тази настройка ще засегне всички споделени мрежи</translation> <translation id="3727187387656390258">Инспектиране на изскачащ прозорец</translation> -<translation id="3728067901555601989">ЕП:</translation> <translation id="3732078975418297900">Грешка в ред <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL сървър с повишаване на сигурността</translation> <translation id="3737536731758327622">Изтеглените от вас неща ще се показват тук</translation> @@ -1869,7 +1865,6 @@ <translation id="38275787300541712">Натиснете „Enter“, когато сте готови</translation> <translation id="3827774300009121996">&На цял екран</translation> <translation id="3828029223314399057">Търсене в отметките</translation> -<translation id="3829932584934971895">Тип на доставчика:</translation> <translation id="3830674330436234648">Възпроизвеждането не е възможно</translation> <translation id="3831486154586836914">Влязохте в режим на общ преглед на прозорците</translation> <translation id="383161972796689579">Собственикът на това устройство е деактивирал добавянето на нови потребители</translation> @@ -1890,6 +1885,7 @@ <translation id="3856921555429624101">Измерването на преноса на данни приключи</translation> <translation id="3857228364945137633">Изпробвайте Smart Lock, за да отключвате своя <ph name="DEVICE_TYPE" /> без парола, когато телефонът ви е наблизо.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: синхронизирането е на пауза</translation> <translation id="3860381078714302691">Добре дошли в Hangouts Meet</translation> <translation id="3862134173397075045">Представяме ви функцията за предаване в Chrome!</translation> <translation id="3862788408946266506">Приложенията с атрибут „kiosk_only“ в манифеста трябва да бъдат инсталирани в павилионния режим на Chrome OS</translation> @@ -1967,7 +1963,6 @@ <translation id="3968261067169026421">Мрежата не можа да се настрои</translation> <translation id="3970114302595058915">Идентификатор</translation> <translation id="397105322502079400">Изчислява се...</translation> -<translation id="3974195870082915331">Кликнете, за да се покаже паролата</translation> <translation id="3975222297214566386">Балонче за опциите за въвеждане</translation> <translation id="397703832102027365">Довършва се...</translation> <translation id="3979395879372752341">Бе добавено ново разширение (<ph name="EXTENSION_NAME" />)</translation> @@ -2009,6 +2004,7 @@ <translation id="4044612648082411741">Въведете паролата си за сертификата</translation> <translation id="404493185430269859">Основна търсеща машина</translation> <translation id="4047112090469382184">Защо това е сигурно</translation> +<translation id="4051049974203704184">Получаване на информация за съдържанието на екрана</translation> <translation id="4052120076834320548">Миниатюрен</translation> <translation id="4055023634561256217">Изисква се да рестартирате устройството си, преди да може да бъде възстановено с Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2037,6 +2033,7 @@ <translation id="4088095054444612037">Приемам за групата</translation> <translation id="4089235344645910861">Настройките бяха запазени. Синхронизирането започна.</translation> <translation id="4090103403438682346">Активиране на удостоверения достъп</translation> +<translation id="4090947011087001172">Да се нулират ли разрешенията за сайта <ph name="SITE" />?</translation> <translation id="4091434297613116013">листа</translation> <translation id="4093955363990068916">Локален файл:</translation> <translation id="4095507791297118304">Основен екран</translation> @@ -2213,7 +2210,6 @@ <translation id="4419556793104466535">Контрол върху синхронизирането, персонализирането и др.</translation> <translation id="4421932782753506458">Пухчо</translation> <translation id="4422347585044846479">Редактиране на отметката за тази страница</translation> -<translation id="4423104065312875417">Инсталиране на допълнителни машини за синтезиран говор</translation> <translation id="4423376891418188461">Възстановяване на настройките</translation> <translation id="4423482519432579560">&Проверка на правописа</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, администраторът ви изисква да промените паролата си.</translation> @@ -2238,7 +2234,6 @@ <translation id="4449996769074858870">В този раздел се възпроизвежда звук.</translation> <translation id="4450974146388585462">Диагностициране</translation> <translation id="4453946976636652378">Търсете с(ъс) <ph name="SEARCH_ENGINE_NAME" /> или въведете URL адрес</translation> -<translation id="445923051607553918">Присъединяване към Wi-Fi мрежа</translation> <translation id="4462159676511157176">Специално зададени сървъри за имена</translation> <translation id="4467100756425880649">Галерия на уеб магазина на Chrome</translation> <translation id="4467101674048705704">Разгъване на „<ph name="FOLDER_NAME" />“</translation> @@ -2374,6 +2369,7 @@ <translation id="4682551433947286597">Тапетите се показват на екрана за вход.</translation> <translation id="4684427112815847243">Синхронизиране на всичко</translation> <translation id="4689421377817139245">Синхронизирайте тази отметка със своя iPhone</translation> +<translation id="4690091457710545971"><Фърмуерът на Intel за Wi-Fi генерира четири файла: csr.lst, fh_regs.lst, radio_reg.lst и monitor.lst.sysmon. Първите три са двоични файлове с копия на данни от системния регистър и според Intel не съдържат лични данни или информация, идентифицираща устройството. Последният е файл за трасиране на изпълнението от фърмуера на Intel. Личните данни и идентифициращата устройството информация са премахнати от него, но той е твърде голям, за да бъде показан тук. Тези файлове са генерирани поради скорошните проблеми с Wi-Fi на устройството ви и ще бъдат споделени с Intel с цел по-лесното им отстраняване.></translation> <translation id="4692302215262324251">Устройството ви <ph name="DEVICE_TYPE" /> е успешно записано за корпоративно управление от <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Ако това е неочаквано, моля, свържете се с екипа за поддръжка.</translation> @@ -2633,6 +2629,7 @@ <translation id="5074318175948309511">Може да се наложи тази страница да бъде презаредена, преди да влязат в сила новите настройки.</translation> <translation id="5075131525758602494">Въвеждане на ПИН за SIM картата</translation> <translation id="5078638979202084724">Запазване на отметки към всички раздели</translation> +<translation id="5079950360618752063">Използване на предложената парола</translation> <translation id="5084230410268011727">Разрешаване на сайтовете да използват сензори за движение и светлина</translation> <translation id="5085162214018721575">Проверява се за актуализации</translation> <translation id="5086082738160935172">HID</translation> @@ -2671,6 +2668,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Изтриване на този елемент</translation> <translation id="5139955368427980650">&Отваряне</translation> +<translation id="5142961317498132443">Удостоверяване</translation> <translation id="5143374789336132547">Разширението „<ph name="EXTENSION_NAME" />“ промени страницата, която се показва при кликване върху бутона „Начална страница“.</translation> <translation id="5143712164865402236">Вход за цял екран</translation> <translation id="5145331109270917438">Дата на промяна</translation> @@ -2841,7 +2839,6 @@ <translation id="5380103295189760361">Задръжте „Control“, „Alt“, „Shift“ или „търсене“, за да видите клавишните комбинации за тези модификатори.</translation> <translation id="5382591305415226340">Управление на поддържаните връзки</translation> <translation id="5384883051496921101">Този сайт е напът да сподели информация с приложение, което не е в режим „инкогнито“.</translation> -<translation id="5388588172257446328">Потребителско име:</translation> <translation id="5388885445722491159">Сдвоено</translation> <translation id="5389237414310520250">Новият потребител не можа да се създаде. Моля, проверете мястото на твърдия си диск и разрешенията и опитайте отново.</translation> <translation id="5390100381392048184">Разрешаване на сайтовете да възпроизвеждат звук</translation> @@ -2966,7 +2963,6 @@ <translation id="5551573675707792127">Клавиатура и въвеждане на текст</translation> <translation id="5553089923092577885">Съответствия на правилата за сертификата</translation> <translation id="5554489410841842733">Тази икона ще се показва, когато разширението може да изпълнява действия върху текущата страница.</translation> -<translation id="5554573843028719904">Друга Wi-Fi мрежа...</translation> <translation id="5554720593229208774">Сертифициращ орган за имейл</translation> <translation id="5556206011531515970">Кликнете върху „Напред“, за да изберете браузъра си по подразбиране.</translation> <translation id="5556459405103347317">Повторно зареждане</translation> @@ -3007,7 +3003,6 @@ <translation id="5610038042047936818">Превключване към режима за фотоапарат</translation> <translation id="5612720917913232150"><ph name="URL" /> иска да използва местоположението на компютъра ви</translation> <translation id="5612734644261457353">За съжаление паролата ви пак не можа да бъде потвърдена. Забележка: Ако наскоро сте я променили, новата ще се приложи, щом излезете от профила си. Моля, използвайте старата парола тук.</translation> -<translation id="5613695965848159202">Анонимна самоличност:</translation> <translation id="5614190747811328134">Известие за потребителя</translation> <translation id="561698261642843490">Затваряне на Firefox</translation> <translation id="5618075537869101857">Ужас! Павилионното приложение не можа да се стартира.</translation> @@ -3226,7 +3221,6 @@ <translation id="5941343993301164315">Моля, влезте в/ъв <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Намаляване</translation> <translation id="5946591249682680882">Идентификатор на отчета: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Добавяне на частна мрежа</translation> <translation id="5949544233750246342">Файлът не може да се анализира синтактично</translation> <translation id="5955282598396714173">Паролата ви е изтекла. Моля, излезте от профила си и влезте отново в него, за да я промените.</translation> <translation id="5956585768868398362">Това ли е очакваната от вас страница за търсене?</translation> @@ -3387,11 +3381,13 @@ <translation id="6198102561359457428">Излезте от профила си и влезте отново...</translation> <translation id="6198252989419008588">Промяна на ПИН</translation> <translation id="6199801702437275229">Информацията за мястото се изчаква...</translation> +<translation id="6204015976622790023">Получавайте подходящи предложения от Асистент, свързани със съдържанието на екрана ви.</translation> <translation id="6205710420833115353">Някои операции отнемат повече време от очакваното. Искате ли да ги прекратите?</translation> <translation id="6206311232642889873">Копи&ране на изображението</translation> <translation id="6207200176136643843">Възстановяване на стандартното ниво на мащаба</translation> <translation id="620722923698527029">Тези типове връзки винаги да се отварят в свързаното приложение</translation> <translation id="6207937957461833379">Държава/Регион</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: синхронизирането не работи</translation> <translation id="6212039847102026977">Показване на разширените свойства на мрежата</translation> <translation id="6212168817037875041">Изключване на екрана</translation> <translation id="6212752530110374741">Изпращане на връзката по имейл</translation> @@ -3429,7 +3425,6 @@ <translation id="6263541650532042179">нулирате синхронизирането</translation> <translation id="6264365405983206840">Избиране на &всички</translation> <translation id="6264422956566238156">Включихте синхронизирането</translation> -<translation id="6265930187414222160">Готово! Опасният софтуер е премахнат.</translation> <translation id="6267166720438879315">Изберете сертификат, за удостоверите самоличността си пред <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Отваряне чрез <ph name="APP" /></translation> <translation id="6268747994388690914">Импортиране на отметки от HTML файл...</translation> @@ -3536,7 +3531,6 @@ Моля, кликнете върху „Напред“, за да продължите с влизането в профила си в/ъв <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Зареждане на разпакетираното</translation> <translation id="642282551015776456">Това име не може да се използва като име на файл или на папка</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Отваряне на настройките на ChromeVox</translation> <translation id="6429384232893414837">Грешка при актуализирането</translation> <translation id="6430814529589430811">ASCII с кодиране Base64, единичен сертификат</translation> @@ -3617,7 +3611,6 @@ <translation id="6544215763872433504">Уеб браузърът, създаден за вас от Google</translation> <translation id="6545665334409411530">Честота на повтаряне</translation> <translation id="6545834809683560467">Използване на услуга за предвиждания за помощ при завършването на заявките за търсене и URL адресите, въвеждани в адресната лента или в полето за търсене в стартовия панел за приложения</translation> -<translation id="6546686722964485737">Присъединяване към WiMAX мрежа</translation> <translation id="6547316139431024316">Без повторно предупреждение за това разширение</translation> <translation id="6547354035488017500">Освободете поне 512 МБ място или устройството ви ще спре да реагира. За целта изтрийте файлове от хранилището му.</translation> <translation id="6549689063733911810">Скорошни</translation> @@ -4036,7 +4029,6 @@ <translation id="7201014958346994077">Файловете за Linux не могат да бъдат показани</translation> <translation id="720110658997053098">Това устройство да е постоянно в павилионен режим</translation> <translation id="7201118060536064622">Изтрихте „<ph name="DELETED_ITEM_NAME" />“</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> се изтегля...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Изход от страницата}other{Изход от страниците}}</translation> <translation id="7216409898977639127">Мобилен оператор</translation> @@ -4514,7 +4506,6 @@ <translation id="7909969815743704077">Изтеглено в режим „инкогнито“</translation> <translation id="7910768399700579500">&Нова папка</translation> <translation id="7912080627461681647">Паролата ви е променена в сървъра. Моля, излезте от профила си и влезте отново в него.</translation> -<translation id="7912883689016444961">Конфигуриране на мобилната мрежа</translation> <translation id="7915471803647590281">Моля, кажете ни какво става, преди да изпратите отзивите.</translation> <translation id="7916556741383518510">При кликване</translation> <translation id="792514962475806987">Ниво на мащаба при прикрепен режим:</translation> @@ -4568,7 +4559,6 @@ <translation id="7988355189918024273">Активиране на функциите за достъпност</translation> <translation id="7994702968232966508">Метод с EAP</translation> <translation id="799547531016638432">Премахване на прекия път</translation> -<translation id="7997479212858899587">Самоличност:</translation> <translation id="7997826902155442747">Приоритет на процесите</translation> <translation id="7999229196265990314">Създадени бяха следните файлове: @@ -4652,7 +4642,6 @@ <translation id="8105368624971345109">Изключване</translation> <translation id="8106045200081704138">Споделени с мен</translation> <translation id="8107015733319732394">Google Play Магазин се инсталира на устройството ви <ph name="DEVICE_TYPE" />. Това може да отнеме няколко минути.</translation> -<translation id="8109930990200908494">За потребителския сертификат се изисква влизане в профила.</translation> <translation id="8111155949205007504">Споделяне на тази парола с вашия iPhone</translation> <translation id="8113043281354018522">Изберете тип лиценз</translation> <translation id="8116190140324504026">Още информация...</translation> @@ -4663,6 +4652,7 @@ <translation id="8118860139461251237">Управление на изтеглянията ви</translation> <translation id="81238879832906896">Жълто-бяло цвете</translation> <translation id="8124313775439841391">Управлявано ONC</translation> +<translation id="8125562866093998907">С цел допълнителна защита на профила ви сайтът иска да потвърди ключа ви за сигурност.</translation> <translation id="813082847718468539">Преглед на информацията за сайта</translation> <translation id="8131740175452115882">Потвърждаване</translation> <translation id="8133676275609324831">&Показване в папката</translation> @@ -4773,7 +4763,6 @@ <translation id="8308179586020895837">Да се получава запитване, ако <ph name="HOST" /> иска достъп до камерата ви</translation> <translation id="830868413617744215">Бета</translation> <translation id="8309458809024885768">Сертификатът вече съществува</translation> -<translation id="8309505303672555187">Изберете мрежа:</translation> <translation id="8312871300878166382">Поставяне в папка</translation> <translation id="8317671367883557781">Добавяне на мрежова връзка</translation> <translation id="8319414634934645341">Удължена употреба на ключа</translation> @@ -4848,7 +4837,6 @@ <translation id="8451512073679317615">асистент</translation> <translation id="8452135315243592079">SIM картата липсва</translation> <translation id="8453482423012550001">$1 елемента се копират...</translation> -<translation id="8454288007744638700">Или изберете нова мрежа:</translation> <translation id="845627346958584683">Час на изтичане</translation> <translation id="8456681095658380701">Невалидно име</translation> <translation id="8457451314607652708">Импортиране на отметки</translation> @@ -4912,6 +4900,7 @@ <translation id="855081842937141170">Фиксиране на раздела</translation> <translation id="8551388862522347954">Лицензи</translation> <translation id="8553342806078037065">Управление на другите хора</translation> +<translation id="8554899698005018844">Без език</translation> <translation id="855773602626431402">На тази страница бе предотвратено изпълняването на приставка извън тестова среда.</translation> <translation id="8557930019681227453">Манифест</translation> <translation id="8559694214572302298">Декодиране на изображения</translation> @@ -4949,7 +4938,6 @@ <translation id="862727964348362408">Спряно</translation> <translation id="862750493060684461">Кеш за CSS</translation> <translation id="8627795981664801467">Само сигурни връзки</translation> -<translation id="8628085465172583869">Име на хоста за сървъра:</translation> <translation id="8630903300770275248">Импортиране на контролиран потребител</translation> <translation id="8631032106121706562">Цвете</translation> <translation id="8637542770513281060">Компютърът ви съдържа модул за сигурност, който служи за реализиране на множество критични защитни функции в Chrome OS. За да научите повече, посетете Помощния център на Chromebook: https://support.google.com/chromebook/?p=sm</translation> @@ -5205,7 +5193,6 @@ <translation id="899403249577094719">Основен URL адрес на сертификат на Netscape</translation> <translation id="8995603266996330174">Управлявано от <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Добавяне на профил...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Създава се образ на диска.</translation> <translation id="9003647077635673607">Разрешаване за всички уебсайтове</translation> <translation id="9003677638446136377">Повторна проверка</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb index 2570a4d..6ce99a2 100644 --- a/chrome/app/resources/generated_resources_bn.xtb +++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -30,7 +30,7 @@ <translation id="1039337018183941703">অবৈধ বা দূষিত ফাইল</translation> <translation id="1042174272890264476">আপনার কম্পিউটারও <ph name="SHORT_PRODUCT_NAME" /> এর RLZ লাইব্রেরি বিল্ট ইনের সাথে আসে৷ RLZ সার্চগুলি পরিমাপ করার জন্য একটি সাধারণ, ব্যক্তিগতভাবে সনাক্তকরণযোগ্য নয় এমন ট্যাগ নির্ধারণ করে এবং <ph name="SHORT_PRODUCT_NAME" /> এর ব্যবহার একটি নির্দিষ্ট প্রচারাভিযানের মাধ্যমে চালিত হয়৷ এই লেবেলগুলি কখনো কখনো <ph name="PRODUCT_NAME" /> এ Google সার্চ ক্যোয়ারিগুলিতে প্রদর্শিত হয়৷</translation> <translation id="1046059554679513793">উপস, নামটি ইতিমধ্যে ব্যবহারে রয়েছে!</translation> -<translation id="1047431265488717055">লিঙ্ক ও পাঠ্য কপি করুন</translation> +<translation id="1047431265488717055">লিঙ্ক ও টেক্সট কপি করুন</translation> <translation id="1047726139967079566">এই পৃষ্ঠাটি বুকমার্ক করুন...</translation> <translation id="1047956942837015229"><ph name="COUNT" />টি আইটেম মুছে ফেলা হচ্ছে...</translation> <translation id="1048286738600630630">প্রদর্শনগুলি</translation> @@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">বিরতির সময় হতে চলেছে</translation> <translation id="1062407476771304334">প্রতিস্থাপন করুন</translation> -<translation id="1064835277883315402">ব্যক্তিগত নেটওয়ার্কে যোগদান করুন</translation> <translation id="1064912851688322329">আপনার Google অ্যাকাউন্ট সংযোগ বিচ্ছিন্ন করুন</translation> <translation id="1067048845568873861">তৈরি হয়েছে</translation> <translation id="1067291318998134776">Linux (বিটা)</translation> @@ -85,14 +84,14 @@ <translation id="1122198203221319518">&সরঞ্জামসমূহ</translation> <translation id="1122242684574577509">প্রমাণীকরণ ব্যর্থ হয়েছে৷ যদি আপনি <ph name="NETWORK_ID" /> ব্যবহার করছেন তাহলে ওয়াই-ফাই নেটওয়ার্কের জন্য লগ ইন পৃষ্ঠায় দেখার জন্য ক্লিক করুন৷</translation> <translation id="1122960773616686544">বুকমার্কের নাম</translation> -<translation id="1123187597739372905">সিঙ্ক সেটিংস দেখান</translation> +<translation id="1123187597739372905">সিঙ্ক সেটিংস দেখুন</translation> <translation id="1123316951456119629">আপনার Google অ্যাকাউন্টকে <ph name="PRODUCT_NAME" /> এর থেকে সংযোগ বিচ্ছিন্ন করার মাধ্যেমে, এই কম্পিউটারে করা আপনার ডেটাতে পরিবর্তনগুলি এখন আর আপনার Google অ্যাকাউন্টের সাথে সিঙ্ক হবে না৷ আপনার Google অ্যাকাউন্টে আগে থেকে সংরক্ষিত ডেটা ততক্ষন অবশিষ্ট থাকবে যতক্ষন না আপনি <ph name="BEGIN_LINK" />Google ড্যাশবোর্ড<ph name="END_LINK" /> ব্যবহার করে এগুলিকে সরাচ্ছেন৷</translation> <translation id="1124772482545689468">ব্যবহারকারী</translation> <translation id="1128109161498068552">কোনো সাইটকে MIDI ডিভাইসগুলি অ্যাক্সেস করার জন্য সিস্টেমের বিশিষ্ট বার্তাগুলি ব্যবহার করার মঞ্জুরি দেবেন না</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">সার্চ ইঞ্জিন সম্পাদনা করুন</translation> <translation id="1134009406053225289">ছদ্মবেশী উইন্ডোতে খুলুন</translation> -<translation id="1136155683023653803">পাসওয়ার্ড, বুকমার্ক, ইতিহাস, এবং আরও অনেক কিছু আপনার অ্যাকাউন্টে সিঙ্ক করা হয়েছে</translation> +<translation id="1136155683023653803">পাসওয়ার্ড, বুকমার্ক, ইতিহাস এবং আরও অনেক কিছু আপনার অ্যাকাউন্টে সিঙ্ক করা হয়েছে</translation> <translation id="1137673463384776352"><ph name="APP" /> এ লিঙ্ক খুলুন</translation> <translation id="1140351953533677694">আপনার ব্লুটুথ এবং সিরিয়াল ডিভাইসগুলি অ্যাক্সেস করুন</translation> <translation id="1140610710803014750">সব ডিভাইসে আপনার বুকমার্কগুলি পেতে সাইন-ইন করুন এবং সিঙ্ক চালু করুন।</translation> @@ -225,7 +224,6 @@ <translation id="1316136264406804862">সার্চ করা হচ্ছে...</translation> <translation id="1316495628809031177">সিঙ্ক থামানো হয়েছে</translation> <translation id="1319979322914001937">Chrome ওয়েব দোকান থেকে এক্সটেনশানগুলির একটি ফিল্টার করা তালিকা দেখায় এমন একটি অ্যাপ্লিকেশান। তালিকার এক্সটেনশানগুলি অ্যাপ্লিকেশানটি থেকে সরাসরি ইনস্টল করা যাবে।</translation> -<translation id="132090119144658135">বিষয়বস্তু মিল:</translation> <translation id="1326317727527857210">আপনার অন্য ডিভাইসগুলি থেকে আপনার ট্যাবগুলি পেতে, Chrome এ প্রবেশ করুন।</translation> <translation id="1327074568633507428">Google ক্লাউড মুদ্রণে থাকা প্রিন্টার</translation> <translation id="1327977588028644528">গেটওয়ে</translation> @@ -481,7 +479,6 @@ <translation id="1701062906490865540">এই ব্যক্তিকে সরান</translation> <translation id="1706586824377653884">আপনার প্রশাসক দ্বারা যোগ করা হয়েছে</translation> <translation id="1706625117072057435">জুম স্তরগুলি</translation> -<translation id="1707463636381878959">অন্য ব্যবহারকারীদের সাথে এই নেটওয়ার্ক শেয়ার করুন</translation> <translation id="1708338024780164500">(নিষ্ক্রিয়)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (আইডি: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (নির্ধারিত)</translation> @@ -517,7 +514,6 @@ <translation id="175772926354468439">থিম সক্ষম করুন</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome ওয়েব স্টোরে দেখুন</translation> -<translation id="1758831820837444715">ইথারনেট নেটওয়ার্ক কনফিগার করুন</translation> <translation id="1763046204212875858">অ্যাপ্লিকেশন শর্টকাটগুলি তৈরি করুন</translation> <translation id="1763108912552529023">অন্বেষণ করা চালিয়ে যান</translation> <translation id="1764226536771329714">বিটা</translation> @@ -858,7 +854,6 @@ <translation id="2291643155573394834">পরবর্তী ট্যাব</translation> <translation id="2292848386125228270">অনুগ্রহ করে একজন সাধারন ব্যবহারকারী হিসেবে <ph name="PRODUCT_NAME" /> আরম্ভ করুন। আপনার যদি বিকাশ করার জন্য রুট হিসাবে চালানোর প্রয়োজন হয়, তাহলে --নো-স্যান্ডবক্স ফ্ল্যাগটি আবার চালান।</translation> <translation id="2294358108254308676">আপনি কি <ph name="PRODUCT_NAME" /> ইনস্টল করতে চান?</translation> -<translation id="2296019197782308739">EAP পদ্ধতি:</translation> <translation id="2297705863329999812">প্রিন্টার খুঁজুন</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> কাস্টমাইজ এবং নিয়ন্ত্রণ করুন</translation> <translation id="2301382460326681002">এক্সটেনশন রুট ডিরেক্টরিটি অবৈধ৷</translation> @@ -915,7 +910,6 @@ <translation id="2379281330731083556">সিস্টেম কথোপকথন ব্যবহার করে প্রিন্ট করুন...<ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">পাঠানোর আগে জিজ্ঞাসা করুন (প্রস্তাবিত)</translation> <translation id="2384436799579181135">একটি ত্রুটি ঘটেছে৷ অনুগ্রহ করে আপনার প্রিন্টারটি পরীক্ষা করে আবার চেষ্টা করুন।</translation> -<translation id="2385700042425247848">পরিষেবার নাম:</translation> <translation id="2387458720915042159">প্রক্সি সংযোগের প্রকার</translation> <translation id="2391419135980381625">মানক হরফ</translation> <translation id="2391762656119864333">প্রত্যাহার করুন</translation> @@ -965,7 +959,6 @@ <translation id="247949520305900375">অডিও ভাগ করুন</translation> <translation id="2480868415629598489">আপনি যে ডেটা কপি করে আটকান তা সংশোধন করুন</translation> <translation id="2482878487686419369">বিজ্ঞপ্তিগুলি</translation> -<translation id="2485056306054380289">সার্ভার CA শংসাপত্র:</translation> <translation id="2485422356828889247">আনইনস্টল</translation> <translation id="2487067538648443797">নতুন বুকমার্ক যোগ করুন</translation> <translation id="248861575772995840">আপনার ফোন খুঁজে পাওয়া যাচ্ছে না। নিশ্চিত করুন আপনার <ph name="DEVICE_TYPE" /> এর ব্লুটুথ চালু আছে। <a>আরও জানুন</a></translation> @@ -1088,7 +1081,6 @@ <translation id="2653659639078652383">জমা দিন</translation> <translation id="265390580714150011">ক্ষেত্রের মান</translation> <translation id="2654166010170466751">সাইটগুলিকে পেমেন্ট হ্যান্ডলার ইনস্টল করার অনুমতি দিন</translation> -<translation id="2655386581175833247">ব্যবহারকারীর শংসাপত্র:</translation> <translation id="2660779039299703961">ইভেন্ট</translation> <translation id="266079277508604648">প্রিন্টারটি সংযুক্ত করা যায়নি। প্রিন্টারটি চালু আছে কিনা এবং ওয়াই-ফাই অথবা USB এর মাধ্যমে Chromebook এর সাথে সংযুক্ত আছে কিনা দেখে নিন।</translation> <translation id="2661146741306740526">১৬x৯</translation> @@ -1386,7 +1378,6 @@ <translation id="3100609564180505575">মডিউল (<ph name="TOTAL_COUNT" />) - জ্ঞাত বিবাদ: <ph name="BAD_COUNT" />, সন্দেহভাজন: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">তারিখ এবং সময়</translation> <translation id="310671807099593501">সাইটটি ব্লুটুথ ব্যবহার করছে</translation> -<translation id="3108967419958202225">বেছে নিন...</translation> <translation id="3115128645424181617">আপনার ফোন খুঁজে পাওয়া যায়নি। এটি সহজে ব্যবহার করা যায় এবং বুলুটুথ চালু রয়েছে সেটি নিশ্চিত করুন।</translation> <translation id="3115147772012638511">ক্যাশের অপেক্ষা করা হচ্ছে...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> সহায়তা</translation> @@ -1431,7 +1422,6 @@ <translation id="3165390001037658081">কিছু পরিষেবা প্রদানকারী এই বৈশিষ্ট্যকে অবরুদ্ধ করতে পারে।</translation> <translation id="316854673539778496">সব ডিভাইসে আপনার এক্সটেনশন পেতে, সাইন-ইন করুন এবং সিঙ্ক চালু করুন।</translation> <translation id="3170072451822350649">এছাড়াও আপনি প্রবেশ করুন এড়িয়ে যেতে ও <ph name="LINK_START" />অতিথি হিসাবে ব্রাউজ<ph name="LINK_END" /> করতে পারেন৷</translation> -<translation id="3177048931975664371">পাসওয়ার্ড লুকাতে ক্লিক করুন</translation> <translation id="3177909033752230686">পৃষ্ঠার ভাষা:</translation> <translation id="3181110748548073003">এগিয়ে যাওয়ার জন্য |<ph name="SHORTCUT" />| টিপুন</translation> <translation id="3182749001423093222">বানান পরীক্ষা</translation> @@ -1462,7 +1452,6 @@ <translation id="3236289833370040187">মালিকানা <ph name="DESTINATION_DOMAIN" /> এ স্থানান্তর করা হবে।</translation> <translation id="323803881985677942">এক্সটেনশান বিকল্পগুলি খুলুন</translation> <translation id="3241680850019875542">প্যাক করার জন্য এক্সটেনশনের রুট ডিরেক্টরিটি নির্বাচন করুন৷ কোন এক্সটেনশন আপডেট করতে, আবার ব্যবহার করার জন্য ব্যক্তিগত কী ফাইলটিও নির্বাচন করুন৷</translation> -<translation id="3242765319725186192">প্রাক্-অংশীদারী করা কী:</translation> <translation id="3244294424315804309">সাউন্ড মিউট করে রাখুন</translation> <translation id="3245321423178950146">অজানা শিল্পী</translation> <translation id="3246097286174000800">Smart Lock ব্যবহার করে দেখুন</translation> @@ -1592,7 +1581,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> এর জন্য আরও অ্যাকশন</translation> <translation id="3440761377721825626">আপনার কম্পিউটার অ্যাক্সেস করার জন্য যখন কোনো সাইট কোনো প্ল্যাগ ইন ব্যবহার করতে চায় তখন জিজ্ঞাসা করবেন</translation> <translation id="3441653493275994384">বাছাই করুন</translation> -<translation id="3445830502289589282">ফেজ 2 প্রমানীকরণ:</translation> <translation id="344630545793878684">কতগুলি ওয়েবসাইটে আপনার ডেটা পড়ে</translation> <translation id="3449839693241009168"><ph name="SEARCH_KEY" />তে আদেশগুলি প্রেরণ করতে <ph name="EXTENSION_NAME" /> টি টিপুন</translation> <translation id="3450157232394774192">নিষ্ক্রিয় স্থিতির ওকুপেন্সির শতকরা হার</translation> @@ -1633,7 +1621,6 @@ <translation id="3495304270784461826"><ph name="COUNT" />টি ত্রুটি৷</translation> <translation id="3495660573538963482">Google সহায়ক সেটিংস</translation> <translation id="3496213124478423963">জুম কমান</translation> -<translation id="3504135463003295723">গ্রুপ নাম:</translation> <translation id="3505030558724226696">ডিভাইসের অ্যাক্সেস প্রত্যাহার করুন</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" এর জন্য বর্তমান অনুমতিগুলি</translation> <translation id="3507547268929739059">Chromebook থেকে Linux অ্যাপ সরিয়ে দিন</translation> @@ -1742,7 +1729,6 @@ <translation id="3661054927247347545">সাইন-ইন সার্টিফিকেশনটি ভুল, <ph name="MINUTES" /> : <ph name="SECONDS" /> এ উইন্ডো বন্ধ হয়ে যাবে।</translation> <translation id="3664511988987167893">এক্সটেনশনের আইকন</translation> <translation id="3665589677786828986">Chrome শনাক্ত করেছে যে অন্য কোনো প্রোগ্রাম আপনার কিছু সেটিংস ক্ষতিগ্রস্ত করেছে এবং সেগুলিকে তাদের মূল ডিফল্টে আবার সেট করেছে।</translation> -<translation id="3665842570601375360">নিরাপত্তা:</translation> <translation id="3668570675727296296">ভাষা সেটিংস</translation> <translation id="3668823961463113931">হ্যান্ডলার</translation> <translation id="3670229581627177274">ব্লুটুথ চালু করুন</translation> @@ -1780,7 +1766,6 @@ <translation id="3726463242007121105">এই ডিভাইসটি ফাইল সিস্টেমটি সমর্থিত না হওয়ার কারণে খুলতে পারা যায়না৷</translation> <translation id="3727148787322499904">এই সেটিং পরিবর্তন করা হলে শেয়ার করা সব নেটওয়ার্ক প্রভাবিত হবে</translation> <translation id="3727187387656390258">পপআপ সংবীক্ষণ</translation> -<translation id="3728067901555601989">ওটিপি</translation> <translation id="3732078975418297900"><ph name="ERROR_LINE" /> নম্বর লাইনে কোনও ভুল আছে</translation> <translation id="3733127536501031542">স্টেপ-আপ সহ SSL সার্ভার</translation> <translation id="3737536731758327622">আপনার ডাউনলোডগুলি এখানে দেখা যাবে</translation> @@ -1855,7 +1840,6 @@ <translation id="38275787300541712">সম্পূর্ণ হলে Enter টিপুন</translation> <translation id="3827774300009121996">&পূর্ণ স্ক্রীণ</translation> <translation id="3828029223314399057">বুকমার্কগুলি খুঁজুন</translation> -<translation id="3829932584934971895">সরবরাহকারীর প্রকার:</translation> <translation id="3830674330436234648">কোনো প্লেব্যাক উপলব্ধ নেই</translation> <translation id="3831486154586836914">প্রবেশ করা উইন্ডোর ওভারভিউ মোড</translation> <translation id="383161972796689579">এই ডিভাইসের মালিক নতুন ব্যবহারকারী জোড়া অক্ষম করেছে</translation> @@ -1951,7 +1935,6 @@ <translation id="3968261067169026421">নেটওয়ার্ক সেট আপ করা যায়নি</translation> <translation id="3970114302595058915">আইডি</translation> <translation id="397105322502079400">গণনা করা হচ্ছে...</translation> -<translation id="3974195870082915331">পাসওয়ার্ড দেখাতে ক্লিক করুন</translation> <translation id="3975222297214566386">ইনপুট বিকল্পের বুদবুদ</translation> <translation id="397703832102027365">চূড়ান্ত হচ্ছে...</translation> <translation id="3979395879372752341">নতুন এক্সটেনশন জোড়া হয়েছে (<ph name="EXTENSION_NAME" />)</translation> @@ -2194,7 +2177,6 @@ <translation id="4419556793104466535">সিঙ্ক, ব্যক্তিগতকরণ এবং আরও অনেক কিছু নিয়ন্ত্রণ করুন</translation> <translation id="4421932782753506458">ফুঁয়োফুঁয়ো</translation> <translation id="4422347585044846479">এই পৃষ্ঠার বুকমার্ক সম্পাদনা করুন</translation> -<translation id="4423104065312875417">অতিরিক্ত ভাষ্য ইঞ্জিন ইনস্টল করুন</translation> <translation id="4423376891418188461">সেটিংস পুনরুদ্ধার করুন</translation> <translation id="4423482519432579560">&বানান পরীক্ষা</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, আপনার প্রশাসক চায় যে আপনি আপনার পাসওয়ার্ড পরিবর্তন করুন।</translation> @@ -2219,7 +2201,6 @@ <translation id="4449996769074858870">এই ট্যাবটি অডিও প্লে করছে৷</translation> <translation id="4450974146388585462">নির্ণয় করুন</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" />-এ সার্চ করুন অথবা ইউআরএল টাইপ করুন</translation> -<translation id="445923051607553918">ওয়াই-ফাই নেটওয়ার্কে যোগ দিন</translation> <translation id="4462159676511157176">কাস্টম নাম সার্ভার</translation> <translation id="4467100756425880649">Chrome ওয়েব দোকান গ্যালারি</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> ফোল্ডারটি বড় করুন</translation> @@ -2813,7 +2794,6 @@ <translation id="5380103295189760361">এই সমস্ত সংশোধকের জন্য Control, Alt, Shift, ধরে থাকুন অথবা কীবোর্ড শর্টকাটগুলি দেখার জন্য সার্চ করুন৷</translation> <translation id="5382591305415226340">সমর্থিত লিঙ্কগুলি পরিচালনা করুন</translation> <translation id="5384883051496921101">এই সাইটটি ছদ্মবেশী মোডের বাইরের একটি অ্যাপের সাথে তথ্য শেয়ার করতে চলেছে।</translation> -<translation id="5388588172257446328">ইউজারনেম:</translation> <translation id="5388885445722491159">জোড়া</translation> <translation id="5389237414310520250">নতুন ব্যবহারকারী তৈরি করা যায়নি৷ আপনার হার্ড ড্রাইভের সঞ্চয়স্থান ও অনুমতিগুলি পরীক্ষা করুন এবং আবার চেষ্টা করুন৷</translation> <translation id="5390100381392048184">সাউন্ডটি প্লে করার জন্য সাইটগুলিতে অনুমতি দিন</translation> @@ -2938,7 +2918,6 @@ <translation id="5551573675707792127">কীবোর্ড এবং টেক্সট ইনপুট</translation> <translation id="5553089923092577885">শংসাপত্র নীতি ম্যাপিং</translation> <translation id="5554489410841842733">এক্সটেনশানটি বর্তমান পৃষ্ঠাতে কাজ করলে এই আইনকটিকে দেখা যাবে৷</translation> -<translation id="5554573843028719904">অন্যান্য ওয়াই-ফাই নেটওয়ার্ক...</translation> <translation id="5554720593229208774">ইমেল শংসাকরণ কর্তৃপক্ষ</translation> <translation id="5556206011531515970">আপনার ডিফল্ট ব্রাউজার চয়ন করতে পরবর্তীতে ক্লিক করুন৷</translation> <translation id="5556459405103347317">আবার লোড করুন</translation> @@ -2979,7 +2958,6 @@ <translation id="5610038042047936818">ক্যামেরা মোডে যান</translation> <translation id="5612720917913232150"><ph name="URL" /> আপনার কম্পিউটারের লোকেশন ব্যবহার করতে চায়</translation> <translation id="5612734644261457353">দুঃখিত, আপনার পাসওয়ার্ড এখনো পর্যন্ত যাচাই করা যায়নি৷ দ্রষ্টব্য: আপনি যদি সম্প্রতি আপনার পাসওয়ার্ড পরিবর্তন করে থাকেন, তাহলে আপনি প্রস্থান করার পর আপনার নতুন পাসওয়ার্ড প্রয়োগ করা হবে, দয়া করে এখানে পুরানো পাসওয়ার্ড ব্যবহার করুন৷</translation> -<translation id="5613695965848159202">নামহীন পরিচয়:</translation> <translation id="5614190747811328134">ব্যবহারকারী বিঞ্জপ্তি</translation> <translation id="561698261642843490">Firefox বন্ধ করুন</translation> <translation id="5618075537869101857">ধ্যাত, kiosk অ্যাপ্লিকেশানটিকে লঞ্চ করা যায়নি৷</translation> @@ -3197,7 +3175,6 @@ <translation id="5941343993301164315">দয়া করে <ph name="TOKEN_NAME" />-এ প্রবেশ করুন৷</translation> <translation id="5941711191222866238">ছোট করুন</translation> <translation id="5946591249682680882">আইডি অভিযোগ করুন <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">ব্যক্তিগত নেটওয়ার্ক যুক্ত করুন</translation> <translation id="5949544233750246342">ফাইল বিশ্লেষণ করতে অক্ষম</translation> <translation id="5955282598396714173">আপনার পাসওয়ার্ডের মেয়াদ শেষ হয়ে গেছে। পাসওয়ার্ড পাল্টানোর জন্য সাইন-আউট করে আবার সাইন-ইন করুন।</translation> <translation id="5956585768868398362">আপনি কি এই পৃষ্ঠাটিকে সার্চ পৃষ্টা হিসেবে আশা করছিলেন?</translation> @@ -3401,7 +3378,6 @@ <translation id="6263541650532042179">সিঙ্ক আবার সেট করুন </translation> <translation id="6264365405983206840">&সকল বেছে নিন</translation> <translation id="6264422956566238156">আপনি সিঙ্ক চালু করেছেন</translation> -<translation id="6265930187414222160">হয়ে গেছে! ক্ষতিকারক সফ্টওয়্যার সরিয়ে দেওয়া হয়েছে।</translation> <translation id="6267166720438879315">নিজেকে <ph name="HOST_NAME" /> এ প্রমাণীকৃত করতে একটি শংসাপত্র বেছে নিন</translation> <translation id="6268252012308737255"><ph name="APP" /> দিয়ে খুলুন</translation> <translation id="6268747994388690914">HTML ফাইল থেকে বুকমার্ক আমদানি করুন...</translation> @@ -3423,7 +3399,7 @@ <translation id="6287852322318138013">এই ফাইলটি খোলার জন্য একটি অ্যাপ্লিকেশান বেছে নিন</translation> <translation id="6289452883081499048">আপনার জন্য তৈরি Google পরিষেবা যেমন Play</translation> <translation id="6290556621549272952">আপনি আপনার টিভি বা অন্যান্য ডিভাইসে Chromium থেকে সামগ্রী প্রদর্শন করার জন্য এই বৈশিষ্ট্যটি ব্যবহার করতে পারেন।</translation> -<translation id="6291949900244949761">একটি সাইট USB ডিভাইস অ্যাক্সেস করতে চাইলে আপনাকে জিজ্ঞাসা করা হবে (প্রস্তাবিত)</translation> +<translation id="6291949900244949761">কোনও সাইট ইউএসবি ডিভাইস অ্যাক্সেস করতে চাইলে আমাকে জিজ্ঞাসা করুন (প্রস্তাবিত)</translation> <translation id="6291953229176937411">ফাইন্ডারে &দেখান</translation> <translation id="6295158916970320988">সমস্ত সাইট</translation> <translation id="6295855836753816081">সংরক্ষণ করা হচ্ছে...</translation> @@ -3506,7 +3482,6 @@ আপনার <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> অ্যাকাউন্টে প্রবেশ করুন চালিয়ে যেতে দয়া করে "পরবর্তী" ক্লিক করুন।</translation> <translation id="6419546358665792306">প্যাকমুক্ত না করা অবস্থায় লোড করুন</translation> <translation id="642282551015776456">ফাইল বা ফোল্ডারের নাম হিসাবে নামটি ব্যবহৃত নাও হতে পারে</translation> -<translation id="6423239382391657905">VPN খুলুন</translation> <translation id="6426200009596957090">ChromeVox এর সেটিংস খুলুন</translation> <translation id="6429384232893414837">আপডেট করতে সমস্যা হয়েছে</translation> <translation id="6430814529589430811">Base64-এনকোডেড ASCII, একক শংসাপত্র</translation> @@ -3586,7 +3561,6 @@ <translation id="6544215763872433504">Google পরিচালিত ওয়েব ব্রাউজার, আপনারই জন্য</translation> <translation id="6545665334409411530">পুনরাবৃত্তির হার</translation> <translation id="6545834809683560467">সার্চগুলি এবং ঠিকানা দণ্ডে টাইপ করা URLগুলি অথবা অ্যাপ্লিকেশান লঞ্চার সার্চ বাক্স সম্পূর্ণ করার বিষয়ে সহায়তা করার জন্য একটি পূর্বানুমান পরিষেবা ব্যবহার করুন</translation> -<translation id="6546686722964485737">WiMAX নেটওয়ার্কে যোগদান করুন</translation> <translation id="6547316139431024316">এই এক্সটেনশানটি জন্য আবার সতর্ক করবেন না</translation> <translation id="6547354035488017500">কমপক্ষে ৫১২ MB জায়গা ফাঁকা করুন, নাহলে আপনার ডিভাইস সাড়া দিবে না। জায়গা খালি করার জন্য, ডিভাইসের সঞ্চয়স্থান থেকে ফাইল মুছুন।</translation> <translation id="6549689063733911810">সাম্প্রতিক</translation> @@ -4003,7 +3977,6 @@ <translation id="7201014958346994077">Linux ফাইল দেখা যায়নি</translation> <translation id="720110658997053098">স্থায়ীভাবে এই ডিভাইসটিকে কিয়স্ক মোডে রাখুন</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' মুছে ফেলা হয়েছে</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> ডাউনলোড হচ্ছে ...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{পৃষ্ঠাটি ছেড়ে যান}one{পৃষ্ঠাগুলি ছেড়ে যান}other{পৃষ্ঠাগুলি ছেড়ে যান}}</translation> <translation id="7216409898977639127">মোবাইল পরিষেবা প্রদানকারী</translation> @@ -4477,7 +4450,6 @@ <translation id="7909969815743704077">ছদ্মবেশী ভাবে ডাউনলোড হয়েছে</translation> <translation id="7910768399700579500">&নতুন ফোল্ডার</translation> <translation id="7912080627461681647">সার্ভারে আপনার পাসওয়ার্ড পাল্টানো হয়েছে। অনুগ্রহ করে সাইন-আউট করে আবার সাইন-ইন করুন।</translation> -<translation id="7912883689016444961">মোবাইল নেটওয়ার্ক কনফিগার করুন</translation> <translation id="7915471803647590281">প্রতিক্রিয়াটি প্রেরণের আগে কী ঘটছে তা দয়া করে আমাদের জানান৷ </translation> <translation id="7916556741383518510">ক্লিক করা হলে</translation> <translation id="792514962475806987">ডক করা জুম লেবেল:</translation> @@ -4530,7 +4502,6 @@ <translation id="7988355189918024273">অ্যাক্সেসযোগ্যতার বৈশিষ্ট্যগুলি সক্ষম করুন</translation> <translation id="7994702968232966508">EAP পদ্ধতি</translation> <translation id="799547531016638432">ডেস্কটপ সরান</translation> -<translation id="7997479212858899587">পরিচয়:</translation> <translation id="7997826902155442747">প্রক্রিয়ার অগ্রাধিকার</translation> <translation id="7999229196265990314">নিম্নোক্ত ফাইলগুলি তৈরি হয়েছে: @@ -4614,7 +4585,6 @@ <translation id="8105368624971345109">বন্ধ করুন</translation> <translation id="8106045200081704138">আমার সাথে শেয়ার করা</translation> <translation id="8107015733319732394">আপনার <ph name="DEVICE_TYPE" /> এ Google Play স্টোর ইনস্টল করা হচ্ছে। এতে কয়েক মিনিট সময় লাগতে পারে।</translation> -<translation id="8109930990200908494">ব্যবহারকারী সার্টিফিকেটের জন্য প্রবেশ করুন প্রয়োজন।</translation> <translation id="8111155949205007504">আপনার iPhone এর সাথে এই পাসওয়ার্ড শেয়ার করুন</translation> <translation id="8113043281354018522">লাইসেন্সের প্রকার বেছে নিন</translation> <translation id="8116190140324504026">আরও তথ্য...</translation> @@ -4735,7 +4705,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> আপনার ক্যামেরা অ্যাক্সেস করতে চায় কিনা জিজ্ঞাসা করুন</translation> <translation id="830868413617744215">বিটা</translation> <translation id="8309458809024885768">শংসাপত্র ইতিমধ্যে বিদ্যমান</translation> -<translation id="8309505303672555187">একটি নেটওয়ার্ক বেছে নিন:</translation> <translation id="8312871300878166382">ফোল্ডারের মধ্যে আটকে দিন</translation> <translation id="8317671367883557781">নেটওয়ার্ক সংযোগ যোগ করুন</translation> <translation id="8319414634934645341">প্রসারিত কী ব্যবহার</translation> @@ -4810,7 +4779,6 @@ <translation id="8451512073679317615">সহায়ক</translation> <translation id="8452135315243592079">সিম কার্ড পাওয়া যাচ্ছে না</translation> <translation id="8453482423012550001">$1 এর আইটেমগুলি অনুলিপি হচ্ছে...</translation> -<translation id="8454288007744638700">অথবা, একটি নতুন নেটওয়ার্ক বেছে নিন:</translation> <translation id="845627346958584683">মেয়াদ শেষ হওয়ার সময়</translation> <translation id="8456681095658380701">অবৈধ নাম</translation> <translation id="8457451314607652708">বুকমার্কগুলি আমদানি করুন</translation> @@ -4911,7 +4879,6 @@ <translation id="862727964348362408">সাসপেন্ড</translation> <translation id="862750493060684461">CSS ক্যাশে</translation> <translation id="8627795981664801467">কেবলমাত্র নিরাপদ কানেকশন</translation> -<translation id="8628085465172583869">সার্ভার আয়োজক নাম:</translation> <translation id="8630903300770275248">তত্ত্বাবধানে থাকা ব্যবহারকারীকে আমদানি করুন</translation> <translation id="8631032106121706562">পাপড়ি</translation> <translation id="8637542770513281060">আপনার কম্পিউটারে একটি নিরাপদ মডিউল আছে, যেটির সাহায্যে Chrome OS এর বিভিন্ন জটিল নিরাপত্তা বৈশিষ্ট্য ব্যবহার করা হয়। আরও জানতে Chromebook সহায়তা কেন্দ্রে যান: https://support.google.com/chromebook/?p=sm</translation> @@ -4947,7 +4914,7 @@ <translation id="8663099077749055505"><ph name="HOST" /> এ সর্বদা একাধিক স্বয়ংক্রিয় ডাউনলোডগুলি অবরুদ্ধ করুন</translation> <translation id="8664389313780386848">পৃষ্ঠা উৎস &দেখুন</translation> <translation id="866611985033792019">ইমেল ব্যবহারকারীদেরকে শনাক্ত করার কাজে এই শংসাপত্রটিকে বিশ্বাস করুন</translation> -<translation id="8666584013686199826">একটি সাইট USB ডিভাইস অ্যাক্সেস করতে চাইলে আমাকে জিজ্ঞাসা করুন</translation> +<translation id="8666584013686199826">কোনও সাইট ইউএসবি ডিভাইস অ্যাক্সেস করতে চাইলে আমাকে জিজ্ঞাসা করুন</translation> <translation id="8667328578593601900"><ph name="FULLSCREEN_ORIGIN" /> এখন সম্পূর্ণ স্ক্রীণে আছে এবং আপনার মাউস কার্সারকে অক্ষম করেছে৷</translation> <translation id="8669284339312441707">ওয়ার্মার</translation> <translation id="8669949407341943408">সরানো হচ্ছে...</translation> @@ -5062,7 +5029,7 @@ <translation id="8820961991571528294">পরীক্ষা করছে</translation> <translation id="8821045908425223359">IP ঠিকানা স্বয়ংক্রিয়ভাবে কনফিগার করুন</translation> <translation id="882204272221080310">নিরাপত্তা আরও সুরক্ষার জন্য ফার্মওয়্যার আপডেট করুন।</translation> -<translation id="8823514049557262177">লিঙ্ক পাঠ্য কপি করুন</translation> +<translation id="8823514049557262177">লিঙ্ক টেক্সট কপি করুন</translation> <translation id="8824701697284169214">&পৃষ্ঠা যোগ করুন...</translation> <translation id="8827752199525959199">আরও অ্যাকশন, <ph name="DOMAIN" />-এ <ph name="USERNAME" />-এর জন্য পাসওয়ার্ড</translation> <translation id="8828933418460119530">DNS নাম</translation> @@ -5167,7 +5134,6 @@ <translation id="899403249577094719">Netscape শংসাপত্র ভিত্তি URL</translation> <translation id="8995603266996330174">পরিচালনা করেছেন <ph name="DOMAIN" /> </translation> <translation id="8996526648899750015">অ্যাকাউন্ট যোগ করুন...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">ডিস্ক ইমেজ তৈরি করা হচ্ছে।</translation> <translation id="9003647077635673607">সমস্ত ওয়েবসাইটে অনুমতি দিন</translation> <translation id="9003677638446136377">আবার পরীক্ষা করে দেখুন</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb index 28c8a127..e809123c 100644 --- a/chrome/app/resources/generated_resources_ca.xtb +++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Ja gairebé és l'hora de fer una pausa</translation> <translation id="1062407476771304334">Substitueix</translation> -<translation id="1064835277883315402">Unió a la xarxa privada</translation> <translation id="1064912851688322329">Desconnexió del vostre compte de Google</translation> <translation id="1067048845568873861">Creada</translation> <translation id="1067291318998134776">Linux (versió beta)</translation> @@ -88,7 +87,7 @@ <translation id="1123187597739372905">Mostra la configuració de sincronització</translation> <translation id="1123316951456119629">Si desconnecteu el compte de Google de <ph name="PRODUCT_NAME" />, les dades restaran en aquest ordinador, però els canvis deixaran de sincronitzar-se amb el vostre compte de Google. Les dades que ja s'hagin emmagatzemat al compte de Google hi restaran fins que les elimineu amb el <ph name="BEGIN_LINK" />Tauler de Google<ph name="END_LINK" />.</translation> <translation id="1124772482545689468">Usuari</translation> -<translation id="1125550662859510761">Sembla que és <ph name="WIDTH" /> x <ph name="HEIGHT" /> (resolució nativa)</translation> +<translation id="1125550662859510761">Resolució: <ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativa)</translation> <translation id="1128109161498068552">No permetis que cap lloc utilitzi els missatges exclusius del sistema per accedir als dispositius MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Edita el motor de cerca</translation> @@ -101,7 +100,7 @@ <translation id="1145292499998999162">Connector bloquejat</translation> <translation id="1145532888383813076">Cerca al dispositiu, en aplicacions i al web.</translation> <translation id="1146204723345436916">Importa les adreces d'interès des d'un fitxer HTML...</translation> -<translation id="114721135501989771">Gaudeix de les eines intel·ligents de Google a Chrome</translation> +<translation id="114721135501989771">Eines intel·ligents a Chrome</translation> <translation id="1148097584170732637">S'han trobat <ph name="FILE_COUNT" />. <ph name="LINE_BREAK1" /> No hi ha prou espai disponible a l'emmagatzematge local. Cal tenir <ph name="FILE_SIZE" /> més. @@ -227,7 +226,6 @@ <translation id="1316136264406804862">S'està cercant...</translation> <translation id="1316495628809031177">La sincronització està en pausa</translation> <translation id="1319979322914001937">Una aplicació que mostra un llista filtrada de les extensions de Chrome Web Store. Les extensions de la llista es poden instal·lar directament des de l'aplicació.</translation> -<translation id="132090119144658135">Coincidència d'assumpte:</translation> <translation id="1326317727527857210">Inicieu la sessió a Chrome per accedir a les vostres pestanyes des dels altres dispositius que tingueu.</translation> <translation id="1327074568633507428">Impressora a Google Cloud Print</translation> <translation id="1327977588028644528">Passarel·la</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Suprimeix aquesta persona</translation> <translation id="1706586824377653884">Afegida per l'administrador</translation> <translation id="1706625117072057435">Nivells de zoom</translation> -<translation id="1707463636381878959">Comparteix aquesta xarxa amb altres usuaris</translation> <translation id="1708338024780164500">(Inactiva)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (identificador: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativa)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Activa el tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Mostra a Chrome Web Store</translation> -<translation id="1758831820837444715">Configuració de la xarxa Ethernet</translation> <translation id="1763046204212875858">Creació de dreceres a aplicacions</translation> <translation id="1763108912552529023">Continua explorant</translation> <translation id="1763808908432309942">S'obre en una pestanya nova</translation> @@ -780,7 +776,7 @@ <translation id="2151576029659734873">Heu introduït un índex de pestanya no vàlid.</translation> <translation id="2154484045852737596">Edita la targeta</translation> <translation id="2154710561487035718">Copia l'URL</translation> -<translation id="2155772377859296191">Sembla que és <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2155772377859296191">Resolució: <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> <translation id="2156283799932971644">Per ajudar a millorar Navegació segura, envia a Google algunes dades del sistema i contingut de les pàgines.</translation> <translation id="215753907730220065">Surt de la pantalla completa</translation> <translation id="2157875535253991059">Ara aquesta pàgina es mostra a pantalla completa.</translation> @@ -875,7 +871,6 @@ <translation id="2291643155573394834">Pestanya següent</translation> <translation id="2292848386125228270">Inicia <ph name="PRODUCT_NAME" /> com un usuari normal. Si l'has d'executar com a arrel per fer-ne desenvolupament, torna a executar-lo amb la marca que indica que no és zona de proves.</translation> <translation id="2294358108254308676">Voleu instal·lar <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Mètode EAP:</translation> <translation id="2297705863329999812">Cerca impressores</translation> <translation id="2300383962156589922">Personalitza i controla <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">El directori arrel de l'extensió no és vàlid.</translation> @@ -933,7 +928,6 @@ <translation id="2379281330731083556">Imprimeix des de la finestra de diàleg del sistema… <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Demana permís abans de fer cap enviament (recomanat)</translation> <translation id="2384436799579181135">S'ha produït un error. Comprova la impressora i torna-ho a provar.</translation> -<translation id="2385700042425247848">Nom del servei:</translation> <translation id="2387458720915042159">Tipus de connexió del servidor intermediari</translation> <translation id="2391419135980381625">Tipus de lletra estàndard</translation> <translation id="2391762656119864333">Revoca</translation> @@ -984,7 +978,6 @@ <translation id="247949520305900375">Comparteix l'àudio</translation> <translation id="2480868415629598489">Modifica les dades que copies i enganxes</translation> <translation id="2482878487686419369">Notificacions</translation> -<translation id="2485056306054380289">Certificat de CA del servidor:</translation> <translation id="2485422356828889247">Desinstal·la</translation> <translation id="2487067538648443797">Afegeix una adreça d'interès nova</translation> <translation id="248861575772995840">No es troba el telèfon. Comprova que <ph name="DEVICE_TYPE" /> tingui el Bluetooth activat. <a>Més informació</a></translation> @@ -1108,7 +1101,6 @@ <translation id="2653659639078652383">Envia</translation> <translation id="265390580714150011">Valor del camp</translation> <translation id="2654166010170466751">Permet que els llocs web instal·lin gestors de pagament</translation> -<translation id="2655386581175833247">Certificat d'usuari:</translation> <translation id="2660779039299703961">Esdeveniment</translation> <translation id="266079277508604648">No es pot contactar amb la impressora. Comprova que estigui encesa i connectada al teu Chromebook per Wi-Fi o USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1408,7 +1400,6 @@ <translation id="3100609564180505575">Mòduls (<ph name="TOTAL_COUNT" />) - Conflictes coneguts: <ph name="BAD_COUNT" />, sospitats: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Data i hora</translation> <translation id="310671807099593501">El lloc web està utilitzant el Bluetooth</translation> -<translation id="3108967419958202225">Trieu...</translation> <translation id="3115128645424181617">No es troba el telèfon. Comprova que sigui a prop i que tingui el Bluetooth activat.</translation> <translation id="3115147772012638511">Esperant la memòria cau...</translation> <translation id="3118319026408854581">Ajuda de <ph name="PRODUCT_NAME" /></translation> @@ -1453,7 +1444,6 @@ <translation id="3165390001037658081">Alguns operadors de telefonia mòbil poden bloquejar aquesta funció.</translation> <translation id="316854673539778496">Per accedir a totes les teves extensions des de tots els dispositius, inicia la sessió i activa la sincronització.</translation> <translation id="3170072451822350649">També podeu <ph name="LINK_START" />navegar com a convidat<ph name="LINK_END" /> sense iniciar sessió.</translation> -<translation id="3177048931975664371">Feu clic per amagar la contrasenya</translation> <translation id="3177909033752230686">Idioma de la pàgina:</translation> <translation id="3181110748548073003">Prem |<ph name="SHORTCUT" />| per avançar</translation> <translation id="3182749001423093222">Corrector ortogràfic</translation> @@ -1484,7 +1474,6 @@ <translation id="3236289833370040187">La propietat es transferirà a <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Obre les opcions de l'extensió</translation> <translation id="3241680850019875542">Seleccioneu el directori arrel de l'extensió que voleu empaquetar. Per actualitzar una extensió, cal que seleccioneu també el fitxer de clau privada que s'utilitzarà.</translation> -<translation id="3242765319725186192">Clau precompartida:</translation> <translation id="3244294424315804309">Continua silenciant el so</translation> <translation id="3245321423178950146">Artista desconegut</translation> <translation id="3246097286174000800">Prova Smart Lock</translation> @@ -1616,7 +1605,6 @@ <translation id="3440663250074896476">Més accions per a <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Pregunta'm quan un lloc vulgui fer servir un connector per accedir a l'ordinador</translation> <translation id="3441653493275994384">Pantalla</translation> -<translation id="3445830502289589282">Autenticació de fase 2:</translation> <translation id="344630545793878684">Llegir les dades d'una sèrie de llocs web</translation> <translation id="3449839693241009168">Premeu <ph name="SEARCH_KEY" /> per enviar ordres a <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Percentatge d'ocupació de l'estat d'inactivitat</translation> @@ -1657,7 +1645,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> errors.</translation> <translation id="3495660573538963482">Configuració de l'Assistent de Google</translation> <translation id="3496213124478423963">Redueix</translation> -<translation id="3504135463003295723">Nom del grup:</translation> <translation id="3505030558724226696">Revoca l'accés als dispositius</translation> <translation id="3507421388498836150">Permisos actuals de l'extensió <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Suprimeix les aplicacions per a Linux de Chromebook</translation> @@ -1766,7 +1753,6 @@ <translation id="3661054927247347545">La certificació d'inici de sessió no és vàlida. La finestra es tancarà d'aquí a <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Icona de l'extensió</translation> <translation id="3665589677786828986">Chrome ha detectat que un altre programa ha malmès alguns dels paràmetres de configuració i els ha restablert als valors predeterminats originals.</translation> -<translation id="3665842570601375360">Seguretat:</translation> <translation id="3668570675727296296">Configuració d'idioma</translation> <translation id="3668823961463113931">Gestors</translation> <translation id="3670229581627177274">Activa el Bluetooth</translation> @@ -1805,7 +1791,6 @@ <translation id="3726463242007121105">Aquest dispositiu no es pot obrir perquè el seu sistema de fitxers no és compatible.</translation> <translation id="3727148787322499904">Els canvis en aquesta opció de configuració afectaran totes les xarxes compartides</translation> <translation id="3727187387656390258">Inspecciona l'element emergent</translation> -<translation id="3728067901555601989">Contrasenya d'ús únic:</translation> <translation id="3732078975418297900">Hi ha un error a la línia <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Servidor SSL amb entrada progressiva</translation> <translation id="3737536731758327622">Les baixades es mostren aquí</translation> @@ -1880,7 +1865,6 @@ <translation id="38275787300541712">Premeu Retorn quan hàgiu acabat</translation> <translation id="3827774300009121996">&Pantalla completa</translation> <translation id="3828029223314399057">Cerca adreces d'interès</translation> -<translation id="3829932584934971895">Tipus de proveïdor:</translation> <translation id="3830674330436234648">No hi ha cap reproducció disponible</translation> <translation id="3831486154586836914">Heu entrat al mode de visió general de la finestra.</translation> <translation id="383161972796689579">El propietari d'aquest dispositiu ha desactivat la possibilitat d'afegir-hi usuaris nous</translation> @@ -1978,7 +1962,6 @@ <translation id="3968261067169026421">No s'ha pogut configurar la xarxa</translation> <translation id="3970114302595058915">Identificador</translation> <translation id="397105322502079400">S’està calculant...</translation> -<translation id="3974195870082915331">Feu clic per mostrar la contrasenya</translation> <translation id="3975222297214566386">Quadre d'ajuda de les opcions d'entrada</translation> <translation id="397703832102027365">S'està finalitzant...</translation> <translation id="3979395879372752341">S'ha afegit una extensió nova (<ph name="EXTENSION_NAME" />)</translation> @@ -2226,7 +2209,6 @@ <translation id="4419556793104466535">Controla la sincronització i la personalització, entre d'altres</translation> <translation id="4421932782753506458">Gatet</translation> <translation id="4422347585044846479">Editeu l'adreça d'interès d'aquesta pàgina</translation> -<translation id="4423104065312875417">Instal·la motors de veu addicionals</translation> <translation id="4423376891418188461">Restaura la configuració</translation> <translation id="4423482519432579560">&Corrector ortogràfic</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, l'administrador necessita que canviïs la contrasenya.</translation> @@ -2251,7 +2233,6 @@ <translation id="4449996769074858870">En aquesta pestanya s'està reproduint àudio.</translation> <translation id="4450974146388585462">Diagnòstic</translation> <translation id="4453946976636652378">Cerca <ph name="SEARCH_ENGINE_NAME" /> o escriu un URL</translation> -<translation id="445923051607553918">Connexió a una xarxa Wi-Fi</translation> <translation id="4462159676511157176">Servidors de noms personalitzats</translation> <translation id="4467100756425880649">Galeria de Chrome Web Store</translation> <translation id="4467101674048705704">Desplega <ph name="FOLDER_NAME" /></translation> @@ -2500,7 +2481,7 @@ <translation id="4862042298115071399"><ph name="WINDOW_TITLE" />: s'està reproduint el vídeo en mode de pantalla en pantalla</translation> <translation id="4862050643946421924">S'està afegint el dispositiu...</translation> <translation id="4862642413395066333">Signatura de respostes OCSP</translation> -<translation id="4863769717153320198">Sembla que és <ph name="WIDTH" /> x <ph name="HEIGHT" /> (resolució predeterminada)</translation> +<translation id="4863769717153320198">Resolució: <ph name="WIDTH" /> x <ph name="HEIGHT" /> (predeterminada)</translation> <translation id="4864369630010738180">S'està iniciant la sessió...</translation> <translation id="486635084936119914">Obre alguns tipus de fitxer automàticament després de baixar-los</translation> <translation id="4869142322204669043">Google pot utilitzar contingut dels llocs web que visites, així com l'activitat de navegació i altres interaccions per personalitzar <ph name="IDS_SHORT_PRODUCT_NAME" /> i altres serveis nostres, com ara el Traductor, la Cerca i els anuncis. Pots personalitzar aquesta opció en qualsevol moment a Configuració.</translation> @@ -2859,7 +2840,6 @@ <translation id="5380103295189760361">Manteniu premudes les tecles Control, Alt, Maj o Cerca per veure les tecles de drecera per a aquests modificadors.</translation> <translation id="5382591305415226340">Gestiona els enllaços admesos</translation> <translation id="5384883051496921101">Aquest lloc està a punt de compartir informació amb una aplicació fora del mode d'incògnit.</translation> -<translation id="5388588172257446328">Nom d'usuari:</translation> <translation id="5388885445722491159">Vinculat</translation> <translation id="5389237414310520250">No s'ha pogut crear l'usuari. Comproveu els vostres permisos i l'espai disponible a la unitat de disc dur i torneu-ho a provar.</translation> <translation id="5390100381392048184">Permet que els llocs web reprodueixin so</translation> @@ -2984,7 +2964,6 @@ <translation id="5551573675707792127">Teclat i introducció de text</translation> <translation id="5553089923092577885">Assignacions de normes de certificats</translation> <translation id="5554489410841842733">Aquesta icona serà visible quan les extensions puguin actuar a la pàgina actual.</translation> -<translation id="5554573843028719904">Una altra xarxa Wi-Fi...</translation> <translation id="5554720593229208774">Correu electrònic de l'entitat emissora de certificats</translation> <translation id="5556206011531515970">Feu clic a Següent per seleccionar el navegador predeterminat.</translation> <translation id="5556459405103347317">Torna a carregar</translation> @@ -3025,7 +3004,6 @@ <translation id="5610038042047936818">Canvia al mode de càmera</translation> <translation id="5612720917913232150"><ph name="URL" /> vol utilitzar la ubicació de l'ordinador</translation> <translation id="5612734644261457353">Encara no s'ha pogut verificar la contrasenya. Nota: Si l'has canviat fa poc, la contrasenya nova s'aplicarà un cop hagis tancat la sessió. Fes servir la contrasenya anterior aquí.</translation> -<translation id="5613695965848159202">Identitat anònima:</translation> <translation id="5614190747811328134">Avís per a l'usuari </translation> <translation id="561698261642843490">Tanca Firefox</translation> <translation id="5618075537869101857">No s'ha pogut iniciar l'aplicació de quiosc.</translation> @@ -3100,7 +3078,7 @@ <translation id="572392919096807438">Recorda la meva decisió</translation> <translation id="5727728807527375859">Les extensions, les aplicacions i els temes poden malmetre el vostre equip. Segur que voleu continuar?</translation> <translation id="5729712731028706266">&Lector</translation> -<translation id="5731185123186077399">Gaudeix de serveis de Google personalitzats, com ara Google Pay</translation> +<translation id="5731185123186077399">Serveis de Google personalitzats, com ara Google Pay</translation> <translation id="5731247495086897348">En&ganxa i ves-hi</translation> <translation id="5731409020711461763">1 foto nova</translation> <translation id="5734362860645681824">Comunicacions</translation> @@ -3244,7 +3222,6 @@ <translation id="5941343993301164315">Inicieu la sessió a <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimitza</translation> <translation id="5946591249682680882">Identificador de l'informe: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Afegeix una xarxa privada</translation> <translation id="5949544233750246342">No es pot analitzar el fitxer</translation> <translation id="5955282598396714173">La contrasenya ha caducat. Tanca la sessió i torna-la a iniciar per canviar-la.</translation> <translation id="5956585768868398362">Aquesta pàgina de cerca és la que esperàveu?</translation> @@ -3449,7 +3426,6 @@ <translation id="6263541650532042179">restableix la sincronització</translation> <translation id="6264365405983206840">Selecciona-ho &tot</translation> <translation id="6264422956566238156">Has activat la sincronització</translation> -<translation id="6265930187414222160">Fet! S'ha suprimit el programari maliciós.</translation> <translation id="6267166720438879315">Seleccioneu un certificat per autenticar-vos a <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Obre amb <ph name="APP" /></translation> <translation id="6268747994388690914">Importa les adreces d'interès des d'un fitxer HTML...</translation> @@ -3556,7 +3532,6 @@ Feu clic a Següent per continuar amb l'inici de sessió al compte del domini <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Carrega una extensió desempaquetada</translation> <translation id="642282551015776456">Aquest nom no es pot utilitzar com a nom de fitxer o de carpeta</translation> -<translation id="6423239382391657905">VPN oberta</translation> <translation id="6426200009596957090">Obre la configuració de ChromeVox</translation> <translation id="6429384232893414837">Error d'actualització</translation> <translation id="6430814529589430811">ASCII codificat en Base64, certificat únic</translation> @@ -3636,7 +3611,6 @@ <translation id="6544215763872433504">El navegador web de Google, pensat per a tu</translation> <translation id="6545665334409411530">Freqüència de repetició</translation> <translation id="6545834809683560467">Utilitza un servei de predicció per completar fàcilment les cerques i els URL introduïts a la barra d'adreces o al quadre de cerca del menú d'aplicacions.</translation> -<translation id="6546686722964485737">Inscripció a la xarxa Wimax</translation> <translation id="6547316139431024316">No em tornis a avisar per a aquesta extensió</translation> <translation id="6547354035488017500">Si no alliberes almenys 512 MB d'espai, el dispositiu deixarà de respondre. Per fer-ho, suprimeix fitxers de l'emmagatzematge del dispositiu.</translation> <translation id="6549689063733911810">Recent</translation> @@ -4055,7 +4029,6 @@ <translation id="7201014958346994077">No es poden veure fitxers de Linux</translation> <translation id="720110658997053098">Activa permanentment el mode quiosc en aquest dispositiu</translation> <translation id="7201118060536064622">S'ha suprimit <ph name="DELETED_ITEM_NAME" /></translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">S'està baixant <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Surt de la pàgina}other{Surt de les pàgines}}</translation> <translation id="7216409898977639127">Proveïdor de dades mòbils</translation> @@ -4531,7 +4504,6 @@ <translation id="7909969815743704077">S'ha baixat en mode d'incògnit</translation> <translation id="7910768399700579500">Carpeta &nova</translation> <translation id="7912080627461681647">La contrasenya s'ha canviat al servidor. Tanca la sessió i torna-la a iniciar.</translation> -<translation id="7912883689016444961">Configura la xarxa mòbil</translation> <translation id="7915471803647590281">Indica'ns el problema abans d'enviar els comentaris.</translation> <translation id="7916556741383518510">En fer clic</translation> <translation id="792514962475806987">Nivell de zoom acoblat:</translation> @@ -4585,7 +4557,6 @@ <translation id="7988355189918024273">Activa les funcions d'accessibilitat</translation> <translation id="7994702968232966508">Mètode EAP</translation> <translation id="799547531016638432">Suprimeix la drecera</translation> -<translation id="7997479212858899587">Identitat:</translation> <translation id="7997826902155442747">Prioritat del procés</translation> <translation id="7999229196265990314">S'han creat els fitxers següents: @@ -4669,7 +4640,6 @@ <translation id="8105368624971345109">Desactiva</translation> <translation id="8106045200081704138">Compartit amb mi</translation> <translation id="8107015733319732394">S'està instal·lant Google Play Store al teu dispositiu <ph name="DEVICE_TYPE" />. Aquest procés pot tardar uns quants minuts.</translation> -<translation id="8109930990200908494">Cal que inicieu la sessió per a la certificació de l'usuari.</translation> <translation id="8111155949205007504">Comparteix aquesta contrasenya amb el dispositiu iPhone</translation> <translation id="8113043281354018522">Tria el tipus de llicència</translation> <translation id="8116190140324504026">Més informació...</translation> @@ -4791,7 +4761,6 @@ <translation id="8308179586020895837">Pregunta si <ph name="HOST" /> vol accedir a la càmera</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">El certificat ja existeix</translation> -<translation id="8309505303672555187">Seleccioneu una xarxa:</translation> <translation id="8312871300878166382">Enganxa a la carpeta</translation> <translation id="8317671367883557781">Afegeix una connexió de xarxa</translation> <translation id="8319414634934645341">Ús ampliat de claus</translation> @@ -4866,7 +4835,6 @@ <translation id="8451512073679317615">Assistent</translation> <translation id="8452135315243592079">Falta la targeta SIM</translation> <translation id="8453482423012550001">S'estan copiant $1 elements...</translation> -<translation id="8454288007744638700">O bé seleccioneu una xarxa nova:</translation> <translation id="845627346958584683">Hora de caducitat</translation> <translation id="8456681095658380701">El nom no és vàlid</translation> <translation id="8457451314607652708">Importa les adreces d'interès</translation> @@ -4968,7 +4936,6 @@ <translation id="862727964348362408">Suspesa</translation> <translation id="862750493060684461">Memòria cau CSS</translation> <translation id="8627795981664801467">Només les connexions segures</translation> -<translation id="8628085465172583869">Nom d'amfitrió del servidor:</translation> <translation id="8630903300770275248">Importa un usuari supervisat</translation> <translation id="8631032106121706562">Flor</translation> <translation id="8637542770513281060">L'ordinador conté un mòdul de seguretat que s'utilitza per implementar un gran nombre de funcions de seguretat clau a Chrome OS. Visita el Centre d'ajuda de Chromebook per obtenir més informació: https://support.google.com/chromebook/?p=sm</translation> @@ -5223,7 +5190,6 @@ <translation id="899403249577094719">URL base de certificat de Netscape</translation> <translation id="8995603266996330174">Gestionat per <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Afegeix un compte...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">S'està creant la imatge de disc.</translation> <translation id="9003647077635673607">Permet-ho en tots els llocs web</translation> <translation id="9003677638446136377">Torna-ho a provar</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb index 4125074..3a0e5fa 100644 --- a/chrome/app/resources/generated_resources_cs.xtb +++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Brzy bude čas na přestávku</translation> <translation id="1062407476771304334">Nahradit</translation> -<translation id="1064835277883315402">Připojit se k privátní síti</translation> <translation id="1064912851688322329">Odpojit účet Google</translation> <translation id="1067048845568873861">Vytvořeno</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Vyhledávání...</translation> <translation id="1316495628809031177">Synchronizace je pozastavena</translation> <translation id="1319979322914001937">Aplikace, která zobrazuje filtrovaný seznam rozšíření v Internetovém obchodu Chrome. Rozšíření v seznamu lze nainstalovat přímo z této aplikace.</translation> -<translation id="132090119144658135">Shoda předmětu:</translation> <translation id="1326317727527857210">Chcete-li získat přístup ke kartám ze svých ostatních zařízení, přihlaste se do Chromu.</translation> <translation id="1327074568633507428">Tiskárna ve službě Google Cloud Print</translation> <translation id="1327977588028644528">Brána</translation> @@ -491,7 +489,6 @@ <translation id="1701062906490865540">Odebrat tohoto uživatele</translation> <translation id="1706586824377653884">Přidáno administrátorem</translation> <translation id="1706625117072057435">Úrovně přiblížení</translation> -<translation id="1707463636381878959">Sdílet tuto síť s ostatními uživateli</translation> <translation id="1708338024780164500">(Neaktivní)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> × <ph name="HEIGHT" /> (nativní)</translation> @@ -527,7 +524,6 @@ <translation id="175772926354468439">Aktivovat motiv</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Zobrazit v Internetovém obchodu Chrome</translation> -<translation id="1758831820837444715">Konfigurace sítě Ethernet</translation> <translation id="1763046204212875858">Vytvořit zástupce aplikací</translation> <translation id="1763108912552529023">Pokračovat v průzkumu</translation> <translation id="1763808908432309942">Otevře se na nové kartě</translation> @@ -876,7 +872,6 @@ <translation id="2291643155573394834">Další karta</translation> <translation id="2292848386125228270">Spusťte prosím aplikaci <ph name="PRODUCT_NAME" /> jako běžný uživatel. Pokud ji pro účely vývoje potřebujete spustit jako uživatel root, spusťte ji znovu s příznakem --no-sandbox.</translation> <translation id="2294358108254308676">Chcete nainstalovat aplikaci <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Metoda EAP:</translation> <translation id="2297705863329999812">Hledat tiskárny</translation> <translation id="2300383962156589922">Přizpůsobení a ovládání aplikace <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Kořenový adresář rozšíření je neplatný.</translation> @@ -934,7 +929,6 @@ <translation id="2379281330731083556">Tisk pomocí dialogového okna systému... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Před odesláním se zeptat (doporučeno)</translation> <translation id="2384436799579181135">Došlo k chybě. Zkontrolujte tiskárnu a zkuste to znovu.</translation> -<translation id="2385700042425247848">Název služby:</translation> <translation id="2387458720915042159">Typ připojení k proxy serveru</translation> <translation id="2391419135980381625">Standardní písmo</translation> <translation id="2391762656119864333">Zrušit</translation> @@ -985,7 +979,6 @@ <translation id="247949520305900375">Sdílet zvuk</translation> <translation id="2480868415629598489">Upravovat data, která kopírujete a vkládáte</translation> <translation id="2482878487686419369">Oznámení</translation> -<translation id="2485056306054380289">Certif. CA serveru:</translation> <translation id="2485422356828889247">Odinstalovat</translation> <translation id="2487067538648443797">Přidat novou záložku</translation> <translation id="248861575772995840">Telefon nebyl nalezen. Zkontrolujte, zda je v zařízení <ph name="DEVICE_TYPE" /> zapnut Bluetooth. <a>Další informace</a></translation> @@ -1110,7 +1103,6 @@ <translation id="2653659639078652383">Odeslat</translation> <translation id="265390580714150011">Hodnota pole</translation> <translation id="2654166010170466751">Povolit webům instalovat obslužné nástroje pro platby</translation> -<translation id="2655386581175833247">Certifikát uživatele:</translation> <translation id="2660779039299703961">Událost</translation> <translation id="266079277508604648">K tiskárně se nelze připojit. Zkontrolujte, zda je tiskárna zapnutá a připojená k Chromebooku přes Wi-Fi nebo USB.</translation> <translation id="2661146741306740526">16 : 9</translation> @@ -1410,7 +1402,6 @@ <translation id="3100609564180505575">Moduly (<ph name="TOTAL_COUNT" />) – Známé konflikty: <ph name="BAD_COUNT" />, předpokládané: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Datum a čas</translation> <translation id="310671807099593501">Web používá Bluetooth</translation> -<translation id="3108967419958202225">Zvolit...</translation> <translation id="3115128645424181617">Telefon nebyl nalezen. Zkontrolujte, zda jej máte u sebe a zda je zapnutý Bluetooth.</translation> <translation id="3115147772012638511">Čekání na mezipaměť</translation> <translation id="3118319026408854581">Nápověda aplikace <ph name="PRODUCT_NAME" /></translation> @@ -1455,7 +1446,6 @@ <translation id="3165390001037658081">Někteří operátoři mohou tuto funkci blokovat.</translation> <translation id="316854673539778496">Chcete-li mít rozšíření ve všech zařízeních, přihlaste se a zapněte synchronizaci.</translation> <translation id="3170072451822350649">Také můžete přihlášení přeskočit a <ph name="LINK_START" />prohlížet v roli hosta<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Kliknutím skryjete heslo</translation> <translation id="3177909033752230686">Jazyk stránky:</translation> <translation id="3181110748548073003">Chcete-li přejít vpřed, stiskněte |<ph name="SHORTCUT" />|</translation> <translation id="3182749001423093222">Kontrola pravopisu</translation> @@ -1486,7 +1476,6 @@ <translation id="3236289833370040187">Vlastnictví bude převedeno na <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Otevřít možnosti rozšíření</translation> <translation id="3241680850019875542">Vyberte kořenový adresář rozšíření, které chcete zabalit. Chcete-li rozšíření aktualizovat, vyberte také soubor soukromého klíče, který chcete znovu použít.</translation> -<translation id="3242765319725186192">Předsdílený klíč:</translation> <translation id="3244294424315804309">Pokračovat v tlumení zvuku</translation> <translation id="3245321423178950146">Neznámý interpret</translation> <translation id="3246097286174000800">Vyzkoušejte funkci Smart Lock</translation> @@ -1617,7 +1606,6 @@ <translation id="3440663250074896476">Další akce se záložkou <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Dotázat se, pokud chce web použít plugin k přístupu do počítače</translation> <translation id="3441653493275994384">Obrazovka</translation> -<translation id="3445830502289589282">Ověření Phase 2:</translation> <translation id="344630545793878684">Čtení vašich dat na mnoha webech</translation> <translation id="3449839693241009168">Stiskem klávesy <ph name="SEARCH_KEY" /> odešlete příkazy pro rozšíření <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Procentuální zastoupení stavu nečinnosti</translation> @@ -1658,7 +1646,6 @@ <translation id="3495304270784461826">Chyby: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Nastavení Asistenta Google</translation> <translation id="3496213124478423963">Oddálit</translation> -<translation id="3504135463003295723">Název skupiny:</translation> <translation id="3505030558724226696">Zrušit přístup k zařízení</translation> <translation id="3507421388498836150">Aktuální oprávnění pro aplikaci <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Odstranit linuxové aplikace pro Chromebook</translation> @@ -1767,7 +1754,6 @@ <translation id="3661054927247347545">Přihlašovací certifikace není platná. Okno se zavře za <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ikona rozšíření</translation> <translation id="3665589677786828986">Prohlížeč Chrome zjistil, že některá z vašich nastavení byla upravena jiným programem, a obnovil je na původní výchozí hodnoty.</translation> -<translation id="3665842570601375360">Zabezpečení:</translation> <translation id="3668570675727296296">Nastavení jazyka</translation> <translation id="3668823961463113931">Obslužné nástroje</translation> <translation id="3670229581627177274">zapněte Bluetooth</translation> @@ -1806,7 +1792,6 @@ <translation id="3726463242007121105">Toto zařízení nelze otevřít, protože jeho systém souborů není podporován.</translation> <translation id="3727148787322499904">Změna tohoto nastavení bude mít dopad na všechny sdílené sítě</translation> <translation id="3727187387656390258">Prozkoumat vyskakovací kontextovou nabídku</translation> -<translation id="3728067901555601989">Jednorázové heslo:</translation> <translation id="3732078975418297900">Chyba na řádku <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Server SSL s technologií Step-up</translation> <translation id="3737536731758327622">Zde se zobrazují vaše stažené soubory</translation> @@ -1881,7 +1866,6 @@ <translation id="38275787300541712">Po dokončení stiskněte klávesu Enter</translation> <translation id="3827774300009121996">&Celá obrazovka</translation> <translation id="3828029223314399057">Hledat v záložkách</translation> -<translation id="3829932584934971895">Druh poskytovatele:</translation> <translation id="3830674330436234648">Přehrávání není k dispozici</translation> <translation id="3831486154586836914">Byl aktivován režim přehledu okna</translation> <translation id="383161972796689579">Vlastník zařízení zakázal přidávat nové uživatele.</translation> @@ -1979,7 +1963,6 @@ <translation id="3968261067169026421">Síť se nepodařilo nastavit</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Probíhá výpočet…</translation> -<translation id="3974195870082915331">Kliknutím zobrazíte heslo</translation> <translation id="3975222297214566386">Bublina s možnostmi vstupu</translation> <translation id="397703832102027365">Dokončování...</translation> <translation id="3979395879372752341">Bylo přidáno nové rozšíření (<ph name="EXTENSION_NAME" />)</translation> @@ -2227,7 +2210,6 @@ <translation id="4419556793104466535">Ovládání synchronizace, personalizace apod.</translation> <translation id="4421932782753506458">Kotě</translation> <translation id="4422347585044846479">Upravit záložku pro tuto stránku</translation> -<translation id="4423104065312875417">Nainstalovat další moduly převodu textu na řeč</translation> <translation id="4423376891418188461">Obnovit nastavení</translation> <translation id="4423482519432579560">&Kontrola pravopisu</translation> <translation id="442397852638519243">Zpráva pro uživatele <ph name="USER_NAME" />: váš administrátor vyžaduje, abyste si změnili heslo.</translation> @@ -2252,7 +2234,6 @@ <translation id="4449996769074858870">Tato karta přehrává zvuk.</translation> <translation id="4450974146388585462">Diagnostikovat</translation> <translation id="4453946976636652378">Zadejte dotaz pro vyhledávač <ph name="SEARCH_ENGINE_NAME" /> nebo adresu URL</translation> -<translation id="445923051607553918">Připojit se k síti Wi-Fi</translation> <translation id="4462159676511157176">Vlastní názvové servery</translation> <translation id="4467100756425880649">Galerie Internetového obchodu Chrome</translation> <translation id="4467101674048705704">Rozbalit složku <ph name="FOLDER_NAME" /></translation> @@ -2857,7 +2838,6 @@ <translation id="5380103295189760361">Chcete-li zjistit klávesové zkratky přidružené ke klávese Ctrl, Alt, Shift nebo Hledat, přidržte příslušnou klávesu.</translation> <translation id="5382591305415226340">Spravovat podporované odkazy</translation> <translation id="5384883051496921101">Tento web chce sdílet informace s aplikací mimo anonymní režim.</translation> -<translation id="5388588172257446328">Uživatelské jméno:</translation> <translation id="5388885445722491159">Párováno</translation> <translation id="5389237414310520250">Vytvoření nového uživatele se nezdařilo. Zkontrolujte místo na disku a oprávnění a zkuste to znovu.</translation> <translation id="5390100381392048184">Povolit webům přehrávat zvuky</translation> @@ -2982,7 +2962,6 @@ <translation id="5551573675707792127">Klávesnice a zadávání textu</translation> <translation id="5553089923092577885">Mapování zásad certifikátu</translation> <translation id="5554489410841842733">Tato ikona se zobrazí, když bude rozšíření moci provádět akce na aktuální stránce.</translation> -<translation id="5554573843028719904">Jiná síť Wi-Fi...</translation> <translation id="5554720593229208774">Certifikační autorita pro ověřování e-mailu</translation> <translation id="5556206011531515970">Výchozí prohlížeč vyberete kliknutím na tlačítko Další.</translation> <translation id="5556459405103347317">Načíst znovu</translation> @@ -3023,7 +3002,6 @@ <translation id="5610038042047936818">Přepnout na režim fotoaparátu</translation> <translation id="5612720917913232150">Web <ph name="URL" /> chce použít polohu vašeho počítače</translation> <translation id="5612734644261457353">Je nám líto, vaše heslo se stále nedaří ověřit. Poznámka: Pokud jste heslo nedávno změnili, vaše nové heslo bude použitelné až po odhlášení. Použijte své staré heslo.</translation> -<translation id="5613695965848159202">Anonymní identita:</translation> <translation id="5614190747811328134">Sdělení pro uživatele</translation> <translation id="561698261642843490">Zavřete Firefox</translation> <translation id="5618075537869101857">Kruci, aplikaci pro režim veřejného terminálu se nepodařilo spustit.</translation> @@ -3241,7 +3219,6 @@ <translation id="5941343993301164315">Přihlaste se prosím do zařízení <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimalizovat</translation> <translation id="5946591249682680882">ID hlášení <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Přidat soukromou síť</translation> <translation id="5949544233750246342">Soubor nelze analyzovat</translation> <translation id="5955282598396714173">Platnost vašeho hesla vypršela. Odhlaste se a poté se znovu přihlaste a změňte jej.</translation> <translation id="5956585768868398362">Je toto stránka vyhledávání, kterou jste očekávali?</translation> @@ -3446,7 +3423,6 @@ <translation id="6263541650532042179">resetovat synchronizaci</translation> <translation id="6264365405983206840">Vybr&at vše</translation> <translation id="6264422956566238156">Zapnuli jste synchronizaci</translation> -<translation id="6265930187414222160">Hotovo! Škodlivý software byl odstraněn.</translation> <translation id="6267166720438879315">Vyberte certifikát pro ověření na serveru <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Otevřít v aplikaci <ph name="APP" /></translation> <translation id="6268747994388690914">Importovat záložky ze souboru HTML...</translation> @@ -3553,7 +3529,6 @@ Chcete-li pokračovat s přihlášením k účtu <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, klikněte na Další.</translation> <translation id="6419546358665792306">Načíst nerozbalené</translation> <translation id="642282551015776456">Tento název nelze použít k pojmenování souboru ani složky.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Otevřít nastavení funkce ChromeVox</translation> <translation id="6429384232893414837">Chyba aktualizace</translation> <translation id="6430814529589430811">Soubor ASCII kódovaný Base64, jeden certifikát</translation> @@ -3634,7 +3609,6 @@ <translation id="6544215763872433504">Webový prohlížeč od Googlu, pro vás</translation> <translation id="6545665334409411530">Rychlost opakování</translation> <translation id="6545834809683560467">Používat službu předpovídání, která pomáhá dokončovat vyhledávací dotazy a adresy URL zadávané do adresního řádku nebo do vyhledávacího pole spouštěče aplikací</translation> -<translation id="6546686722964485737">Připojit k síti WiMAX</translation> <translation id="6547316139431024316">Pro toto rozšíření již upozornění nezobrazovat</translation> <translation id="6547354035488017500">Uvolněte alespoň 512 MB místa, jinak zařízení přestane reagovat. Místo uvolníte smazáním souborů z úložiště zařízení.</translation> <translation id="6549689063733911810">Poslední</translation> @@ -4053,7 +4027,6 @@ <translation id="7201014958346994077">Soubory systému Linux nelze zobrazit</translation> <translation id="720110658997053098">Trvale toto zařízení ponechat v režimu veřejného terminálu</translation> <translation id="7201118060536064622">Položka „<ph name="DELETED_ITEM_NAME" />“ byla smazána</translation> -<translation id="7205869271332034173">Identifikátor SSID:</translation> <translation id="7206693748120342859">Stahování pluginu <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Opustit stránku}few{Opustit stránky}many{Opustit stránky}other{Opustit stránky}}</translation> <translation id="7216409898977639127">Poskytovatel mobilních dat</translation> @@ -4529,7 +4502,6 @@ <translation id="7909969815743704077">Staženo v anonymním režimu</translation> <translation id="7910768399700579500">Nová složka</translation> <translation id="7912080627461681647">Vaše heslo bylo na serveru změněno. Odhlaste se a poté se znovu přihlaste.</translation> -<translation id="7912883689016444961">Nakonfigurovat mobilní síť</translation> <translation id="7915471803647590281">Než nám odešlete zpětnou vazbu, sdělte nám prosím, co se děje.</translation> <translation id="7916556741383518510">Při kliknutí</translation> <translation id="792514962475806987">Úroveň přiblížení zadokované lupy:</translation> @@ -4583,7 +4555,6 @@ <translation id="7988355189918024273">Aktivovat funkce usnadnění přístupu</translation> <translation id="7994702968232966508">Metoda EAP</translation> <translation id="799547531016638432">Odebrat zástupce</translation> -<translation id="7997479212858899587">Identita:</translation> <translation id="7997826902155442747">Priorita procesu</translation> <translation id="7999229196265990314">Byly vytvořeny následující soubory: @@ -4667,7 +4638,6 @@ <translation id="8105368624971345109">Vypnout</translation> <translation id="8106045200081704138">Sdíleno se mnou</translation> <translation id="8107015733319732394">Instalace Obchodu Google Play do zařízení <ph name="DEVICE_TYPE" />. Tato operace může několik minut trvat.</translation> -<translation id="8109930990200908494">Uživatelský certifikát vyžaduje přihlášení.</translation> <translation id="8111155949205007504">Sdílejte toto heslo se svým iPhonem</translation> <translation id="8113043281354018522">Vyberte typ licence</translation> <translation id="8116190140324504026">Další informace...</translation> @@ -4789,7 +4759,6 @@ <translation id="8308179586020895837">Zobrazit dotaz, pokud bude chtít web <ph name="HOST" /> používat kameru</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certifikát již existuje</translation> -<translation id="8309505303672555187">Vyberte síť:</translation> <translation id="8312871300878166382">Vložit do složky</translation> <translation id="8317671367883557781">Přidat připojení k síti</translation> <translation id="8319414634934645341">Rozšířené použití klíče</translation> @@ -4864,7 +4833,6 @@ <translation id="8451512073679317615">asistent</translation> <translation id="8452135315243592079">Chybí SIM karta</translation> <translation id="8453482423012550001">Kopírování $1 položek...</translation> -<translation id="8454288007744638700">Případně vyberte novou síť:</translation> <translation id="845627346958584683">Čas vypršení platnosti</translation> <translation id="8456681095658380701">Neplatný název</translation> <translation id="8457451314607652708">Import záložek</translation> @@ -4966,7 +4934,6 @@ <translation id="862727964348362408">Pozastaveno</translation> <translation id="862750493060684461">Mezipaměť CSS</translation> <translation id="8627795981664801467">Pouze zabezpečená spojení</translation> -<translation id="8628085465172583869">Název hostitele serveru:</translation> <translation id="8630903300770275248">Importovat dozorovaného uživatele</translation> <translation id="8631032106121706562">Kopretina</translation> <translation id="8637542770513281060">Ve vašem počítači je bezpečnostní modul, jehož pomocí je do systému Chrome OS implementováno mnoho důležitých bezpečnostních prvků. Další informace najdete v centru nápovědy k Chromebookům: http://support.google.com/chromebook/?p=sm</translation> @@ -5222,7 +5189,6 @@ <translation id="899403249577094719">Základní adresa URL certifikátu Netscape</translation> <translation id="8995603266996330174">Správce: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Přidat účet...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Probíhá vytváření obrazu disku.</translation> <translation id="9003647077635673607">Povolit na všech webech</translation> <translation id="9003677638446136377">Zkontrolovat znovu</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb index 70071ce..96b2f73 100644 --- a/chrome/app/resources/generated_resources_da.xtb +++ b/chrome/app/resources/generated_resources_da.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK-kode</translation> <translation id="1061904396131502319">Det er snart tid til en pause</translation> <translation id="1062407476771304334">Erstat</translation> -<translation id="1064835277883315402">Deltag i et privat netværk</translation> <translation id="1064912851688322329">Afbryd din Google-konto</translation> <translation id="1067048845568873861">Oprettet</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Søger...</translation> <translation id="1316495628809031177">Synkroniseringen er sat på pause</translation> <translation id="1319979322914001937">En app, der viser en filtreret liste over udvidelser fra Chrome Webshop. Udvidelserne på listen kan installeres direkte fra appen.</translation> -<translation id="132090119144658135">Emnematch:</translation> <translation id="1326317727527857210">Log ind på Chrome for at få adgang til dine faner på dine andre enheder.</translation> <translation id="1327074568633507428">Printer i Google Cloudprinter</translation> <translation id="1327977588028644528">Gateway</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Appvindue</translation> <translation id="1534389735079119190">FEJL: Containeren i VM kunne ikke startes.</translation> <translation id="15373452373711364">Stor musemarkør</translation> +<translation id="1540605929960647700">Aktivér demotilstand</translation> <translation id="1543284117603151572">Importeret fra Edge</translation> <translation id="1545177026077493356">Automatisk terminaltilstand</translation> <translation id="1545775234664667895">Installerede temaet "<ph name="THEME_NAME" />"</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">Vær med til at gøre <ph name="PRODUCT_NAME" /> bedre ved automatisk at sende forbrugsstatistikker og rapportere om nedbrud til Google</translation> <translation id="1658424621194652532">Denne side har adgang til din mikrofon.</translation> <translation id="1660204651932907780">Tillad, at websites afspiller lyd (anbefales)</translation> +<translation id="1660938185063657230">Bekræft din sikkerhedsnøgle</translation> <translation id="1661156625580498328">Gennemtving AES-kryptering (anbefalet).</translation> <translation id="1661245713600520330">Denne side angiver alle moduler, der er indlæst i hovedprocessen, og moduler, der er registreret til at blive indlæst på et senere tidspunkt.</translation> <translation id="166179487779922818">Adgangskoden er for kort.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">Tillad ikke, at websites kan se tekst og billeder, der er kopieret til udklipsholderen</translation> <translation id="1682548588986054654">Nyt inkognitovindue</translation> <translation id="168715261339224929">Aktivér synkronisering for at se dine bogmærker på alle dine enheder.</translation> +<translation id="1688867105868176567">Ville du rydde websitets data?</translation> <translation id="1688935057616748272">Skriv et bogstav</translation> <translation id="168991973552362966">Tilføj en printer i nærheden</translation> <translation id="1689945336726856614">Kopiér &webadresse</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">Fjern denne person</translation> <translation id="1706586824377653884">Tilføjet af din administrator</translation> <translation id="1706625117072057435">Zoomniveauer</translation> -<translation id="1707463636381878959">Del dette netværk med andre brugere</translation> <translation id="1708338024780164500">(inaktiv)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (id: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Oprindelig)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">Aktivér tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Se i Chrome Webshop</translation> -<translation id="1758831820837444715">Konfigurer Ethernet-netværk</translation> <translation id="1763046204212875858">Opret programgenveje</translation> <translation id="1763108912552529023">Udforsk videre</translation> <translation id="1763808908432309942">Åbnes på en ny fane</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">Rediger, hvordan denne fil deles</translation> <translation id="1841545962859478868">Administratoren af enheden kan overvåge følgende:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> er deaktiveret</translation> +<translation id="1842766183094193446">Er du sikker på, at du vil aktivere demotilstand?</translation> <translation id="1844692022597038441">Denne fil er ikke tilgængelig offline.</translation> <translation id="1846308012215045257">Hold ctrl-tasten nede, og klik for at køre <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Gemt</translation> <translation id="1848219224579402567">Log ud, når låget er lukket</translation> <translation id="184823282865851239">Bloker, hvis websitet har tendens til at vise påtrængende annoncer</translation> <translation id="1849186935225320012">Denne side har fuld kontrol over MIDI-enheder.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">Du kan altid ændre dette senere i Indstillinger</translation> <translation id="2006638907958895361">Åbn linket i <ph name="APP" /></translation> <translation id="2007404777272201486">Rapportér et problem...</translation> +<translation id="2016237810978710652">Åbner Linux-filer...</translation> <translation id="2016430552235416146">Traditionelt</translation> <translation id="2017334798163366053">Deaktiver registrering af data om ydeevne</translation> <translation id="2017836877785168846">Nulstiller historikken og autofuldførelser i adresselinjen.</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">Rediger kort</translation> <translation id="2154710561487035718">Kopier webadresse</translation> <translation id="2155772377859296191">Ligner <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Du kan hjælpe med at forbedre Beskyttet browsing ved at sende nogle systemoplysninger og noget sideindhold til Google.</translation> <translation id="215753907730220065">Afslut fuld skærm</translation> <translation id="2157875535253991059">Denne side er nu i fuld skærm.</translation> <translation id="216169395504480358">Tilføj Wi-Fi...</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">Føj rekvisitions-id til denne enhed</translation> <translation id="2175042898143291048">Gør altid dette</translation> <translation id="2175607476662778685">Hurtig start</translation> +<translation id="2176087259161165020">Andre kilder</translation> <translation id="2177950615300672361">Inkognitofane: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Pluginnet <ph name="PEPPER_PLUGIN_NAME" /> på <ph name="PEPPER_PLUGIN_DOMAIN" /> anmoder om adgang til din computer</translation> <translation id="2178614541317717477">Sammensat nøglecenter</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">Næste fane</translation> <translation id="2292848386125228270">Start <ph name="PRODUCT_NAME" /> som en normal bruger. Hvis du har brug for at køre med et rodcertifikat til udvikling, skal du køre med markeringen --ikke sandbox igen.</translation> <translation id="2294358108254308676">Vil du installere <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP-metode:</translation> <translation id="2297705863329999812">Søg efter printere</translation> <translation id="2300383962156589922">Tilpas og administrer <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Udvidelsens rodmappe er ugyldig.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">FEJL: <ph name="APP_NAME" /> kunne ikke afinstalleres.</translation> <translation id="2367199180085172140">Tilføj fildeling</translation> <translation id="2367972762794486313">Vis apps</translation> +<translation id="2369536625682139252">Alle data, der lagres af <ph name="SITE" />, slettes – med undtagelse af cookies.</translation> <translation id="2371076942591664043">Åbn når &færdigt</translation> <translation id="2377319039870049694">Skift til listevisning</translation> <translation id="2377667304966270281">Hårde fejl</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">Dialogboks til Udskriv via system... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Spørg inden afsendelse (anbefales)</translation> <translation id="2384436799579181135">Der opstod en fejl. Tjek din printer, og prøv igen.</translation> -<translation id="2385700042425247848">Tjenestens navn:</translation> <translation id="2387458720915042159">Proxy-forbindelsestype</translation> <translation id="2391419135980381625">Standardskriftstørrelse</translation> <translation id="2391762656119864333">Tilbagekald</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">Del lyd</translation> <translation id="2480868415629598489">Redigere data, du kopierer og indsætter</translation> <translation id="2482878487686419369">Underretninger</translation> -<translation id="2485056306054380289">Serverens CA-certifikat:</translation> <translation id="2485422356828889247">Afinstaller</translation> <translation id="2487067538648443797">Tilføj nyt bogmærke</translation> <translation id="248861575772995840">Din telefon blev ikke fundet. Sørg for, at Bluetooth er slået til på din <ph name="DEVICE_TYPE" />. <a>Få flere oplysninger</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">Powerwash for at nulstille din <ph name="IDS_SHORT_PRODUCT_NAME" />-enhed til fabriksindstillingerne.</translation> <translation id="2567257616420533738">Adgangskoden blev gemt. Se og administrer gemte adgangskoder på <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Container til oplysningsbjælke</translation> +<translation id="2570454805927264159">Få mest muligt ud af Google Assistent</translation> <translation id="257088987046510401">Temaer</translation> <translation id="2572032849266859634">Skrivebeskyttet adgang til <ph name="VOLUME_NAME" /> er blevet tildelt.</translation> <translation id="2573269395582837871">Vælg et billede og et navn</translation> @@ -1097,7 +1100,6 @@ <translation id="2653659639078652383">Indsend</translation> <translation id="265390580714150011">Feltværdi</translation> <translation id="2654166010170466751">Tillad, at websites installerer betalingshandlere</translation> -<translation id="2655386581175833247">Brugercertifikat:</translation> <translation id="2660779039299703961">Hændelse</translation> <translation id="266079277508604648">Der kan ikke oprettes forbindelse til printeren. Tjek, at printeren er tændt og tilsluttet din Chromebook via Wi-Fi eller USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1330,6 +1332,7 @@ <translation id="3006881078666935414">Ingen brugsdata</translation> <translation id="3007214526293698309">Korriger formatforhold</translation> <translation id="3007771295016901659">Dupliker fane</translation> +<translation id="3008272652534848354">Nulstil tilladelser</translation> <translation id="3009300415590184725">Er du sikker på, at du vil annullere konfigurationen af en mobildatatjeneste?</translation> <translation id="3009779501245596802">Indekserede databaser</translation> <translation id="3010279545267083280">Adgangskoden er slettet</translation> @@ -1396,7 +1399,6 @@ <translation id="3100609564180505575">Moduler (<ph name="TOTAL_COUNT" />) – Kendte konflikter: <ph name="BAD_COUNT" />, under mistanke: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Dato og klokkeslæt</translation> <translation id="310671807099593501">Websitet anvender Bluetooth</translation> -<translation id="3108967419958202225">Vælg...</translation> <translation id="3115128645424181617">Din telefon blev ikke fundet. Sørg for, at den er ved hånden, og at Bluetooth er slået til.</translation> <translation id="3115147772012638511">Venter på cache...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Hjælp</translation> @@ -1441,7 +1443,6 @@ <translation id="3165390001037658081">Nogle mobilselskaber blokerer muligvis denne funktion.</translation> <translation id="316854673539778496">Log ind, og aktivér synkronisering for at få alle dine udvidelser på alle dine enheder.</translation> <translation id="3170072451822350649">Du kan også springe login over og <ph name="LINK_START" />anvende som gæst<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Klik for at skjule adgangskode</translation> <translation id="3177909033752230686">Sidens sprog:</translation> <translation id="3181110748548073003">Tryk på |<ph name="SHORTCUT" />| for at gå fremad</translation> <translation id="3182749001423093222">Stavekontrol</translation> @@ -1472,7 +1473,6 @@ <translation id="3236289833370040187">Ejerskabet overføres til <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Åbn valgmuligheder for udvidelser</translation> <translation id="3241680850019875542">Vælg rodmappen for udvidelsen, der skal pakkes. Opdater en udvidelse ved også at vælge den private nøglefil til genbrug.</translation> -<translation id="3242765319725186192">Foruddelt nøgle:</translation> <translation id="3244294424315804309">Lad lyden forblive slået fra</translation> <translation id="3245321423178950146">Ukendt kunstner</translation> <translation id="3246097286174000800">Prøv Smart Lock</translation> @@ -1605,7 +1605,6 @@ <translation id="3440663250074896476">Flere handlinger for <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Spørg om tilladelse, når et website ønsker at anvende et plugin til at få adgang til din computer</translation> <translation id="3441653493275994384">Skærm</translation> -<translation id="3445830502289589282">Fase 2-godkendelse:</translation> <translation id="344630545793878684">Læs dine data på en række websites</translation> <translation id="3449839693241009168">Tryk på <ph name="SEARCH_KEY" /> for at sende kommandoer til <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Anvendt andel for inaktiv tilstand</translation> @@ -1646,7 +1645,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> fejl.</translation> <translation id="3495660573538963482">Indstillinger for Google Assistent</translation> <translation id="3496213124478423963">Zoom ud</translation> -<translation id="3504135463003295723">Gruppenavn:</translation> <translation id="3505030558724226696">Tilbagekald adgang til enhed</translation> <translation id="3507421388498836150">Nuværende tilladelser for "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Fjern Linux-apps til Chromebook</translation> @@ -1755,7 +1753,6 @@ <translation id="3661054927247347545">Bekræftelsen af login er ikke gyldig. Vinduet lukker om <ph name="MINUTES" />.<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Udvidelsesikon</translation> <translation id="3665589677786828986">Chrome har registreret, at nogle af dine indstillinger er blevet ændret af et andet program, og har derfor gendannet standardindstillingerne.</translation> -<translation id="3665842570601375360">Sikkerhed:</translation> <translation id="3668570675727296296">Sprogindstillinger</translation> <translation id="3668823961463113931">Håndtering</translation> <translation id="3670229581627177274">Slå Bluetooth til</translation> @@ -1794,7 +1791,6 @@ <translation id="3726463242007121105">Denne enhed kan ikke åbnes, fordi dens filsystem ikke understøttes.</translation> <translation id="3727148787322499904">Hvis denne indstilling ændres, påvirker det alle delte netværk</translation> <translation id="3727187387656390258">Undersøg pop op-vindue</translation> -<translation id="3728067901555601989">Engangskode:</translation> <translation id="3732078975418297900">Der er fejl på linjen <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-server med optrapning</translation> <translation id="3737536731758327622">Dine downloads vises her</translation> @@ -1869,7 +1865,6 @@ <translation id="38275787300541712">Tryk på Enter, når du er færdig</translation> <translation id="3827774300009121996">&Fuld skærm</translation> <translation id="3828029223314399057">Søg i bogmærker</translation> -<translation id="3829932584934971895">Type udbyder:</translation> <translation id="3830674330436234648">Der er ingen tilgængelig afspilning.</translation> <translation id="3831486154586836914">Tilstanden for vinduesoversigt er aktiveret</translation> <translation id="383161972796689579">Ejeren af denne enhed har deaktiveret tilføjelse af nye brugere</translation> @@ -1890,6 +1885,7 @@ <translation id="3856921555429624101">Måling af dataforbrug er afsluttet</translation> <translation id="3857228364945137633">Prøv Smart Lock for at låse din <ph name="DEVICE_TYPE" /> op uden en adgangskode, når din telefon er i nærheden.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Synkronisering er sat på pause</translation> <translation id="3860381078714302691">Velkommen til Hangouts Meet</translation> <translation id="3862134173397075045">Velkommen til Cast-oplevelsen i Chrome!</translation> <translation id="3862788408946266506">Appen med manifestattributten "kiosk_only" skal installeres i ChromeOS-terminaltilstand</translation> @@ -1967,7 +1963,6 @@ <translation id="3968261067169026421">Netværket kunne ikke konfigureres</translation> <translation id="3970114302595058915">Id</translation> <translation id="397105322502079400">Beregner...</translation> -<translation id="3974195870082915331">Klik for at vise adgangskode</translation> <translation id="3975222297214566386">Boble med indtastningsmuligheder</translation> <translation id="397703832102027365">Afslutter...</translation> <translation id="3979395879372752341">Ny udvidelse er tilføjet (<ph name="EXTENSION_NAME" />)</translation> @@ -2009,6 +2004,7 @@ <translation id="4044612648082411741">Angiv adgangskoden til dit certifikat</translation> <translation id="404493185430269859">Standardsøgemaskine</translation> <translation id="4047112090469382184">Hvordan er denne funktion sikker?</translation> +<translation id="4051049974203704184">Få oplysninger om, hvad der vises på skærmen</translation> <translation id="4052120076834320548">Lillebitte</translation> <translation id="4055023634561256217">Enheden skal genstartes, før den kan nulstilles med Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2037,6 +2033,7 @@ <translation id="4088095054444612037">Acceptér for gruppe</translation> <translation id="4089235344645910861">Indstillingerne blev gemt, og synkroniseringen er nu startet.</translation> <translation id="4090103403438682346">Aktivér Bekræftet adgang</translation> +<translation id="4090947011087001172">Vil du nulstille tilladelserne for <ph name="SITE" />?</translation> <translation id="4091434297613116013">ark papir</translation> <translation id="4093955363990068916">Lokal fil:</translation> <translation id="4095507791297118304">Primær skærm</translation> @@ -2213,7 +2210,6 @@ <translation id="4419556793104466535">Styr synkronisering, tilpasning og meget mere</translation> <translation id="4421932782753506458">Pjuske</translation> <translation id="4422347585044846479">Rediger bogmærke for denne side</translation> -<translation id="4423104065312875417">Installer yderligere oplæsningsmaskiner</translation> <translation id="4423376891418188461">Gendan indstillinger</translation> <translation id="4423482519432579560">&Stavekontrol</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, din administrator kræver, at du ændrer din adgangskode.</translation> @@ -2238,7 +2234,6 @@ <translation id="4449996769074858870">Denne fane afspiller lyd.</translation> <translation id="4450974146388585462">Diagnosticer</translation> <translation id="4453946976636652378">Søg på <ph name="SEARCH_ENGINE_NAME" />, eller angiv en webadresse</translation> -<translation id="445923051607553918">Vælg Wi-Fi-netværk</translation> <translation id="4462159676511157176">Tilpassede navneservere</translation> <translation id="4467100756425880649">Chrome Webshop Galleri</translation> <translation id="4467101674048705704">Udvid <ph name="FOLDER_NAME" /></translation> @@ -2374,6 +2369,7 @@ <translation id="4682551433947286597">Baggrunde vises på loginskærmen.</translation> <translation id="4684427112815847243">Synkroniser alt</translation> <translation id="4689421377817139245">Synkroniser dette bogmærke med din iPhone</translation> +<translation id="4690091457710545971"><Fire filer er genereret af Intel Wi-Fi-firmware: Csr.lst, fh_regs.lst, radio_reg.lst og monitor.lst.sysmon. De første tre er binære filer, der indeholder register dumps, og som ifølge Intel ikke indeholder nogen personlige eller enhedsidentificerende oplysninger. Den sidste fil er et udførelsesspor fra Intel-firmwaren. De personlige eller enhedsidentificerende oplysninger er blevet ryddet fra denne fil, men fylder for meget til at blive vist her. Disse filer blev genereret som følge af nyligt registrerede problemer med Wi-Fi-forbindelsen på din enhed og deles med Intel for at hjælpe med at løse de pågældende problemer.></translation> <translation id="4692302215262324251">Din <ph name="DEVICE_TYPE" /> er nu tilmeldt virksomhedsadministration hos <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Hvis du ikke forventede dette, bedes du kontakte supportafdelingen.</translation> @@ -2633,6 +2629,7 @@ <translation id="5074318175948309511">Det kan være nødvendigt at genindlæse siden, så de nye indstillinger kan træde i kraft.</translation> <translation id="5075131525758602494">Angiv pinkode til SIM-kort</translation> <translation id="5078638979202084724">Tilføj alle faner som bogmærker</translation> +<translation id="5079950360618752063">Brug den foreslåede adgangskode</translation> <translation id="5084230410268011727">Tillad, at websites anvender bevægelses- og lyssensorer</translation> <translation id="5085162214018721575">Søger efter opdateringer</translation> <translation id="5086082738160935172">HID</translation> @@ -2671,6 +2668,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Slet dette element</translation> <translation id="5139955368427980650">&Åbn</translation> +<translation id="5142961317498132443">Godkendelse</translation> <translation id="5143374789336132547">Udvidelsen <ph name="EXTENSION_NAME" /> har ændret, hvilken side der vises, når du klikker på knappen Startside.</translation> <translation id="5143712164865402236">Åbn Fuld skærm</translation> <translation id="5145331109270917438">Dato for ændring</translation> @@ -2841,7 +2839,6 @@ <translation id="5380103295189760361">Hold Ctrl, Alt, Shift eller Søg nede for at se tastaturgenveje for disse ændringstaster.</translation> <translation id="5382591305415226340">Administrer understøttede links</translation> <translation id="5384883051496921101">Dette website skal til at dele oplysninger med en app uden for inkognitotilstand.</translation> -<translation id="5388588172257446328">Brugernavn:</translation> <translation id="5388885445722491159">Parret</translation> <translation id="5389237414310520250">Den nye bruger kunne ikke oprettes. Kontrollér, om der er ledig plads på din harddisk, og at du har de rette tilladelser, og prøv igen.</translation> <translation id="5390100381392048184">Tillad, at websites afspiller lyd</translation> @@ -2966,7 +2963,6 @@ <translation id="5551573675707792127">Tastatur og tekstindtastning</translation> <translation id="5553089923092577885">Beskrivelse af certifikatpolitik</translation> <translation id="5554489410841842733">Dette ikon er synligt, når udvidelsen kan fungere på den aktuelle side.</translation> -<translation id="5554573843028719904">Andet Wi-Fi-netværk...</translation> <translation id="5554720593229208774">Mail-certificeringsautoritet</translation> <translation id="5556206011531515970">Klik på Næste for at vælge din standardbrowser.</translation> <translation id="5556459405103347317">Genindlæs</translation> @@ -3007,7 +3003,6 @@ <translation id="5610038042047936818">Skift til kameratilstand</translation> <translation id="5612720917913232150"><ph name="URL" /> anmoder om at anvende computerens placering</translation> <translation id="5612734644261457353">Din adgangskode kunne desværre stadig ikke bekræftes. Bemærk! Hvis du har ændret din adgangskode for nylig, anvendes din nye adgangskode først, når du har logget ud. Du skal bruge den gamle adgangskode her.</translation> -<translation id="5613695965848159202">Anonym identitet:</translation> <translation id="5614190747811328134">Brugerbesked</translation> <translation id="561698261642843490">Luk Firefox</translation> <translation id="5618075537869101857">Kioskapplikationen kunne desværre ikke startes.</translation> @@ -3225,7 +3220,6 @@ <translation id="5941343993301164315">Log ind på <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimer</translation> <translation id="5946591249682680882">Rapport-id <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Tilføj privat netværk</translation> <translation id="5949544233750246342">Filen kan ikke parses</translation> <translation id="5955282598396714173">Din adgangskode er udløbet. Log ud, og log derefter ind igen for at ændre den.</translation> <translation id="5956585768868398362">Var det den søgeside, du havde forventet?</translation> @@ -3387,11 +3381,13 @@ <translation id="6198102561359457428">Log ud, og log derefter ind igen...</translation> <translation id="6198252989419008588">Skift pinkode</translation> <translation id="6199801702437275229">Venter på oplysninger om ledig plads...</translation> +<translation id="6204015976622790023">Se relevante forslag fra Google-assistenten, som er relateret til det, der vises på skærmen.</translation> <translation id="6205710420833115353">Nogle handlinger tager længere tid end forventet. Vil du afbryde dem?</translation> <translation id="6206311232642889873">Ko&pier billede</translation> <translation id="6207200176136643843">Nulstil til standardniveauet for zoom</translation> <translation id="620722923698527029">Åbn altid denne type links i den tilknyttede app</translation> <translation id="6207937957461833379">Land/Region</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Synkronisering fungerer ikke</translation> <translation id="6212039847102026977">Vis avancerede netværksegenskaber</translation> <translation id="6212168817037875041">Sluk skærmen</translation> <translation id="6212752530110374741">Send link via mail</translation> @@ -3429,7 +3425,6 @@ <translation id="6263541650532042179">nulstil synkronisering</translation> <translation id="6264365405983206840">Vælg &alle</translation> <translation id="6264422956566238156">Du har aktiveret Chrome-synkronisering</translation> -<translation id="6265930187414222160">Sådan! Den skadelige software er fjernet.</translation> <translation id="6267166720438879315">Vælg et certifikat til at bekræfte dig selv over for <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Åbn med <ph name="APP" /></translation> <translation id="6268747994388690914">Importér bogmærker fra HTML-fil...</translation> @@ -3536,7 +3531,6 @@ Klik på "Næste" for at fortsætte med at logge ind på din konto på <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Indlæs upakket</translation> <translation id="642282551015776456">Dette navn kan ikke bruges som fil- eller mappenavn</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Åbn indstillinger for ChromeVox</translation> <translation id="6429384232893414837">Opdateringsfejl</translation> <translation id="6430814529589430811">Base64-kodet ASCII, enkeltcertifikat</translation> @@ -3617,7 +3611,6 @@ <translation id="6544215763872433504">Googles webbrowser til dig</translation> <translation id="6545665334409411530">Gentagelseshastighed</translation> <translation id="6545834809683560467">Brug en forslagstjeneste til at færdiggøre søgninger og webadresser, der indtastes i adresselinjen eller søgefeltet i applisten</translation> -<translation id="6546686722964485737">Opret forbindelse til WiMAX-netværk</translation> <translation id="6547316139431024316">Advar ikke om denne udvidelse igen</translation> <translation id="6547354035488017500">Din enhed holder op med at svare, hvis du ikke frigør mindst 512 MB. Slet filer fra lageret på enheden for at frigøre plads.</translation> <translation id="6549689063733911810">Seneste</translation> @@ -4036,7 +4029,6 @@ <translation id="7201014958346994077">Linux-filerne kan ikke ses</translation> <translation id="720110658997053098">Lad kiosktilstand forblive aktiveret på denne enhed</translation> <translation id="7201118060536064622">"<ph name="DELETED_ITEM_NAME" />" er slettet</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Downloader <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Forlad side}one{Forlad side}other{Forlad sider}}</translation> <translation id="7216409898977639127">Mobilselskab</translation> @@ -4513,7 +4505,6 @@ <translation id="7909969815743704077">Downloadet i inkognitotilstand</translation> <translation id="7910768399700579500">&Ny mappe</translation> <translation id="7912080627461681647">Din adgangskode er blevet ændret på serveren. Log ud, og log derefter ind igen.</translation> -<translation id="7912883689016444961">Konfigurer mobilnetværk</translation> <translation id="7915471803647590281">Fortæl os, hvad der sker, inden du sender feedback.</translation> <translation id="7916556741383518510">Ved klik</translation> <translation id="792514962475806987">Zoomniveau i fastgjort lupvindue</translation> @@ -4567,7 +4558,6 @@ <translation id="7988355189918024273">Aktiver tilgængelighedsfunktioner</translation> <translation id="7994702968232966508">EAP-metode</translation> <translation id="799547531016638432">Fjern genvej</translation> -<translation id="7997479212858899587">Identitet:</translation> <translation id="7997826902155442747">Procesprioritet</translation> <translation id="7999229196265990314">Oprettede følgende filer: @@ -4651,7 +4641,6 @@ <translation id="8105368624971345109">Deaktiver</translation> <translation id="8106045200081704138">Delt med mig</translation> <translation id="8107015733319732394">Google Play Butik installeres på din <ph name="DEVICE_TYPE" />. Det kan tage nogle minutter.</translation> -<translation id="8109930990200908494">Login påkrævet for brugercertifikat.</translation> <translation id="8111155949205007504">Del denne adgangskode med din iPhone</translation> <translation id="8113043281354018522">Vælg licenstype</translation> <translation id="8116190140324504026">Flere oplysninger...</translation> @@ -4662,6 +4651,7 @@ <translation id="8118860139461251237">Administrere dine downloads</translation> <translation id="81238879832906896">Gul og hvid blomst</translation> <translation id="8124313775439841391">Administreret ONC</translation> +<translation id="8125562866093998907">Websitet vil gerne bekræfte din sikkerhedsnøgle for at føje et ekstra lag sikkerhed til din konto.</translation> <translation id="813082847718468539">Se websiteoplysninger</translation> <translation id="8131740175452115882">Bekræft</translation> <translation id="8133676275609324831">&Vis i mappe</translation> @@ -4772,7 +4762,6 @@ <translation id="8308179586020895837">Spørg, om <ph name="HOST" /> vil have adgang til dit kamera</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certifikatet eksisterer allerede</translation> -<translation id="8309505303672555187">Vælg et netværk:</translation> <translation id="8312871300878166382">Indsæt i mappe</translation> <translation id="8317671367883557781">Tilføj netværksforbindelse</translation> <translation id="8319414634934645341">Udvidet brug af nøgle</translation> @@ -4847,7 +4836,6 @@ <translation id="8451512073679317615">assistent</translation> <translation id="8452135315243592079">SIM-kort mangler</translation> <translation id="8453482423012550001">Kopierer $1 elementer...</translation> -<translation id="8454288007744638700">Du kan også vælge et nyt netværk:</translation> <translation id="845627346958584683">Udløbstid</translation> <translation id="8456681095658380701">Ugyldigt navn</translation> <translation id="8457451314607652708">Importér bogmærker</translation> @@ -4911,6 +4899,7 @@ <translation id="855081842937141170">Fastgør fane</translation> <translation id="8551388862522347954">Licenser</translation> <translation id="8553342806078037065">Administrer andre personer</translation> +<translation id="8554899698005018844">Intet sprog</translation> <translation id="855773602626431402">Et plugin, der ikke er gemt i sandbox, blev forhindret i at køre på denne side.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Værktøj til afkodning af billeder</translation> @@ -4948,7 +4937,6 @@ <translation id="862727964348362408">Midlertidigt standset</translation> <translation id="862750493060684461">CSS-cache</translation> <translation id="8627795981664801467">Kun sikre forbindelser</translation> -<translation id="8628085465172583869">Serverens hostname:</translation> <translation id="8630903300770275248">Importér administreret bruger</translation> <translation id="8631032106121706562">Marguerit</translation> <translation id="8637542770513281060">Computeren indeholder et sikkerhedsmodul, som bruges til at implementere flere vigtige sikkerhedsfunktioner i Chrome OS. Du kan få flere oplysninger i Hjælp til Chromebook: https://support.google.com/chromebook/?p=sm</translation> @@ -5205,7 +5193,6 @@ <translation id="899403249577094719">Webadresse for Netscape-certifikatbase</translation> <translation id="8995603266996330174">Administreres af <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Tilføj konto...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Opretter diskbillede.</translation> <translation id="9003647077635673607">Tillad på alle websites</translation> <translation id="9003677638446136377">Kontrollér igen</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb index dd6eb0e..e46fc31 100644 --- a/chrome/app/resources/generated_resources_de.xtb +++ b/chrome/app/resources/generated_resources_de.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Bald ist es Zeit für eine Pause</translation> <translation id="1062407476771304334">Ersetzen</translation> -<translation id="1064835277883315402">Privatem Netzwerk beitreten</translation> <translation id="1064912851688322329">Verbindung zum Google-Konto trennen</translation> <translation id="1067048845568873861">Erstellt</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Suche läuft...</translation> <translation id="1316495628809031177">Synchronisierung pausiert</translation> <translation id="1319979322914001937">Eine App, in der eine gefilterte Liste mit Erweiterungen für den Chrome Web Store angezeigt wird. Die angezeigten Erweiterungen können direkt aus der App installiert werden.</translation> -<translation id="132090119144658135">subject-match:</translation> <translation id="1326317727527857210">Melden Sie sich in Chrome an, um Tabs von Ihren anderen Geräten abzurufen.</translation> <translation id="1327074568633507428">Google Cloud Print-Drucker</translation> <translation id="1327977588028644528">Gateway</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">Anwendungsfenster</translation> <translation id="1534389735079119190">FEHLER: Container konnte nicht innerhalb der VM gestartet werden.</translation> <translation id="15373452373711364">Großer Cursor</translation> +<translation id="1540605929960647700">Demomodus aktivieren</translation> <translation id="1543284117603151572">Aus Edge importiert</translation> <translation id="1545177026077493356">Automatischer Kioskmodus</translation> <translation id="1545775234664667895">Design "<ph name="THEME_NAME" />" installiert</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">Zur Verbesserung von <ph name="PRODUCT_NAME" /> Nutzungsstatistiken und Absturzberichte automatisch an Google senden</translation> <translation id="1658424621194652532">Diese Seite greift auf Ihr Mikrofon zu.</translation> <translation id="1660204651932907780">Wiedergabe von Ton auf Websites zulassen (empfohlen)</translation> +<translation id="1660938185063657230">Sicherheitsschlüssel überprüfen</translation> <translation id="1661156625580498328">AES-Verschlüsselung durchsetzen (empfohlen).</translation> <translation id="1661245713600520330">Auf dieser Seite werden alle Module aufgelistet, die im Hauptprozess geladen werden, sowie Module, die zu einem späteren Zeitpunkt geladen werden.</translation> <translation id="166179487779922818">Das Passwort ist zu kurz.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">Websites keinen Zugriff auf Texte und Bilder gewähren, die sich in der Zwischenablage befinden</translation> <translation id="1682548588986054654">Neues &Inkognitofenster</translation> <translation id="168715261339224929">Aktivieren Sie die Synchronisierung, um Ihre Lesezeichen auf allen Ihren Geräten zu sehen.</translation> +<translation id="1688867105868176567">Websitedaten löschen?</translation> <translation id="1688935057616748272">Geben Sie einen Buchstaben ein</translation> <translation id="168991973552362966">Drucker in der Nähe hinzufügen</translation> <translation id="1689945336726856614">&URL kopieren</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">Diese Person entfernen</translation> <translation id="1706586824377653884">Von Ihrem Administrator hinzugefügt</translation> <translation id="1706625117072057435">Zoomstufen</translation> -<translation id="1707463636381878959">Dieses Netzwerk für andere freigeben</translation> <translation id="1708338024780164500">(Inaktiv)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativ)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">Design aktivieren</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Im Chrome Web Store ansehen</translation> -<translation id="1758831820837444715">Ethernetnetzwerk konfigurieren</translation> <translation id="1763046204212875858">App-Verknüpfungen erstellen</translation> <translation id="1763108912552529023">Weiter erkunden</translation> <translation id="1763808908432309942">Wird in einem neuen Tab geöffnet</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">Angeben, wie die Datei geteilt werden soll</translation> <translation id="1841545962859478868">Der Geräteadministrator überwacht eventuell Folgendes:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> ist deaktiviert</translation> +<translation id="1842766183094193446">Möchten Sie den Demomodus wirklich aktivieren?</translation> <translation id="1844692022597038441">Diese Datei ist offline nicht verfügbar.</translation> <translation id="1846308012215045257">Zum Ausführen von <ph name="PLUGIN_NAME" /> die Strg-Taste drücken und mit der Maus klicken</translation> +<translation id="1847880352285315359">Gespeichert</translation> <translation id="1848219224579402567">Beim Zuklappen abmelden</translation> <translation id="184823282865851239">Blockieren, wenn Website für gewöhnlich aufdringliche Werbung anzeigt</translation> <translation id="1849186935225320012">Diese Seite hat vollständige Kontrolle über MIDI-Geräte.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">Dies kann jederzeit in den Einstellungen geändert werden</translation> <translation id="2006638907958895361">Link in <ph name="APP" /> öffnen</translation> <translation id="2007404777272201486">Problem melden...</translation> +<translation id="2016237810978710652">Linux-Dateien werden geöffnet…</translation> <translation id="2016430552235416146">Traditionell</translation> <translation id="2017334798163366053">Erfassung von Leistungsdaten deaktivieren</translation> <translation id="2017836877785168846">Löscht den Verlauf sowie Autovervollständigungen in der Adressleiste.</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">Karte bearbeiten</translation> <translation id="2154710561487035718">URL kopieren</translation> <translation id="2155772377859296191">Auflösung <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Sie können uns dabei helfen, Safe Browsing weiter zu verbessern, indem Sie einige Systeminformationen und Seiteninhalte an Google senden.</translation> <translation id="215753907730220065">Vollbildmodus aus</translation> <translation id="2157875535253991059">Diese Seite wird nun im Vollbildmodus angezeigt.</translation> <translation id="216169395504480358">WLAN hinzufügen...</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">Diesem Gerät eine Anforderungs-ID hinzufügen</translation> <translation id="2175042898143291048">Immer so verfahren</translation> <translation id="2175607476662778685">Schnellstartleiste</translation> +<translation id="2176087259161165020">Andere Quellen</translation> <translation id="2177950615300672361">Inkognito-Tab: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Das Plug-in <ph name="PEPPER_PLUGIN_NAME" /> auf <ph name="PEPPER_PLUGIN_DOMAIN" /> möchte auf Ihren Computer zugreifen</translation> <translation id="2178614541317717477">Kompromittierung der Zertifizierungsstelle</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">Nächster Tab</translation> <translation id="2292848386125228270">Starten Sie <ph name="PRODUCT_NAME" /> als normaler Nutzer. Um Chrome für Entwicklungszwecke als Root auszuführen, müssen Sie den Browser noch einmal mit dem Kennzeichen "--no-sandbox" ausführen.</translation> <translation id="2294358108254308676">Möchten Sie <ph name="PRODUCT_NAME" /> installieren?</translation> -<translation id="2296019197782308739">EAP-Methode:</translation> <translation id="2297705863329999812">Drucker suchen</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> anpassen und verwalten</translation> <translation id="2301382460326681002">Stammverzeichnis der Erweiterung ist ungültig.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">FEHLER: <ph name="APP_NAME" /> konnte nicht deinstalliert werden.</translation> <translation id="2367199180085172140">Netzwerkfreigabe hinzufügen</translation> <translation id="2367972762794486313">Apps anzeigen</translation> +<translation id="2369536625682139252">Alle von <ph name="SITE" /> gespeicherten Daten werden gelöscht, mit Ausnahme von Cookies.</translation> <translation id="2371076942591664043">Nach &Download öffnen</translation> <translation id="2377319039870049694">Zur Listenansicht wechseln</translation> <translation id="2377667304966270281">Harte Fehler</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">Über das Systemdialogfeld drucken... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Vor dem Senden nachfragen (empfohlen)</translation> <translation id="2384436799579181135">Ein Fehler ist aufgetreten. Bitte überprüfen Sie Ihren Drucker und versuchen Sie es noch einmal.</translation> -<translation id="2385700042425247848">Dienstname</translation> <translation id="2387458720915042159">Proxy-Verbindungstyp</translation> <translation id="2391419135980381625">Standardschrift</translation> <translation id="2391762656119864333">Aufheben</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">Audio freigeben</translation> <translation id="2480868415629598489">Daten ändern, die Sie kopieren und einfügen</translation> <translation id="2482878487686419369">Benachrichtigungen</translation> -<translation id="2485056306054380289">CA-Serverzertifikat:</translation> <translation id="2485422356828889247">Deinstallieren</translation> <translation id="2487067538648443797">Neues Lesezeichen hinzufügen</translation> <translation id="248861575772995840">Smartphone wurde nicht gefunden. Vergewissern Sie sich, dass auf Ihrem <ph name="DEVICE_TYPE" /> Bluetooth aktiviert ist. <a>Weitere Informationen</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">Durch einen Powerwash wird Ihr <ph name="IDS_SHORT_PRODUCT_NAME" />-Gerät auf den Werkszustand zurückgesetzt.</translation> <translation id="2567257616420533738">Passwort gespeichert. Sie können gespeicherte Passwörter unter <ph name="SAVED_PASSWORDS_LINK" /> aufrufen und verwalten</translation> <translation id="2568774940984945469">Infoleisten-Container</translation> +<translation id="2570454805927264159">Google Assistant optimal nutzen</translation> <translation id="257088987046510401">Designs</translation> <translation id="2572032849266859634">Nur Lesezugriff auf <ph name="VOLUME_NAME" /> wurde zugelassen.</translation> <translation id="2573269395582837871">Ein Bild und einen Namen auswählen</translation> @@ -1095,7 +1098,6 @@ <translation id="2653659639078652383">Senden</translation> <translation id="265390580714150011">Feldwert</translation> <translation id="2654166010170466751">Installation von Zahlungs-Handlern auf Websites zulassen</translation> -<translation id="2655386581175833247">Nutzerzertifikat:</translation> <translation id="2660779039299703961">Ereignis</translation> <translation id="266079277508604648">Verbindung zum Drucker nicht möglich. Vergewissern Sie sich, dass der Drucker aktiviert und über WLAN oder USB mit Ihrem Chromebook verbunden ist.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1328,6 +1330,7 @@ <translation id="3006881078666935414">Keine Nutzungsdaten</translation> <translation id="3007214526293698309">Verhältnis korrigieren</translation> <translation id="3007771295016901659">Tab duplizieren</translation> +<translation id="3008272652534848354">Berechtigungen zurücksetzen</translation> <translation id="3009300415590184725">Möchten Sie die Einrichtung des mobilen Datendiensts wirklich abbrechen?</translation> <translation id="3009779501245596802">Indexierte Datenbanken</translation> <translation id="3010279545267083280">Passwort wurde gelöscht.</translation> @@ -1394,7 +1397,6 @@ <translation id="3100609564180505575">Module (<ph name="TOTAL_COUNT" />) - Bekannte Konflikte: <ph name="BAD_COUNT" />, verdächtig: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Datum und Uhrzeit</translation> <translation id="310671807099593501">Die Website verwendet Bluetooth</translation> -<translation id="3108967419958202225">Auswählen...</translation> <translation id="3115128645424181617">Smartphone wurde nicht gefunden. Vergewissern Sie sich, dass es sich in Reichweite befindet und dass Bluetooth aktiviert ist.</translation> <translation id="3115147772012638511">Warten auf den Cache...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" />-Hilfe</translation> @@ -1439,7 +1441,6 @@ <translation id="3165390001037658081">Einige Mobilfunkanbieter blockieren diese Funktion möglicherweise.</translation> <translation id="316854673539778496">Wenn Sie Ihre Erweiterungen auf allen Ihren Geräten verfügbar haben möchten, melden Sie sich an und aktivieren Sie die Synchronisierung.</translation> <translation id="3170072451822350649">Sie können die Anmeldung auch überspringen und <ph name="LINK_START" />als Gast surfen<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Hier klicken, um Passwort zu verbergen</translation> <translation id="3177909033752230686">Sprache der Seite:</translation> <translation id="3181110748548073003">Zum Weitergehen |<ph name="SHORTCUT" />| drücken</translation> <translation id="3182749001423093222">Rechtschreibprüfung</translation> @@ -1470,7 +1471,6 @@ <translation id="3236289833370040187">Die Inhaberschaft wird übertragen an <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Erweiterungsoptionen öffnen</translation> <translation id="3241680850019875542">Wählen Sie das Stammverzeichnis der Erweiterung, die gepackt werden soll. Zur Aktualisierung einer Erweiterung wählen Sie eine private Schlüsseldatei zur Wiederverwendung.</translation> -<translation id="3242765319725186192">Vorinstallierter Schlüssel:</translation> <translation id="3244294424315804309">Töne weiterhin stummschalten</translation> <translation id="3245321423178950146">Unbekannter Musiker</translation> <translation id="3246097286174000800">Smart Lock ausprobieren</translation> @@ -1603,7 +1603,6 @@ <translation id="3440663250074896476">Weitere Aktionen für <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Nachfragen, wenn eine Website ein Plug-in für den Zugriff auf Ihren Computer verwenden möchte</translation> <translation id="3441653493275994384">Bildschirm</translation> -<translation id="3445830502289589282">Authentifizierung 2:</translation> <translation id="344630545793878684">Ihre Daten auf verschiedenen Websites lesen</translation> <translation id="3449839693241009168">Drücken Sie <ph name="SEARCH_KEY" />, um Befehle an <ph name="EXTENSION_NAME" /> zu senden.</translation> <translation id="3450157232394774192">Inaktiver Zustand – Auslastung in Prozent</translation> @@ -1644,7 +1643,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> Fehler</translation> <translation id="3495660573538963482">Google Assistant-Einstellungen</translation> <translation id="3496213124478423963">Verkleinern</translation> -<translation id="3504135463003295723">Gruppenname:</translation> <translation id="3505030558724226696">Gerätezugriff aufheben</translation> <translation id="3507421388498836150">Aktuelle Berechtigungen für "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Linux-Apps für Chromebook entfernen</translation> @@ -1753,7 +1751,6 @@ <translation id="3661054927247347545">Die Anmeldezertifizierung ist ungültig. Das Fenster wird in <ph name="MINUTES" />:<ph name="SECONDS" /> geschlossen.</translation> <translation id="3664511988987167893">Erweiterungssymbol</translation> <translation id="3665589677786828986">Chrome hat festgestellt, dass einige Ihrer Einstellungen von einem anderen Programm manipuliert wurden, und hat sie auf die ursprünglichen Standardwerte zurückgesetzt.</translation> -<translation id="3665842570601375360">Sicherheit:</translation> <translation id="3668570675727296296">Spracheinstellungen</translation> <translation id="3668823961463113931">Handler</translation> <translation id="3670229581627177274">Bluetooth aktivieren</translation> @@ -1792,7 +1789,6 @@ <translation id="3726463242007121105">Dieses Gerät kann nicht geöffnet werden, da das zugehörige Dateisystem nicht unterstützt wird.</translation> <translation id="3727148787322499904">Änderungen dieser Einstellung wirken sich auf alle freigegebenen Netzwerke aus</translation> <translation id="3727187387656390258">Pop-up prüfen</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Fehler in Zeile <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-Server mit Step-up</translation> <translation id="3737536731758327622">Hier werden Ihre Downloads angezeigt</translation> @@ -1867,7 +1863,6 @@ <translation id="38275787300541712">Drücken Sie die Eingabetaste, wenn Sie fertig sind.</translation> <translation id="3827774300009121996">&Vollbildmodus</translation> <translation id="3828029223314399057">In Lesezeichen suchen</translation> -<translation id="3829932584934971895">Providertyp:</translation> <translation id="3830674330436234648">Keine Wiedergabe verfügbar</translation> <translation id="3831486154586836914">Sie befinden sich nun im Modus "Fensterübersicht".</translation> <translation id="383161972796689579">Der Besitzer dieses Geräts hat die Funktion zum Hinzufügen neuer Nutzer deaktiviert.</translation> @@ -1888,6 +1883,7 @@ <translation id="3856921555429624101">Messung der Datennutzung ist beendet</translation> <translation id="3857228364945137633">Mit Smart Lock können Sie Ihr <ph name="DEVICE_TYPE" /> ohne Passwort entsperren, wenn Ihr Smartphone in der Nähe ist.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Synchronisierung pausiert</translation> <translation id="3860381078714302691">Willkommen bei Hangouts Meet</translation> <translation id="3862134173397075045">Herzlich willkommen bei Cast in Chrome!</translation> <translation id="3862788408946266506">App mit Manifest-Attribut "kiosk_only" muss im Chrome OS-Kioskmodus installiert werden</translation> @@ -1965,7 +1961,6 @@ <translation id="3968261067169026421">Netzwerk konnte nicht eingerichtet werden</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Wird berechnet...</translation> -<translation id="3974195870082915331">Hier klicken, um Passwort anzuzeigen</translation> <translation id="3975222297214566386">Infofeld für Eingabeoptionen</translation> <translation id="397703832102027365">Aktualisierung wird abgeschlossen...</translation> <translation id="3979395879372752341">Neue Erweiterung hinzugefügt (<ph name="EXTENSION_NAME" />)</translation> @@ -2007,6 +2002,7 @@ <translation id="4044612648082411741">Sie müssen Ihr Zertifikatspasswort eingeben</translation> <translation id="404493185430269859">Standardsuchmaschine</translation> <translation id="4047112090469382184">Warum ist das sicher?</translation> +<translation id="4051049974203704184">Informationen zu Bildschirminhalten erhalten</translation> <translation id="4052120076834320548">Winzig</translation> <translation id="4055023634561256217">Für das Zurücksetzen Ihres Geräts mit Powerwash ist ein Neustart erforderlich.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2035,6 +2031,7 @@ <translation id="4088095054444612037">Für Gruppe akzeptieren</translation> <translation id="4089235344645910861">Einstellungen gespeichert. Synchronisation gestartet.</translation> <translation id="4090103403438682346">Bestätigten Zugriff aktivieren</translation> +<translation id="4090947011087001172">Websiteberechtigungen für <ph name="SITE" /> zurücksetzen?</translation> <translation id="4091434297613116013">Blatt Papier</translation> <translation id="4093955363990068916">Lokale Datei:</translation> <translation id="4095507791297118304">Hauptbildschirm</translation> @@ -2211,7 +2208,6 @@ <translation id="4419556793104466535">Synchronisierung, Personalisierung und mehr steuern</translation> <translation id="4421932782753506458">Miez</translation> <translation id="4422347585044846479">Lesezeichen für diese Seite bearbeiten</translation> -<translation id="4423104065312875417">Weitere Sprach-Engines installieren</translation> <translation id="4423376891418188461">Einstellungen wiederherstellen</translation> <translation id="4423482519432579560">&Rechtschreibprüfung</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, Ihr Administrator fordert Sie zum Ändern Ihres Passworts auf.</translation> @@ -2236,7 +2232,6 @@ <translation id="4449996769074858870">Auf diesem Tab wird Audio wiedergegeben.</translation> <translation id="4450974146388585462">Diagnose</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> durchsuchen oder URL eingeben</translation> -<translation id="445923051607553918">Mit WLAN verbinden</translation> <translation id="4462159676511157176">Benutzerdefinierte Nameserver</translation> <translation id="4467100756425880649">Chrome Web Store-Galerie</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> maximieren</translation> @@ -2372,6 +2367,7 @@ <translation id="4682551433947286597">Hintergründe werden auf dem Anmeldebildschirm angezeigt.</translation> <translation id="4684427112815847243">Alles synchronisieren</translation> <translation id="4689421377817139245">Lesezeichen mit meinem iPhone synchronisieren</translation> +<translation id="4690091457710545971"><Vier Dateien wurden von der Intel-WLAN-Firmware erstellt: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Bei den ersten drei handelt es sich um Binärdateien mit Registrierungsabbildern, für die Intel angibt, dass sie keine personenbezogenen oder zur Geräteidentifikation nutzbaren Informationen enthält. Die letzte Datei ist eine Ablaufverfolgungsdatei von der Intel-Firmware, aus der alle personenbezogenen oder zur Geräteidentifikation nutzbaren Informationen entfernt wurden. Sie ist allerdings zu groß, um hier angezeigt zu werden. Diese Dateien wurden wegen WLAN-Problemen auf Ihrem Gerät erstellt, die kürzlich aufgetreten sind. Sie werden zur Fehlerbehebung an Intel weitergegeben.></translation> <translation id="4692302215262324251">Ihr <ph name="DEVICE_TYPE" /> wurde von <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> erfolgreich für die Unternehmensverwaltung angemeldet. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Falls dies eine unerwartete Aktion ist, wenden Sie sich bitte an den Support.</translation> @@ -2631,6 +2627,7 @@ <translation id="5074318175948309511">Damit die neuen Einstellungen wirksam werden, muss die Seite eventuell neu geladen werden.</translation> <translation id="5075131525758602494">SIM-PIN eingeben</translation> <translation id="5078638979202084724">Alle Tabs als Lesezeichen speichern</translation> +<translation id="5079950360618752063">Vorgeschlagenes Passwort verwenden</translation> <translation id="5084230410268011727">Verwendung von Bewegungs- und Lichtsensoren für Websites zulassen</translation> <translation id="5085162214018721575">Suche nach Updates...</translation> <translation id="5086082738160935172">HID</translation> @@ -2669,6 +2666,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Diesen Eintrag löschen</translation> <translation id="5139955368427980650">Ö&ffnen</translation> +<translation id="5142961317498132443">Authentifizierung</translation> <translation id="5143374789336132547">Durch die Erweiterung <ph name="EXTENSION_NAME" /> wurde die Seite geändert, die beim Klicken auf die Schaltfläche "Startseite" erscheint.</translation> <translation id="5143712164865402236">Vollbildmodus ein</translation> <translation id="5145331109270917438">Änderungsdatum</translation> @@ -2839,7 +2837,6 @@ <translation id="5380103295189760361">Halten Sie Strg, Alt, Umschalttaste oder Suchen gedrückt, um die Tastenkombinationen für diese Modifikatoren anzuzeigen.</translation> <translation id="5382591305415226340">Unterstützte Links verwalten</translation> <translation id="5384883051496921101">Diese Website ist im Begriff, Informationen mit einer App außerhalb des Inkognitomodus zu teilen.</translation> -<translation id="5388588172257446328">Nutzername:</translation> <translation id="5388885445722491159">Gepaart</translation> <translation id="5389237414310520250">Der neue Nutzer konnte nicht erstellt werden. Bitte überprüfen Sie Ihren Festplattenspeicherplatz und Ihre Berechtigungen und versuchen Sie es dann erneut.</translation> <translation id="5390100381392048184">Wiedergabe von Ton auf Websites zulassen</translation> @@ -2964,7 +2961,6 @@ <translation id="5551573675707792127">Tastatur und Texteingabe</translation> <translation id="5553089923092577885">Zuordnungen von Zertifikatrichtlinien</translation> <translation id="5554489410841842733">Dieses Symbol wird eingeblendet, wenn die Erweiterung auf die aktuelle Seite angewendet werden kann.</translation> -<translation id="5554573843028719904">Anderes WLAN...</translation> <translation id="5554720593229208774">E-Mail-Zertifizierungsstelle</translation> <translation id="5556206011531515970">Klicken Sie auf "Weiter", um Ihren Standardbrowser zu wählen.</translation> <translation id="5556459405103347317">Neu laden</translation> @@ -3005,7 +3001,6 @@ <translation id="5610038042047936818">Zum Kameramodus wechseln</translation> <translation id="5612720917913232150"><ph name="URL" /> möchte den Standort Ihres Computers nutzen</translation> <translation id="5612734644261457353">Ihr Passwort konnte leider immer noch nicht bestätigt werden. Hinweis: Falls Sie Ihr Passwort kürzlich geändert haben, wird Ihr neues Passwort übernommen, sobald Sie sich abmelden. Verwenden Sie hier das alte Passwort.</translation> -<translation id="5613695965848159202">Anonyme Identität:</translation> <translation id="5614190747811328134">Nutzerhinweis</translation> <translation id="561698261642843490">Firefox schließen</translation> <translation id="5618075537869101857">Die Kioskanwendung konnte nicht gestartet werden.</translation> @@ -3223,7 +3218,6 @@ <translation id="5941343993301164315">Melden Sie sich in <ph name="TOKEN_NAME" /> an.</translation> <translation id="5941711191222866238">Verkleinern</translation> <translation id="5946591249682680882">Bericht-ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Privates Netzwerk hinzufügen</translation> <translation id="5949544233750246342">Datei kann nicht geparst werden</translation> <translation id="5955282598396714173">Ihr Passwort ist abgelaufen. Melden Sie sich ab und dann wieder an, um es zu ändern.</translation> <translation id="5956585768868398362">Ist das Ihre erwartete Seite für die Suche?</translation> @@ -3384,11 +3378,13 @@ <translation id="6198102561359457428">Abmelden und dann erneut anmelden...</translation> <translation id="6198252989419008588">PIN ändern</translation> <translation id="6199801702437275229">Speicherplatzangaben werden abgerufen...</translation> +<translation id="6204015976622790023">Sie erhalten relevante Vorschläge von Google Assistant zu Bildschirminhalten.</translation> <translation id="6205710420833115353">Einige Vorgänge dauern länger als erwartet. Möchten Sie sie abbrechen?</translation> <translation id="6206311232642889873">Bild kop&ieren</translation> <translation id="6207200176136643843">Auf Standard-Zoomstufe zurücksetzen</translation> <translation id="620722923698527029">Diese Arten von Links immer in der verknüpften App öffnen</translation> <translation id="6207937957461833379">Land/Region</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Synchronisierung funktioniert nicht</translation> <translation id="6212039847102026977">Erweiterte Netzwerkeigenschaften anzeigen</translation> <translation id="6212168817037875041">Display deaktivieren</translation> <translation id="6212752530110374741">Link per E-Mail versenden</translation> @@ -3426,7 +3422,6 @@ <translation id="6263541650532042179">Synchronisierung zurücksetzen</translation> <translation id="6264365405983206840">&Alles auswählen</translation> <translation id="6264422956566238156">Sie haben die Chrome-Synchronisierung aktiviert</translation> -<translation id="6265930187414222160">Erledigt! Schädliche Software entfernt.</translation> <translation id="6267166720438879315">Wählen Sie ein Zertifikat für die Authentifizierung bei <ph name="HOST_NAME" /> aus.</translation> <translation id="6268252012308737255">Öffnen mit <ph name="APP" /></translation> <translation id="6268747994388690914">Lesezeichen aus HTML-Datei importieren...</translation> @@ -3533,7 +3528,6 @@ Klicken Sie auf "Weiter", um sich in Ihrem <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />-Konto anzumelden.</translation> <translation id="6419546358665792306">Entpackte Erweiterung laden</translation> <translation id="642282551015776456">Dieser Name darf nicht als Datei- oder Ordnername verwendet werden.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox-Einstellungen öffnen</translation> <translation id="6429384232893414837">Fehler beim Aktualisieren</translation> <translation id="6430814529589430811">Base64-codierter ASCII-Code, Einzelzertifikat</translation> @@ -3614,7 +3608,6 @@ <translation id="6544215763872433504">Der Webbrowser von Google, für Sie</translation> <translation id="6545665334409411530">Wiederholungsrate</translation> <translation id="6545834809683560467">Funktion zur Vervollständigung von Suchanfragen und URLs verwenden, die in die Adressleiste oder die Suchleiste des App Launchers eingegeben werden</translation> -<translation id="6546686722964485737">Mit WiMAX-Netzwerk verbinden</translation> <translation id="6547316139431024316">Für diese Erweiterung keine Warnung mehr</translation> <translation id="6547354035488017500">Geben Sie mindestens 512 MB Speicherplatz frei oder Ihr Gerät reagiert nicht mehr. Löschen Sie Dateien aus dem Gerätespeicher, um Speicherplatz freizugeben.</translation> <translation id="6549689063733911810">Zuletzt geöffnet</translation> @@ -4033,7 +4026,6 @@ <translation id="7201014958346994077">Linux-Dateien können nicht angezeigt werden</translation> <translation id="720110658997053098">Gerät dauerhaft im Kioskmodus betreiben</translation> <translation id="7201118060536064622">"<ph name="DELETED_ITEM_NAME" />" wurde gelöscht</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> wird heruntergeladen...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Seite verlassen}other{Seiten verlassen}}</translation> <translation id="7216409898977639127">Mobilfunkanbieter</translation> @@ -4511,7 +4503,6 @@ <translation id="7909969815743704077">Im Inkognitomodus heruntergeladen</translation> <translation id="7910768399700579500">&Neuer Ordner</translation> <translation id="7912080627461681647">Ihr Passwort wurde auf dem Server geändert. Bitte melden Sie sich ab und dann wieder an.</translation> -<translation id="7912883689016444961">Mobilfunknetz konfigurieren</translation> <translation id="7915471803647590281">Bitte beschreiben Sie das Problem, bevor Sie das Feedback abschicken.</translation> <translation id="7916556741383518510">Bei Klick</translation> <translation id="792514962475806987">Zoomstufe für angedockte Lupe:</translation> @@ -4565,7 +4556,6 @@ <translation id="7988355189918024273">Bedienungshilfen aktivieren</translation> <translation id="7994702968232966508">EAP-Methode</translation> <translation id="799547531016638432">Verknüpfung entfernen</translation> -<translation id="7997479212858899587">Identität:</translation> <translation id="7997826902155442747">Prozesspriorität</translation> <translation id="7999229196265990314">Folgende Dateien wurden erstellt: @@ -4649,7 +4639,6 @@ <translation id="8105368624971345109">Deaktivieren</translation> <translation id="8106045200081704138">Für mich freigegeben</translation> <translation id="8107015733319732394">Google Play Store wird auf Ihrem <ph name="DEVICE_TYPE" /> installiert. Dies kann ein paar Minuten dauern.</translation> -<translation id="8109930990200908494">Anmeldung für Nutzerzertifikate erforderlich</translation> <translation id="8111155949205007504">Dieses Passwort für Ihr iPhone freigeben</translation> <translation id="8113043281354018522">Lizenztyp auswählen</translation> <translation id="8116190140324504026">Weitere Informationen</translation> @@ -4660,6 +4649,7 @@ <translation id="8118860139461251237">Downloads verwalten</translation> <translation id="81238879832906896">Gelbe und weiße Blume</translation> <translation id="8124313775439841391">Verwaltete ONC-Eigenschaften</translation> +<translation id="8125562866093998907">Die Website möchte Ihren Sicherheitsschlüssel überprüfen, um die Sicherheit für Ihr Konto zu erhöhen.</translation> <translation id="813082847718468539">Website-Informationen anzeigen</translation> <translation id="8131740175452115882">Bestätigen</translation> <translation id="8133676275609324831">&In Ordner anzeigen</translation> @@ -4770,7 +4760,6 @@ <translation id="8308179586020895837">Nachfragen, wenn <ph name="HOST" /> auf Ihre Kamera zugreifen möchte</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Das Zertifikat ist bereits vorhanden</translation> -<translation id="8309505303672555187">Netzwerk auswählen:</translation> <translation id="8312871300878166382">In Ordner einfügen</translation> <translation id="8317671367883557781">Netzwerkverbindung hinzufügen</translation> <translation id="8319414634934645341">Erweiterte Schlüsselverwendung</translation> @@ -4846,7 +4835,6 @@ <translation id="8451512073679317615">Assistant</translation> <translation id="8452135315243592079">Keine SIM-Karte vorhanden</translation> <translation id="8453482423012550001">$1-Elemente werden kopiert...</translation> -<translation id="8454288007744638700">Sie können auch ein anderes Netzwerk auswählen:</translation> <translation id="845627346958584683">Ablaufzeit</translation> <translation id="8456681095658380701">Ungültiger Name</translation> <translation id="8457451314607652708">Lesezeichen importieren</translation> @@ -4910,6 +4898,7 @@ <translation id="855081842937141170">Anheften</translation> <translation id="8551388862522347954">Lizenzen</translation> <translation id="8553342806078037065">Andere Nutzer verwalten</translation> +<translation id="8554899698005018844">Keine Sprache</translation> <translation id="855773602626431402">Ein Plug-in ohne Sandbox wurde auf dieser Seite blockiert.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Bild-Decodierer</translation> @@ -4947,7 +4936,6 @@ <translation id="862727964348362408">Ausgesetzt</translation> <translation id="862750493060684461">CSS-Cache</translation> <translation id="8627795981664801467">Nur sichere Verbindungen</translation> -<translation id="8628085465172583869">Hostname des Servers:</translation> <translation id="8630903300770275248">Betreuten Nutzer importieren</translation> <translation id="8631032106121706562">Margerite</translation> <translation id="8637542770513281060">Ihr Computer enthält ein Sicherheitsmodul, über das viele wichtige Sicherheitsfunktionen in Chrome OS implementiert werden. Weitere Informationen dazu finden Sie in der Chromebook-Hilfe unter https://support.google.com/chromebook/?p=sm.</translation> @@ -5203,7 +5191,6 @@ <translation id="899403249577094719">Basis-URL für Netscape-Zertifikate</translation> <translation id="8995603266996330174">Verwaltet von <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Konto hinzufügen...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Laufwerk-Image wird erstellt.</translation> <translation id="9003647077635673607">Auf allen Websites zulassen</translation> <translation id="9003677638446136377">Erneut prüfen</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb index 576271e..a4b3a58 100644 --- a/chrome/app/resources/generated_resources_el.xtb +++ b/chrome/app/resources/generated_resources_el.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">Κωδικός PUK</translation> <translation id="1061904396131502319">Πλησιάζει η ώρα για διάλειμμα</translation> <translation id="1062407476771304334">Αντικατάσταση</translation> -<translation id="1064835277883315402">Συνδεθείτε σε ιδιωτικό δίκτυο</translation> <translation id="1064912851688322329">Αποσύνδεση του Λογαριασμού σας Google</translation> <translation id="1067048845568873861">Δημιουργήθηκε</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Αναζήτηση...</translation> <translation id="1316495628809031177">Ο συγχρονισμός τέθηκε σε παύση</translation> <translation id="1319979322914001937">Μια εφαρμογή που εμφανίζει μια φιλτραρισμένη λίστα των επεκτάσεων από το Chrome Web Store. Οι επεκτάσεις στον κατάλογο μπορούν να εγκατασταθούν απευθείας από την εφαρμογή.</translation> -<translation id="132090119144658135">Αντιστοιχία θέματος:</translation> <translation id="1326317727527857210">Για να εμφανίζονται οι καρτέλες από τις άλλες συσκευές σας, συνδεθείτε στο Chrome.</translation> <translation id="1327074568633507428">Εκτυπωτής στο Google Cloud Print</translation> <translation id="1327977588028644528">Πύλη</translation> @@ -377,6 +375,7 @@ <translation id="1531004739673299060">Παράθυρο εφαρμογής</translation> <translation id="1534389735079119190">ΣΦΑΛΜΑ: Αποτυχία έναρξης του κοντέινερ εντός του VM.</translation> <translation id="15373452373711364">Μεγάλος δείκτης ποντικιού</translation> +<translation id="1540605929960647700">Ενεργοποίηση λειτουργίας επίδειξης</translation> <translation id="1543284117603151572">Εισαγωγή από το Edge</translation> <translation id="1545177026077493356">Αυτόματη λειτουργία kiosk</translation> <translation id="1545775234664667895">Εγκατεστημένο θέμα "<ph name="THEME_NAME" />"</translation> @@ -460,6 +459,7 @@ <translation id="1657406563541664238">Συμβάλετε στη βελτίωση του <ph name="PRODUCT_NAME" /> στέλνοντας αυτόματα στην Google στατιστικά στοιχεία χρήσης και αναφορές σφαλμάτων</translation> <translation id="1658424621194652532">Αυτή η σελίδα έχει πρόσβαση στο μικρόφωνό σας.</translation> <translation id="1660204651932907780">Να επιτρέπεται στους ιστοτόπους να αναπαράγουν ήχο (συνιστάται)</translation> +<translation id="1660938185063657230">Επαληθεύστε το Κλειδί ασφαλείας σας</translation> <translation id="1661156625580498328">Επιβολή κρυπτογράφησης AES (συνιστάται).</translation> <translation id="1661245713600520330">Σε αυτήν τη σελίδα αναφέρονται όλες οι λειτουργικές μονάδες που φορτώθηκαν στην κύρια διαδικασία και οι λειτουργικές μονάδες που εγγράφηκαν για φόρτωση αργότερα.</translation> <translation id="166179487779922818">Ο κωδικός πρόσβασης είναι πολύ σύντομος.</translation> @@ -477,6 +477,7 @@ <translation id="16815041330799488">Να μην επιτρέπεται στους ιστοτόπους να βλέπουν κείμενο και εικόνες που αντιγράψατε στο πρόχειρο</translation> <translation id="1682548588986054654">Νέο παράθυρο ανώνυμης περιήγησης</translation> <translation id="168715261339224929">Για να εμφανίζονται οι σελιδοδείκτες σας σε όλες τις συσκευές σας, ενεργοποιήστε τον συγχρονισμό.</translation> +<translation id="1688867105868176567">Να διαγραφούν τα δεδομένα ιστοτόπου;</translation> <translation id="1688935057616748272">Πληκτρολογήστε ένα γράμμα</translation> <translation id="168991973552362966">Προσθήκη εκτυπωτή που βρίσκεται σε κοντινή απόσταση</translation> <translation id="1689945336726856614">Αντιγραφή &URL</translation> @@ -488,7 +489,6 @@ <translation id="1701062906490865540">Κατάργηση αυτού του ατόμου</translation> <translation id="1706586824377653884">Προστέθηκε από τον διαχειριστή σας</translation> <translation id="1706625117072057435">Επίπεδα εστίασης</translation> -<translation id="1707463636381878959">Μοιραστείτε αυτό το δίκτυο με άλλους χρήστες</translation> <translation id="1708338024780164500">(Ανενεργή)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (Αναγνωριστικό: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Εγγενής)</translation> @@ -524,7 +524,6 @@ <translation id="175772926354468439">Ενεργοποίηση θέματος</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Προβολή στο Chrome Web Store</translation> -<translation id="1758831820837444715">Διαμόρφωση δικτύου Ethernet</translation> <translation id="1763046204212875858">Δημιουργία συντομεύσεων εφαρμογής</translation> <translation id="1763108912552529023">Συνεχίστε την εξερεύνηση</translation> <translation id="1763808908432309942">Ανοίγει σε νέα καρτέλα</translation> @@ -583,8 +582,10 @@ <translation id="1839704667838141620">Αλλάξτε τον τρόπο κοινοποίησης αυτού του αρχείου</translation> <translation id="1841545962859478868">Ο διαχειριστής της συσκευής μπορεί να παρακολουθεί τα παρακάτω:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> απενεργοποιήθηκε</translation> +<translation id="1842766183094193446">Είστε βέβαιοι ότι θέλετε να ενεργοποιήσετε τη λειτουργία επίδειξης;</translation> <translation id="1844692022597038441">Αυτό το αρχείο δεν είναι διαθέσιμο εκτός σύνδεσης.</translation> <translation id="1846308012215045257">Κάντε κλικ για εκτέλεση της προσθήκης <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Αποθηκεύτηκε</translation> <translation id="1848219224579402567">Αποσύνδεση όταν το καπάκι είναι κλειστό</translation> <translation id="184823282865851239">Αποκλεισμός εάν ο ιστότοπος τείνει να εμφανίζει παρεμβατικές διαφημίσεις</translation> <translation id="1849186935225320012">Αυτή η σελίδα έχει τον πλήρη έλεγχο των συσκευών MIDI.</translation> @@ -682,6 +683,7 @@ <translation id="200544492091181894">Μπορείτε να αλλάξετε αυτήν την επιλογή στις ρυθμίσεις οποιαδήποτε στιγμή</translation> <translation id="2006638907958895361">Άνοιγμα Συνδέσμου στην εφαρμογή <ph name="APP" /></translation> <translation id="2007404777272201486">Αναφορά προβλήματος...</translation> +<translation id="2016237810978710652">Άνοιγμα Αρχείων Linux...</translation> <translation id="2016430552235416146">Τυπική</translation> <translation id="2017334798163366053">Απενεργοποίηση συλλογής δεδομένων απόδοσης</translation> <translation id="2017836877785168846">Διαγράφει το ιστορικό και τις αυτόματες συμπληρώσεις στη γραμμή διευθύνσεων.</translation> @@ -776,6 +778,7 @@ <translation id="2154484045852737596">Επεξεργασία κάρτας</translation> <translation id="2154710561487035718">Αντιγραφή διεύθυνσης URL</translation> <translation id="2155772377859296191">Θα εμφανίζεται ως <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Μπορείτε να συμβάλετε στη βελτίωση της Ασφαλούς περιήγησης στέλνοντας ορισμένες πληροφορίες συστήματος και περιεχόμενο σελίδων στην Google.</translation> <translation id="215753907730220065">Έξοδος από πλήρη οθόνη</translation> <translation id="2157875535253991059">Αυτή η σελίδα εμφανίζεται σε πλήρη οθόνη</translation> <translation id="216169395504480358">Προσθήκη Wi-Fi…</translation> @@ -785,6 +788,7 @@ <translation id="2173801458090845390">Προσθήκη αναγνωριστικού επίταξης σε αυτήν τη συσκευή</translation> <translation id="2175042898143291048">Να γίνεται πάντα</translation> <translation id="2175607476662778685">Γραμμή γρήγορης εκκίνησης</translation> +<translation id="2176087259161165020">Άλλες πηγές</translation> <translation id="2177950615300672361">Καρτέλα ανώνυμης περιήγησης: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Η προσθήκη <ph name="PEPPER_PLUGIN_NAME" /> στον τομέα <ph name="PEPPER_PLUGIN_DOMAIN" /> επιθυμεί να αποκτήσει πρόσβαση στον υπολογιστή σας</translation> <translation id="2178614541317717477">Παραβίαση αρχής έκδοσης πιστοποιητικών</translation> @@ -868,7 +872,6 @@ <translation id="2291643155573394834">Επόμενη καρτέλα</translation> <translation id="2292848386125228270">Εκκινήστε το <ph name="PRODUCT_NAME" /> ως απλός χρήστης. Εάν απαιτείται εκτέλεση ως ρίζας για ανάπτυξη, εκτελέστε το ξανά με την ετικέτα --no-sandbox.</translation> <translation id="2294358108254308676">Θέλετε να εγκαταστήσετε το <ph name="PRODUCT_NAME" />;</translation> -<translation id="2296019197782308739">Μέθοδος EAP:</translation> <translation id="2297705863329999812">Αναζήτηση εκτυπωτών</translation> <translation id="2300383962156589922">Προσαρμογή και έλεγχος της εφαρμογής <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Ο κατάλογος ρίζας επέκτασης δεν είναι έγκυρος.</translation> @@ -916,6 +919,7 @@ <translation id="2366463953911599217">ΣΦΑΛΜΑ: Αποτυχία απεγκατάστασης <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Προσθήκη κοινόχρηστου αρχείου</translation> <translation id="2367972762794486313">Εμφάνιση εφαρμογών</translation> +<translation id="2369536625682139252">Όλα τα δεδομένα που αποθηκεύτηκαν από τον ιστότοπο <ph name="SITE" /> θα διαγραφούν, εκτός από τα cookie.</translation> <translation id="2371076942591664043">Άνοιγμα κατά την &ολοκλήρωση</translation> <translation id="2377319039870049694">Εναλλαγή σε προβολή λίστας</translation> <translation id="2377667304966270281">Σοβαρά σφάλματα</translation> @@ -925,7 +929,6 @@ <translation id="2379281330731083556">Εκτύπωση με χρήση του παραθύρου διαλόγου συστήματος... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Ερώτηση πριν από την αποστολή (συνιστάται)</translation> <translation id="2384436799579181135">Προέκυψε σφάλμα. Ελέγξτε τον εκτυπωτή σας και δοκιμάστε ξανά.</translation> -<translation id="2385700042425247848">Όνομα υπηρεσίας:</translation> <translation id="2387458720915042159">Τύπος σύνδεσης διακομιστή μεσολάβησης</translation> <translation id="2391419135980381625">Τυπική γραμματοσειρά</translation> <translation id="2391762656119864333">Ανάκληση</translation> @@ -976,7 +979,6 @@ <translation id="247949520305900375">Κοινοποίηση ήχου</translation> <translation id="2480868415629598489">Τροποποίηση των δεδομένων που αντιγράφετε και επικολλάτε</translation> <translation id="2482878487686419369">Ειδοποιήσεις</translation> -<translation id="2485056306054380289">Πιστοποιητικό διακομιστή CA:</translation> <translation id="2485422356828889247">Κατάργηση Εγκατάστασης</translation> <translation id="2487067538648443797">Προσθήκη νέου σελιδοδείκτη</translation> <translation id="248861575772995840">Δεν είναι δυνατή η εύρεση του τηλεφώνου σας. Βεβαιωθείτε ότι το Bluetooth του <ph name="DEVICE_TYPE" /> είναι ενεργοποιημένο. <a>Μάθετε περισσότερα</a></translation> @@ -1037,6 +1039,7 @@ <translation id="2566124945717127842">Το Powerwash θα επαναφέρει τη συσκευή σας <ph name="IDS_SHORT_PRODUCT_NAME" /> και θα την κάνει σαν καινούρια.</translation> <translation id="2567257616420533738">Ο κωδικός πρόσβασης αποθηκεύτηκε. Δείτε και διαχειριστείτε τους αποθηκευμένους κωδικούς πρόσβασης στη διεύθυνση <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Υποδοχέας γραμμής πληροφοριών</translation> +<translation id="2570454805927264159">Αξιοποιήστε πλήρως τον Βοηθό σας</translation> <translation id="257088987046510401">Θέματα</translation> <translation id="2572032849266859634">Παραχωρήθηκε πρόσβαση ανάγνωσης σε <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Επιλογή εικόνας και ονόματος</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">Υποβολή</translation> <translation id="265390580714150011">Τιμή πεδίου</translation> <translation id="2654166010170466751">Να επιτρέπεται σε ιστοτόπους η εγκατάσταση δεικτών χειρισμού για πληρωμές</translation> -<translation id="2655386581175833247">Πιστοποιητικό χρήστη:</translation> <translation id="2660779039299703961">Συμβάν</translation> <translation id="266079277508604648">Δεν είναι δυνατή η σύνδεση του εκτυπωτή. Βεβαιωθείτε ότι ο εκτυπωτής είναι ενεργοποιημένος και ότι είναι συνδεδεμένος στο Chromebook μέσω Wi-Fi ή USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">Δεν υπάρχουν δεδομένα χρήσης</translation> <translation id="3007214526293698309">Επιδιόρθωση αναλογίας</translation> <translation id="3007771295016901659">Δημιουργία διπλότυπης καρτέλας</translation> +<translation id="3008272652534848354">Επαναφορά αδειών</translation> <translation id="3009300415590184725">Είστε βέβαιοι ότι θέλετε να ακυρώσετε τη διαδικασία ρύθμισης της υπηρεσίας δεδομένων κινητής τηλεφωνίας;</translation> <translation id="3009779501245596802">Ευρετηριασμένες βάσεις δεδομένων</translation> <translation id="3010279545267083280">Ο κωδικός πρόσβασης διαγράφηκε</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">Λειτουργικές μονάδες (<ph name="TOTAL_COUNT" />) - Γνωστές διενέξεις: <ph name="BAD_COUNT" />, πιθανές: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Ημερομηνία και ώρα</translation> <translation id="310671807099593501">Ο ιστότοπος χρησιμοποιεί bluetooth</translation> -<translation id="3108967419958202225">Επιλογή...</translation> <translation id="3115128645424181617">Δεν είναι δυνατή η εύρεση του τηλεφώνου σας. Βεβαιωθείτε ότι είναι διαθέσιμο και ότι το Bluetooth είναι ενεργοποιημένο.</translation> <translation id="3115147772012638511">Αναμονή για προσωρινή μνήμη...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Βοήθεια</translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">Ορισμένες εταιρείες κινητής τηλεφωνίας ενδέχεται να αποκλείσουν αυτήν τη λειτουργία.</translation> <translation id="316854673539778496">Για να έχετε όλες τις επεκτάσεις σας σε όλες τις συσκευές σας, συνδεθείτε και ενεργοποιήστε τον συγχρονισμό.</translation> <translation id="3170072451822350649">Μπορείτε επίσης να παραλείψετε τη σύνδεση και να <ph name="LINK_START" />πραγματοποιήσετε περιήγηση ως Επισκέπτης<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Κάντε κλικ για να αποκρύψετε τον κωδικό πρόσβασης</translation> <translation id="3177909033752230686">Γλώσσα σελίδας:</translation> <translation id="3181110748548073003">Πατήστε |<ph name="SHORTCUT" />| για να μεταβείτε στην επόμενη σελίδα</translation> <translation id="3182749001423093222">Ορθογραφικός έλεγχος</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187">Η ιδιοκτησία θα μεταφερθεί στον τομέα <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Άνοιγμα επιλογών επεκτάσεων</translation> <translation id="3241680850019875542">Επιλέξτε τον κατάλογο ρίζας της επέκτασης που θέλετε να στοιβάξετε. Για να ενημερώσετε μια επέκταση, επιλέξτε επίσης το αρχείο ιδιωτικού κλειδιού που θα επαναχρησιμοποιηθεί.</translation> -<translation id="3242765319725186192">Ήδη κοινόχρηστο κλειδί:</translation> <translation id="3244294424315804309">Συνέχιση σίγασης ήχου</translation> <translation id="3245321423178950146">Άγνωστος καλλιτέχνης</translation> <translation id="3246097286174000800">Δοκιμάστε το Smart Lock</translation> @@ -1608,7 +1608,6 @@ <translation id="3440663250074896476">Περισσότερες ενέργειες για το σελιδοδείκτη <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Να γίνεται ερώτηση κάθε φορά που ένας ιστότοπος επιθυμεί να χρησιμοποιήσει μια προσθήκη, για να αποκτήσει πρόσβαση στον υπολογιστή σας</translation> <translation id="3441653493275994384">Έλεγχος</translation> -<translation id="3445830502289589282">2η φάση ελέγχου ταυτότητας:</translation> <translation id="344630545793878684">Ανάγνωση των δεδομένων σας σε ορισμένους ιστότοπους</translation> <translation id="3449839693241009168">Πατήστε <ph name="SEARCH_KEY" /> για να αποστείλετε εντολές στο <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Ποσοστό κατοχής κατάστασης αδράνειας</translation> @@ -1649,7 +1648,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> σφάλματα.</translation> <translation id="3495660573538963482">Ρυθμίσεις του Βοηθού Google</translation> <translation id="3496213124478423963">Σμίκρυνση</translation> -<translation id="3504135463003295723">Όνομα ομάδας:</translation> <translation id="3505030558724226696">Ανάκληση πρόσβασης στη συσκευή</translation> <translation id="3507421388498836150">Τρέχοντα δικαιώματα για "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Κατάργηση εφαρμογών Linux για Chromebook</translation> @@ -1758,7 +1756,6 @@ <translation id="3661054927247347545">Η πιστοποίηση σύνδεσης δεν είναι έγκυρη. Το παράθυρο κλείνει σε <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Εικονίδιο επέκτασης</translation> <translation id="3665589677786828986">Το Chrome διαπιστώσαμε ότι ορισμένες από τις ρυθμίσεις σας καταστράφηκαν από άλλο πρόγραμμα και τις επανέφερε στις αρχικές τους προεπιλογές.</translation> -<translation id="3665842570601375360">Ασφάλεια:</translation> <translation id="3668570675727296296">Ρυθμίσεις γλώσσας</translation> <translation id="3668823961463113931">Προγράμματα χειρισμού</translation> <translation id="3670229581627177274">Ενεργοποίηση Bluetooth</translation> @@ -1797,7 +1794,6 @@ <translation id="3726463242007121105">Δεν είναι δυνατό το άνοιγμα αυτής της συσκευής επειδή δεν υποστηρίζεται το σύστημα αρχείων της.</translation> <translation id="3727148787322499904">Η αλλαγή αυτής της ρύθμισης θα επηρεάσει όλα τα κοινόχρηστα δίκτυα</translation> <translation id="3727187387656390258">Έλεγχος αναδυόμενου παραθύρου</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Σφάλμα στη γραμμή <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Διακομιστής SSL με αναβάθμιση</translation> <translation id="3737536731758327622">Οι λήψεις σας εμφανίζονται εδώ</translation> @@ -1872,7 +1868,6 @@ <translation id="38275787300541712">Πατήστε το πλήκτρο Enter όταν τελειώσετε</translation> <translation id="3827774300009121996">&Πλήρης Οθόνη</translation> <translation id="3828029223314399057">Αναζήτηση σελιδοδεικτών</translation> -<translation id="3829932584934971895">Τύπος παρόχου:</translation> <translation id="3830674330436234648">Δεν διατίθεται αναπαραγωγή</translation> <translation id="3831486154586836914">Έχετε μεταβεί στη λειτουργία προεπισκόπησης παράθυρου</translation> <translation id="383161972796689579">Ο κάτοχος αυτής της συσκευής έχει απενεργοποιήσει την προσθήκη νέων χρηστών</translation> @@ -1893,6 +1888,7 @@ <translation id="3856921555429624101">Η μέτρηση της χρήσης δεδομένων έληξε</translation> <translation id="3857228364945137633">Δοκιμάστε το Smart Lock, για να ξεκλειδώσετε το <ph name="DEVICE_TYPE" /> χωρίς κωδικό πρόσβασης, όταν το τηλέφωνό σας είναι κοντά.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Ο συγχρονισμός τέθηκε σε παύση</translation> <translation id="3860381078714302691">Καλώς ήρθατε στο Hangouts Meet</translation> <translation id="3862134173397075045">Καλώς ήρθατε στην εμπειρία Μετάδοσης στο Chrome!</translation> <translation id="3862788408946266506">Θα πρέπει να εγκατασταθεί μια εφαρμογή με χαρακτηριστικό μανιφέστου "kiosk_only" στη λειτουργία kiosk του Chrome OS</translation> @@ -1970,7 +1966,6 @@ <translation id="3968261067169026421">Δεν ήταν δυνατή η ρύθμιση του δικτύου</translation> <translation id="3970114302595058915">Αναγνωριστικό</translation> <translation id="397105322502079400">Υπολογισμός…</translation> -<translation id="3974195870082915331">Κάντε κλικ για να εμφανίσετε τον κωδικό πρόσβασης</translation> <translation id="3975222297214566386">Συννεφάκι επιλογών εισαγωγής</translation> <translation id="397703832102027365">Ολοκλήρωση…</translation> <translation id="3979395879372752341">Προστέθηκε νέα επέκταση (<ph name="EXTENSION_NAME" />)</translation> @@ -2012,6 +2007,7 @@ <translation id="4044612648082411741">Εισαγάγετε τον κωδικό πρόσβασης του πιστοποιητικού σας</translation> <translation id="404493185430269859">Προεπιλεγμένη μηχανή αναζήτησης</translation> <translation id="4047112090469382184">Γιατί είναι ασφαλής</translation> +<translation id="4051049974203704184">Λάβετε πληροφορίες σχετικά με το περιεχόμενο που εμφανίζεται στην οθόνη</translation> <translation id="4052120076834320548">Πάρα πολύ μικρό</translation> <translation id="4055023634561256217">Απαιτείται επανεκκίνηση προκειμένου να είναι δυνατή η επαναφορά της συσκευής σας με Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2040,6 +2036,7 @@ <translation id="4088095054444612037">Αποδοχή για την ομάδα</translation> <translation id="4089235344645910861">Οι ρυθμίσεις αποθηκεύτηκαν. Ο συγχρονισμός ξεκίνησε.</translation> <translation id="4090103403438682346">Ενεργοποίηση επαληθευμένης πρόσβασης</translation> +<translation id="4090947011087001172">Να γίνει επαναφορά των αδειών για τον ιστότοπο <ph name="SITE" />;</translation> <translation id="4091434297613116013">φύλλα χαρτιού</translation> <translation id="4093955363990068916">Τοπικό αρχείο:</translation> <translation id="4095507791297118304">Κύρια οθόνη</translation> @@ -2216,7 +2213,6 @@ <translation id="4419556793104466535">Ελέγξτε τον συγχρονισμό, την εξατομίκευση και άλλα</translation> <translation id="4421932782753506458">Χνουδωτός</translation> <translation id="4422347585044846479">Επεξεργασία σελιδοδείκτη για αυτή τη σελίδα</translation> -<translation id="4423104065312875417">Εγκατάσταση επιπλέον μηχανών ομιλίας</translation> <translation id="4423376891418188461">Επαναφορά ρυθμίσεων</translation> <translation id="4423482519432579560">&Ορθογραφικός έλεγχος</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, ο διαχειριστής σας απαιτεί να αλλάξετε τον κωδικό πρόσβασης.</translation> @@ -2241,7 +2237,6 @@ <translation id="4449996769074858870">Αυτή η καρτέλα πραγματοποιεί αναπαραγωγή ήχου.</translation> <translation id="4450974146388585462">Διάγνωση</translation> <translation id="4453946976636652378">Αναζητήστε στο <ph name="SEARCH_ENGINE_NAME" /> ή πληκτρολογήστε κάποιο URL</translation> -<translation id="445923051607553918">Σύνδεση με δίκτυο Wi-Fi</translation> <translation id="4462159676511157176">Προσαρμοσμένοι διακομιστές ονομάτων</translation> <translation id="4467100756425880649">Chrome Web Store Gallery</translation> <translation id="4467101674048705704">Ανάπτυξη <ph name="FOLDER_NAME" /></translation> @@ -2377,6 +2372,7 @@ <translation id="4682551433947286597">Οι ταπετσαρίες εμφανίζονται στην οθόνη σύνδεσης.</translation> <translation id="4684427112815847243">Συγχρονισμός όλων</translation> <translation id="4689421377817139245">Συγχρονίστε αυτόν τον σελιδοδείκτη στο iPhone</translation> +<translation id="4690091457710545971"><Δημιουργήθηκαν τέσσερα αρχεία από το υλικολογισμικό Intel Wi-Fi: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Τα τρία πρώτα είναι δυαδικά αρχεία τα οποία περιέχουν αρχεία ένδειξης σφαλμάτων εγγραφής και η Intel διαβεβαιώνει ότι δεν περιέχουν στοιχεία προσωπικής ταυτοποίησης ή ταυτοποίησης συσκευής. Το τελευταίο αρχείο αποτελεί ίχνος εκτέλεσης από το υλικολογισμικό της Intel. Έχει εκκαθαριστεί από τυχόν στοιχεία προσωπικής ταυτοποίησης ή ταυτοποίησης συσκευής, αλλά είναι πάρα πολύ μεγάλο για να προβληθεί εδώ. Αυτά τα αρχεία δημιουργήθηκαν ως απόκριση στα προβλήματα σχετικά με τη σύνδεση Wi-Fi που αντιμετώπισε η συσκευή σας και θα κοινοποιηθεί στην Intel προκειμένου να λάβετε βοήθεια για την αντιμετώπιση αυτών των προβλημάτων.></translation> <translation id="4692302215262324251">Η συσκευή <ph name="DEVICE_TYPE" /> εγγράφηκε επιτυχώς για εταιρική διαχείριση από <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Εάν αυτή η συμπεριφορά είναι μη αναμενόμενη επικοινωνήστε με την υποστήριξη.</translation> @@ -2636,6 +2632,7 @@ <translation id="5074318175948309511">Αυτή η σελίδα ενδεχομένως να πρέπει να φορτωθεί εκ νέου προτού ενεργοποιηθούν οι νέες ρυθμίσεις.</translation> <translation id="5075131525758602494">Εισαγωγή PIN SIM</translation> <translation id="5078638979202084724">Δημιουργία σελιδοδείκτη για όλες τις καρτέλες</translation> +<translation id="5079950360618752063">Χρήση προτεινόμενου κωδικού πρόσβασης</translation> <translation id="5084230410268011727">Να επιτρέπεται στους ιστοτόπους να χρησιμοποιούν αισθητήρες κίνησης και φωτός</translation> <translation id="5085162214018721575">Έλεγχος για ενημερώσεις</translation> <translation id="5086082738160935172">HID</translation> @@ -2674,6 +2671,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Διαγραφή αυτού του στοιχείο</translation> <translation id="5139955368427980650">Άν&οιγμα</translation> +<translation id="5142961317498132443">Έλεγχος ταυτότητας</translation> <translation id="5143374789336132547">Η επέκταση <ph name="EXTENSION_NAME" /> άλλαξε τη σελίδα που εμφανίζεται όταν κάνετε κλικ στο κουμπί αρχικής σελίδας.</translation> <translation id="5143712164865402236">Ενεργοποίηση πλήρους οθόνης</translation> <translation id="5145331109270917438">Ημερομηνία τροποποίησης</translation> @@ -2844,7 +2842,6 @@ <translation id="5380103295189760361">Κρατήστε πατημένα τα Control, Alt Shift ή Search για να δείτε τις συντομεύσεις πληκτρολογίου για αυτούς τους τροποποιητές.</translation> <translation id="5382591305415226340">Διαχείριση υποστηριζόμενων συνδέσμων</translation> <translation id="5384883051496921101">Αυτός ο ιστότοπος πρόκειται να κοινοποιήσει πληροφορίες με μια εφαρμογή εκτός της κατάστασης ανώνυμης περιήγησης.</translation> -<translation id="5388588172257446328">Όνομα χρήστη:</translation> <translation id="5388885445722491159">Με σύζευξη</translation> <translation id="5389237414310520250">Δεν ήταν δυνατή η δημιουργία του νέου χρήστη. Ελέγξτε τον ελεύθερο χώρο στο σκληρό δίσκο και τα δικαιώματά σας και προσπαθήστε ξανά.</translation> <translation id="5390100381392048184">Να επιτρέπεται στους ιστοτόπους να αναπαράγουν ήχο</translation> @@ -2969,7 +2966,6 @@ <translation id="5551573675707792127">Πληκτρολόγιο και εισαγωγή κειμένου</translation> <translation id="5553089923092577885">Αντιστοιχίσεις πολιτικής πιστοποιητικών</translation> <translation id="5554489410841842733">Αυτό το εικονίδιο θα είναι ορατό όταν η επέκταση θα μπορεί να ενεργεί στην τρέχουσα σελίδα.</translation> -<translation id="5554573843028719904">Άλλο δίκτυο Wi-Fi...</translation> <translation id="5554720593229208774">Αρχή πιστοποίησης ηλεκτρονικού ταχυδρομείου</translation> <translation id="5556206011531515970">Πατήστε Επόμενο για να επιλέξετε το προεπιλεγμένο πρόγραμμα περιήγησης.</translation> <translation id="5556459405103347317">Επαναφόρτωση</translation> @@ -3010,7 +3006,6 @@ <translation id="5610038042047936818">Εναλλαγή σε λειτουργία κάμερας</translation> <translation id="5612720917913232150">Ο ιστότοπος <ph name="URL" /> επιθυμεί να χρησιμοποιήσει την τοποθεσία του υπολογιστή σας</translation> <translation id="5612734644261457353">Λυπούμαστε, η επαλήθευση του κωδικού πρόσβασής σας εξακολουθεί να μην είναι δυνατή. Λάβετε υπόψη σας: εάν έχετε αλλάξει πρόσφατα τον κωδικό πρόσβασής σας, ο νέος κωδικός πρόσβασής σας θα τεθεί σε ισχύ αφού αποσυνδεθείτε, χρησιμοποιήστε εδώ τον παλιό κωδικό πρόσβασης.</translation> -<translation id="5613695965848159202">Ανώνυμη ταυτότητα:</translation> <translation id="5614190747811328134">Σημείωση για τους χρήστες</translation> <translation id="561698261642843490">Κλείσιμο Firefox</translation> <translation id="5618075537869101857">Δυστυχώς, δεν ήταν δυνατή η εκκίνηση της εφαρμογής kiosk.</translation> @@ -3229,7 +3224,6 @@ <translation id="5941343993301164315">Συνδεθείτε στο <ph name="TOKEN_NAME" /> .</translation> <translation id="5941711191222866238">Ελαχιστοποίηση</translation> <translation id="5946591249682680882">Αναγνωριστικό αναφοράς <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Προσθήκη ιδιωτικού δικτύου</translation> <translation id="5949544233750246342">Δεν είναι δυνατή η ανάλυση του αρχείου</translation> <translation id="5955282598396714173">Ο κωδικός πρόσβασής σας έληξε. Αποσυνδεθείτε και συνδεθείτε ξανά για να τον αλλάξετε.</translation> <translation id="5956585768868398362">Είναι αυτή η σελίδα αναζήτησης που περιμένατε;</translation> @@ -3390,11 +3384,13 @@ <translation id="6198102561359457428">Αποσυνδεθείτε και συνδεθείτε ξανά...</translation> <translation id="6198252989419008588">Αλλαγή PIN</translation> <translation id="6199801702437275229">Αναμονή για πληροφορίες χώρου...</translation> +<translation id="6204015976622790023">Δείτε σχετικές προτάσεις από τον Βοηθό σχετικά με το περιεχόμενο που εμφανίζεται στην οθόνη σας.</translation> <translation id="6205710420833115353">Ορισμένες λειτουργίες διαρκούν περισσότερο από το αναμενόμενο. Θέλετε να τις ματαιώσετε;</translation> <translation id="6206311232642889873">Αντι&γραφή Εικόνας</translation> <translation id="6207200176136643843">Επαναφορά στο προεπιλεγμένο επίπεδο εστίασης</translation> <translation id="620722923698527029">Να ανοίγουν πάντα αυτοί οι τύποι συνδέσμων στη συσχετισμένη εφαρμογή</translation> <translation id="6207937957461833379">Χώρα/Περιοχή</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Ο συγχρονισμός δεν λειτουργεί</translation> <translation id="6212039847102026977">Προβολή σύνθετων ιδιοτήτων δικτύου</translation> <translation id="6212168817037875041">Απενεργοποίηση οθόνης</translation> <translation id="6212752530110374741">Σύνδεσμος ηλεκτρονικού ταχυδρομείου</translation> @@ -3432,7 +3428,6 @@ <translation id="6263541650532042179">επαναφορά συγχρονισμού</translation> <translation id="6264365405983206840">Επιλογή Όλ&ων</translation> <translation id="6264422956566238156">Ενεργοποιήσατε τον συγχρονισμό</translation> -<translation id="6265930187414222160">Τέλος! Το επιβλαβές λογισμικό καταργήθηκε.</translation> <translation id="6267166720438879315">Επιλέξτε ένα πιστοποιητικό για την επαλήθευση της ταυτότητάς σας στον κεντρικό υπολογιστή <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Άνοιγμα με <ph name="APP" /></translation> <translation id="6268747994388690914">Εισαγωγή σελιδοδεικτών από αρχείο HTML...</translation> @@ -3539,7 +3534,6 @@ Κάντε κλικ στο "Επόμενο" για να συνεχίσετε τη σύνδεση στον λογαριασμό σας <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Φόρτωση ανεπτυγμένης επέκτασης</translation> <translation id="642282551015776456">Αυτό το όνομα δεν μπορεί να χρησιμοποιηθεί ως όνομα αρχείου ή φακέλου</translation> -<translation id="6423239382391657905">Άνοιγμα VPN</translation> <translation id="6426200009596957090">Άνοιγμα ρυθμίσεων ChromeVox</translation> <translation id="6429384232893414837">Σφάλμα ενημέρωσης</translation> <translation id="6430814529589430811">ASCII με κωδικοποίηση Base64, πιστοποιητικό</translation> @@ -3620,7 +3614,6 @@ <translation id="6544215763872433504">Το πρόγραμμα περιήγησης από την Google, για εσάς</translation> <translation id="6545665334409411530">Ρυθμός επανάληψης</translation> <translation id="6545834809683560467">Χρησιμοποιήστε την υπηρεσία προβλέψεων για να συμπληρώσετε τις αναζητήσεις και τις διευθύνσεις URL που πληκτρολογείτε στη γραμμή διευθύνσεων ή το πλαίσιο αναζήτησης της Εφαρμογής εκκίνησης.</translation> -<translation id="6546686722964485737">Συμμετοχή στο δίκτυο Wimax</translation> <translation id="6547316139431024316">Να μη γίνει ξανά προειδοποίηση γι' αυτήν την επέκταση</translation> <translation id="6547354035488017500">Ελευθερώστε χώρο 512 MB τουλάχιστον, διαφορετικά η συσκευή σας θα σταματήσει να ανταποκρίνεται. Για να ελευθερώσετε χώρο, διαγράψτε αρχεία από τον αποθηκευτικό χώρο της συσκευής.</translation> <translation id="6549689063733911810">Πρόσφατα</translation> @@ -4039,7 +4032,6 @@ <translation id="7201014958346994077">Δεν είναι δυνατή η προβολή Αρχείων Linux</translation> <translation id="720110658997053098">Μόνιμη διατήρηση της παρούσας συσκευής σε λειτουργία Kiosk</translation> <translation id="7201118060536064622">Το "<ph name="DELETED_ITEM_NAME" />" διαγράφηκε</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Γίνεται λήψη της προσθήκης <ph name="PLUGIN_NAME" />…</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Έξοδος από τη σελίδα}other{Έξοδος από τις σελίδες}}</translation> <translation id="7216409898977639127">Πάροχος δικτύου κινητής τηλεφωνίας</translation> @@ -4517,7 +4509,6 @@ <translation id="7909969815743704077">Έγινε λήψη στην ανώνυμη περιήγηση</translation> <translation id="7910768399700579500">Νέος &φάκελος</translation> <translation id="7912080627461681647">Ο κωδικός πρόσβασής σας έχει αλλάξει στον διακομιστή. Αποσυνδεθείτε και συνδεθείτε ξανά.</translation> -<translation id="7912883689016444961">Διαμόρφωση δικτύου κινητής τηλεφωνίας</translation> <translation id="7915471803647590281">Πριν από την αποστολή σχολίων, πείτε μας τι συμβαίνει.</translation> <translation id="7916556741383518510">Όταν κάνετε κλικ</translation> <translation id="792514962475806987">Επίπεδο εστίασης σε παράθυρο:</translation> @@ -4571,7 +4562,6 @@ <translation id="7988355189918024273">Ενεργοποιήστε τις λειτουργίες προσβασιμότητας</translation> <translation id="7994702968232966508">Μέθοδος EAP</translation> <translation id="799547531016638432">Κατάργηση συντόμευσης</translation> -<translation id="7997479212858899587">Ταυτότητα:</translation> <translation id="7997826902155442747">Προτεραιότητα διεργασίας</translation> <translation id="7999229196265990314">Δημιουργήθηκαν τα παρακάτω αρχεία: @@ -4655,7 +4645,6 @@ <translation id="8105368624971345109">Απενεργοποίηση</translation> <translation id="8106045200081704138">Κοινόχρηστο με εμένα</translation> <translation id="8107015733319732394">Εγκατάσταση του Google Play Store στη συσκευή σας <ph name="DEVICE_TYPE" />. Αυτό μπορεί να διαρκέσει μερικά λεπτά.</translation> -<translation id="8109930990200908494">Απαιτείται σύνδεση για πιστοποιητικό χρήστη.</translation> <translation id="8111155949205007504">Κοινοποίηση αυτού του κωδικού πρόσβασης στο iPhone σας</translation> <translation id="8113043281354018522">Επιλογή τύπου άδειας</translation> <translation id="8116190140324504026">Περισσότερες πληροφορίες...</translation> @@ -4666,6 +4655,7 @@ <translation id="8118860139461251237">Διαχείριση των λήψεών σας</translation> <translation id="81238879832906896">Κίτρινο και λευκό λουλούδι</translation> <translation id="8124313775439841391">ONC με ιδιότητες διαχείρισης</translation> +<translation id="8125562866093998907">Ο ιστότοπος θέλει να επαληθεύσει το Κλειδί ασφαλείας σας για πρόσθετη ασφάλεια για τον λογαριασμό σας.</translation> <translation id="813082847718468539">Προβολή πληροφοριών τοποθεσίας</translation> <translation id="8131740175452115882">Επιβεβαίωση</translation> <translation id="8133676275609324831">&Εμφάνιση στο φάκελο</translation> @@ -4776,7 +4766,6 @@ <translation id="8308179586020895837">Ερώτηση αν το <ph name="HOST" /> επιθυμεί να αποκτήσει πρόσβαση στην κάμερά σας</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Το πιστοποιητικό υπάρχει ήδη</translation> -<translation id="8309505303672555187">Επιλέξτε δίκτυο:</translation> <translation id="8312871300878166382">Επικόλληση στο φάκελο</translation> <translation id="8317671367883557781">Προσθήκη σύνδεσης δικτύου</translation> <translation id="8319414634934645341">Εκτεταμένη χρήση κλειδιού</translation> @@ -4851,7 +4840,6 @@ <translation id="8451512073679317615">βοηθός</translation> <translation id="8452135315243592079">Κάρτα SIM που λείπει</translation> <translation id="8453482423012550001">Αντιγραφή $1 στοιχείων…</translation> -<translation id="8454288007744638700">Εναλλακτικά, επιλέξτε ένα νέο δίκτυο:</translation> <translation id="845627346958584683">Χρόνος λήξης</translation> <translation id="8456681095658380701">Μη έγκυρο όνομα</translation> <translation id="8457451314607652708">Εισαγωγή σελιδοδεικτών</translation> @@ -4915,6 +4903,7 @@ <translation id="855081842937141170">Καρφίτσωμα καρτέλας</translation> <translation id="8551388862522347954">Άδειες</translation> <translation id="8553342806078037065">Διαχείριση άλλων ατόμων</translation> +<translation id="8554899698005018844">Καμία γλώσσα</translation> <translation id="855773602626431402">Παρεμποδίστηκε η εκτέλεση μιας προσθήκης εκτός περιβάλλοντος δοκιμών σε αυτήν τη σελίδα.</translation> <translation id="8557930019681227453">Μανιφέστο</translation> <translation id="8559694214572302298">Εργαλείο αποκωδικοποίησης εικόνων</translation> @@ -4952,7 +4941,6 @@ <translation id="862727964348362408">Σε αναστολή</translation> <translation id="862750493060684461">Προσωρινή μνήμη CSS</translation> <translation id="8627795981664801467">Μόνο ασφαλείς συνδέσεις</translation> -<translation id="8628085465172583869">Όνομα κεντρικού υπολογιστή διακομιστή:</translation> <translation id="8630903300770275248">Εισαγωγή χρήστη υπό επίβλεψη</translation> <translation id="8631032106121706562">Πέταλα</translation> <translation id="8637542770513281060">Ο υπολογιστής σας περιέχει μια ασφαλή λειτουργική μονάδα, η οποία χρησιμοποιείται για την εφαρμογή πολλών κρίσιμων λειτουργιών ασφαλείας στο Chrome OS. Επισκεφτείτε το Κέντρο βοήθειας του Chromebook, για να μάθετε περισσότερα: https://support.google.com/chromebook/?p=sm</translation> @@ -5206,7 +5194,6 @@ <translation id="899403249577094719">Βασική διεύθυνση URL πιστοποιητικού Netscape</translation> <translation id="8995603266996330174">Έγινε διαχείριση από <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Προσθήκη λογαριασμού…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Δημιουργία εικόνας δίσκου.</translation> <translation id="9003647077635673607">Να επιτρέπεται σε όλους τους ιστότοπους</translation> <translation id="9003677638446136377">Έλεγχος ξανά</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb index fc0a91ba..80c8592 100644 --- a/chrome/app/resources/generated_resources_en-GB.xtb +++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Almost time for a break</translation> <translation id="1062407476771304334">Replace</translation> -<translation id="1064835277883315402">Join private network</translation> <translation id="1064912851688322329">Disconnect your Google Account</translation> <translation id="1067048845568873861">Created</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Searching...</translation> <translation id="1316495628809031177">Sync is paused</translation> <translation id="1319979322914001937">An app that shows a filtered list of extensions from Chrome Web Store. Extensions in the list can be installed directly from the app.</translation> -<translation id="132090119144658135">Subject Match:</translation> <translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> <translation id="1327074568633507428">Printer on Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -491,7 +489,6 @@ <translation id="1701062906490865540">Remove this person</translation> <translation id="1706586824377653884">Added by your administrator</translation> <translation id="1706625117072057435">Zoom levels</translation> -<translation id="1707463636381878959">Share this network with other users</translation> <translation id="1708338024780164500">(Inactive)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Native)</translation> @@ -527,7 +524,6 @@ <translation id="175772926354468439">Enable theme</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">View in Chrome Web Store</translation> -<translation id="1758831820837444715">Configure Ethernet network</translation> <translation id="1763046204212875858">Create application shortcuts</translation> <translation id="1763108912552529023">Keep exploring</translation> <translation id="1763808908432309942">Opens in a new tab</translation> @@ -876,7 +872,6 @@ <translation id="2291643155573394834">Next tab</translation> <translation id="2292848386125228270">Please start <ph name="PRODUCT_NAME" /> as a normal user. If you need to run as root for development, re-run with the – no-sandbox flag.</translation> <translation id="2294358108254308676">Do you want to install <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP method:</translation> <translation id="2297705863329999812">Search printers</translation> <translation id="2300383962156589922">Customise and control <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Extension root directory is invalid.</translation> @@ -934,7 +929,6 @@ <translation id="2379281330731083556">Print using system dialogue... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Ask before sending (recommended)</translation> <translation id="2384436799579181135">An error has occurred. Please check your printer and try again.</translation> -<translation id="2385700042425247848">Service name:</translation> <translation id="2387458720915042159">Proxy connection type</translation> <translation id="2391419135980381625">Standard font</translation> <translation id="2391762656119864333">Revoke</translation> @@ -985,7 +979,6 @@ <translation id="247949520305900375">Share audio</translation> <translation id="2480868415629598489">Modify data that you copy and paste</translation> <translation id="2482878487686419369">Notifications</translation> -<translation id="2485056306054380289">Server CA certificate:</translation> <translation id="2485422356828889247">Uninstall</translation> <translation id="2487067538648443797">Add new bookmark</translation> <translation id="248861575772995840">Can’t find your phone. Make sure that your <ph name="DEVICE_TYPE" />'s Bluetooth is turned on. <a>Learn more</a></translation> @@ -1109,7 +1102,6 @@ <translation id="2653659639078652383">Submit</translation> <translation id="265390580714150011">Field Value</translation> <translation id="2654166010170466751">Allow sites to install payment handlers</translation> -<translation id="2655386581175833247">User certificate:</translation> <translation id="2660779039299703961">Event</translation> <translation id="266079277508604648">Can’t connect to printer. Check that the printer is turned on and is connected to your Chromebook by Wi-Fi or USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1409,7 +1401,6 @@ <translation id="3100609564180505575">Modules (<ph name="TOTAL_COUNT" />) - Known conflicts: <ph name="BAD_COUNT" />, suspected: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Date and time</translation> <translation id="310671807099593501">Site is using Bluetooth</translation> -<translation id="3108967419958202225">Choose...</translation> <translation id="3115128645424181617">Can’t find your phone. Make sure that it’s handy and Bluetooth is turned on.</translation> <translation id="3115147772012638511">Waiting for cache...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Help</translation> @@ -1454,7 +1445,6 @@ <translation id="3165390001037658081">Some operators might block this feature.</translation> <translation id="316854673539778496">To get all your extensions on all your devices, sign in and turn on sync.</translation> <translation id="3170072451822350649">You may also skip signing in and <ph name="LINK_START" />browse as Guest<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Click to hide password</translation> <translation id="3177909033752230686">Page language:</translation> <translation id="3181110748548073003">Press |<ph name="SHORTCUT" />| to go forward</translation> <translation id="3182749001423093222">Spell check</translation> @@ -1485,7 +1475,6 @@ <translation id="3236289833370040187">Ownership will be transferred to <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Open extension options</translation> <translation id="3241680850019875542">Select the root directory of the extension to pack. To update an extension, also select the private key file to reuse.</translation> -<translation id="3242765319725186192">Preshared key:</translation> <translation id="3244294424315804309">Continue muting sound</translation> <translation id="3245321423178950146">Unknown Artist</translation> <translation id="3246097286174000800">Try Smart Lock</translation> @@ -1618,7 +1607,6 @@ <translation id="3440663250074896476">More actions for <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Ask when a site wants to use a plug-in to access your computer</translation> <translation id="3441653493275994384">Screen</translation> -<translation id="3445830502289589282">Phase 2 authentication:</translation> <translation id="344630545793878684">Read your data on a number of websites</translation> <translation id="3449839693241009168">Press <ph name="SEARCH_KEY" /> to send commands to <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Idle State Occupancy Percentage</translation> @@ -1659,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> errors.</translation> <translation id="3495660573538963482">Google Assistant settings</translation> <translation id="3496213124478423963">Zoom Out</translation> -<translation id="3504135463003295723">Group name:</translation> <translation id="3505030558724226696">Revoke device access</translation> <translation id="3507421388498836150">Current Permissions for "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Remove Linux Apps for Chromebook</translation> @@ -1768,7 +1755,6 @@ <translation id="3661054927247347545">Sign in certification is not valid, window closing in <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Extension Icon</translation> <translation id="3665589677786828986">Chrome detected that some of your settings were corrupted by another program and reset them to their original defaults.</translation> -<translation id="3665842570601375360">Security:</translation> <translation id="3668570675727296296">Language settings</translation> <translation id="3668823961463113931">Handlers</translation> <translation id="3670229581627177274">Turn on Bluetooth</translation> @@ -1807,7 +1793,6 @@ <translation id="3726463242007121105">This device cannot be opened because its file system is not supported.</translation> <translation id="3727148787322499904">Changing this setting will affect all shared networks</translation> <translation id="3727187387656390258">Inspect pop-up</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Error on line <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL Server with Step-up</translation> <translation id="3737536731758327622">Your downloads appear here</translation> @@ -1882,7 +1867,6 @@ <translation id="38275787300541712">Press Enter when you've finished</translation> <translation id="3827774300009121996">&Full Screen</translation> <translation id="3828029223314399057">Search bookmarks</translation> -<translation id="3829932584934971895">Provider type:</translation> <translation id="3830674330436234648">No playback available.</translation> <translation id="3831486154586836914">Entered window overview mode</translation> <translation id="383161972796689579">The owner of this device has disabled new users from being added</translation> @@ -1981,7 +1965,6 @@ <translation id="3968261067169026421">Could not set up network</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Calculating...</translation> -<translation id="3974195870082915331">Click to show password</translation> <translation id="3975222297214566386">Input options bubble</translation> <translation id="397703832102027365">Finalising...</translation> <translation id="3979395879372752341">New extension added (<ph name="EXTENSION_NAME" />)</translation> @@ -2229,7 +2212,6 @@ <translation id="4419556793104466535">Control sync, personalisation and more</translation> <translation id="4421932782753506458">Fluffy</translation> <translation id="4422347585044846479">Edit bookmark for this page</translation> -<translation id="4423104065312875417">Install additional speech engines</translation> <translation id="4423376891418188461">Restore Settings</translation> <translation id="4423482519432579560">&Spellcheck</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, your administrator requires you to change your password.</translation> @@ -2254,7 +2236,6 @@ <translation id="4449996769074858870">This tab is playing audio.</translation> <translation id="4450974146388585462">Diagnose</translation> <translation id="4453946976636652378">Search <ph name="SEARCH_ENGINE_NAME" /> or type a URL</translation> -<translation id="445923051607553918">Join Wi-Fi network</translation> <translation id="4462159676511157176">Custom name servers</translation> <translation id="4467100756425880649">Chrome Web Store Gallery</translation> <translation id="4467101674048705704">Expand <ph name="FOLDER_NAME" /></translation> @@ -2860,7 +2841,6 @@ <translation id="5380103295189760361">Hold Control, Alt, Shift or Search to see keyboard shortcuts for those modifiers.</translation> <translation id="5382591305415226340">Manage supported links</translation> <translation id="5384883051496921101">This site is about to share information with an app outside of incognito mode.</translation> -<translation id="5388588172257446328">Username:</translation> <translation id="5388885445722491159">Paired</translation> <translation id="5389237414310520250">The new user couldn't be created. Please check your hard drive space and permissions and try again.</translation> <translation id="5390100381392048184">Allow sites to play sound</translation> @@ -2985,7 +2965,6 @@ <translation id="5551573675707792127">Keyboard and text input</translation> <translation id="5553089923092577885">Certificate Policy Mappings</translation> <translation id="5554489410841842733">This icon will be visible when the extension can act on the current page.</translation> -<translation id="5554573843028719904">Other Wi-Fi network...</translation> <translation id="5554720593229208774">Email Certification Authority</translation> <translation id="5556206011531515970">Click next to choose your default browser.</translation> <translation id="5556459405103347317">Reload</translation> @@ -3026,7 +3005,6 @@ <translation id="5610038042047936818">Switch to camera mode</translation> <translation id="5612720917913232150"><ph name="URL" /> wants to use your computer's location</translation> <translation id="5612734644261457353">Sorry, your password still could not be verified. Note: if you changed your password recently, your new password will be applied once you sign out, please use the old password here.</translation> -<translation id="5613695965848159202">Anonymous identity:</translation> <translation id="5614190747811328134">User Notice</translation> <translation id="561698261642843490">Close Firefox</translation> <translation id="5618075537869101857">Oh no, the kiosk application could not be launched.</translation> @@ -3244,7 +3222,6 @@ <translation id="5941343993301164315">Please sign in to <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimise</translation> <translation id="5946591249682680882">Report ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Add private network</translation> <translation id="5949544233750246342">Unable to parse file</translation> <translation id="5955282598396714173">Your password has expired. Please sign out then sign in again to change it.</translation> <translation id="5956585768868398362">Is this the search page that you were expecting?</translation> @@ -3449,7 +3426,6 @@ <translation id="6263541650532042179">reset sync</translation> <translation id="6264365405983206840">Select &All</translation> <translation id="6264422956566238156">You've turned on Sync</translation> -<translation id="6265930187414222160">Done! Harmful software removed.</translation> <translation id="6267166720438879315">Select a certificate to which you want to authenticate <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Open with <ph name="APP" /></translation> <translation id="6268747994388690914">Import Bookmarks from HTML File...</translation> @@ -3556,7 +3532,6 @@ Please click "Next" to continue signing in to your <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> account.</translation> <translation id="6419546358665792306">Load unpacked</translation> <translation id="642282551015776456">This name may not be used as a file or folder name</translation> -<translation id="6423239382391657905">Open VPN</translation> <translation id="6426200009596957090">Open ChromeVox settings</translation> <translation id="6429384232893414837">Update error</translation> <translation id="6430814529589430811">Base64-encoded ASCII, single certificate</translation> @@ -3637,7 +3612,6 @@ <translation id="6544215763872433504">The web browser by Google, for you</translation> <translation id="6545665334409411530">Repeat rate</translation> <translation id="6545834809683560467">Use a prediction service to help complete searches and URLs typed in the address bar or the app launcher search box</translation> -<translation id="6546686722964485737">Join WiMAX network</translation> <translation id="6547316139431024316">Don't warn again for this extension</translation> <translation id="6547354035488017500">Free up at least 512 MB of space or your device will become unresponsive. To free up space, delete files from device storage.</translation> <translation id="6549689063733911810">Recent</translation> @@ -4056,7 +4030,6 @@ <translation id="7201014958346994077">Unable to view Linux Files</translation> <translation id="720110658997053098">Permanently keep this device in kiosk mode</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' deleted</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Downloading <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Exit page}other{Exit pages}}</translation> <translation id="7216409898977639127">Mobile provider</translation> @@ -4534,7 +4507,6 @@ <translation id="7909969815743704077">Downloaded in Incognito</translation> <translation id="7910768399700579500">&New folder</translation> <translation id="7912080627461681647">Your password has been changed on the server. Please sign out then sign in again.</translation> -<translation id="7912883689016444961">Configure mobile network</translation> <translation id="7915471803647590281">Please tell us what is happening before sending the feedback.</translation> <translation id="7916556741383518510">On Click</translation> <translation id="792514962475806987">Docked zoom level:</translation> @@ -4588,7 +4560,6 @@ <translation id="7988355189918024273">Enable accessibility features</translation> <translation id="7994702968232966508">EAP method</translation> <translation id="799547531016638432">Remove shortcut</translation> -<translation id="7997479212858899587">Identity:</translation> <translation id="7997826902155442747">Process Priority</translation> <translation id="7999229196265990314">Created the following files: @@ -4672,7 +4643,6 @@ <translation id="8105368624971345109">Turn Off</translation> <translation id="8106045200081704138">Shared with me</translation> <translation id="8107015733319732394">Installing the Google Play Store on your <ph name="DEVICE_TYPE" />. This could take a few minutes.</translation> -<translation id="8109930990200908494">Sign-in required for user certificate.</translation> <translation id="8111155949205007504">Share this password with your iPhone</translation> <translation id="8113043281354018522">Choose license type</translation> <translation id="8116190140324504026">More info...</translation> @@ -4794,7 +4764,6 @@ <translation id="8308179586020895837">Ask if <ph name="HOST" /> wants to access your camera</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certificate already exists</translation> -<translation id="8309505303672555187">Select a network:</translation> <translation id="8312871300878166382">Paste into folder</translation> <translation id="8317671367883557781">Add network connection</translation> <translation id="8319414634934645341">Extended Key Usage</translation> @@ -4869,7 +4838,6 @@ <translation id="8451512073679317615">assistant</translation> <translation id="8452135315243592079">Missing SIM card</translation> <translation id="8453482423012550001">Copying $1 items...</translation> -<translation id="8454288007744638700">Or, select a new network:</translation> <translation id="845627346958584683">Expiry Time</translation> <translation id="8456681095658380701">Invalid name</translation> <translation id="8457451314607652708">Import bookmarks</translation> @@ -4971,7 +4939,6 @@ <translation id="862727964348362408">Suspended</translation> <translation id="862750493060684461">CSS cache</translation> <translation id="8627795981664801467">Secure connections only</translation> -<translation id="8628085465172583869">Server hostname:</translation> <translation id="8630903300770275248">Import supervised user</translation> <translation id="8631032106121706562">Petals</translation> <translation id="8637542770513281060">Your computer contains a secure module, which is used to implement many critical security features in Chrome OS. Visit the Chromebook Help Centre to learn more: https://support.google.com/chromebook/?p=sm</translation> @@ -5227,7 +5194,6 @@ <translation id="899403249577094719">Netscape Certificate Base URL</translation> <translation id="8995603266996330174">Managed by <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Add account...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Creating disk image.</translation> <translation id="9003647077635673607">Allow on all websites</translation> <translation id="9003677638446136377">Check again</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb index 650b34b..91827501 100644 --- a/chrome/app/resources/generated_resources_es-419.xtb +++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Casi es hora de un descanso</translation> <translation id="1062407476771304334">Reemplazar</translation> -<translation id="1064835277883315402">Conectarse a una red privada</translation> <translation id="1064912851688322329">Desconecta tu cuenta de Google.</translation> <translation id="1067048845568873861">Creada</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Buscando...</translation> <translation id="1316495628809031177">Se pausó la sincronización</translation> <translation id="1319979322914001937">Se trata de una aplicación que muestra una lista filtrada de extensiones de Chrome Web Store. Las extensiones de la lista se pueden instalar directamente desde la aplicación.</translation> -<translation id="132090119144658135">Coincidencia de asunto:</translation> <translation id="1326317727527857210">Accede a Chrome para obtener las pestañas de tus otros dispositivos.</translation> <translation id="1327074568633507428">Impresora en Google Cloud Print</translation> <translation id="1327977588028644528">Puerta de enlace</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">Ventana de la app</translation> <translation id="1534389735079119190">ERROR: No se pudo iniciar el contenedor en la VM.</translation> <translation id="15373452373711364">Cursor del mouse grande</translation> +<translation id="1540605929960647700">Activar el modo de demostración</translation> <translation id="1543284117603151572">Importados desde Edge</translation> <translation id="1545177026077493356">Modo kiosco automático</translation> <translation id="1545775234664667895">Tema instalado "<ph name="THEME_NAME" />"</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">Ayúdanos a <ph name="PRODUCT_NAME" /> mejorar enviando automáticamente estadísticas de uso e informes de fallos a Google.</translation> <translation id="1658424621194652532">Esta página está accediendo al micrófono.</translation> <translation id="1660204651932907780">Permitir que los sitios reproduzcan sonido (recomendado)</translation> +<translation id="1660938185063657230">Verificar la llave de seguridad</translation> <translation id="1661156625580498328">Implementa la encriptación AES (recomendado).</translation> <translation id="1661245713600520330">Esta página enumera todos los módulos que se cargaron en el proceso principal y los módulos registrados para cargarse más adelante.</translation> <translation id="166179487779922818">La contraseña es demasiado corta.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">No permitir que los sitios vean el texto ni las imágenes copiados en el portapapeles</translation> <translation id="1682548588986054654">Nueva ventana de incógnito</translation> <translation id="168715261339224929">Activa la sincronización para que tus favoritos estén en todos tus dispositivos.</translation> +<translation id="1688867105868176567">¿Quieres borrar los datos del sitio?</translation> <translation id="1688935057616748272">Escribe una letra</translation> <translation id="168991973552362966">Agregar una impresora cercana</translation> <translation id="1689945336726856614">Copiar &URL</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">Eliminar a esta persona</translation> <translation id="1706586824377653884">Agregado por el administrador</translation> <translation id="1706625117072057435">Niveles de zoom</translation> -<translation id="1707463636381878959">Compartir esta red con otros usuarios</translation> <translation id="1708338024780164500">(Inactiva)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> × <ph name="HEIGHT" /> (resolución nativa)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">Habilitar tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Ver en Chrome Web Store</translation> -<translation id="1758831820837444715">Configurar la red Ethernet</translation> <translation id="1763046204212875858">Crear accesos directos a aplicaciones</translation> <translation id="1763108912552529023">Seguir explorando</translation> <translation id="1763808908432309942">Se abre en una pestaña nueva</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">Cambiar la forma de compartir este archivo</translation> <translation id="1841545962859478868">Es posible que el administrador de dispositivos supervise lo siguiente:</translation> <translation id="1841705068325380214">Se inhabilitó la extensión <ph name="EXTENSION_NAME" /></translation> +<translation id="1842766183094193446">¿Realmente quieres habilitar el modo de demostración?</translation> <translation id="1844692022597038441">Este archivo no está disponible sin conexión.</translation> <translation id="1846308012215045257">Presionar Ctrl+clic para ejecutar <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Guardado</translation> <translation id="1848219224579402567">Salir cuando se cierra la tapa</translation> <translation id="184823282865851239">Bloquear si el sitio tiende a mostrar anuncios intrusivos</translation> <translation id="1849186935225320012">Esta página tiene el control total de los dispositivos MIDI.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">Puedes cambiar esta opción más tarde en Configuración</translation> <translation id="2006638907958895361">Abrir vínculo en <ph name="APP" /></translation> <translation id="2007404777272201486">Informar de un problema...</translation> +<translation id="2016237810978710652">Abriendo archivos de Linux…</translation> <translation id="2016430552235416146">Tradicional</translation> <translation id="2017334798163366053">Inhabilitar recopilación de datos de rendimiento</translation> <translation id="2017836877785168846">Borra el historial y las opciones de autocompletado en la barra de direcciones.</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">Editar tarjeta</translation> <translation id="2154710561487035718">Copiar URL</translation> <translation id="2155772377859296191">Resolución: <ph name="WIDTH" /> × <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Para mejorar la Navegación segura, envía información del sistema y contenido de la página a Google.</translation> <translation id="215753907730220065">Salir de pantalla completa</translation> <translation id="2157875535253991059">Esta página está en modo de pantalla completa.</translation> <translation id="216169395504480358">Agregar Wi-Fi</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">Agregar la ID de la solicitud a este dispositivo</translation> <translation id="2175042898143291048">Realizar siempre esta acción</translation> <translation id="2175607476662778685">Barra de inicio rápido</translation> +<translation id="2176087259161165020">Otras fuentes</translation> <translation id="2177950615300672361">Pestaña de incógnito: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">El complemento <ph name="PEPPER_PLUGIN_NAME" /> del dominio <ph name="PEPPER_PLUGIN_DOMAIN" /> desea acceder a tu computadora</translation> <translation id="2178614541317717477">Compromiso de entidad de certificación</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">Siguiente pestaña</translation> <translation id="2292848386125228270">Inicia <ph name="PRODUCT_NAME" /> como usuario normal. Si necesitas ejecutarlo como administrador para su desarrollo, vuelve a ejecutarlo con la marca --no-sandbox.</translation> <translation id="2294358108254308676">¿Deseas instalar <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Método EAP:</translation> <translation id="2297705863329999812">Buscar impresoras</translation> <translation id="2300383962156589922">Personaliza y controla <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">El directorio de raíz de la extensión no es válido.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">ERROR: No se pudo desinstalar <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Agregar uso compartido del archivo</translation> <translation id="2367972762794486313">Mostrar aplicaciones</translation> +<translation id="2369536625682139252">Se borrarán todos los datos que almacenó <ph name="SITE" />, excepto las cookies.</translation> <translation id="2371076942591664043">Abrir al &finalizar</translation> <translation id="2377319039870049694">Cambiar a la vista de lista</translation> <translation id="2377667304966270281">Fallos graves</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">Imprimir mediante el sistema de diálogo... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Preguntar antes de enviar (recomendado)</translation> <translation id="2384436799579181135">Se produjo un error. Revisa la impresora y vuelve a intentarlo.</translation> -<translation id="2385700042425247848">Nombre del servicio:</translation> <translation id="2387458720915042159">Tipo de conexión proxy</translation> <translation id="2391419135980381625">Fuente estándar</translation> <translation id="2391762656119864333">Revocar</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">Compartir audio</translation> <translation id="2480868415629598489">Modificar los datos copiados y pegados</translation> <translation id="2482878487686419369">Notificaciones</translation> -<translation id="2485056306054380289">Certificado CA del servidor:</translation> <translation id="2485422356828889247">Desinstalación</translation> <translation id="2487067538648443797">Agregar un favorito nuevo</translation> <translation id="248861575772995840">No se puede encontrar el teléfono. Asegúrate de que tu dispositivo <ph name="DEVICE_TYPE" /> tenga Bluetooth encendido. <a>Más información</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">Usa la función Powerwash para restablecer el dispositivo <ph name="IDS_SHORT_PRODUCT_NAME" /> y que quede como nuevo.</translation> <translation id="2567257616420533738">Se guardó la contraseña. Visualiza y administra las contraseñas guardadas en <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Contenedor de la barra de información</translation> +<translation id="2570454805927264159">Aprovecha tu Asistente al máximo</translation> <translation id="257088987046510401">Temas</translation> <translation id="2572032849266859634">Se concedió acceso de solo lectura a <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Selecciona una imagen y un nombre</translation> @@ -1096,7 +1099,6 @@ <translation id="2653659639078652383">Enviar</translation> <translation id="265390580714150011">Valor de campo</translation> <translation id="2654166010170466751">Permitir que los sitios instalen controladores de pago</translation> -<translation id="2655386581175833247">Certificado de usuario:</translation> <translation id="2660779039299703961">Evento</translation> <translation id="266079277508604648">No se puede establecer conexión con la impresora. Comprueba que esté encendida y conectada a la Chromebook mediante Wi-Fi o USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1329,6 +1331,7 @@ <translation id="3006881078666935414">No hay datos de uso</translation> <translation id="3007214526293698309">Fijar proporción</translation> <translation id="3007771295016901659">Duplicar pestaña</translation> +<translation id="3008272652534848354">Restablecer permisos</translation> <translation id="3009300415590184725">¿Estás seguro de que deseas cancelar el proceso de configuración del servicio de datos para celulares?</translation> <translation id="3009779501245596802">Bases de datos indexadas</translation> <translation id="3010279545267083280">Contraseña eliminada</translation> @@ -1395,7 +1398,6 @@ <translation id="3100609564180505575">Módulos (<ph name="TOTAL_COUNT" />) - conflictos conocidos: <ph name="BAD_COUNT" />, supuestos: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Fecha y hora</translation> <translation id="310671807099593501">El sitio está usando la conexión Bluetooth</translation> -<translation id="3108967419958202225">Elige...</translation> <translation id="3115128645424181617">No se puede encontrar el teléfono. Asegúrate de que esté cerca y de que Bluetooth esté activado.</translation> <translation id="3115147772012638511">Esperando caché...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Ayuda</translation> @@ -1440,7 +1442,6 @@ <translation id="3165390001037658081">Es posible que algunos proveedores bloqueen esta función.</translation> <translation id="316854673539778496">Para obtener todas tus extensiones en todos los dispositivos, accede a tu cuenta y activa la sincronización.</translation> <translation id="3170072451822350649">También puedes omitir el acceso y <ph name="LINK_START" />navegar como invitado<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Haz clic para ocultar la contraseña</translation> <translation id="3177909033752230686">Idioma de la página:</translation> <translation id="3181110748548073003">Presionar |<ph name="SHORTCUT" />| para avanzar</translation> <translation id="3182749001423093222">Corrector ortográfico</translation> @@ -1471,7 +1472,6 @@ <translation id="3236289833370040187">La propiedad se transferirá al dominio <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Abrir opciones de extensión</translation> <translation id="3241680850019875542">Seleccionar el directorio de raíz de la extensión que debe empaquetarse. Para actualizar una extensión, también debes seleccionar el archivo de clave privada que será reutilizado.</translation> -<translation id="3242765319725186192">Clave previamente compartida:</translation> <translation id="3244294424315804309">Continuar silenciando el sonido</translation> <translation id="3245321423178950146">Artista desconocido</translation> <translation id="3246097286174000800">Probar Smart Lock</translation> @@ -1604,7 +1604,6 @@ <translation id="3440663250074896476">Más acciones para <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Preguntarme cuando un sitio intente usar un complemento para acceder a mi computadora</translation> <translation id="3441653493275994384">Pantalla</translation> -<translation id="3445830502289589282">Autenticación de fase 2:</translation> <translation id="344630545793878684">Leer los datos en un número de sitios web</translation> <translation id="3449839693241009168">Presiona <ph name="SEARCH_KEY" /> para enviar comandos a<ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Porcentaje de ocupación de estado de inactividad</translation> @@ -1645,7 +1644,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> errores</translation> <translation id="3495660573538963482">Configuración del Asistente de Google</translation> <translation id="3496213124478423963">Alejar</translation> -<translation id="3504135463003295723">Nombre del grupo:</translation> <translation id="3505030558724226696">Revocar el acceso al dispositivo</translation> <translation id="3507421388498836150">Permisos actuales para "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Quitar las apps de Linux para la Chromebook</translation> @@ -1754,7 +1752,6 @@ <translation id="3661054927247347545">La certificación de acceso no es válida. La ventana se cerrará en <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ícono de extensión</translation> <translation id="3665589677786828986">Chrome detectó que otro programa dañó algunas opciones de configuración, por lo que la restableció a los valores predeterminados.</translation> -<translation id="3665842570601375360">Seguridad:</translation> <translation id="3668570675727296296">Configuración de idiomas</translation> <translation id="3668823961463113931">Controladores</translation> <translation id="3670229581627177274">Activar Bluetooth</translation> @@ -1793,7 +1790,6 @@ <translation id="3726463242007121105">Este dispositivo no puede abrirse porque su sistema de archivos no es compatible.</translation> <translation id="3727148787322499904">Si cambias esta configuración, las redes compartidas se verán afectadas</translation> <translation id="3727187387656390258">Inspeccionar ventana emergente</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Error en la línea <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Servidor SLL con suplemento especial</translation> <translation id="3737536731758327622">Tus descargas aparecen aquí</translation> @@ -1868,7 +1864,6 @@ <translation id="38275787300541712">Presiona Intro al terminar</translation> <translation id="3827774300009121996">&Pantalla completa</translation> <translation id="3828029223314399057">Buscar favoritos</translation> -<translation id="3829932584934971895">Tipo de proveedor:</translation> <translation id="3830674330436234648">No hay reproducciones disponibles</translation> <translation id="3831486154586836914">Modo de vista general de ventana activado</translation> <translation id="383161972796689579">El propietario de este dispositivo ha inhabilitado a nuevos usuarios para evitar que se agreguen.</translation> @@ -1889,6 +1884,7 @@ <translation id="3856921555429624101">Se terminó de medir el uso de datos</translation> <translation id="3857228364945137633">Prueba Smart Lock para desbloquear tu <ph name="DEVICE_TYPE" /> sin necesidad de una contraseña cuando el teléfono está cerca.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Se pausó la sincronización</translation> <translation id="3860381078714302691">Bienvenido a Meet de Hangouts</translation> <translation id="3862134173397075045">¡Bienvenido a la experiencia de transmisión en Chrome!</translation> <translation id="3862788408946266506">Se debe instalar la app con el atributo del manifiesto "kiosk_only" en el modo kiosco del Sistema operativo Chrome</translation> @@ -1966,7 +1962,6 @@ <translation id="3968261067169026421">No se pudo configurar la red</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Calculando...</translation> -<translation id="3974195870082915331">Haz clic para mostrar la contraseña</translation> <translation id="3975222297214566386">Cuadro de opciones de entrada</translation> <translation id="397703832102027365">Finalizando...</translation> <translation id="3979395879372752341">Se agregó una extensión nueva (<ph name="EXTENSION_NAME" />).</translation> @@ -2008,6 +2003,7 @@ <translation id="4044612648082411741">Ingresar la contraseña del certificado</translation> <translation id="404493185430269859">Motor de búsqueda predeterminado</translation> <translation id="4047112090469382184">Seguridad</translation> +<translation id="4051049974203704184">Obtener información de lo que se muestra en la pantalla</translation> <translation id="4052120076834320548">Diminuto</translation> <translation id="4055023634561256217">Es necesario que reinicies tu dispositivo para poder restablecerlo con Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2036,6 +2032,7 @@ <translation id="4088095054444612037">Aceptar la invitación realizada al grupo</translation> <translation id="4089235344645910861">Se guardó la configuración y comenzó la sincronización.</translation> <translation id="4090103403438682346">Habilita el acceso verificado.</translation> +<translation id="4090947011087001172">¿Quieres restablecer los permisos del sitio <ph name="SITE" />?</translation> <translation id="4091434297613116013">hojas de papel</translation> <translation id="4093955363990068916">Archivo local:</translation> <translation id="4095507791297118304">Pantalla principal</translation> @@ -2212,7 +2209,6 @@ <translation id="4419556793104466535">Controlar la sincronización, la personalización y mucho más</translation> <translation id="4421932782753506458">Peludito</translation> <translation id="4422347585044846479">Editar marcador para esta página</translation> -<translation id="4423104065312875417">Instalar motores de comentarios de texto a voz adicionales</translation> <translation id="4423376891418188461">Restaurar configuración</translation> <translation id="4423482519432579560">&Corrección ortográfica</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, tu administrador te solicita que cambies la contraseña.</translation> @@ -2237,7 +2233,6 @@ <translation id="4449996769074858870">Esta pestaña está reproduciendo audio.</translation> <translation id="4450974146388585462">Diagnosticar</translation> <translation id="4453946976636652378">Buscar en <ph name="SEARCH_ENGINE_NAME" /> o escribir una URL</translation> -<translation id="445923051607553918">Únete a la red Wi-Fi</translation> <translation id="4462159676511157176">Servidores de nombres personalizados</translation> <translation id="4467100756425880649">Galería de Chrome Web Store</translation> <translation id="4467101674048705704">Expandir <ph name="FOLDER_NAME" /></translation> @@ -2373,6 +2368,7 @@ <translation id="4682551433947286597">Los fondos de pantalla aparecen en la pantalla de acceso.</translation> <translation id="4684427112815847243">Sincronizar todo</translation> <translation id="4689421377817139245">Sincronizar este favorito con tu iPhone</translation> +<translation id="4690091457710545971"><El firmware de Wi-Fi de Intel generó cuatro archivos: csr.lst, fh_regs.lst, radio_reg.lst y monitor.lst.sysmon. Intel utiliza los primeros tres, archivos binarios con volcados de registros, para incluir información que no identifique personas ni dispositivos. El último archivo es un rastro de ejecución del firmware de Intel del cual se eliminan los datos de identificación personal o de dispositivo; sin embargo, es demasiado grande para mostrarlo aquí. Se generaron estos archivos en respuesta a los recientes problemas de conectividad Wi-Fi en tu dispositivo y se compartirán con Intel para solucionarlos.></translation> <translation id="4692302215262324251">El dominio <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> registró tu dispositivo <ph name="DEVICE_TYPE" /> correctamente para la administración empresarial. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Si esta acción fue inesperada, comunícate con el equipo de asistencia.</translation> @@ -2632,6 +2628,7 @@ <translation id="5074318175948309511">Es posible que debas actualizar la página para que se aplique la nueva configuración.</translation> <translation id="5075131525758602494">Ingresar el PIN de la tarjeta SIM</translation> <translation id="5078638979202084724">Agregar a favoritos todas las pestañas</translation> +<translation id="5079950360618752063">Usar la contraseña sugerida</translation> <translation id="5084230410268011727">Permitir el uso de los sensores de luz y movimiento en los sitios</translation> <translation id="5085162214018721575">Buscando actualizaciones...</translation> <translation id="5086082738160935172">Dispositivos de interfaz humana (HID)</translation> @@ -2670,6 +2667,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Borrar este elemento</translation> <translation id="5139955368427980650">&Abrir</translation> +<translation id="5142961317498132443">Autenticación</translation> <translation id="5143374789336132547">La extensión "<ph name="EXTENSION_NAME" />" cambió la página que se muestra al hacer clic en el botón Página prinicpal.</translation> <translation id="5143712164865402236">Ingresar a pantalla completa</translation> <translation id="5145331109270917438">Fecha de modificación</translation> @@ -2840,7 +2838,6 @@ <translation id="5380103295189760361">Mantén presionadas las teclas Control, Alt, Mayús o Buscar para ver las combinaciones de teclas para acceso directo de esos modificadores.</translation> <translation id="5382591305415226340">Administrar los vínculos compatibles</translation> <translation id="5384883051496921101">Este sitio está a punto de compartir información con una app fuera del modo de navegación incógnito.</translation> -<translation id="5388588172257446328">Nombre de usuario:</translation> <translation id="5388885445722491159">Vinculado</translation> <translation id="5389237414310520250">No se pudo crear el usuario nuevo. Comprueba los permisos y el espacio en tu disco duro y vuelve a intentarlo.</translation> <translation id="5390100381392048184">Permitir que los sitios reproduzcan sonido</translation> @@ -2965,7 +2962,6 @@ <translation id="5551573675707792127">Entrada de texto y teclado</translation> <translation id="5553089923092577885">Asignaciones de directivas para certificados</translation> <translation id="5554489410841842733">Este ícono será visible cuando la extensión pueda actuar en la página actual.</translation> -<translation id="5554573843028719904">Otra red Wi-Fi...</translation> <translation id="5554720593229208774">Entidad de certificación de correo electrónico</translation> <translation id="5556206011531515970">Haz clic en Siguiente para seleccionar el navegador predeterminado.</translation> <translation id="5556459405103347317">Cargar de nuevo</translation> @@ -3006,7 +3002,6 @@ <translation id="5610038042047936818">Cambiar al modo de cámara</translation> <translation id="5612720917913232150"><ph name="URL" /> desea usar la ubicación de tu computadora</translation> <translation id="5612734644261457353">Aún no se pudo verificar tu contraseña. Ten en cuenta que si cambiaste tu contraseña recientemente, podrás usar tu nueva contraseña cuando salgas. Usa la contraseña antigua aquí.</translation> -<translation id="5613695965848159202">Identidad anónima:</translation> <translation id="5614190747811328134">Aviso de usuario</translation> <translation id="561698261642843490">Cerrar Firefox</translation> <translation id="5618075537869101857">No se pudo iniciar la aplicación del kiosco.</translation> @@ -3224,7 +3219,6 @@ <translation id="5941343993301164315">Accede a <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimizar</translation> <translation id="5946591249682680882">ID de informe: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Agregar red privada</translation> <translation id="5949544233750246342">No se puede analizar el archivo</translation> <translation id="5955282598396714173">Tu contraseña caducó. Para cambiarla, sal de la cuenta y vuelve a acceder.</translation> <translation id="5956585768868398362">¿Esta es la página de búsqueda que esperabas ver?</translation> @@ -3385,11 +3379,13 @@ <translation id="6198102561359457428">Salir y volver a acceder</translation> <translation id="6198252989419008588">Cambiar PIN</translation> <translation id="6199801702437275229">Esperando información sobre espacio...</translation> +<translation id="6204015976622790023">Obtén sugerencias relevantes del Asistente relacionadas con lo que aparece en tu pantalla.</translation> <translation id="6205710420833115353">Algunas operaciones están tardando más de lo esperado. ¿Quieres cancelarlas?</translation> <translation id="6206311232642889873">Cop&iar imagen</translation> <translation id="6207200176136643843">Restablece el nivel de zoom predeterminado</translation> <translation id="620722923698527029">Siempre abrir este tipo de vínculos en la app asociada</translation> <translation id="6207937957461833379">País/Región</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: La sincronización no funciona</translation> <translation id="6212039847102026977">Mostrar las propiedades de red avanzadas</translation> <translation id="6212168817037875041">Apagar la pantalla</translation> <translation id="6212752530110374741">Compartir vínculo por correo electrónico</translation> @@ -3427,7 +3423,6 @@ <translation id="6263541650532042179">restablecer sincronización</translation> <translation id="6264365405983206840">Seleccion&ar todo</translation> <translation id="6264422956566238156">Activaste la sincronización</translation> -<translation id="6265930187414222160">Se quitó el software dañino.</translation> <translation id="6267166720438879315">Seleccionar un certificado para autenticarte como <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Abrir con <ph name="APP" /></translation> <translation id="6268747994388690914">Importar favoritos desde un archivo HTML...</translation> @@ -3534,7 +3529,6 @@ Haz clic en "Siguiente" para continuar con el acceso a tu cuenta de <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Cargar extensión sin empaquetar</translation> <translation id="642282551015776456">Este nombre no se puede utilizar como archivo del nombre de la carpeta</translation> -<translation id="6423239382391657905">VPN abierto</translation> <translation id="6426200009596957090">Abrir configuración de ChromeVox</translation> <translation id="6429384232893414837">Error en la actualización</translation> <translation id="6430814529589430811">Certificado único ASCII con codificación Base64</translation> @@ -3615,7 +3609,6 @@ <translation id="6544215763872433504">El navegador web de Google, perfecto para ti</translation> <translation id="6545665334409411530">Frecuencia de repetición</translation> <translation id="6545834809683560467">Utilizar un servicio de predicción que ayude a completar las búsquedas y URL que se escriben en la barra de direcciones o en el cuadro de búsqueda del Selector de aplicaciones.</translation> -<translation id="6546686722964485737">Unirse a la red Wimax</translation> <translation id="6547316139431024316">No volver a advertirme sobre esta extensión</translation> <translation id="6547354035488017500">Libera al menos 512 MB de espacio o tu dispositivo dejará de funcionar. Para liberar espacio, borra archivos del almacenamiento del dispositivo.</translation> <translation id="6549689063733911810">Recientes</translation> @@ -4034,7 +4027,6 @@ <translation id="7201014958346994077">No se pueden ver los archivos de Linux</translation> <translation id="720110658997053098">Mantener este dispositivo en modo kiosco de forma permanente</translation> <translation id="7201118060536064622">Se borró "<ph name="DELETED_ITEM_NAME" />"</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Descargando <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Salir de la página}other{Salir de las páginas}}</translation> <translation id="7216409898977639127">Proveedor de red celular</translation> @@ -4512,7 +4504,6 @@ <translation id="7909969815743704077">Descargado en el modo de navegación de incógnito</translation> <translation id="7910768399700579500">&Nueva carpeta</translation> <translation id="7912080627461681647">Se cambió la contraseña en el servidor. Sal de la cuenta y vuelve a acceder.</translation> -<translation id="7912883689016444961">Configurar red móvil</translation> <translation id="7915471803647590281">Comunícanos lo que está pasando antes de enviarnos tus comentarios</translation> <translation id="7916556741383518510">Al hacer clic</translation> <translation id="792514962475806987">Nivel de zoom en vista acoplada:</translation> @@ -4566,7 +4557,6 @@ <translation id="7988355189918024273">Habilitar funciones de accesibilidad</translation> <translation id="7994702968232966508">Método EAP</translation> <translation id="799547531016638432">Eliminar acceso directo</translation> -<translation id="7997479212858899587">Identidad:</translation> <translation id="7997826902155442747">Prioridad de proceso</translation> <translation id="7999229196265990314">Los siguientes archivos fueron creados: @@ -4650,7 +4640,6 @@ <translation id="8105368624971345109">Desactivar</translation> <translation id="8106045200081704138">Compartidos conmigo</translation> <translation id="8107015733319732394">Se está instalando Google Play Store en tu <ph name="DEVICE_TYPE" />. Esta acción puede tardar unos minutos.</translation> -<translation id="8109930990200908494">Se requiere el acceso para el certificado de usuario.</translation> <translation id="8111155949205007504">Compartir esta contraseña con tu iPhone</translation> <translation id="8113043281354018522">Elige un tipo de licencia</translation> <translation id="8116190140324504026">Más información...</translation> @@ -4661,6 +4650,7 @@ <translation id="8118860139461251237">Administrar tus descargas</translation> <translation id="81238879832906896">Flor amarilla y blanca</translation> <translation id="8124313775439841391">ONC administrado</translation> +<translation id="8125562866093998907">El sitio quiere verificar la llave de seguridad para mejorar la protección de tu cuenta.</translation> <translation id="813082847718468539">Consulta la información del sitio</translation> <translation id="8131740175452115882">Confirmar</translation> <translation id="8133676275609324831">Mo&strar en carpeta</translation> @@ -4771,7 +4761,6 @@ <translation id="8308179586020895837">Preguntar si <ph name="HOST" /> quiere acceder a la cámara</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">El certificado ya existe</translation> -<translation id="8309505303672555187">Selecciona una red:</translation> <translation id="8312871300878166382">Pegar en la carpeta</translation> <translation id="8317671367883557781">Agregar conexión de red</translation> <translation id="8319414634934645341">Uso extendido de la clave</translation> @@ -4847,7 +4836,6 @@ <translation id="8451512073679317615">asistente</translation> <translation id="8452135315243592079">Falta la tarjeta SIM</translation> <translation id="8453482423012550001">Copiando $1 elementos…</translation> -<translation id="8454288007744638700">O bien, selecciona una nueva red:</translation> <translation id="845627346958584683">Hora de vencimiento</translation> <translation id="8456681095658380701">Nombre no válido</translation> <translation id="8457451314607652708">Importar favoritos</translation> @@ -4911,6 +4899,7 @@ <translation id="855081842937141170">Fijar pestaña</translation> <translation id="8551388862522347954">Licencias</translation> <translation id="8553342806078037065">Administrar otras personas</translation> +<translation id="8554899698005018844">Ningún idioma</translation> <translation id="855773602626431402">Se impidió que un complemento no incluido en la zona de pruebas se ejecutara en la página.</translation> <translation id="8557930019681227453">Manifiesto</translation> <translation id="8559694214572302298">Decodificador de imágenes</translation> @@ -4948,7 +4937,6 @@ <translation id="862727964348362408">En suspensión</translation> <translation id="862750493060684461">Caché CSS</translation> <translation id="8627795981664801467">Conexiones seguras solamente</translation> -<translation id="8628085465172583869">Nombre de host del servidor:</translation> <translation id="8630903300770275248">Importar usuario supervisado</translation> <translation id="8631032106121706562">Pétalos</translation> <translation id="8637542770513281060">Tu computadora cuenta con un módulo de seguridad que se usa para implementar varias funciones clave de seguridad en Sistema operativo Chrome. Para obtener más información, visita el Centro de ayuda de Chromebook: https://support.google.com/chromebook/?p=sm</translation> @@ -5205,7 +5193,6 @@ <translation id="899403249577094719">URL base del certificado Netscape</translation> <translation id="8995603266996330174">Administrado por <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Agregar cuenta…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Se está creando la imagen de disco.</translation> <translation id="9003647077635673607">Permitir en todos los sitios web</translation> <translation id="9003677638446136377">Volver a comprobar</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index d29dd32..a0b13d6 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Ya casi es la hora de hacer un descanso</translation> <translation id="1062407476771304334">Sustituir</translation> -<translation id="1064835277883315402">Conectarse a una red privada</translation> <translation id="1064912851688322329">Desvincular tu cuenta de Google</translation> <translation id="1067048845568873861">Creada</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Buscando...</translation> <translation id="1316495628809031177">La sincronización está en pausa</translation> <translation id="1319979322914001937">Una aplicación que muestra una lista de extensiones filtrada de Chrome Web Store. Las extensiones de la lista se pueden instalar directamente desde la aplicación.</translation> -<translation id="132090119144658135">Coincidencia de asunto:</translation> <translation id="1326317727527857210">Inicia sesión en Chrome para ver las pestañas de tus otros dispositivos.</translation> <translation id="1327074568633507428">Impresora en Google Cloud Print</translation> <translation id="1327977588028644528">Pasarela</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Eliminar este perfil</translation> <translation id="1706586824377653884">Añadido por tu administrador</translation> <translation id="1706625117072057435">Niveles de zoom</translation> -<translation id="1707463636381878959">Compartir esta red con otros usuarios</translation> <translation id="1708338024780164500">(Inactiva)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (resolución nativa)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Habilitar tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Ver en Chrome Web Store</translation> -<translation id="1758831820837444715">Configurar la red Ethernet</translation> <translation id="1763046204212875858">Crear accesos directos a aplicaciones</translation> <translation id="1763108912552529023">Seguir explorando</translation> <translation id="1763808908432309942">Se abre en una nueva pestaña</translation> @@ -875,7 +871,6 @@ <translation id="2291643155573394834">Siguiente pestaña</translation> <translation id="2292848386125228270">Inicia <ph name="PRODUCT_NAME" /> como un usuario normal. Si debes ejecutarlo como root para el desarrollo, vuelve a iniciarlo con el indicador "--no-sandbox".</translation> <translation id="2294358108254308676">¿Quieres instalar <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Método EAP:</translation> <translation id="2297705863329999812">Buscar impresoras</translation> <translation id="2300383962156589922">Personalizar y controlar <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">El directorio raíz de la extensión no es válido.</translation> @@ -933,7 +928,6 @@ <translation id="2379281330731083556">Imprimir utilizando el cuadro de diálogo del sistema <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Preguntar antes de enviar (recomendado)</translation> <translation id="2384436799579181135">Se ha producido un error. Comprueba tu impresora y vuelve a intentarlo.</translation> -<translation id="2385700042425247848">Nombre del servicio:</translation> <translation id="2387458720915042159">Tipo de conexión con proxy</translation> <translation id="2391419135980381625">Fuente estándar</translation> <translation id="2391762656119864333">Revocar</translation> @@ -984,7 +978,6 @@ <translation id="247949520305900375">Compartir audio</translation> <translation id="2480868415629598489">Modificar los datos que se copian y se pegan</translation> <translation id="2482878487686419369">Notificaciones</translation> -<translation id="2485056306054380289">Certific. CA servidor:</translation> <translation id="2485422356828889247">Desinstalar</translation> <translation id="2487067538648443797">Añadir nuevo marcador</translation> <translation id="248861575772995840">No se encuentra tu teléfono. Asegúrate de que el Bluetooth esté activado en tu <ph name="DEVICE_TYPE" />. <a>Más información</a></translation> @@ -1109,7 +1102,6 @@ <translation id="2653659639078652383">Enviar</translation> <translation id="265390580714150011">Valor de campo</translation> <translation id="2654166010170466751">Permitir a los sitios web instalar controladores de pago</translation> -<translation id="2655386581175833247">Certificado usuario:</translation> <translation id="2660779039299703961">Evento</translation> <translation id="266079277508604648">No se puede establecer conexión con la impresora. Comprueba que esté encendida y conectada a tu Chromebook por red Wi‑Fi o USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1409,7 +1401,6 @@ <translation id="3100609564180505575">Módulos (<ph name="TOTAL_COUNT" />) - conflictos conocidos: <ph name="BAD_COUNT" />; conflictos sospechosos: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Fecha y hora</translation> <translation id="310671807099593501">El sitio web está usando el Bluetooth</translation> -<translation id="3108967419958202225">Seleccionar...</translation> <translation id="3115128645424181617">No se encuentra tu teléfono. Asegúrate de que lo tienes cerca y de que el Bluetooth está activado.</translation> <translation id="3115147772012638511">Esperando caché...</translation> <translation id="3118319026408854581">Ayuda de <ph name="PRODUCT_NAME" /></translation> @@ -1454,7 +1445,6 @@ <translation id="3165390001037658081">Es posible que algunos operadores bloqueen esta función.</translation> <translation id="316854673539778496">Inicia sesión y activa la sincronización para ver tus extensiones en todos tus dispositivos.</translation> <translation id="3170072451822350649">También puedes <ph name="LINK_START" />navegar como invitado<ph name="LINK_END" /> sin iniciar sesión.</translation> -<translation id="3177048931975664371">Haz clic aquí para ocultar la contraseña</translation> <translation id="3177909033752230686">Idioma de la página:</translation> <translation id="3181110748548073003">Pulsa |<ph name="SHORTCUT" />| para ir a la página siguiente</translation> <translation id="3182749001423093222">Revisión ortográfica</translation> @@ -1485,7 +1475,6 @@ <translation id="3236289833370040187">La propiedad se transferirá a <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Abrir opciones de la extensión</translation> <translation id="3241680850019875542">Selecciona el directorio raíz de las extensiones que quieras empaquetar. Para actualizar una extensión, debes seleccionar también el archivo de clave privada que se va a volver a usar.</translation> -<translation id="3242765319725186192">Clave precompartida:</translation> <translation id="3244294424315804309">Seguir silenciando el sonido</translation> <translation id="3245321423178950146">Artista desconocido</translation> <translation id="3246097286174000800">Probar Smart Lock</translation> @@ -1616,7 +1605,6 @@ <translation id="3440663250074896476">Más acciones aplicables a <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Preguntar cuando un sitio web quiera utilizar un complemento para acceder a tu ordenador</translation> <translation id="3441653493275994384">Pantalla</translation> -<translation id="3445830502289589282">Autenticación fase 2:</translation> <translation id="344630545793878684">Leer tus datos en varios sitios web</translation> <translation id="3449839693241009168">Pulsa <ph name="SEARCH_KEY" /> para enviar comandos a <ph name="EXTENSION_NAME" />.</translation> <translation id="3450157232394774192">Porcentaje de ocupación de estado de inactividad</translation> @@ -1657,7 +1645,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> errores.</translation> <translation id="3495660573538963482">Configuración del Asistente de Google</translation> <translation id="3496213124478423963">Alejar</translation> -<translation id="3504135463003295723">Nombre del grupo:</translation> <translation id="3505030558724226696">Revocar acceso al dispositivo</translation> <translation id="3507421388498836150">Permisos actuales para <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Eliminar aplicaciones de Linux del Chromebook</translation> @@ -1766,7 +1753,6 @@ <translation id="3661054927247347545">La certificación de inicio de sesión no es válida; la ventana se cerrará en <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Icono de la extensión</translation> <translation id="3665589677786828986">Chrome ha detectado que otro programa ha dañado algunas opciones de configuración y ha restablecido la configuración predeterminada original.</translation> -<translation id="3665842570601375360">Seguridad:</translation> <translation id="3668570675727296296">Configuración de idioma</translation> <translation id="3668823961463113931">Controladores</translation> <translation id="3670229581627177274">Activar Bluetooth</translation> @@ -1805,7 +1791,6 @@ <translation id="3726463242007121105">No se puede abrir este dispositivo porque no se admite su sistema de archivos.</translation> <translation id="3727148787322499904">Si cambias esta opción, todas las redes compartidas se verán afectadas</translation> <translation id="3727187387656390258">Inspeccionar ventana emergente</translation> -<translation id="3728067901555601989">Contraseña de un solo uso (OTP):</translation> <translation id="3732078975418297900">Error en la línea <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Servidor SSL con certificado Step-Up</translation> <translation id="3737536731758327622">Tus descargas aparecen en esta sección</translation> @@ -1880,7 +1865,6 @@ <translation id="38275787300541712">Pulsa Intro al terminar</translation> <translation id="3827774300009121996">&Pantalla completa</translation> <translation id="3828029223314399057">Buscar marcadores</translation> -<translation id="3829932584934971895">Tipo de proveedor:</translation> <translation id="3830674330436234648">No se puede reproducir</translation> <translation id="3831486154586836914">Se ha introducido el modo de vista general de pestañas</translation> <translation id="383161972796689579">El propietario de este dispositivo ha desactivado la opción de añadir nuevos usuarios</translation> @@ -1978,7 +1962,6 @@ <translation id="3968261067169026421">No se ha podido configurar la red</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Calculando...</translation> -<translation id="3974195870082915331">Haz clic para mostrar la contraseña</translation> <translation id="3975222297214566386">Cuadro de opciones de entrada</translation> <translation id="397703832102027365">Finalizando...</translation> <translation id="3979395879372752341">Nueva extensión añadida (<ph name="EXTENSION_NAME" />)</translation> @@ -2226,7 +2209,6 @@ <translation id="4419556793104466535">Controlar la sincronización, la personalización y mucho más</translation> <translation id="4421932782753506458">Gatito</translation> <translation id="4422347585044846479">Editar marcador para esta página</translation> -<translation id="4423104065312875417">Instalar motores de voz adicionales</translation> <translation id="4423376891418188461">Restaurar configuración</translation> <translation id="4423482519432579560">&Corrector ortográfico</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, tu administrador solicita que cambies la contraseña.</translation> @@ -2251,7 +2233,6 @@ <translation id="4449996769074858870">Esta pestaña está reproduciendo audio.</translation> <translation id="4450974146388585462">Diagnosticar</translation> <translation id="4453946976636652378">Busca <ph name="SEARCH_ENGINE_NAME" /> o introduce una URL</translation> -<translation id="445923051607553918">Conectar a una red Wi-Fi</translation> <translation id="4462159676511157176">Servidores de nombres personalizados</translation> <translation id="4467100756425880649">Galería de Chrome Web Store</translation> <translation id="4467101674048705704">Mostrar <ph name="FOLDER_NAME" /></translation> @@ -2856,7 +2837,6 @@ <translation id="5380103295189760361">Mantén pulsada la tecla de control, la tecla Alt, la tecla de mayúsculas o la tecla de búsqueda para ver combinaciones de teclas de esos modificadores.</translation> <translation id="5382591305415226340">Administrar enlaces compatibles</translation> <translation id="5384883051496921101">Este sitio web va a compartir información con una aplicación con la que no se utilizará el modo incógnito.</translation> -<translation id="5388588172257446328">Nombre de usuario:</translation> <translation id="5388885445722491159">Sincronizado</translation> <translation id="5389237414310520250">No se ha podido crear el nuevo usuario. Comprueba los permisos y el espacio de tu disco duro y vuelve a intentarlo.</translation> <translation id="5390100381392048184">Permitir que los sitios web reproduzcan sonidos</translation> @@ -2981,7 +2961,6 @@ <translation id="5551573675707792127">Teclado e introducción de texto</translation> <translation id="5553089923092577885">Asignaciones de políticas de certificados</translation> <translation id="5554489410841842733">Este icono aparecerá cuando la extensión pueda actuar en la página actual.</translation> -<translation id="5554573843028719904">Otra red Wi-Fi...</translation> <translation id="5554720593229208774">Entidad emisora de certificados de correo electrónico</translation> <translation id="5556206011531515970">Haz clic en Siguiente para seleccionar el navegador predeterminado.</translation> <translation id="5556459405103347317">Volver a cargar</translation> @@ -3022,7 +3001,6 @@ <translation id="5610038042047936818">Cambiar al modo de cámara</translation> <translation id="5612720917913232150"><ph name="URL" /> quiere utilizar la ubicación de tu ordenador</translation> <translation id="5612734644261457353">No ha sido posible verificar tu contraseña. Nota: si has cambiado la contraseña recientemente, la nueva contraseña se aplicará una vez que hayas cerrado sesión. Utiliza la antigua contraseña aquí.</translation> -<translation id="5613695965848159202">Identidad anónima:</translation> <translation id="5614190747811328134">Aviso al usuario</translation> <translation id="561698261642843490">Cerrar Firefox</translation> <translation id="5618075537869101857">No se ha podido iniciar la aplicación Darn del kiosco.</translation> @@ -3240,7 +3218,6 @@ <translation id="5941343993301164315">Inicia sesión en <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimizar</translation> <translation id="5946591249682680882">ID de informe <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Añadir red privada</translation> <translation id="5949544233750246342">No se ha podido analizar el archivo</translation> <translation id="5955282598396714173">Tu contraseña ha caducado. Cierra la sesión y vuelve a iniciarla para cambiarla.</translation> <translation id="5956585768868398362">¿Es esta la página de búsqueda que esperabas?</translation> @@ -3445,7 +3422,6 @@ <translation id="6263541650532042179">restablecer la sincronización</translation> <translation id="6264365405983206840">Seleccionar &todo</translation> <translation id="6264422956566238156">Has activado la sincronización</translation> -<translation id="6265930187414222160">Listo. Se ha eliminado el software dañino.</translation> <translation id="6267166720438879315">Selecciona un certificado para autenticar tu identidad en <ph name="HOST_NAME" />.</translation> <translation id="6268252012308737255">Abrir con <ph name="APP" /></translation> <translation id="6268747994388690914">Importar marcadores desde archivo HTML...</translation> @@ -3552,7 +3528,6 @@ Haz clic en Siguiente para continuar iniciando sesión en tu cuenta de <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Cargar descomprimida</translation> <translation id="642282551015776456">Este nombre no se puede utilizar como nombre de archivo de carpeta.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Abrir la configuración de ChromeVox</translation> <translation id="6429384232893414837">Error de actualización</translation> <translation id="6430814529589430811">ASCII codificado en Base64, certificado único</translation> @@ -3632,7 +3607,6 @@ <translation id="6544215763872433504">El navegador web de Google a tu disposición</translation> <translation id="6545665334409411530">Frecuencia de repetición</translation> <translation id="6545834809683560467">Utilizar un servicio de predicción para completar las búsquedas y las URL introducidas en la barra de direcciones o en el cuadro de búsqueda del menú de aplicaciones</translation> -<translation id="6546686722964485737">Conectarse a la red WiMAX</translation> <translation id="6547316139431024316">No volver a advertirme sobre esta extensión</translation> <translation id="6547354035488017500">Libera al menos 512 MB de espacio o el dispositivo no responderá. Para ello, elimina archivos del almacenamiento del dispositivo.</translation> <translation id="6549689063733911810">Reciente</translation> @@ -4051,7 +4025,6 @@ <translation id="7201014958346994077">No se pueden ver archivos de Linux</translation> <translation id="720110658997053098">Mantener este dispositivo en modo kiosco de forma permanente</translation> <translation id="7201118060536064622">Se ha eliminado "<ph name="DELETED_ITEM_NAME" />"</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Descargando <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Salir de la página}other{Salir de las páginas}}</translation> <translation id="7216409898977639127">Proveedor de servicios móviles</translation> @@ -4529,7 +4502,6 @@ <translation id="7909969815743704077">Se ha descargado en modo incógnito</translation> <translation id="7910768399700579500">&Nueva carpeta</translation> <translation id="7912080627461681647">Tu contraseña se ha cambiado en el servidor. Cierra la sesión y vuelve a iniciarla.</translation> -<translation id="7912883689016444961">Configurar red móvil</translation> <translation id="7915471803647590281">Debes describir el error.</translation> <translation id="7916556741383518510">Al hacer clic</translation> <translation id="792514962475806987">Nivel de zoom fijado:</translation> @@ -4583,7 +4555,6 @@ <translation id="7988355189918024273">Habilitar funciones de accesibilidad</translation> <translation id="7994702968232966508">Método EAP</translation> <translation id="799547531016638432">Eliminar acceso directo</translation> -<translation id="7997479212858899587">Identidad:</translation> <translation id="7997826902155442747">Prioridad del proceso</translation> <translation id="7999229196265990314">Se han creado los siguientes archivos: @@ -4667,7 +4638,6 @@ <translation id="8105368624971345109">Desactivar</translation> <translation id="8106045200081704138">Compartido conmigo</translation> <translation id="8107015733319732394">Se está instalando Google Play Store en tu <ph name="DEVICE_TYPE" />. Este proceso puede tardar unos minutos.</translation> -<translation id="8109930990200908494">Se requiere el inicio de sesión para el certificado de usuario.</translation> <translation id="8111155949205007504">Comparte esta contraseña con tu iPhone</translation> <translation id="8113043281354018522">Elige un tipo de licencia</translation> <translation id="8116190140324504026">Más información...</translation> @@ -4789,7 +4759,6 @@ <translation id="8308179586020895837">Preguntar si <ph name="HOST" /> quiere acceder a la cámara</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">El certificado ya existe</translation> -<translation id="8309505303672555187">Selecciona una red:</translation> <translation id="8312871300878166382">Pegar en la carpeta</translation> <translation id="8317671367883557781">Añadir conexión de red</translation> <translation id="8319414634934645341">Uso mejorado de clave</translation> @@ -4864,7 +4833,6 @@ <translation id="8451512073679317615">asistente</translation> <translation id="8452135315243592079">Falta la tarjeta SIM</translation> <translation id="8453482423012550001">Copiando $1 elementos...</translation> -<translation id="8454288007744638700">O selecciona una nueva red:</translation> <translation id="845627346958584683">Fecha de vencimiento</translation> <translation id="8456681095658380701">El nombre no es válido</translation> <translation id="8457451314607652708">Importar marcadores</translation> @@ -4966,7 +4934,6 @@ <translation id="862727964348362408">En suspensión</translation> <translation id="862750493060684461">Caché de CSS</translation> <translation id="8627795981664801467">Conexiones seguras solamente</translation> -<translation id="8628085465172583869">Nombre de host del servidor:</translation> <translation id="8630903300770275248">Importar usuario supervisado</translation> <translation id="8631032106121706562">Pétalos</translation> <translation id="8637542770513281060">Tu ordenador contiene un módulo de seguridad, que se utiliza para implementar un gran número de funciones importantes de seguridad en Chrome OS. Accede al Centro de Ayuda de los Chromebooks (https://support.google.com/chromebook/?p=sm) para obtener más información.</translation> @@ -5222,7 +5189,6 @@ <translation id="899403249577094719">URL base de certificado de Netscape</translation> <translation id="8995603266996330174">Administrado por <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Añadir cuenta...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Creando imagen de disco.</translation> <translation id="9003647077635673607">Permitir en todos los sitios web</translation> <translation id="9003677638446136377">Comprobar de nuevo</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb index 8c936c0..e620c03 100644 --- a/chrome/app/resources/generated_resources_et.xtb +++ b/chrome/app/resources/generated_resources_et.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK-kood</translation> <translation id="1061904396131502319">Pausiaeg on peagi käes</translation> <translation id="1062407476771304334">Asenda</translation> -<translation id="1064835277883315402">Privaatse võrguga liitumine</translation> <translation id="1064912851688322329">Katkestage oma Google'i konto ühendus</translation> <translation id="1067048845568873861">Loodud</translation> <translation id="1067291318998134776">Linux (beetaversioon)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Otsimine ...</translation> <translation id="1316495628809031177">Sünkroonimine on peatatud</translation> <translation id="1319979322914001937">Rakendus, mis näitab laienduste filtreeritud loendit Chrome'i veebipoest. Selles loendis olevad laiendused saab installida otse rakendusest.</translation> -<translation id="132090119144658135">Teema vaste:</translation> <translation id="1326317727527857210">Vahelehtede hankimiseks oma teistest seadmetest logige Chrome'i sisse.</translation> <translation id="1327074568633507428">Printer Google'i pilvprintimises</translation> <translation id="1327977588028644528">Lüüs</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Rakenduse aken</translation> <translation id="1534389735079119190">VIGA: konteineri käivitamine VM-is nurjus.</translation> <translation id="15373452373711364">Suur hiirekursor</translation> +<translation id="1540605929960647700">Demorežiimi lubamine</translation> <translation id="1543284117603151572">Imporditud teenusest Edge</translation> <translation id="1545177026077493356">Automaatne kioskirežiim</translation> <translation id="1545775234664667895">Teema „<ph name="THEME_NAME" />“ installitud</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Aidake muuta rakendus <ph name="PRODUCT_NAME" /> paremaks, saates Google'ile automaatselt kasutusstatistikat ja veaaruandeid</translation> <translation id="1658424621194652532">See leht pääseb teie mikrofoni juurde.</translation> <translation id="1660204651932907780">Saitidel lubatakse esitada heli (soovitatav)</translation> +<translation id="1660938185063657230">Turvavõtme kinnitamine</translation> <translation id="1661156625580498328">AES-krüpteerimise jõustamine (soovitatud).</translation> <translation id="1661245713600520330">Sellel lehel on loetletud kõik põhiprotsessi laaditud moodulid ja hilisemaks laadimiseks registreeritud moodulid.</translation> <translation id="166179487779922818">Parool on liiga lühike.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Ära luba saitidel näha lõikelauale kopeeritud teksti ega kujutisi</translation> <translation id="1682548588986054654">Uus inkognito aken</translation> <translation id="168715261339224929">Järjehoidjate hankimiseks kõigisse oma seadmetesse lülitage sünkroonimine sisse.</translation> +<translation id="1688867105868176567">Kas soovite saidi andmed kustutada?</translation> <translation id="1688935057616748272">Sisestage täht</translation> <translation id="168991973552362966">Lähedalasuva printeri lisamine</translation> <translation id="1689945336726856614">Kopeeri &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Eemalda see isik</translation> <translation id="1706586824377653884">Lisas teie administraator</translation> <translation id="1706625117072057435">Suumitasemed</translation> -<translation id="1707463636381878959">Jaga seda võrku teiste kasutajatega</translation> <translation id="1708338024780164500">(Passiivne)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (omaeraldusvõime)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Luba teema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Kuva Chrome'i veebipoes</translation> -<translation id="1758831820837444715">Etherneti-võrgu seadistamine</translation> <translation id="1763046204212875858">Rakenduse otseteede loomine</translation> <translation id="1763108912552529023">Jätka uurimist</translation> <translation id="1763808908432309942">Avaneb uuel vahekaardil</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Muutke seda, kuidas faili jagatakse</translation> <translation id="1841545962859478868">Seadme administraator võib jälgida järgmist:</translation> <translation id="1841705068325380214">Laiendus <ph name="EXTENSION_NAME" /> on keelatud</translation> +<translation id="1842766183094193446">Kas soovite kindlasti demorežiimi lubada?</translation> <translation id="1844692022597038441">Fail ei ole võrguühenduseta saadaval.</translation> <translation id="1846308012215045257">Pistikprogrammi <ph name="PLUGIN_NAME" /> käitamiseks klõpsake juhtklahvil</translation> +<translation id="1847880352285315359">Salvestatud</translation> <translation id="1848219224579402567">Logi välja, kui kaas on suletud</translation> <translation id="184823282865851239">Blokeeri, kui sait näitab sekkuvaid reklaame</translation> <translation id="1849186935225320012">See leht saab MIDI-seadmeid täielikult juhtida.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Seda saab menüüs Seaded alati hiljem muuta</translation> <translation id="2006638907958895361">Ava link rakenduses <ph name="APP" /></translation> <translation id="2007404777272201486">Anna probleemist teada ...</translation> +<translation id="2016237810978710652">Linuxi failide avamine …</translation> <translation id="2016430552235416146">Traditsiooniline</translation> <translation id="2017334798163366053">Keela toimivusandmete kogumine</translation> <translation id="2017836877785168846">Kustutab aadressiribalt ajaloo ja automaatse täitmise teabe.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Kaardi muutmine</translation> <translation id="2154710561487035718">Kopeeri URL</translation> <translation id="2155772377859296191">Näib kui <ph name="WIDTH" /> × <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Võite aidata ohutut sirvimist täiustada, saates Google'ile süsteemiteavet ja lehesisu.</translation> <translation id="215753907730220065">Täisekraanilt väljumine</translation> <translation id="2157875535253991059">See leht kuvati nüüd täisekraanil.</translation> <translation id="216169395504480358">Lisa WiFi ...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Lisa seadmesse nõude ID</translation> <translation id="2175042898143291048">Tee seda alati</translation> <translation id="2175607476662778685">Kiirkäivitusriba</translation> +<translation id="2176087259161165020">Muud allikad</translation> <translation id="2177950615300672361">Inkognito vaheleht: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> domeenil <ph name="PEPPER_PLUGIN_DOMAIN" /> soovib juurdepääsu teie arvutile</translation> <translation id="2178614541317717477">CA turvarike</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Järgmine vahekaart</translation> <translation id="2292848386125228270">Käivitage teenus <ph name="PRODUCT_NAME" /> tavakasutajana. Kui soovite arendamiseks käivitada juurversiooni, käivitage uuesti märgistusega --no-sandbox.</translation> <translation id="2294358108254308676">Kas soovite installida <ph name="PRODUCT_NAME" />'i?</translation> -<translation id="2296019197782308739">EAP meetod:</translation> <translation id="2297705863329999812">Printerite otsimine</translation> <translation id="2300383962156589922">Rakenduse <ph name="APP_NAME" /> kohandamine ja juhtimine</translation> <translation id="2301382460326681002">Laienduse juurkaust on kehtetu.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">VIGA: rakenduse <ph name="APP_NAME" /> desinstallimine ebaõnnestus.</translation> <translation id="2367199180085172140">Lisa failide võrguhoidla</translation> <translation id="2367972762794486313">Rakenduste kuvamine</translation> +<translation id="2369536625682139252">Kõik saidi <ph name="SITE" /> talletatud andmed peale küpsisefailide kustutatakse.</translation> <translation id="2371076942591664043">Ava, kui on &valmis</translation> <translation id="2377319039870049694">Lülita loendivaatele</translation> <translation id="2377667304966270281">Tõsised vead</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Prindi süsteemidialoogi abil ... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Küsib enne saatmist (soovitatav)</translation> <translation id="2384436799579181135">Ilmnes viga. Kontrollige printerit ja proovige uuesti.</translation> -<translation id="2385700042425247848">Teenuse nimi:</translation> <translation id="2387458720915042159">Puhverserveri ühenduse tüüp</translation> <translation id="2391419135980381625">Standardne font</translation> <translation id="2391762656119864333">Tühista</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Jaga heli</translation> <translation id="2480868415629598489">Kopeeritud ja kleebitud andmete muutmine</translation> <translation id="2482878487686419369">Märguanded</translation> -<translation id="2485056306054380289">Serveri CA-sertifikaat</translation> <translation id="2485422356828889247">Desinstalli</translation> <translation id="2487067538648443797">Uue järjehoidja lisamine</translation> <translation id="248861575772995840">Teie telefoni ei õnnestu leida. Veenduge, et seadme <ph name="DEVICE_TYPE" /> Bluetooth oleks sisse lülitatud. <a>Lisateave</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Pärast Powerwashiga lähtestamist on teie toote <ph name="IDS_SHORT_PRODUCT_NAME" /> seade just nagu uus.</translation> <translation id="2567257616420533738">Parool salvestati. Vaadake ja hallake salvestatud paroole saidil <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Teaberiba ümbris</translation> +<translation id="2570454805927264159">Kasutage Google'i assistenti parimal moel</translation> <translation id="257088987046510401">Teemad</translation> <translation id="2572032849266859634">On antud kirjutuskaitstud juurdepääs seadmele <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Valige pilt ja nimi</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Esita</translation> <translation id="265390580714150011">Välja väärtus</translation> <translation id="2654166010170466751">Luba saitidel maksetöötlejaid installida</translation> -<translation id="2655386581175833247">Kasutaja sertifikaat:</translation> <translation id="2660779039299703961">Sündmus</translation> <translation id="266079277508604648">Printeriga ei saa ühendada. Kontrollige, kas printer on sisse lülitatud ja teie Chromebookiga WiFi või USB kaudu ühendatud.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Kasutusandmed puuduvad</translation> <translation id="3007214526293698309">Fikseeri suhe</translation> <translation id="3007771295016901659">Topeltvaheleht</translation> +<translation id="3008272652534848354">Lähtesta load</translation> <translation id="3009300415590184725">Kas soovite mobiilse andmesideteenuse seadistamise protsessi kindlasti tühistada?</translation> <translation id="3009779501245596802">Indekseeritud andmebaasid</translation> <translation id="3010279545267083280">Parool on kustutatud</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Moodulid (<ph name="TOTAL_COUNT" />) – teadaolevad vastuolud: <ph name="BAD_COUNT" />, oletatavad: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Kuupäev ja kellaaeg</translation> <translation id="310671807099593501">Sait kasutab Bluetoothi</translation> -<translation id="3108967419958202225">Valige ...</translation> <translation id="3115128645424181617">Teie telefoni ei õnnestu leida. Veenduge, et see oleks käepärast ja Bluetooth oleks sisse lülitatud.</translation> <translation id="3115147772012638511">Puhvri ootel...</translation> <translation id="3118319026408854581">Toote <ph name="PRODUCT_NAME" /> abi</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Mõned operaatorid võivad selle funktsooni blokeerida.</translation> <translation id="316854673539778496">Selleks et hankida kõik oma laiendused kõikidesse seadmetesse, logige sisse ja lülitage sünkroonimine sisse.</translation> <translation id="3170072451822350649">Võite sisselogimise vahele jätta ja <ph name="LINK_START" />sirvida külalisena<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Parooli peitmiseks klõpsake</translation> <translation id="3177909033752230686">Lehe keel:</translation> <translation id="3181110748548073003">Edasiliikumiseks vajutage klaviatuuri otseteed |<ph name="SHORTCUT" />|</translation> <translation id="3182749001423093222">Õigekirjakontroll</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Omandiline kuuluvus kantakse üle domeenile <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Ava laienduse valikud</translation> <translation id="3241680850019875542">Valige pakitava laienduse juurkaust. Laienduse värskendamiseks valige uuesti kasutamiseks ka privaatvõtme fail.</translation> -<translation id="3242765319725186192">Eeljagatud võti:</translation> <translation id="3244294424315804309">Jätka heli vaigistamist</translation> <translation id="3245321423178950146">Tundmatu esitaja</translation> <translation id="3246097286174000800">Proovige funktsiooni Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Rohkem toiminguid: <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Küsi, kui sait soovib arvutile juurdepääsemiseks pistikprogrammi kasutada</translation> <translation id="3441653493275994384">Ekraan</translation> -<translation id="3445830502289589282">2. etapi autentimine:</translation> <translation id="344630545793878684">Lugege oma andmeid mitmel veebisaidil</translation> <translation id="3449839693241009168">Vajutage nuppu <ph name="SEARCH_KEY" />, et saata käsud teenusesse <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Jõudeoleku protsent</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> viga.</translation> <translation id="3495660573538963482">Google'i assistendi seaded</translation> <translation id="3496213124478423963">Vähenda</translation> -<translation id="3504135463003295723">Rühma nimi:</translation> <translation id="3505030558724226696">Tühista juurdepääs seadmele</translation> <translation id="3507421388498836150">Laiendi „<ph name="EXTENSION_NAME" />” praegused õigused</translation> <translation id="3507547268929739059">Linuxi rakenduste eemaldamine Chromebookist</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Sisselogimise sertifikaat ei ole kehtiv, aken suletakse <ph name="MINUTES" />:<ph name="SECONDS" /> pärast</translation> <translation id="3664511988987167893">Laienduse ikoon</translation> <translation id="3665589677786828986">Chrome tuvastas, et teine programm rikkus teie seadeid, ja lähtestas need algsetele vaikevalikutele.</translation> -<translation id="3665842570601375360">Turvalisus:</translation> <translation id="3668570675727296296">Keeleseaded</translation> <translation id="3668823961463113931">Töötlejad</translation> <translation id="3670229581627177274">Lülita Bluetooth sisse</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Seadet ei saa avada, sest selle failisüsteemi ei toetata.</translation> <translation id="3727148787322499904">Selle seade muutmine mõjutab kõiki jagatud võrke</translation> <translation id="3727187387656390258">Hüpiku kontrollimine</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Viga real <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-server koos seadistamisega</translation> <translation id="3737536731758327622">Teie allalaadimised kuvatakse siin</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Kui olete valmis, vajutage sisestusklahvi</translation> <translation id="3827774300009121996">&Täisekraan</translation> <translation id="3828029223314399057">Otsi jäjehoidjaid</translation> -<translation id="3829932584934971895">Teenusepakkuja tüüp:</translation> <translation id="3830674330436234648">Taasesitus ei ole saadaval</translation> <translation id="3831486154586836914">Sisenes akna ülevaate režiimi</translation> <translation id="383161972796689579">Selle seadme omanik on keelanud uute kasutajate lisamise</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Andmemahu kasutuse mõõtmine on lõppenud</translation> <translation id="3857228364945137633">Proovige funktsiooni Smart Lock, et avada oma seade <ph name="DEVICE_TYPE" /> paroolita, kui teie telefon on läheduses.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: sünkroonimine on peatatud</translation> <translation id="3860381078714302691">Tere tulemast teenusesse Hangouts Meet!</translation> <translation id="3862134173397075045">Tere tulemast Chrome'is Cast'i avastama!</translation> <translation id="3862788408946266506">Rakendus manifesti atribuudiga „kiosk_only” tuleb installida Chrome OS-i kioskirežiimis</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Võrku ei õnnestunud seadistada</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Arvutamine ...</translation> -<translation id="3974195870082915331">Parooli kuvamiseks klõpsake</translation> <translation id="3975222297214566386">Sisestusvalikute mull</translation> <translation id="397703832102027365">Lõpetamine ...</translation> <translation id="3979395879372752341">Lisati uus laiendus (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Sisestage oma sertifikaadi parool</translation> <translation id="404493185430269859">Vaikeotsingumootor</translation> <translation id="4047112090469382184">Kuidas see on turvaline?</translation> +<translation id="4051049974203704184">Hankige teavet ekraanil kuvatava kohta</translation> <translation id="4052120076834320548">Tilluke</translation> <translation id="4055023634561256217">Seade tuleb taaskäivitada, enne kui saate selle Powerwashiga lähtestada.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Anna nõusolek rühma jaoks</translation> <translation id="4089235344645910861">Seaded on salvestatud. Sünkroonimine algas.</translation> <translation id="4090103403438682346">Luba kinnitatud juurdepääs</translation> +<translation id="4090947011087001172">Kas lähtestada saidi <ph name="SITE" /> load?</translation> <translation id="4091434297613116013">paberilehed</translation> <translation id="4093955363990068916">Kohalik fail:</translation> <translation id="4095507791297118304">Peamine ekraan</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Sünkroonimise, isikupärastamise jms juhtimine</translation> <translation id="4421932782753506458">Miisu</translation> <translation id="4422347585044846479">Muuda selle lehekülje järjehoidjat</translation> -<translation id="4423104065312875417">Installi veel kõnesünteesimootoreid</translation> <translation id="4423376891418188461">Taasta seaded</translation> <translation id="4423482519432579560">&Õigekirjakontroll</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, administraator nõuab, et muudaksite parooli.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">See vahekaart esitab heli.</translation> <translation id="4450974146388585462">Diagnoosi</translation> <translation id="4453946976636652378">Otsige teenusega <ph name="SEARCH_ENGINE_NAME" /> või sisestage URL</translation> -<translation id="445923051607553918">WiFi-võrguga ühinemine</translation> <translation id="4462159676511157176">Kohandatud nimeserverid</translation> <translation id="4467100756425880649">Chrome'i veebipoe galerii</translation> <translation id="4467101674048705704">Laienda kausta <ph name="FOLDER_NAME" /></translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Taustapildid kuvatakse sisselogimisekraanil.</translation> <translation id="4684427112815847243">Sünkrooni kõik</translation> <translation id="4689421377817139245">Sünkroonige see järjehoidja oma iPhone'iga</translation> +<translation id="4690091457710545971"><Inteli WiFi püsivara lõi neli faili: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Esimesed kolm on binaarfailid, mis sisaldavad registritõmmiseid, ja Intel kinnitab, et need ei hõlma isiklikke andmeid ega seadme tuvastamist võimaldavat teavet. Viimane fail on Inteli püsivara käivitusjälg, kust on eemaldatud kõik isiklikud ja seadme andmed, ent fail on siin kuvamiseks liiga suur. Need failid loodi seadmes hiljuti esinenud WiFi probleemide tõttu ning neid jagatakse Inteliga, et hõlbustada probleemide veaotsingut.></translation> <translation id="4692302215262324251">Teie <ph name="DEVICE_TYPE" /> registreeriti ettevõtte halduse jaoks domeenil <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Kui see on ootamatu, võtke ühendust toega.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Uute seadete jõustamiseks peate lehe võib-olla uuesti laadima.</translation> <translation id="5075131525758602494">Sisestage SIM-kaardi PIN-kood</translation> <translation id="5078638979202084724">Lisab kõik vahelehed järjehoidjatesse</translation> +<translation id="5079950360618752063">Kasuta soovitatud parooli</translation> <translation id="5084230410268011727">Luba saitidel liikumis- ja valgusandureid kasutada</translation> <translation id="5085162214018721575">Värskenduste otsimine</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Kustuta see üksus</translation> <translation id="5139955368427980650">&Ava</translation> +<translation id="5142961317498132443">Autentimine</translation> <translation id="5143374789336132547">Laiendus „<ph name="EXTENSION_NAME" />” muutis seda, milline leht kuvatakse avalehe nupul klõpsamisel.</translation> <translation id="5143712164865402236">Kuvamine täisekraanil</translation> <translation id="5145331109270917438">Muutmise kuupäev</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Hoidke all juhtklahvi, klahvi Alt, tõstuklahvi või otsinguklahvi, et näha nende muuteklahvide klaviatuuri otseteid.</translation> <translation id="5382591305415226340">Toetatud linkide haldamine</translation> <translation id="5384883051496921101">See sait jagab teavet väljaspool inkognito režiimi oleva rakendusega.</translation> -<translation id="5388588172257446328">Kasutajanimi:</translation> <translation id="5388885445722491159">Seotud</translation> <translation id="5389237414310520250">Uut kasutajat ei saanud luua. Kontrollige kõvakettaruumi ja lube ning proovige uuesti.</translation> <translation id="5390100381392048184">Luba saitidel heli esitada</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Klaviatuur ja tekstisisestus</translation> <translation id="5553089923092577885">Sertifikaadi reeglite vastendused</translation> <translation id="5554489410841842733">See ikoon on nähtav, kui laiendit saab vaadataval lehel kasutada.</translation> -<translation id="5554573843028719904">Muu WiFi-võrk ...</translation> <translation id="5554720593229208774">Saatke meil sertifitseerimisorganile</translation> <translation id="5556206011531515970">Vaikebrauseri valimiseks klõpsake käsul Edasi.</translation> <translation id="5556459405103347317">Laadi uuesti</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Lülita kaamerarežiimile</translation> <translation id="5612720917913232150"><ph name="URL" /> soovib kasutada teie arvuti asukohta</translation> <translation id="5612734644261457353">Kahjuks ei saanud teie parooli kinnitada. Märkus: kui muutsite hiljuti parooli, rakendub uus parool pärast väljalogimist. Kasutage siin vana parooli.</translation> -<translation id="5613695965848159202">Anonüümne identiteet:</translation> <translation id="5614190747811328134">Teatis kasutajale</translation> <translation id="561698261642843490">Firefoxi sulgemine</translation> <translation id="5618075537869101857">Paha lugu! Kioski rakendust ei saanud käivitada.</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">Logige üksusele <ph name="TOKEN_NAME" /> sisse.</translation> <translation id="5941711191222866238">Minimeeri</translation> <translation id="5946591249682680882">Aruande ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Lisa privaatne võrk</translation> <translation id="5949544233750246342">Faili ei saa sõeluda</translation> <translation id="5955282598396714173">Teie parool on aegunud. Selle muutmiseks logige välja ja seejärel uuesti sisse.</translation> <translation id="5956585768868398362">Kas see on otsinguleht, mida ootasite?</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">Logige välja ja uuesti sisse ...</translation> <translation id="6198252989419008588">Muuda PIN-koodi</translation> <translation id="6199801702437275229">Talletusruumi teabe ootamine ...</translation> +<translation id="6204015976622790023">Laske assistendil anda teile asjakohaseid soovitusi seoses ekraanil kuvatuga.</translation> <translation id="6205710420833115353">Mõned toimingud võtavad oodatust kauem aega. Kas soovite need katkestada?</translation> <translation id="6206311232642889873">Kop&eeri pilt</translation> <translation id="6207200176136643843">Lähtesta suumi vaiketasemele</translation> <translation id="620722923698527029">Ava seda tüüpi lingid alati seotud rakenduses</translation> <translation id="6207937957461833379">Riik/regioon</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: sünkroonimine ei tööta</translation> <translation id="6212039847102026977">Kuva täpsemad võrguatribuudid</translation> <translation id="6212168817037875041">Lülita ekraan välja</translation> <translation id="6212752530110374741">Saada link meiliga</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">lähtesta sünkroonimine</translation> <translation id="6264365405983206840">Vali &kõik</translation> <translation id="6264422956566238156">Olete sünkroonimise sisse lülitanud</translation> -<translation id="6265930187414222160">Valmis! Ohtlik tarkvara eemaldati.</translation> <translation id="6267166720438879315">Valige sertifikaat, et tuvastada ennast hostile <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Ava rakendusega <ph name="APP" /></translation> <translation id="6268747994388690914">Impordi järjehoidjad HTML-failist ...</translation> @@ -3537,7 +3532,6 @@ Domeeni <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> kontole sisselogimise jätkamiseks klõpsake valikul „Järgmine”.</translation> <translation id="6419546358665792306">Laadi lahti pakkimata</translation> <translation id="642282551015776456">Seda nime ei saa faili või kausta nimena kasutada</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Ava ChromeVoxi seaded</translation> <translation id="6429384232893414837">Viga värskendamisel</translation> <translation id="6430814529589430811">Base64 kodeeritud ASCII, üks sertifikaat</translation> @@ -3618,7 +3612,6 @@ <translation id="6544215763872433504">Google'i loodud veebibrauser teie jaoks</translation> <translation id="6545665334409411530">Kordussagedus</translation> <translation id="6545834809683560467">Kasuta ennustusteenust, mis aitab lõpetada otsingud, ja URL-e, mis sisestatakse aadressiribale või rakenduste käivitaja otsingukasti</translation> -<translation id="6546686722964485737">WiMAX-i võrguga liitumine</translation> <translation id="6547316139431024316">Ära hoiata uuesti selle laienduse puhul</translation> <translation id="6547354035488017500">Vabastage vähemalt 512 MB kettaruumi, muidu seade ei reageeri. Kettaruumi vabastamiseks kustutage seadme salvestusruumist faile.</translation> <translation id="6549689063733911810">Hiljutised</translation> @@ -4037,7 +4030,6 @@ <translation id="7201014958346994077">Linuxi faile ei õnnestu vaadata</translation> <translation id="720110658997053098">Jäta seade püsivalt kioskirežiimile.</translation> <translation id="7201118060536064622">Üksus „<ph name="DELETED_ITEM_NAME" />” kustutati</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Pistikprogrammi <ph name="PLUGIN_NAME" /> allalaadimine ...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Välju lehelt}other{Välju lehtedelt}}</translation> <translation id="7216409898977639127">Mobiilsideteenuse pakkuja</translation> @@ -4515,7 +4507,6 @@ <translation id="7909969815743704077">Alla laaditud inkognito režiimis</translation> <translation id="7910768399700579500">&Uus kaust</translation> <translation id="7912080627461681647">Teie parool serveris on muutunud. Logige välja ja seejärel uuesti sisse.</translation> -<translation id="7912883689016444961">Seadista mobiilsidevõrk</translation> <translation id="7915471803647590281">Teatage meile enne tagasiside saatmist, mis toimub.</translation> <translation id="7916556741383518510">Klõpsamisel</translation> <translation id="792514962475806987">Dokitud luubi suumitase:</translation> @@ -4569,7 +4560,6 @@ <translation id="7988355189918024273">Luba juurdepääsetavuse funktsioonid</translation> <translation id="7994702968232966508">EAP meetod</translation> <translation id="799547531016638432">Eemalda otsetee</translation> -<translation id="7997479212858899587">Identiteet:</translation> <translation id="7997826902155442747">Protsessi prioriteet</translation> <translation id="7999229196265990314">Loodi järgmised failid: @@ -4653,7 +4643,6 @@ <translation id="8105368624971345109">Lülita välja</translation> <translation id="8106045200081704138">Minuga jagatud</translation> <translation id="8107015733319732394">Google Play pood installitakse teie seadmesse <ph name="DEVICE_TYPE" />. See võib võtta mõne minuti.</translation> -<translation id="8109930990200908494">Kasutaja sertifikaadi jaoks on vaja sisselogimist.</translation> <translation id="8111155949205007504">Jagage seda parooli oma iPhone'iga</translation> <translation id="8113043281354018522">Valige litsentsi tüüp</translation> <translation id="8116190140324504026">Rohkem teavet ...</translation> @@ -4664,6 +4653,7 @@ <translation id="8118860139461251237">Allalaadimiste haldamine</translation> <translation id="81238879832906896">Kollane ja valge lill</translation> <translation id="8124313775439841391">Hallatud ONC</translation> +<translation id="8125562866093998907">Sait soovib teie turvavõtme kinnitada, et teie kontot kaitsta.</translation> <translation id="813082847718468539">Kuvab saidi teabe</translation> <translation id="8131740175452115882">Kinnita</translation> <translation id="8133676275609324831">&Kuva kaustas</translation> @@ -4774,7 +4764,6 @@ <translation id="8308179586020895837">Küsi, kui sait <ph name="HOST" /> soovib juurdepääsu kaamerale</translation> <translation id="830868413617744215">Beeta</translation> <translation id="8309458809024885768">Sertifikaat on juba olemas</translation> -<translation id="8309505303672555187">Valige võrk:</translation> <translation id="8312871300878166382">Kleebi kausta</translation> <translation id="8317671367883557781">Lisa võrguühendus</translation> <translation id="8319414634934645341">Laiendatud võtmekasutus</translation> @@ -4850,7 +4839,6 @@ <translation id="8451512073679317615">assistent</translation> <translation id="8452135315243592079">SIM-kaart puudub</translation> <translation id="8453482423012550001">$1 üksuse kopeerimine ...</translation> -<translation id="8454288007744638700">Või valige uus võrk:</translation> <translation id="845627346958584683">Lõppemisaeg</translation> <translation id="8456681095658380701">Kehtetu nimi</translation> <translation id="8457451314607652708">Impordi järjehoidjad</translation> @@ -4914,6 +4902,7 @@ <translation id="855081842937141170">Kinnita vaheleht</translation> <translation id="8551388862522347954">Litsentsid</translation> <translation id="8553342806078037065">Teiste inimeste haldamine</translation> +<translation id="8554899698005018844">Keel puudub</translation> <translation id="855773602626431402">Lehel keelati liivakastist eemaldatud pistikprogrammi käitamine.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Pildi dekodeerija</translation> @@ -4951,7 +4940,6 @@ <translation id="862727964348362408">Peatatud</translation> <translation id="862750493060684461">CSS-i vahemälu</translation> <translation id="8627795981664801467">Turvalised ühendused ainult</translation> -<translation id="8628085465172583869">Serveri hosti nimi:</translation> <translation id="8630903300770275248">Impordi jälgitavad kasutajad</translation> <translation id="8631032106121706562">Kroonlehed</translation> <translation id="8637542770513281060">Teie arvuti sisaldab turvamoodulit, mida kasutatakse paljude väga tähtsate turvafunktsioonide rakendamiseks Chrome OS-is. Lisateavet leiate Chromebooki abikeskusest: https://support.google.com/chromebook/?p=sm</translation> @@ -5208,7 +5196,6 @@ <translation id="899403249577094719">Netscape'i sertifikaadi baas-URL</translation> <translation id="8995603266996330174">Haldaja: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Konto lisamine ...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Kettakujutise loomine.</translation> <translation id="9003647077635673607">Luba kõikidel veebisaitidel</translation> <translation id="9003677638446136377">Kontrolli uuesti</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index d50a6fa..94c394d 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">تقریباً زمان استراحت است</translation> <translation id="1062407476771304334">جایگزینی</translation> -<translation id="1064835277883315402">پیوستن به شبکه خصوصی</translation> <translation id="1064912851688322329">قطع ارتباط حساب Google شما</translation> <translation id="1067048845568873861">ایجاد شد</translation> <translation id="1067291318998134776">Linux (بتا)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">در حال جستجو...</translation> <translation id="1316495628809031177">همگامسازی موقتاً متوقف شده است</translation> <translation id="1319979322914001937">برنامهای که فهرست فیلترشدهای از افزونهها از فروشگاه وب Chrome را نشان میدهد. میتوان افزونهها در این فهرست را بهطور مستقیم از برنامه نصب کرد.</translation> -<translation id="132090119144658135">مطابقت موضوع:</translation> <translation id="1326317727527857210">برای دسترسی به برگههایتان در دستگاههای دیگر، به سیستم Chrome وارد شوید.</translation> <translation id="1327074568633507428">چاپگر در Google Cloud Print</translation> <translation id="1327977588028644528">دروازه</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">پنجره برنامه</translation> <translation id="1534389735079119190">خطا: محتوی درون VM شروع نشد.</translation> <translation id="15373452373711364">نشانگر موشواره بزرگ</translation> +<translation id="1540605929960647700">فعال کردن حالت نمایشی</translation> <translation id="1543284117603151572">وارد شده از Edge</translation> <translation id="1545177026077493356">حالت کیوسک خودکار</translation> <translation id="1545775234664667895">طرح زمینه نصب شده "<ph name="THEME_NAME" />"</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">با ارسال خودکار آمار استفاده و گزارشهای خرابی به Google، به بهتر شدن <ph name="PRODUCT_NAME" /> کمک کنید.</translation> <translation id="1658424621194652532">این صفحه به میکروفون شما دسترسی دارد.</translation> <translation id="1660204651932907780">به سایتها اجازه داده شود صدا پخش کنند (توصیه میشود)</translation> +<translation id="1660938185063657230">به تأیید رساندن کلید امنیتی</translation> <translation id="1661156625580498328">اجرای اجباری استاندارد رمزگذاری پیشرفته (توصیهشده).</translation> <translation id="1661245713600520330">این صفحه همه مدول های بارگیری شده در پردازش اصلی و مدول های فهرست شده را برای بارگیری در فرصت دیگری فهرست میکند.</translation> <translation id="166179487779922818">گذرواژه بیش از حد کوتاه است.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">به سایتها اجازه داده نشود به نوشتار و تصاویر کپیشده در بریدهدان دسترسی پیدا کنند</translation> <translation id="1682548588986054654">پنجره جدید ناشناس</translation> <translation id="168715261339224929">برای دریافت نشانکها در همه دستگاههایتان، همگامسازی را روشن کنید.</translation> +<translation id="1688867105868176567">دادههای سایت پاک شود؟</translation> <translation id="1688935057616748272">حرفی تایپ کنید</translation> <translation id="168991973552362966">افزودن چاپگری در این اطراف</translation> <translation id="1689945336726856614">کپی کردن &نشانی وب</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">حذف این شخص</translation> <translation id="1706586824377653884">افزودهشده توسط سرپرست سیستم</translation> <translation id="1706625117072057435">سطوح بزرگنمایی</translation> -<translation id="1707463636381878959">همرسانی این شبکه با سایر کاربران</translation> <translation id="1708338024780164500">(غیرفعال)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (شناسه: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> × <ph name="HEIGHT" /> (اصلی)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">فعال کردن طرح زمینه</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">مشاهده در «نتبازار Chrome»</translation> -<translation id="1758831820837444715">پیکربندی شبکه اترنت</translation> <translation id="1763046204212875858">ایجاد میانبرهای برنامه</translation> <translation id="1763108912552529023">به کاوش ادامه دهید</translation> <translation id="1763808908432309942">در برگه جدیدی باز میشود</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">نحوه اشتراکگذاری این فایل را تغییر دهید</translation> <translation id="1841545962859478868">سرپرست دستگاه ممکن است موارد زیر را پایش کند</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> غیرفعال شده است</translation> +<translation id="1842766183094193446">مطمئنید میخواهید حالت نمایشی را فعال کنید؟</translation> <translation id="1844692022597038441">این فایل بهصورت آفلاین در دسترس نیست.</translation> <translation id="1846308012215045257">برای اجرای <ph name="PLUGIN_NAME" /> کنترل-کلیک کنید</translation> +<translation id="1847880352285315359">ذخیره شد</translation> <translation id="1848219224579402567">خروج از سیستم، وقتی دستگاه بسته میشود</translation> <translation id="184823282865851239">اگر سایت تمایل داشته باشد آگهیهای مزاحم نشان دهد مسدود شود</translation> <translation id="1849186935225320012">این صفحه کنترل کامل دستگاههای MIDI را دارد.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">همیشه میتوانید این مورد را بعداً در تنظیمات تغییر دهید</translation> <translation id="2006638907958895361">باز کردن پیوند در <ph name="APP" /></translation> <translation id="2007404777272201486">گزارش یک مسئله...</translation> +<translation id="2016237810978710652">درحال باز کردن فایلهای Linux…</translation> <translation id="2016430552235416146">سنتی</translation> <translation id="2017334798163366053">غیرفعال کردن جمعآوری دادههای عملکرد</translation> <translation id="2017836877785168846">سابقه و تکمیل خودکار را در نوار نشانی پاک میکند.</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">ویرایش کارت</translation> <translation id="2154710561487035718">کپی نشانی وب</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> × <ph name="HEIGHT" /> بهنظر میرسد</translation> +<translation id="2156283799932971644">میتوانید با ارسال برخی از اطلاعات سیستم و محتوای صفحه به Google، به بهبود «مرور ایمن» کمک کنید.</translation> <translation id="215753907730220065">خروج از حالت تمام صفحه</translation> <translation id="2157875535253991059">این صفحه اکنون در حالت تمام صفحه است.</translation> <translation id="216169395504480358">افزودن Wi-Fi…</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">افزودن شناسه درخواست به این دستگاه</translation> <translation id="2175042898143291048">همیشه این کار انجام شود</translation> <translation id="2175607476662778685">نوار راهاندازی سریع</translation> +<translation id="2176087259161165020">سایر منابع</translation> <translation id="2177950615300672361">برگه ناشناس: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">افزایه <ph name="PEPPER_PLUGIN_NAME" /> در <ph name="PEPPER_PLUGIN_DOMAIN" /> میخواهد به رایانه شما دسترسی پیدا کند</translation> <translation id="2178614541317717477">بی اعتبارشدن CA</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">برگه بعدی</translation> <translation id="2292848386125228270">لطفاً <ph name="PRODUCT_NAME" /> را بهعنوان یک کاربر معمولی راهاندازی کنید. اگر میخواهید آن را بهعنوان ریشه برای طراحی اجرا کنید، با پرچم no-sandbox آن را دوباره اجرا کنید.</translation> <translation id="2294358108254308676">آیا میخواهید <ph name="PRODUCT_NAME" /> را نصب کنید؟</translation> -<translation id="2296019197782308739">روش EAP:</translation> <translation id="2297705863329999812">جستجوی چاپگرها</translation> <translation id="2300383962156589922">سفارشی ساختن و کنترل <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">دایرکتوری ریشه برنامهٔ افزودنی نامعتبر است.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">خطا: <ph name="APP_NAME" /> حذف نصب نشد.</translation> <translation id="2367199180085172140">افزودن فایل همرسانی</translation> <translation id="2367972762794486313">نمایش برنامهها</translation> +<translation id="2369536625682139252">همه دادههای ذخیرهشده توسط <ph name="SITE" />، بهجز کوکیها حذف خواهد شد.</translation> <translation id="2371076942591664043">پس از &تکمیل باز شود</translation> <translation id="2377319039870049694">جابهجایی به نمای فهرستی</translation> <translation id="2377667304966270281">خطاهای سختافزاری</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">چاپ با استفاده از گفتگوی سیستم... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">قبل از ارسال سؤال شود (توصیه میشود)</translation> <translation id="2384436799579181135">خطایی روی داده است. لطفاً چاپگرتان را بررسی و دوباره امتحان کنید.</translation> -<translation id="2385700042425247848">نام سرویس:</translation> <translation id="2387458720915042159">نوع اتصال پراکسی</translation> <translation id="2391419135980381625">قلم استاندارد</translation> <translation id="2391762656119864333">ابطال</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">همرسانی صوت</translation> <translation id="2480868415629598489">اصلاح دادههایی که کپی و جایگذاری میکنید</translation> <translation id="2482878487686419369">اعلانها</translation> -<translation id="2485056306054380289">گواهی CA سرور:</translation> <translation id="2485422356828889247">حذف نصب</translation> <translation id="2487067538648443797">افزودن نشانک جدید</translation> <translation id="248861575772995840">تلفنتان پیدا نمیشود. مطمئن شوید بلوتوث <ph name="DEVICE_TYPE" /> روشن است. <a>بیشتر بدانید</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">Powerwash، دستگاه <ph name="IDS_SHORT_PRODUCT_NAME" /> شما را بازنشانی میکند، به نحوی که مانند یک دستگاه جدید به نظر میرسد.</translation> <translation id="2567257616420533738">گذرواژه ذخیر شد. مشاهده و مدیریت گذرواژههای ذخیرهشده در <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">قسمت نوار اطلاعات</translation> +<translation id="2570454805927264159">بیشترین بهره را از «دستیار» ببرید</translation> <translation id="257088987046510401">طرحهای قسمت</translation> <translation id="2572032849266859634">مجوز دسترسی فقط خواندنی به <ph name="VOLUME_NAME" /> صادر شد.</translation> <translation id="2573269395582837871">انتخاب عکس و نام</translation> @@ -1095,7 +1098,6 @@ <translation id="2653659639078652383">ارائه</translation> <translation id="265390580714150011">مقدار قسمت</translation> <translation id="2654166010170466751">اجازه به سایتها برای نصب کنترلکنندههای پرداخت</translation> -<translation id="2655386581175833247">گواهی کاربر:</translation> <translation id="2660779039299703961">رویداد</translation> <translation id="266079277508604648">چاپگر متصل نشد. بررسی کنید چاپگر روشن و ازطریق Wi-Fi یا USB به Chromebook متصل باشد.</translation> <translation id="2661146741306740526">۱۶x۹</translation> @@ -1328,6 +1330,7 @@ <translation id="3006881078666935414">هیچ داده مصرفی وجود ندارد</translation> <translation id="3007214526293698309">تثبیت نسبت</translation> <translation id="3007771295016901659">کپی کردن برگه</translation> +<translation id="3008272652534848354">بازنشانی مجوزها</translation> <translation id="3009300415590184725">آیا مطمئن هستید که میخواهید مرحله تنظیم سرویس داده تلفن همراه را لغو کنید؟</translation> <translation id="3009779501245596802">پایگاههای داده فهرستبندی شده</translation> <translation id="3010279545267083280">گذرواژه حذف شد</translation> @@ -1394,7 +1397,6 @@ <translation id="3100609564180505575">مدول ها (<ph name="TOTAL_COUNT" />) - تداخل های شناخته شده: <ph name="BAD_COUNT" />، مشکوک: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">تاریخ و ساعت</translation> <translation id="310671807099593501">سایت درحال استفاده از بلوتوث شما است</translation> -<translation id="3108967419958202225">انتخاب...</translation> <translation id="3115128645424181617">تلفنتان پیدا نمیشود. مطمئن شوید در دسترس است و بلوتوث روشن است.</translation> <translation id="3115147772012638511">منتظر حافظهٔ پنهان...</translation> <translation id="3118319026408854581">راهنمای <ph name="PRODUCT_NAME" /></translation> @@ -1439,7 +1441,6 @@ <translation id="3165390001037658081">برخی شرکتهای مخابراتی ممکن است این قابلیت را مسدود کنند.</translation> <translation id="316854673539778496">برای اینکه همه افزونههایتان را در همه دستگاهها دریافت کنید، به سیستم وارد شوید و همگامسازی را روشن کنید.</translation> <translation id="3170072451822350649">همچنین میتوانید از ورود به سیستم صرفنظر کرده، <ph name="LINK_START" />به عنوان مهمان مرور کنید<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">برای پنهان کردن گذرواژه، کلیک کنید</translation> <translation id="3177909033752230686">زبان صفحه:</translation> <translation id="3181110748548073003">برای رفتن به جلو، |<ph name="SHORTCUT" />| را فشار دهید</translation> <translation id="3182749001423093222">غلطگیر املا</translation> @@ -1470,7 +1471,6 @@ <translation id="3236289833370040187">مالکیت به <ph name="DESTINATION_DOMAIN" /> منتقل میشود.</translation> <translation id="323803881985677942">باز کردن گزینههای افزونه</translation> <translation id="3241680850019875542">دایرکتوری ریشه برنامهٔ افزودنی را برای فشرده کردن انتخاب کنید. همچنین برای بهروزرسانی برنامهٔ افزودنی، فایل کلید خصوصی را برای استفاده مجدد انتخاب کنید.</translation> -<translation id="3242765319725186192">کلید از قبل مشترک شده:</translation> <translation id="3244294424315804309">همچنان بیصدا</translation> <translation id="3245321423178950146">هنرمند ناشناس</translation> <translation id="3246097286174000800">Smart Lock را امتحان کنید</translation> @@ -1603,7 +1603,6 @@ <translation id="3440663250074896476">کنشهای بیشتر برای <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">وقتی سایتی میخواهد از افزایهای برای دسترسی به رایانهتان استفاده کند، سؤال شود</translation> <translation id="3441653493275994384">صفحه</translation> -<translation id="3445830502289589282">راستیآزمایی مرحله 2:</translation> <translation id="344630545793878684">خواندن دادههای شما در تعدادی از وبسایتها</translation> <translation id="3449839693241009168"><ph name="SEARCH_KEY" /> را فشار دهید تا فرمانها به <ph name="EXTENSION_NAME" /> ارسال شود</translation> <translation id="3450157232394774192">درصد اشغال حالت بدون فعالیت</translation> @@ -1644,7 +1643,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> خطا.</translation> <translation id="3495660573538963482">تنظیمات «دستیار Google»</translation> <translation id="3496213124478423963">کوچک نمایی</translation> -<translation id="3504135463003295723">نام گروه:</translation> <translation id="3505030558724226696">لغو دسترسی دستگاه</translation> <translation id="3507421388498836150">اجازههای فعلی برای «<ph name="EXTENSION_NAME" />»</translation> <translation id="3507547268929739059">حذف برنامههای Linux برای Chromebook</translation> @@ -1753,7 +1751,6 @@ <translation id="3661054927247347545">گواهی ورود به سیستم معتبر نیست، پنجره پس از <ph name="MINUTES" />:<ph name="SECONDS" /> بسته میشود</translation> <translation id="3664511988987167893">نماد افزونه</translation> <translation id="3665589677786828986">Chrome تشخیص داد که برنامه دیگری برخی از تنظیمات شما را خراب کرده است و این تنظیمات را به پیشفرضهای اولیه آنها بازنشانی کرد.</translation> -<translation id="3665842570601375360">امنیت:</translation> <translation id="3668570675727296296">تنظیمات زبان</translation> <translation id="3668823961463113931">کنترلکنندهها</translation> <translation id="3670229581627177274">روشن کردن بلوتوث</translation> @@ -1792,7 +1789,6 @@ <translation id="3726463242007121105">این دستگاه باز نمیشود زیرا سیستم فایل آن پشتیبانی نمیشود.</translation> <translation id="3727148787322499904">تغییر این تنظیم همه شبکههای به اشتراکگذاشتهشده را تحت تأثیر قرار میدهد</translation> <translation id="3727187387656390258">بازرسی پنجره بازشو</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">خطا در خط <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">سرور SSL با ارتقا</translation> <translation id="3737536731758327622">بارگیریهایتان در اینجا نشان داده میشود</translation> @@ -1867,7 +1863,6 @@ <translation id="38275787300541712">پس از انجام کار، Enter را فشار دهید</translation> <translation id="3827774300009121996">&تمام صفحه</translation> <translation id="3828029223314399057">جستجوی نشانکها</translation> -<translation id="3829932584934971895">نوع ارائه دهنده:</translation> <translation id="3830674330436234648">بازپخش در دسترس نیست</translation> <translation id="3831486154586836914">وارد حالت مرور کلی پنجره شدید</translation> <translation id="383161972796689579">مالک این دستگاه امکان افزوده شدن کاربران جدید را غیرفعال کرده است</translation> @@ -1888,6 +1883,7 @@ <translation id="3856921555429624101">اندازهگیری مصرف داده به پایان رسیده است</translation> <translation id="3857228364945137633">وقتی تلفنتان در اطرافتان است، برای باز کردن قفل <ph name="DEVICE_TYPE" /> بدون استفاده از گذرواژه، Smart Lock را امتحان کنید.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: همگامسازی موقتاً متوقف شد</translation> <translation id="3860381078714302691">به Hangouts Meet خوش آمدید</translation> <translation id="3862134173397075045">به تجربه ارسال محتوا در Chrome خوش آمدید!</translation> <translation id="3862788408946266506">برنامهای با ویژگی مانیفست «kiosk_only» باید در حالت کیوسک سیستم عامل Chrome نصب شود</translation> @@ -1965,7 +1961,6 @@ <translation id="3968261067169026421">شبکه راهاندازی نشد</translation> <translation id="3970114302595058915">شناسه</translation> <translation id="397105322502079400">در حال محاسبه…</translation> -<translation id="3974195870082915331">برای نمایش گذرواژه، کلیک کنید</translation> <translation id="3975222297214566386">ابزارک اعلان گزینههای ورودی</translation> <translation id="397703832102027365">نهاییسازی…</translation> <translation id="3979395879372752341">افزودنههای جدید اضافه شد (<ph name="EXTENSION_NAME" />)</translation> @@ -2007,6 +2002,7 @@ <translation id="4044612648082411741">گذرواژه گواهیتان را وارد کنید</translation> <translation id="404493185430269859">موتور جستجوی پیشفرض</translation> <translation id="4047112090469382184">ایمنی آن به چه صورت است</translation> +<translation id="4051049974203704184">دریافت اطلاعات برای آنچه روی صفحه است</translation> <translation id="4052120076834320548">بسیار کوچک</translation> <translation id="4055023634561256217">قبل از اینکه دستگاه شما با Powerwash بازنشانی شود، راهاندازی مجدد لازم است.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2035,6 +2031,7 @@ <translation id="4088095054444612037">پذیرش برای گروه</translation> <translation id="4089235344645910861">تنظیمات ذخیره شد. همگامسازی شروع شد.</translation> <translation id="4090103403438682346">فعال کردن دسترسی تأییدشده</translation> +<translation id="4090947011087001172">مجوزهای سایت برای <ph name="SITE" /> بازنشانی شود؟</translation> <translation id="4091434297613116013">صفحات کاغذ</translation> <translation id="4093955363990068916">فایل محلی:</translation> <translation id="4095507791297118304">نمایشگر اصلی</translation> @@ -2211,7 +2208,6 @@ <translation id="4419556793104466535">کنترل همگامسازی، شخصیسازی و موارد دیگر</translation> <translation id="4421932782753506458">پشمالو</translation> <translation id="4422347585044846479">ویرایش نشانک برای این صفحه</translation> -<translation id="4423104065312875417">نصب موتورهای گفتار بیشتر</translation> <translation id="4423376891418188461">بازیابی تنظیمات</translation> <translation id="4423482519432579560">&غلطگیر املا</translation> <translation id="442397852638519243">سرپرستتان (<ph name="USER_NAME" />)، از شما میخواهد که گذرواژهتان را عوض کنید.</translation> @@ -2236,7 +2232,6 @@ <translation id="4449996769074858870">این برگه در حال پخش صدا است.</translation> <translation id="4450974146388585462">تشخیص</translation> <translation id="4453946976636652378">جستجوی <ph name="SEARCH_ENGINE_NAME" /> یا تایپ نشانی وب</translation> -<translation id="445923051607553918">پیوستن به شبکه Wi-Fi</translation> <translation id="4462159676511157176">سرورهای نام سفارشی</translation> <translation id="4467100756425880649">گالری فروشگاه وب Chrome</translation> <translation id="4467101674048705704">بزرگ کردن <ph name="FOLDER_NAME" /></translation> @@ -2372,6 +2367,7 @@ <translation id="4682551433947286597">تصاویر پسزمینه در صفحه ورود به سیستم نمایان میشوند.</translation> <translation id="4684427112815847243">همگامسازی همه</translation> <translation id="4689421377817139245">این نشانک را در iPhone خود همگامسازی کنید</translation> +<translation id="4690091457710545971"><چهار فایل توسط سفتافزار Wi-Fi Intel ایجاد میشود: csr.lst، fh_regs.lst، radio_reg.lst، monitor.lst.sysmon. سه فایل اول فایلهای دودویی حاوی رونوشتهای ثبت هستند و Intel تصریح کرده این فایلها حاوی اطلاعات شخصی یا اطلاعات هویتی دستگاه نیست. فایل آخر ردیابی اجرا از سفتافزار Intel است؛ هرگونه اطلاعات شخصی یا هویتی دستگاه از این فایل حذف شده اما برای نمایش در اینجا بسیار حجیم است. این فایلها جهت رفع مشکلات اخیر Wi-Fi در دستگاهتان ایجاد شده است و با Intel همرسانی خواهد شد تا به عیبیابی این مشکلات کمک کند.></translation> <translation id="4692302215262324251"><ph name="DEVICE_TYPE" /> شما باموفقیت برای مدیریت شرکت توسط <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ثبت شد. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> اگر این کار غیرمنتظره است، لطفاً با پشتیبانی تماس بگیرید.</translation> @@ -2631,6 +2627,7 @@ <translation id="5074318175948309511">شاید لازم باشد که این صفحه قبل از اعمال شدن تنظیمات جدید، بارگذاری مجدد شود.</translation> <translation id="5075131525758602494">پین سیم کارت را وارد کنید</translation> <translation id="5078638979202084724">نشانک گذاری همه برگهها</translation> +<translation id="5079950360618752063">استفاده از گذرواژه پیشنهادی</translation> <translation id="5084230410268011727">استفاده از حسگرهای نوری و حرکتی توسط سایتها مجاز شود</translation> <translation id="5085162214018721575">در حال بررسی بهروزرسانیها</translation> <translation id="5086082738160935172">HID</translation> @@ -2669,6 +2666,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">حذف این مورد</translation> <translation id="5139955368427980650">&بازکردن</translation> +<translation id="5142961317498132443">احراز هویت</translation> <translation id="5143374789336132547">افزونه «<ph name="EXTENSION_NAME" />»، صفحهای را با کلیک روی دکمه صفحه اصلی نمایش داده میشود، تغییر داده است.</translation> <translation id="5143712164865402236">رفتن به حالت تمام صفحه</translation> <translation id="5145331109270917438">تاریخ تغییر</translation> @@ -2839,7 +2837,6 @@ <translation id="5380103295189760361">برای مشاهده میانبرهای صفحه کلید مربوط به این اصلاحکنندهها کلیدهای Shift ،Alt ،Control یا Search را نگه دارید.</translation> <translation id="5382591305415226340">مدیریت پیوندهای پشتیبانیشده</translation> <translation id="5384883051496921101">این سایت میخواهد خارج از حالت ناشناس، اطلاعاتی را با برنامهای به اشتراک بگذارد.</translation> -<translation id="5388588172257446328">نام کاربری:</translation> <translation id="5388885445722491159">مرتبط شده</translation> <translation id="5389237414310520250">کاربر جدید ایجاد نشد. لطفاً فضای دیسک سخت و مجوزهایتان را بررسی کرده و دوباره امتحان کنید.</translation> <translation id="5390100381392048184">پخش صدا در سایتها مجاز شود</translation> @@ -2964,7 +2961,6 @@ <translation id="5551573675707792127">صفحهکلید و ورود نوشتار</translation> <translation id="5553089923092577885">نگاشتهای سیاست گواهی</translation> <translation id="5554489410841842733">این نماد وقتی قابل رؤیت است که برنامهٔ افزودنی بتواند برای صفحه فعلی کار کند.</translation> -<translation id="5554573843028719904">شبکههای دیگر Wi-Fi ...</translation> <translation id="5554720593229208774">ارائه دهنده مجوز رایانامه</translation> <translation id="5556206011531515970">برای انتخاب مرورگر پیشفرض روی بعدی کلیک کنید.</translation> <translation id="5556459405103347317">تازهسازی</translation> @@ -3005,7 +3001,6 @@ <translation id="5610038042047936818">تغییر به حالت دوربین</translation> <translation id="5612720917913232150"><ph name="URL" /> میخواهد از موقعیت مکانی رایانه شما استفاده کند</translation> <translation id="5612734644261457353">متأسفیم، تأیید گذرواژه شما همچنان امکانپذیر نیست. اگر بهتازگی گذرواژه خود را تغییر دادهاید، گذرواژه جدید شما هنگامیکه از سیستم خارج شدید، اعمال میشود؛ لطفاً اینجا از گذرواژه قدیمی خود استفاده کنید.</translation> -<translation id="5613695965848159202">شناسه ناشناس:</translation> <translation id="5614190747811328134">اعلامیه کاربر</translation> <translation id="561698261642843490">بستن Firefox</translation> <translation id="5618075537869101857">وای، برنامه کاربردی کیوسک راهاندازی نشد.</translation> @@ -3223,7 +3218,6 @@ <translation id="5941343993301164315">لطفاً به <ph name="TOKEN_NAME" /> وارد شوید.</translation> <translation id="5941711191222866238">کوچک کردن</translation> <translation id="5946591249682680882">شناسه گزارش <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">افزودن شبکه خصوصی</translation> <translation id="5949544233750246342">تجزیه فایل امکانپذیر نیست</translation> <translation id="5955282598396714173">گذرواژهتان منقضی شده است. لطفاً برای تغییر آن از سیستم خارج شوید و دوباره به سیستم وارد شوید.</translation> <translation id="5956585768868398362">آیا این همان صفحه جستجویی است که انتظار داشتید؟</translation> @@ -3384,11 +3378,13 @@ <translation id="6198102561359457428">خارج شده و دوباره وارد سیستم شوید...</translation> <translation id="6198252989419008588">تغییر دادن پین</translation> <translation id="6199801702437275229">منتظر اطلاعات فضا...</translation> +<translation id="6204015976622790023">دیدن پیشنهادهایی از «دستیار» که مرتبط با محتوای صفحهتان است.</translation> <translation id="6205710420833115353">برخی از کارکردها بیشتر از انتظار طول میکشند. میخواهید از آنها صرفنظر کنید؟</translation> <translation id="6206311232642889873">&کپی تصویر</translation> <translation id="6207200176136643843">بازنشانی به سطح بزرگنمایی پیشفرض</translation> <translation id="620722923698527029">همیشه این نوع پیوندها در برنامه مرتبط باز شوند</translation> <translation id="6207937957461833379">کشور/منطقه</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: همگامسازی کار نمیکند</translation> <translation id="6212039847102026977">نمایش ویژگیهای پیشرفته شبکه</translation> <translation id="6212168817037875041">خاموش کردن نمایشگر</translation> <translation id="6212752530110374741">پیوند رایانامه</translation> @@ -3426,7 +3422,6 @@ <translation id="6263541650532042179">بازنشانی همگامسازی</translation> <translation id="6264365405983206840">انتخاب &همه</translation> <translation id="6264422956566238156">همگامسازی را روشن کردید</translation> -<translation id="6265930187414222160">تمام شد! نرمافزار مضر برداشته شد.</translation> <translation id="6267166720438879315">انتخاب گواهی برای راستیآزمایی خودتان در <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">باز کردن با <ph name="APP" /></translation> <translation id="6268747994388690914">وارد کردن نشانکها از فایل HTML...</translation> @@ -3533,7 +3528,6 @@ برای ادامه ورود به سیستم در حساب <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> خود، لطفاً روی «بعدی» کلیک کنید.</translation> <translation id="6419546358665792306">بار کردن غیرفشرده</translation> <translation id="642282551015776456">این نام ممکن است بهعنوان نام فایلی از پوشه استفاده نشود</translation> -<translation id="6423239382391657905">باز کردن VPN</translation> <translation id="6426200009596957090">باز کردن تنظیمات ChromeVox</translation> <translation id="6429384232893414837">خطای بهروزرسانی</translation> <translation id="6430814529589430811">Base64-ASCII رمزدار، تک گواهی</translation> @@ -3614,7 +3608,6 @@ <translation id="6544215763872433504">مرورگر وب از Google، برای شما</translation> <translation id="6545665334409411530">سرعت تکرار</translation> <translation id="6545834809683560467">استفاده از یک سرویس پیشبینی برای کمک به تکمیل جستجوها و نشانیهای وب تایپ شده در نوار آدرس یا کادر جستجوی راهانداز برنامه</translation> -<translation id="6546686722964485737">پیوستن به شبکه Wimax</translation> <translation id="6547316139431024316">برای این برنامه افزودنی دیگر هشدار داده نشود</translation> <translation id="6547354035488017500">اگر حداقل ۵۱۲ مگابایت از حافظه دستگاه را خالی نکنید، پاسخگویی دستگاه متوقف خواهد شد. برای آزاد کردن فضا، فایلها را از حافظه دستگاه حذف کنید.</translation> <translation id="6549689063733911810">اخیر</translation> @@ -4033,7 +4026,6 @@ <translation id="7201014958346994077">نمیتوان فایلهای Linux را مشاهده کرد</translation> <translation id="720110658997053098">این دستگاه همیشه در حالت کیوسک نگه داشته شود</translation> <translation id="7201118060536064622">«<ph name="DELETED_ITEM_NAME" />» حذف شد</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">در حال بارگیری <ph name="PLUGIN_NAME" />…</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{خروج از صفحه}one{خروج از صفحهها}other{خروج از صفحهها}}</translation> <translation id="7216409898977639127">ارائهدهنده شبکه تلفن همراه</translation> @@ -4511,7 +4503,6 @@ <translation id="7909969815743704077">دانلودشده در ناشناس</translation> <translation id="7910768399700579500">پوشه &جدید</translation> <translation id="7912080627461681647">گذرواژهتان در سرور تغییر کرده است. لطفاً از سیستم خارج شوید و سپس دوباره به سیستم وارد شوید.</translation> -<translation id="7912883689016444961">پیکربندی شبکه تلفن همراه</translation> <translation id="7915471803647590281">لطفاً قبل از ارسال بازخورد، به ما بگویید چه اتفاقی در حال وقوع است.</translation> <translation id="7916556741383518510">با کلیک</translation> <translation id="792514962475806987">میزان بزرگنمایی متصل:</translation> @@ -4565,7 +4556,6 @@ <translation id="7988355189918024273">فعالسازی ویژگیهای دسترسی</translation> <translation id="7994702968232966508">روش EAP</translation> <translation id="799547531016638432">حذف میانبر</translation> -<translation id="7997479212858899587">هویت:</translation> <translation id="7997826902155442747">پردازش اولویتدار</translation> <translation id="7999229196265990314">فایلهای زیر ایجاد شده است: @@ -4649,7 +4639,6 @@ <translation id="8105368624971345109">خاموش کردن</translation> <translation id="8106045200081704138">اشتراکگذاری شده با من</translation> <translation id="8107015733319732394">«فروشگاه Google Play» در <ph name="DEVICE_TYPE" /> شما درحال نصب شدن است. ممکن است این کار چند دقیقه طول بکشد.</translation> -<translation id="8109930990200908494">ورود به سیستم برای گواهینامه کاربر مورد نیاز است.</translation> <translation id="8111155949205007504">اشتراکگذاری این گذرواژه با iPhone</translation> <translation id="8113043281354018522">انتخاب نوع مجوز</translation> <translation id="8116190140324504026">اطلاعات بیشتر...</translation> @@ -4660,6 +4649,7 @@ <translation id="8118860139461251237">مدیریت بارگیریها</translation> <translation id="81238879832906896">گل زرد و سفید</translation> <translation id="8124313775439841391">ONC مدیریت شده</translation> +<translation id="8125562866093998907">این سایت میخواهد «کلید امنیتی» مربوط به امنیت اضافهشده حسابتان را به تأیید برساند.</translation> <translation id="813082847718468539">مشاهدهٔ اطلاعات سایت</translation> <translation id="8131740175452115882">تأیید</translation> <translation id="8133676275609324831">&نمایش در پوشه</translation> @@ -4770,7 +4760,6 @@ <translation id="8308179586020895837">اگر <ph name="HOST" /> میخواهد به دوربین شما دسترسی داشته باشد از من سوال شود</translation> <translation id="830868413617744215">بتا</translation> <translation id="8309458809024885768">گواهی درحالحاضر وجود دارد</translation> -<translation id="8309505303672555187">انتخاب شبکه:</translation> <translation id="8312871300878166382">جایگذاری در پوشه</translation> <translation id="8317671367883557781">افزودن اتصال شبکه</translation> <translation id="8319414634934645341">کاربرد کلید توسعه یافته</translation> @@ -4845,7 +4834,6 @@ <translation id="8451512073679317615">دستیار</translation> <translation id="8452135315243592079">سیمکارت وجود ندارد</translation> <translation id="8453482423012550001">در حال کپی $1 مورد...</translation> -<translation id="8454288007744638700">یا یک شبکه جدید انتخاب کنید:</translation> <translation id="845627346958584683">زمان انقضا</translation> <translation id="8456681095658380701">نام نامعتبر</translation> <translation id="8457451314607652708">وارد کردن نشانکها</translation> @@ -4909,6 +4897,7 @@ <translation id="855081842937141170">پین کردن برگه</translation> <translation id="8551388862522347954">مجوزها</translation> <translation id="8553342806078037065">مدیریت افراد دیگر</translation> +<translation id="8554899698005018844">زبانی موجود نیست</translation> <translation id="855773602626431402">از اجرای یک افزایه آزمایشی نشده در این صفحه جلوگیری شد.</translation> <translation id="8557930019681227453">مانیفست</translation> <translation id="8559694214572302298">کدگشای تصویر</translation> @@ -4946,7 +4935,6 @@ <translation id="862727964348362408">معلق شد</translation> <translation id="862750493060684461">حافظهٔ پنهان CSS</translation> <translation id="8627795981664801467">فقط اتصالات ایمن</translation> -<translation id="8628085465172583869">نام سرور میزبان:</translation> <translation id="8630903300770275248">وارد کردن کاربر نظارت شده</translation> <translation id="8631032106121706562">گل</translation> <translation id="8637542770513281060">رایانه شما مدول امنی دارد که برای پیادهسازی بسیاری از قابلیتهای امنیتی ضروری در سیستمعامل Chrome استفاده میشود. برای اطلاعات بیشتر از «مرکز راهنمایی Chromebook» دیدن کنید: https://support.google.com/chromebook/?p=sm</translation> @@ -5202,7 +5190,6 @@ <translation id="899403249577094719">نشانی وب گواهی Netscape</translation> <translation id="8995603266996330174">مدیریت شده توسط <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">افزودن حساب...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">درحال ایجاد تصویر دیسک.</translation> <translation id="9003647077635673607">در همه وبسایتها مجاز باشد</translation> <translation id="9003677638446136377">بررسی مجدد</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb index b2f08a2..483846c6 100644 --- a/chrome/app/resources/generated_resources_fi.xtb +++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK-koodi</translation> <translation id="1061904396131502319">Pian on tauon paikka</translation> <translation id="1062407476771304334">Korvaa</translation> -<translation id="1064835277883315402">Liity VPN-verkkoon</translation> <translation id="1064912851688322329">Irrota Google-tilisi</translation> <translation id="1067048845568873861">Luotu</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Haetaan...</translation> <translation id="1316495628809031177">Synkronointi on keskeytetty</translation> <translation id="1319979322914001937">Sovellus, joka näyttää suodatetun luettelon laajennuksia Chrome Web Storesta. Luettelon laajennukset voi asentaa suoraan sovelluksesta.</translation> -<translation id="132090119144658135">Aiheen vastaavuus:</translation> <translation id="1326317727527857210">Käytä välilehtiä muilta laitteiltasi kirjautumalla Chromeen.</translation> <translation id="1327074568633507428">Tulostin Google Cloud Printissä</translation> <translation id="1327977588028644528">Yhdyskäytävä</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Poista tämä henkilö</translation> <translation id="1706586824377653884">Järjestelmänvalvojan lisäämä</translation> <translation id="1706625117072057435">Zoomaustasot</translation> -<translation id="1707463636381878959">Jaa tämä verkosto muiden käyttäjien kanssa</translation> <translation id="1708338024780164500">(Ei-aktiivinen)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (tunnus: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (natiivitarkkuus)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Ota teema käyttöön</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Näytä Chrome Web Storessa</translation> -<translation id="1758831820837444715">Määritä Ethernet-verkko</translation> <translation id="1763046204212875858">Luo sovelluspikakuvakkeita</translation> <translation id="1763108912552529023">Jatka tutkimista</translation> <translation id="1763808908432309942">Avautuu uuteen välilehteen</translation> @@ -875,7 +871,6 @@ <translation id="2291643155573394834">Seuraava välilehti</translation> <translation id="2292848386125228270">Käynnistä <ph name="PRODUCT_NAME" /> tavallisena käyttäjänä. Jos sinun on käytettävä sitä pääkäyttäjänä, käynnistä se uudelleen --no-sandbox-merkinnän kanssa.</translation> <translation id="2294358108254308676">Haluatko asentaa tuotteen <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP-tapa:</translation> <translation id="2297705863329999812">Hae tulostimia</translation> <translation id="2300383962156589922">Muokkaus ja hallinta: <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Laajennuksen juurihakemisto on virheellinen.</translation> @@ -933,7 +928,6 @@ <translation id="2379281330731083556">Tulosta järjestelmän tulostusikkunalla... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Kysy ennen lähettämistä (suositus)</translation> <translation id="2384436799579181135">Tapahtui virhe. Tarkista tulostimesi ja yritä uudelleen.</translation> -<translation id="2385700042425247848">Palvelun nimi:</translation> <translation id="2387458720915042159">Välityspalvelinyhteyden tyyppi</translation> <translation id="2391419135980381625">Peruskirjasin</translation> <translation id="2391762656119864333">Peruuta</translation> @@ -984,7 +978,6 @@ <translation id="247949520305900375">Jaa ääni</translation> <translation id="2480868415629598489">muokata kopioituja ja liitettyjä tietoja</translation> <translation id="2482878487686419369">Ilmoitukset</translation> -<translation id="2485056306054380289">Palvelimen CA-varmenne:</translation> <translation id="2485422356828889247">Poista</translation> <translation id="2487067538648443797">Lisää kirjanmerkki</translation> <translation id="248861575772995840">Puhelintasi ei löydy. Varmista, että laitteen <ph name="DEVICE_TYPE" /> Bluetooth on otettu käyttöön. <a>Lisätietoja</a></translation> @@ -1110,7 +1103,6 @@ <translation id="2653659639078652383">Lähetä</translation> <translation id="265390580714150011">Kentän arvo</translation> <translation id="2654166010170466751">Salli sivustojen asentaa maksujen käsittelijöitä</translation> -<translation id="2655386581175833247">Käyttäjävarmenne:</translation> <translation id="2660779039299703961">Tapahtuma</translation> <translation id="266079277508604648">Tulostimeen yhdistäminen epäonnistui. Tarkista, että tulostin on päällä ja yhteydessä Chromebookiin Wi-Fi-yhteydellä tai USB:llä.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1410,7 +1402,6 @@ <translation id="3100609564180505575">Moduulit (<ph name="TOTAL_COUNT" />) - Tunnettuja ristiriitoja: <ph name="BAD_COUNT" />, epäiltyjä: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Aika ja päivämäärä</translation> <translation id="310671807099593501">Sivusto käyttää Bluetoothia</translation> -<translation id="3108967419958202225">Valitse...</translation> <translation id="3115128645424181617">Puhelintasi ei löydy. Varmista, että se on mukanasi ja että Bluetooth on päällä.</translation> <translation id="3115147772012638511">Odotetaan välimuistia...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Ohje</translation> @@ -1455,7 +1446,6 @@ <translation id="3165390001037658081">Jotkin operaattorit saattavat estää tämän ominaisuuden.</translation> <translation id="316854673539778496">Kirjaudu sisään ja ota synkronointi käyttöön, niin voit käyttää laajennuksiasi kaikilla laitteilla.</translation> <translation id="3170072451822350649">Voit myös ohittaa sisäänkirjautumisen ja <ph name="LINK_START" />selata vierailijana<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Piilota salasana klikkaamalla</translation> <translation id="3177909033752230686">Sivun kieli:</translation> <translation id="3181110748548073003">Siirry eteenpäin painamalla |<ph name="SHORTCUT" />|.</translation> <translation id="3182749001423093222">Oikeinkirjoituksen tarkistus</translation> @@ -1486,7 +1476,6 @@ <translation id="3236289833370040187">Omistajuus siirtyy verkkotunnukselle <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Avaa laajennusasetukset.</translation> <translation id="3241680850019875542">Voit pakata laajennuksen valitsemalla sen juurihakemiston. Jos haluat päivittää laajennuksen, valitse myös yksityinen avaintiedosto, jotta laajennusta voidaan käyttää uudelleen.</translation> -<translation id="3242765319725186192">Esijaettu avain:</translation> <translation id="3244294424315804309">Jatka äänen mykistystä</translation> <translation id="3245321423178950146">Tuntematon esittäjä</translation> <translation id="3246097286174000800">Kokeile Smart Lockia</translation> @@ -1619,7 +1608,6 @@ <translation id="3440663250074896476">Lisää toimintoja: <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Kysy aina, kun sivusto haluaa käyttää tietokonettasi laajennuksen avulla</translation> <translation id="3441653493275994384">Näyttö</translation> -<translation id="3445830502289589282">Vaihe 2: Todennus</translation> <translation id="344630545793878684">Lukea tietojasi useissa sivustoissa</translation> <translation id="3449839693241009168">Lähetä laajennukselle <ph name="EXTENSION_NAME" /> komentoja painamalla <ph name="SEARCH_KEY" /></translation> <translation id="3450157232394774192">Käyttämätön-tilan käyttöprosentti</translation> @@ -1660,7 +1648,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> virhettä.</translation> <translation id="3495660573538963482">Google Assistantin asetukset</translation> <translation id="3496213124478423963">Loitonna</translation> -<translation id="3504135463003295723">Ryhmän nimi:</translation> <translation id="3505030558724226696">Peruuta laitteen käyttöoikeus</translation> <translation id="3507421388498836150">Laajennuksen <ph name="EXTENSION_NAME" /> nykyiset käyttöoikeudet</translation> <translation id="3507547268929739059">Poista Linux-sovellukset Chromebookista</translation> @@ -1769,7 +1756,6 @@ <translation id="3661054927247347545">Kirjautumisen varmenne ei kelpaa, ikkuna sulkeutuu <ph name="MINUTES" /> minuutin ja <ph name="SECONDS" /> sekunnin kuluttua.</translation> <translation id="3664511988987167893">Laajennuskuvake</translation> <translation id="3665589677786828986">Chrome havaitsi, että toinen ohjelma oli muokannut joitakin selainasetuksia, ja palautti asetukset alkuperäisiksi.</translation> -<translation id="3665842570601375360">Turvallisuus:</translation> <translation id="3668570675727296296">Kieliasetukset</translation> <translation id="3668823961463113931">Käsittelypalvelut</translation> <translation id="3670229581627177274">Ota Bluetooth käyttöön</translation> @@ -1808,7 +1794,6 @@ <translation id="3726463242007121105">Tätä laitetta ei voi avata, sillä sen tiedostojärjestelmää ei tueta.</translation> <translation id="3727148787322499904">Tämän asetuksen muuttaminen vaikuttaa kaikkiin jaettuihin verkkoihin.</translation> <translation id="3727187387656390258">Näytä ponnahdusikkuna</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Virhe rivillä <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-palvelin ja Step-up</translation> <translation id="3737536731758327622">Latauksesi näkyvät täällä.</translation> @@ -1883,7 +1868,6 @@ <translation id="38275787300541712">Paina Enter, kun olet valmis</translation> <translation id="3827774300009121996">&Koko näyttö</translation> <translation id="3828029223314399057">Hae kirjanmerkeistä</translation> -<translation id="3829932584934971895">Verkon tarjoajan tyyppi:</translation> <translation id="3830674330436234648">Toistoa ei ole saatavilla.</translation> <translation id="3831486154586836914">Siirryttiin ikkunoiden yleiskatsaustilaan</translation> <translation id="383161972796689579">Tämän laitteen omistaja on estänyt uusien käyttäjien lisäämisen</translation> @@ -1979,7 +1963,6 @@ <translation id="3968261067169026421">Verkon määritys epäonnistui</translation> <translation id="3970114302595058915">Tunnus</translation> <translation id="397105322502079400">Lasketaan...</translation> -<translation id="3974195870082915331">Näytä salasana klikkaamalla</translation> <translation id="3975222297214566386">Syöttöasetuskupla</translation> <translation id="397703832102027365">Viimeistellään...</translation> <translation id="3979395879372752341">Uusi laajennus lisätty (<ph name="EXTENSION_NAME" />)</translation> @@ -2227,7 +2210,6 @@ <translation id="4419556793104466535">Hallitse synkronointia, personointia ja muuta</translation> <translation id="4421932782753506458">Pörrö</translation> <translation id="4422347585044846479">Muokkaa tämän sivun kirjanmerkkiä</translation> -<translation id="4423104065312875417">Asenna lisää puhemoottoreita</translation> <translation id="4423376891418188461">Palauta asetukset</translation> <translation id="4423482519432579560">&Oikoluku</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, järjestelmänvalvojasi vaatii sinua vaihtamaan salasanasi.</translation> @@ -2252,7 +2234,6 @@ <translation id="4449996769074858870">Tämä välilehti toistaa ääntä.</translation> <translation id="4450974146388585462">Diagnosoi</translation> <translation id="4453946976636652378">Tee <ph name="SEARCH_ENGINE_NAME" />-haku tai kirjoita URL-osoite</translation> -<translation id="445923051607553918">Yhdistä Wi-Fi-verkkoon</translation> <translation id="4462159676511157176">Omat nimipalvelimet</translation> <translation id="4467100756425880649">Chrome Web Store Gallery</translation> <translation id="4467101674048705704">Laajenna <ph name="FOLDER_NAME" /></translation> @@ -2858,7 +2839,6 @@ <translation id="5380103295189760361">Kun painat pitkään Control-, Alt-, Shift- tai hakunäppäintä, näet sen pikanäppäimet.</translation> <translation id="5382591305415226340">Hallinnoi tuettuja linkkejä</translation> <translation id="5384883051496921101">Tämä sivusto aikoo jakaa tietoja sovellukselle incognito-tilan ulkopuolella.</translation> -<translation id="5388588172257446328">Käyttäjätunnus:</translation> <translation id="5388885445722491159">Laitepari muodostettu</translation> <translation id="5389237414310520250">Uuden käyttäjän luominen epäonnistui. Tarkista kiintolevytila ja käyttöluvat ja yritä sitten uudelleen.</translation> <translation id="5390100381392048184">Salli sivustojen toistaa ääniä</translation> @@ -2983,7 +2963,6 @@ <translation id="5551573675707792127">Näppäimistö ja tekstinsyöttö</translation> <translation id="5553089923092577885">Varmenteen käytäntökytkennät</translation> <translation id="5554489410841842733">Tämä kuvake näytetään, kun laajennus voi toimia nykyisellä sivulla.</translation> -<translation id="5554573843028719904">Muu Wi-Fi-verkko...</translation> <translation id="5554720593229208774">Sähköpostivarmenteen myöntäjä</translation> <translation id="5556206011531515970">Valitse oletusselain klikkaamalla seuraava.</translation> <translation id="5556459405103347317">Lataa uudelleen</translation> @@ -3024,7 +3003,6 @@ <translation id="5610038042047936818">Vaihda kameratilaan</translation> <translation id="5612720917913232150"><ph name="URL" /> haluaa käyttää tietokoneesi sijaintia.</translation> <translation id="5612734644261457353">Salasanan vahvistaminen ei onnistunut vieläkään. Huomaa: Jos vaihdoit salasanasi äskettäin, uusi salasana otetaan käyttöön kirjauduttuasi ulos. Käytä tässä vanhaa salasanaasi.</translation> -<translation id="5613695965848159202">Anonyymi henkilöllisyys:</translation> <translation id="5614190747811328134">Käyttäjäilmoitus</translation> <translation id="561698261642843490">Sulje Firefox</translation> <translation id="5618075537869101857">Samperi, kioskisovelluksen käynnistäminen ei onnistu.</translation> @@ -3242,7 +3220,6 @@ <translation id="5941343993301164315">Kirjaudu sisään palveluun <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Pienennä</translation> <translation id="5946591249682680882">Raporttitunnus: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Lisää salattu verkko</translation> <translation id="5949544233750246342">Tiedoston jäsentäminen ei onnistu.</translation> <translation id="5955282598396714173">Salasana on vanhentunut. Kirjaudu ulos ja uudelleen sisään, niin voit vaihtaa sen.</translation> <translation id="5956585768868398362">Onko tämä haluamasi hakusivu?</translation> @@ -3449,7 +3426,6 @@ <translation id="6263541650532042179">nollaa synkronointi</translation> <translation id="6264365405983206840">Valitse k&aikki</translation> <translation id="6264422956566238156">Synkronointi on käytössä</translation> -<translation id="6265930187414222160">Valmista. Haittaohjelmia poistettiin.</translation> <translation id="6267166720438879315">Valitse varmenne, jolla todennat itsesi kohteelle <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Avaa sovelluksella <ph name="APP" /></translation> <translation id="6268747994388690914">Tuo kirjanmerkit HTML-tiedostosta...</translation> @@ -3556,7 +3532,6 @@ Jatka tilillesi (<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />) kirjautumista valitsemalla Seuraava.</translation> <translation id="6419546358665792306">Lataus purettu</translation> <translation id="642282551015776456">Tätä nimeä ei voi käyttää tiedoston tai kansion nimenä.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Avaa ChromeVox-asetukset</translation> <translation id="6429384232893414837">Päivitysvirhe</translation> <translation id="6430814529589430811">Base64-koodattu ASCII, yksittäinen varmenne</translation> @@ -3637,7 +3612,6 @@ <translation id="6544215763872433504">Googlen verkkoselain, juuri sinulle</translation> <translation id="6545665334409411530">Toistonopeus</translation> <translation id="6545834809683560467">Käytä ennakointipalvelua, niin osoitepalkkiin tai sovelluksien käynnistysohjelman hakukenttään kirjoitetut hakulausekkeet ja URL-osoitteet täydennetään</translation> -<translation id="6546686722964485737">Muodosta yhteys WiMAX-verkkoon</translation> <translation id="6547316139431024316">Älä varoita uudelleen tästä laajennuksesta</translation> <translation id="6547354035488017500">Vapauta vähintään 512 Mt tilaa, tai laite ei enää vastaa. Voit vapauttaa tilaa poistamalla laitteelle tallennettuja tiedostoja.</translation> <translation id="6549689063733911810">Viimeisimmät</translation> @@ -4056,7 +4030,6 @@ <translation id="7201014958346994077">Linux-tiedostoja ei voi näyttää</translation> <translation id="720110658997053098">Pidä tämä laite pysyvästi kioskitilassa</translation> <translation id="7201118060536064622"><ph name="DELETED_ITEM_NAME" /> poistettu</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Ladataan <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Sulje sivu}other{Sulje sivut}}</translation> <translation id="7216409898977639127">Mobiilioperaattori</translation> @@ -4533,7 +4506,6 @@ <translation id="7909969815743704077">Ladattiin incognito-tilassa</translation> <translation id="7910768399700579500">&Uusi kansio</translation> <translation id="7912080627461681647">Salasana vaihdettiin palvelimella. Kirjaudu ulos ja sitten uudelleen sisään.</translation> -<translation id="7912883689016444961">Mobiiliverkon määritys</translation> <translation id="7915471803647590281">Kerro meille tapahtumista ennen kun lähetät palautteen.</translation> <translation id="7916556741383518510">Klikkaamalla</translation> <translation id="792514962475806987">Kiinnitetyn zoomauksen taso:</translation> @@ -4587,7 +4559,6 @@ <translation id="7988355189918024273">Ota käyttöön esteettömyystoimintoja</translation> <translation id="7994702968232966508">EAP-tapa</translation> <translation id="799547531016638432">Poista pikakuvake</translation> -<translation id="7997479212858899587">Identiteetti:</translation> <translation id="7997826902155442747">Prosessien tärkeysjärjestys</translation> <translation id="7999229196265990314">Luotiin seuraavat tiedostot: @@ -4671,7 +4642,6 @@ <translation id="8105368624971345109">Poista käytöstä</translation> <translation id="8106045200081704138">Jaettu minun kanssani</translation> <translation id="8107015733319732394"><ph name="DEVICE_TYPE" /> asentaa Google Play Kauppaa. Tämä voi kestää pari minuuttia.</translation> -<translation id="8109930990200908494">Käyttäjävarmenteen käyttö edellyttää kirjautumista.</translation> <translation id="8111155949205007504">Jaa tämä salasana iPhonellesi</translation> <translation id="8113043281354018522">Valitse lisenssityyppi</translation> <translation id="8116190140324504026">Lisätietoja...</translation> @@ -4793,7 +4763,6 @@ <translation id="8308179586020895837">Kysy, jos <ph name="HOST" /> haluaa käyttää kameraasi</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Sertifikaatti on jo olemassa.</translation> -<translation id="8309505303672555187">Valitse verkko:</translation> <translation id="8312871300878166382">Liitä kansioon</translation> <translation id="8317671367883557781">Lisää verkkoyhteys</translation> <translation id="8319414634934645341">Laajennettu avaimen käyttö</translation> @@ -4868,7 +4837,6 @@ <translation id="8451512073679317615">assistant</translation> <translation id="8452135315243592079">SIM-kortti puuttuu.</translation> <translation id="8453482423012550001">Kopioidaan $1 kohdetta…</translation> -<translation id="8454288007744638700">Tai valitse uusi verkko:</translation> <translation id="845627346958584683">Päättymisaika</translation> <translation id="8456681095658380701">Nimi ei kelpaa</translation> <translation id="8457451314607652708">Tuo kirjanmerkkejä</translation> @@ -4970,7 +4938,6 @@ <translation id="862727964348362408">Pysäytetty</translation> <translation id="862750493060684461">CSS-välimuisti</translation> <translation id="8627795981664801467">Vain suojatut yhteydet</translation> -<translation id="8628085465172583869">Palvelimen verkkoaseman tunnus:</translation> <translation id="8630903300770275248">Tuo valvottu käyttäjä</translation> <translation id="8631032106121706562">Kukka</translation> <translation id="8637542770513281060">Tietokoneesi sisältää suojausmoduulin, jonka avulla käytetään monia tärkeitä turvallisuusominaisuuksia Chrome-käyttöjärjestelmässä. Lisätietoja on Chromebook-ohjekeskuksessa: https://support.google.com/chromebook/?p=sm</translation> @@ -5226,7 +5193,6 @@ <translation id="899403249577094719">Netscape-varmenteen URL-osoite</translation> <translation id="8995603266996330174">Hallinnoija: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Lisää tili…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Luodaan näköistiedostoa.</translation> <translation id="9003647077635673607">Salli kaikissa verkkosivustoissa</translation> <translation id="9003677638446136377">Tarkista uudelleen</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb index d5df9c7..7628b06 100644 --- a/chrome/app/resources/generated_resources_fil.xtb +++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Halos oras na para magpahinga</translation> <translation id="1062407476771304334">Palitan</translation> -<translation id="1064835277883315402">Sumali sa pribadong network</translation> <translation id="1064912851688322329">Idiskonekta ang iyong Google Account</translation> <translation id="1067048845568873861">Ginawa</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Naghahanap...</translation> <translation id="1316495628809031177">Naka-pause ang pag-sync</translation> <translation id="1319979322914001937">Isang app na nagpapakita ng naka-filter na listahan ng mga extension mula sa Chrome Web Store. Maaaring i-install nang direkta ang mga extension mula sa app.</translation> -<translation id="132090119144658135">Pagtugma ng Paksa:</translation> <translation id="1326317727527857210">Upang makuha ang iyong mga tab mula sa iba mo pang mga device, mag-sign in sa Chrome.</translation> <translation id="1327074568633507428">Printer sa Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Window ng Application</translation> <translation id="1534389735079119190">ERROR: Hindi nasimulan ang container sa loob ng VM.</translation> <translation id="15373452373711364">Malaking mouse cursor</translation> +<translation id="1540605929960647700">I-enable ang demo mode</translation> <translation id="1543284117603151572">Na-import Mula Sa Edge</translation> <translation id="1545177026077493356">Awtomatikong Kiosk Mode</translation> <translation id="1545775234664667895">Naka-install na temang "<ph name="THEME_NAME" />"</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Tulungan ang <ph name="PRODUCT_NAME" /> na maging mas mahusay sa pamamagitan ng awtomatikong pagpapadala ng mga istatistika ng paggamit at mga crash report sa Google</translation> <translation id="1658424621194652532">Ina-access ng pahinang ito ang iyong mikropono.</translation> <translation id="1660204651932907780">Payagan ang mga site na mag-play ng tunog (inirerekomenda)</translation> +<translation id="1660938185063657230">I-verify ang iyong Security Key</translation> <translation id="1661156625580498328">Ipatupad ang AES encryption (inirerekomenda).</translation> <translation id="1661245713600520330">Inililista ng pahinang ito ang lahat ng mga module na na-load sa pangunahing pagpoproseso at mga module na nairehistro upang i-load sa ibang pagkakataon.</translation> <translation id="166179487779922818">Masyadong maikli ang password.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Huwag payagan ang mga site na makita ang text at mga larawang kinopya sa clipboard</translation> <translation id="1682548588986054654">New Incognito Window</translation> <translation id="168715261339224929">Upang mailagay ang iyong mga bookmark sa lahat ng device mo, i-on ang sync.</translation> +<translation id="1688867105868176567">I-clear ang data ng site?</translation> <translation id="1688935057616748272">Mag-type ng titik</translation> <translation id="168991973552362966">Magdagdag ng kalapit na printer</translation> <translation id="1689945336726856614">Kopyahin ang &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Alisin ang taong ito</translation> <translation id="1706586824377653884">Idinagdag ng iyong administrator</translation> <translation id="1706625117072057435">Mga antas ng pag-zoom</translation> -<translation id="1707463636381878959">Ibahagi ang network na ito sa iba pang mga user</translation> <translation id="1708338024780164500">(Hindi aktibo)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Native)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Paganahin ang tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Tingnan sa Chrome Web Store</translation> -<translation id="1758831820837444715">I-configure ang network ng Ethernet</translation> <translation id="1763046204212875858">Gumawa ng mga shortcut ng application</translation> <translation id="1763108912552529023">Magpatuloy sa pag-explore</translation> <translation id="1763808908432309942">Magbubukas sa bagong tab</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Baguhin kung paano ibinabahagi ang file na ito</translation> <translation id="1841545962859478868">Maaaring subaybayan ng admin ng device ang mga sumusunod:</translation> <translation id="1841705068325380214">Naka-disable ang <ph name="EXTENSION_NAME" /></translation> +<translation id="1842766183094193446">Sigurado ka bang gusto mong i-enable ang demo mode?</translation> <translation id="1844692022597038441">Hindi available offline ang file na ito.</translation> <translation id="1846308012215045257">Pindutin ang control at i-click upang patakbuhin ang <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Na-save</translation> <translation id="1848219224579402567">Mag-sign out kapag isinara ang takip</translation> <translation id="184823282865851239">I-block kung malamang na magpakita ang site ng mga nakakasagabal na ad</translation> <translation id="1849186935225320012">May buong kontrol sa mga MIDI device ang pahinang ito.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Maaari mo itong baguhin sa mga setting sa ibang pagkakataon, anumang oras</translation> <translation id="2006638907958895361">Buksan ang Link sa <ph name="APP" /></translation> <translation id="2007404777272201486">Mag-ulat ng Isyu...</translation> +<translation id="2016237810978710652">Binubuksan ang Mga Linux File...</translation> <translation id="2016430552235416146">Tradisyonal</translation> <translation id="2017334798163366053">I-disable ang pagkolekta ng data ng pagganap</translation> <translation id="2017836877785168846">Kini-clear ang history at mga awtomatikong pagkumpleto sa address bar.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">I-edit ang card</translation> <translation id="2154710561487035718">Kopyahin ang URL</translation> <translation id="2155772377859296191">Mukhang <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Makakatulong ka sa pagpapahusay ng Ligtas na Pag-browse sa pamamagitan ng pagpapadala ng ilang impormasyon ng system at content ng page sa Google.</translation> <translation id="215753907730220065">Umalis sa Full Screen</translation> <translation id="2157875535253991059">Full screen na ngayon ang pahinang ito.</translation> <translation id="216169395504480358">Magdagdag ng Wi-Fi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Magdagdag ng requisition ID sa device na ito</translation> <translation id="2175042898143291048">Palagi itong gawin</translation> <translation id="2175607476662778685">Quick launch bar</translation> +<translation id="2176087259161165020">Iba pang source</translation> <translation id="2177950615300672361">Tab na Incognito: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Gustong i-access ng <ph name="PEPPER_PLUGIN_NAME" /> sa <ph name="PEPPER_PLUGIN_DOMAIN" /> ang iyong computer</translation> <translation id="2178614541317717477">CA Compromise</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Susunod na tab</translation> <translation id="2292848386125228270">Pakisimulan ang <ph name="PRODUCT_NAME" /> bilang isang normal na user. Kung kailangan mong patakbuhin bilang isang root para sa pag-develop, muling patakbuhin gamit ang flag na --no-sandbox.</translation> <translation id="2294358108254308676">Nais mo bang i-install ang <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Pamamaraang EAP:</translation> <translation id="2297705863329999812">Maghanap ng mga printer</translation> <translation id="2300383962156589922">I-customize at kontrolin ang <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Hindi wasto ang pinagmulang direktoryo ng extension.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">ERROR: Hindi na-uninstall ang <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Magdagdag ng Pagbabahagi ng File</translation> <translation id="2367972762794486313">Ipakita ang apps</translation> +<translation id="2369536625682139252">Ide-delete ang lahat ng data na na-store ng <ph name="SITE" />, maliban sa cookies.</translation> <translation id="2371076942591664043">Buksan kapag &tapos na</translation> <translation id="2377319039870049694">Lumipat sa list view</translation> <translation id="2377667304966270281">Mga Hard Fault</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">I-print gamit ang dialog ng system... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Magtanong bago magpadala (inirerekomenda)</translation> <translation id="2384436799579181135">Nagka-error. Pakisuri ang iyong printer at subukang muli.</translation> -<translation id="2385700042425247848">Pangalan ng serbisyo:</translation> <translation id="2387458720915042159">Uri ng koneksyon sa proxy</translation> <translation id="2391419135980381625">Karaniwang font</translation> <translation id="2391762656119864333">Bawiin</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Ibahagi ang audio</translation> <translation id="2480868415629598489">Baguhin ang data na kinokopya at pine-paste mo</translation> <translation id="2482878487686419369">Mga Abiso</translation> -<translation id="2485056306054380289">Certificate ng server CA:</translation> <translation id="2485422356828889247">I-uninstall</translation> <translation id="2487067538648443797">Magdagdag ng bagong bookmark</translation> <translation id="248861575772995840">Hindi mahanap ang iyong telepono. Siguraduhing naka-on ang Bluetooth ng <ph name="DEVICE_TYPE" /> mo. <a>Matuto pa</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Mag-powerwash upang i-reset ang iyong <ph name="IDS_SHORT_PRODUCT_NAME" /> device upang maging parang bago.</translation> <translation id="2567257616420533738">Na-save ang password. Tingnan at pamahalaan ang mga naka-save na password sa <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Infobar Container</translation> +<translation id="2570454805927264159">Sulitin ang iyong Assistant</translation> <translation id="257088987046510401">Mga tema</translation> <translation id="2572032849266859634">Ipinagkaloob na sa <ph name="VOLUME_NAME" /> ang read-only na access.</translation> <translation id="2573269395582837871">Pumili ng larawan at pangalan</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Isumite</translation> <translation id="265390580714150011">Field Value</translation> <translation id="2654166010170466751">Payagan ang mga site na mag-install ng mga tagapangasiwa ng pagbabayad</translation> -<translation id="2655386581175833247">Certificate ng user:</translation> <translation id="2660779039299703961">Kaganapan</translation> <translation id="266079277508604648">Hindi makakonekta sa printer. Tiyaking naka-on ang printer at nakakonekta ito sa iyong Chromebook sa pamamagitan ng Wi-Fi o USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Walang data ng paggamit</translation> <translation id="3007214526293698309">Itakda ang ratio</translation> <translation id="3007771295016901659">I-duplicate ang Tab</translation> +<translation id="3008272652534848354">I-reset ang mga pahintulot</translation> <translation id="3009300415590184725">Sigurado ka bang gusto mong kanselahin ang proseso ng pag-setup ng serbisyo ng mobile data?</translation> <translation id="3009779501245596802">Mga naka-index na database</translation> <translation id="3010279545267083280">Tinanggal ang password</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Mga module (<ph name="TOTAL_COUNT" />) - Mga kilalang salungatan: <ph name="BAD_COUNT" />, pinaghihinalaan: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Petsa at oras</translation> <translation id="310671807099593501">Gumagamit ng bluetooth ang site</translation> -<translation id="3108967419958202225">Pumili...</translation> <translation id="3115128645424181617">Hindi mahanap ang iyong telepono. Siguraduhing malapit ito at naka-on ang Bluetooth.</translation> <translation id="3115147772012638511">Naghihintay para sa cache...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Help</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Maaaring i-block ng ilang carrier ang feature na ito.</translation> <translation id="316854673539778496">Upang mailagay ang lahat ng iyong extension sa lahat ng device mo, mag-sign in at i-on ang pag-sync.</translation> <translation id="3170072451822350649">Maaari mo ring laktawan ang pag-sign in at <ph name="LINK_START" />mag-browse bilang Bisita<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">I-click upang itago ang password</translation> <translation id="3177909033752230686">Wika ng Page:</translation> <translation id="3181110748548073003">Pindutin ang |<ph name="SHORTCUT" />| upang pumunta sa susunod</translation> <translation id="3182749001423093222">Pang-check ng pagbabaybay</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Ililipat ang pagmamay-ari sa <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Buksan ang mga opsyon ng extension</translation> <translation id="3241680850019875542">Piliin ang pinagmulang direktoryo ng extension sa pack. Upang mai-update ang extension, piliin rin ang file ng private na key na muling gagamitin.</translation> -<translation id="3242765319725186192">Pre-shared na key:</translation> <translation id="3244294424315804309">Patuloy na i-mute ang tunog</translation> <translation id="3245321423178950146">Hindi Kilalang Artist</translation> <translation id="3246097286174000800">Subukan ang Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Higit pang aksyon para sa <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Magtanong kapag gusto ng isang site na gumamit ng plugin upang i-access ang iyong computer</translation> <translation id="3441653493275994384">Screen</translation> -<translation id="3445830502289589282">Phase 2 na authentication</translation> <translation id="344630545793878684">Basahin ang iyong data sa ilang website</translation> <translation id="3449839693241009168">Pindutin ang <ph name="SEARCH_KEY" /> upang magpadala ng mga command sa <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Porsyento ng Ginagamit sa Estadong Idle</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> (na) error.</translation> <translation id="3495660573538963482">Mga setting ng Google Assistant</translation> <translation id="3496213124478423963">Zoom Out</translation> -<translation id="3504135463003295723">Pangalan ng pangkat:</translation> <translation id="3505030558724226696">Bawiin ang access sa device</translation> <translation id="3507421388498836150">Mga Kasalukuyang Pahintulot para sa "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Alisin ang mga App ng Linux sa Chromebook</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Di-wasto ang certification ng pag-sign in, magsasara ang window sa loob ng <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Icon ng Extension</translation> <translation id="3665589677786828986">Natunton ng Chrome na ilan sa iyong mga setting ay nasira ng isa pang program at ni-reset ang mga ito sa kanilang mga orihinal na default.</translation> -<translation id="3665842570601375360">Seguridad:</translation> <translation id="3668570675727296296">Mga setting ng wika</translation> <translation id="3668823961463113931">Mga Handler</translation> <translation id="3670229581627177274">I-on ang Bluetooth</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Hindi mabuksan ang device na ito dahil hindi sinusuportahan ang filesystem nito.</translation> <translation id="3727148787322499904">Maaapektuhan ang lahat ng nakabahaging network kung babaguhin ang setting na ito</translation> <translation id="3727187387656390258">Siyasatin ang popup</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Error sa linya <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL Server na may Step-up</translation> <translation id="3737536731758327622">Lalabas dito ang iyong mga download</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Pindutin ang Enter kapag tapos na</translation> <translation id="3827774300009121996">&Full Screen</translation> <translation id="3828029223314399057">Bookmark sa paghahanap</translation> -<translation id="3829932584934971895">Uri ng provider:</translation> <translation id="3830674330436234648">Walang available na playback</translation> <translation id="3831486154586836914">Pumasok ka sa overview mode ng window</translation> <translation id="383161972796689579">Hindi pinagana ng may-ari ng device na ito ang pagdaragdag ng mga bagong user</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Natapos na ang pagsusukat sa paggamit ng data</translation> <translation id="3857228364945137633">Subukan ang Smart Lock upang i-unlock ang iyong <ph name="DEVICE_TYPE" /> nang walang password kapag nasa malapit ang telepono mo.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Na-pause ang pag-sync</translation> <translation id="3860381078714302691">Welcome sa Hangouts Meet</translation> <translation id="3862134173397075045">Welcome sa karanasan sa Cast sa Chrome!</translation> <translation id="3862788408946266506">Naka-install dapat sa kiosk mode ng Chrome OS ang app na may 'kiosk_only' na manifest attribute</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Hindi ma-set up ang network</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Kinakalkula...</translation> -<translation id="3974195870082915331">I-click upang ipakita ang password</translation> <translation id="3975222297214566386">Bubble ng mga opsyon sa input</translation> <translation id="397703832102027365">Tinatapos...</translation> <translation id="3979395879372752341">Nagdagdag ng bagong extension (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Ilagay ang password ng iyong certificate</translation> <translation id="404493185430269859">Default na search engine</translation> <translation id="4047112090469382184">Paano ito naging secure</translation> +<translation id="4051049974203704184">Kumuha ng impormasyon tungkol sa nasa screen</translation> <translation id="4052120076834320548">Maliit</translation> <translation id="4055023634561256217">Kinakailangang mag-restart bago maaaring ma-reset ang iyong device gamit ang Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Tanggapin para sa pangkat</translation> <translation id="4089235344645910861">Na-save ang mga setting. Nasimulan ang pag-sync.</translation> <translation id="4090103403438682346">I-enable ang Bine-verify na Access</translation> +<translation id="4090947011087001172">I-reset ang mga pahintulot sa site para sa <ph name="SITE" />?</translation> <translation id="4091434297613116013">mga sheet ng papel</translation> <translation id="4093955363990068916">Lokal na file:</translation> <translation id="4095507791297118304">Pangunahing display</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Kontrolin ang pag-sync, pag-personalize, at higit pa</translation> <translation id="4421932782753506458">Mingming</translation> <translation id="4422347585044846479">I-edit ang bookmark para sa pahinang ito</translation> -<translation id="4423104065312875417">Mag-install ng mga karagdagang engine sa pagsasalita</translation> <translation id="4423376891418188461">I-restore ang Mga Setting</translation> <translation id="4423482519432579560">&Spellcheck</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, hinihiling sa iyo ng administrator mo na palitan ang iyong password.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Nagpe-play ng audio ang tab na ito.</translation> <translation id="4450974146388585462">I-diagnose</translation> <translation id="4453946976636652378">Maghanap sa <ph name="SEARCH_ENGINE_NAME" /> o mag-type ng URL</translation> -<translation id="445923051607553918">Sumali sa network ng Wi-Fi</translation> <translation id="4462159676511157176">Custom na mga server ng pangalan</translation> <translation id="4467100756425880649">Gallery ng Chrome Web Store</translation> <translation id="4467101674048705704">I-expand ang <ph name="FOLDER_NAME" /></translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Lumalabas ang mga wallpaper sa Screen sa Pag-sign in.</translation> <translation id="4684427112815847243">I-sync lahat</translation> <translation id="4689421377817139245">I-sync ang bookmark na ito sa iyong iPhone</translation> +<translation id="4690091457710545971"><Apat na file na ginawa ng Intel Wi-Fi firmware: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Ang unang tatlo ay mga binary file na may mga dump sa pagpaparehistro at iginiit ng Intel na walang personal na impormasyon o impormasyong nakakapagpakilala sa device. Ang panghuling file ay isang execution trace mula sa Intel firmware; tinanggalan ito ng anumang personal na impormasyon o impormasyong nakakapagpakilala sa device, ngunit masyado itong malaki para maipakita rito. Nagawa ang mga file na ito bilang tugon sa mga kamakailang naging problema sa Wi-Fi sa iyong device, at ibabahagi ito sa Intel para makatulong sa pag-troubleshoot ng mga problemang ito.></translation> <translation id="4692302215262324251">Matagumpay na na-enroll ang iyong <ph name="DEVICE_TYPE" /> para sa pamamahala ng enterprise ng <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Kung hindi ito inaasahan, mangyaring makipag-ugnayan sa suporta.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Maaaring kailangan na muling i-load ang page na ito bago gumana ang mga bagong setting.</translation> <translation id="5075131525758602494">Ilagay ang PIN ng SIM</translation> <translation id="5078638979202084724">I-bookmark ang lahat ng mga tab</translation> +<translation id="5079950360618752063">Gamitin ang iminumungkahing password</translation> <translation id="5084230410268011727">Payagan ang mga site na gumamit ng mga motion at light sensor</translation> <translation id="5085162214018721575">Tumitingin ng mga update</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Tanggalin ang item na ito</translation> <translation id="5139955368427980650">&Buksan</translation> +<translation id="5142961317498132443">Pag-authenticate</translation> <translation id="5143374789336132547">Binago ng extension na "<ph name="EXTENSION_NAME" />" ang ipinapakitang page kapag na-click mo ang button ng Home.</translation> <translation id="5143712164865402236">Pumasok sa Full Screen</translation> <translation id="5145331109270917438">Petsa ng pagbabago</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Pindutin nang matagal ang Control, Alt, Shift, o Search upang makita ang mga keyboard shortcut para sa mga modifier na iyon.</translation> <translation id="5382591305415226340">Pamahalaan ang mga sinusuportahang link</translation> <translation id="5384883051496921101">Magbabahagi ang site na ito ng impormasyon sa isang app sa labas ng incognito mode.</translation> -<translation id="5388588172257446328">Username:</translation> <translation id="5388885445722491159">Ipinares</translation> <translation id="5389237414310520250">Hindi magawa ang bagong user. Pakitingnan ang espasyo at mga pahintulot sa iyong hard drive at subukang muli.</translation> <translation id="5390100381392048184">Payagan ang mga site na mag-play ng tunog</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Keyboard at pag-input ng text</translation> <translation id="5553089923092577885">Certificate Policy Mappings</translation> <translation id="5554489410841842733">Makikita ang icon na ito kapag maaaring kumilos ang extension sa kasalukuyang pahina.</translation> -<translation id="5554573843028719904">Ibang network ng Wi-Fi...</translation> <translation id="5554720593229208774">Email Certification Authority</translation> <translation id="5556206011531515970">I-click ang susunod upang pumili ng iyong default na browser.</translation> <translation id="5556459405103347317">I-reload</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Lumipat sa camera mode</translation> <translation id="5612720917913232150">Gustong gamitin ng <ph name="URL" /> ang lokasyon ng iyong computer</translation> <translation id="5612734644261457353">Paumanhin, hindi pa rin ma-verify ang iyong password. Tandaan: kung pinalitan mo kamakailan ang iyong password, malalapat ang iyong bagong password sa sandaling mag-sign out ka, pakigamit ang lumang password dito.</translation> -<translation id="5613695965848159202">Hindi kilalang pagkakakilanlan:</translation> <translation id="5614190747811328134">Notice sa User</translation> <translation id="561698261642843490">Isara ang Firefox</translation> <translation id="5618075537869101857">Naku, hindi mailunsad ang kiosk application.</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">Mangyaring mag-sign in sa <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimize</translation> <translation id="5946591249682680882">Report ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Magdagdag ng pribadong network</translation> <translation id="5949544233750246342">Hindi ma-parse ang file</translation> <translation id="5955282598396714173">Nag-expire na ang iyong password. Mag-sign out at muling mag-sign in upang palitan ito.</translation> <translation id="5956585768868398362">Ito ba ang inaasahan mong pahina sa paghahanap?</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">Mag-sign out pagkatapos ay mag-sign in muli...</translation> <translation id="6198252989419008588">Palitan ang PIN</translation> <translation id="6199801702437275229">Hinihintay ang impormasyon ng espasyo...</translation> +<translation id="6204015976622790023">Makakita ng mga nauugnay na suhestyon mula sa iyong Assistant na nauugnay sa kung ano ang nasa screen mo.</translation> <translation id="6205710420833115353">Mas matagal kaysa sa inaasahan ang ilang operasyon. Gusto mo bang i-abort ang mga ito?</translation> <translation id="6206311232642889873">Kop&yahin ang Imahe</translation> <translation id="6207200176136643843">I-reset sa default na antas ng pag-zoom</translation> <translation id="620722923698527029">Palaging buksan ang ganitong mga uri ng link sa nauugnay na app</translation> <translation id="6207937957461833379">Bansa/Rehiyon</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Hindi gumagana ang pag-sync</translation> <translation id="6212039847102026977">Ipakita ang mga advanced na property ng network</translation> <translation id="6212168817037875041">I-off ang display</translation> <translation id="6212752530110374741">I-email ang Link</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">i-reset ang pag-sync</translation> <translation id="6264365405983206840">Piliin &Lahat</translation> <translation id="6264422956566238156">Na-on mo ang Pag-sync</translation> -<translation id="6265930187414222160">Tapos na! Naalis na ang mapaminsalang software.</translation> <translation id="6267166720438879315">Pumili ng certificate upang patunayan ang iyong sarili sa <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Buksan sa <ph name="APP" /></translation> <translation id="6268747994388690914">Mag-import ng Mga Bookmark mula sa HTML File...</translation> @@ -3537,7 +3532,6 @@ Paki-click ang "Susunod" upang magpatuloy sa pagsa-sign in sa iyong <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> account.</translation> <translation id="6419546358665792306">I-load ang naka-unpack</translation> <translation id="642282551015776456">Hindi maaaring gamitin ang pangalang ito bilang isang pangalan ng file o folder</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Buksan ang mga setting ng ChromeVox</translation> <translation id="6429384232893414837">Error sa pag-update</translation> <translation id="6430814529589430811">Base64-encoded ASCII, single certificate</translation> @@ -3618,7 +3612,6 @@ <translation id="6544215763872433504">Ang web browser ng Google, para sa iyo</translation> <translation id="6545665334409411530">Rate ng pag-uulit</translation> <translation id="6545834809683560467">Gumamit ng serbisyo sa paghula upang makatulong sa pagkumpleto ng mga paghahanap at URL na itina-type sa address bar o sa box para sa paghahanap ng app launcher</translation> -<translation id="6546686722964485737">Sumali sa WiMAX network</translation> <translation id="6547316139431024316">Huwag muling magbabala para sa extension na ito</translation> <translation id="6547354035488017500">Magbakante ng hindi bababa sa 512 MB ng espasyo ng iyong device, kung hindi ay hindi gagana nang maayos ang iyong device. Upang magbakante ng espasyo, mag-delete ng mga file mula sa storage ng device.</translation> <translation id="6549689063733911810">Kamakailan</translation> @@ -4037,7 +4030,6 @@ <translation id="7201014958346994077">Hindi matingnan ang Mga Linux File</translation> <translation id="720110658997053098">Permanenteng panatilihin sa kiosk mode ang device na ito</translation> <translation id="7201118060536064622">Na-delete ang '<ph name="DELETED_ITEM_NAME" />'</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Dina-download ang <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Umalis sa Page}one{Umalis sa Mga Page}other{Umalis sa Mga Page}}</translation> <translation id="7216409898977639127">Cellular provider</translation> @@ -4515,7 +4507,6 @@ <translation id="7909969815743704077">Na-download sa Incognito</translation> <translation id="7910768399700579500">&Bagong folder</translation> <translation id="7912080627461681647">Napalitan na ang iyong password sa server. Mag-sign out at muling mag-sign in.</translation> -<translation id="7912883689016444961">I-configure ang mobile network</translation> <translation id="7915471803647590281">Mangyaring sabihin sa amin kung ano ang nangyayari bago ang pagpapadala ng feedback.</translation> <translation id="7916556741383518510">Sa Pag-click</translation> <translation id="792514962475806987">Antas ng naka-dock na pag-zoom:</translation> @@ -4569,7 +4560,6 @@ <translation id="7988355189918024273">Paganahin ang mga tampok sa pagiging maa-access</translation> <translation id="7994702968232966508">Pamamaraang EAP</translation> <translation id="799547531016638432">Alisin ang shortcut</translation> -<translation id="7997479212858899587">Pagkakakilanlan:</translation> <translation id="7997826902155442747">Priority ng Proseso</translation> <translation id="7999229196265990314">Nilkha ang mga sumusunod na file: @@ -4653,7 +4643,6 @@ <translation id="8105368624971345109">I-off</translation> <translation id="8106045200081704138">Ibinahagi sa akin</translation> <translation id="8107015733319732394">Ini-install ang Google Play Store sa iyong <ph name="DEVICE_TYPE" />. Maaaring abutin ito nang ilang minuto.</translation> -<translation id="8109930990200908494">Kinakailangan ang pag-sign in para sa certificate ng user.</translation> <translation id="8111155949205007504">Ibahagi ang password na ito sa iyong iPhone</translation> <translation id="8113043281354018522">Pumili ng uri ng lisensya</translation> <translation id="8116190140324504026">Higit pang impormasyon...</translation> @@ -4664,6 +4653,7 @@ <translation id="8118860139461251237">Pamahalaan ang iyong mga download</translation> <translation id="81238879832906896">Dilaw at puting bulaklak</translation> <translation id="8124313775439841391">Pinamamahalaang ONC</translation> +<translation id="8125562866093998907">Gustong i-verify ng site ang iyong Security Key para sa pinaigting na seguridad para sa account mo.</translation> <translation id="813082847718468539">Tingnan ang impormasyon ng site</translation> <translation id="8131740175452115882">Kumpirmahin</translation> <translation id="8133676275609324831">&Ipakita sa folder</translation> @@ -4774,7 +4764,6 @@ <translation id="8308179586020895837">Itanong kung gusto ng <ph name="HOST" /> na i-access ang iyong camera</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Mayroon na ng certificate</translation> -<translation id="8309505303672555187">Pumili ng network:</translation> <translation id="8312871300878166382">I-paste sa loob ng folder</translation> <translation id="8317671367883557781">Idagdag ang koneksyon sa network</translation> <translation id="8319414634934645341">Extended na Paggamit ng Key</translation> @@ -4850,7 +4839,6 @@ <translation id="8451512073679317615">assistant</translation> <translation id="8452135315243592079">Walang nakalagay na SIM card</translation> <translation id="8453482423012550001">Kumokopya ng $1 item...</translation> -<translation id="8454288007744638700">O kaya, pumili ng bagong network:</translation> <translation id="845627346958584683">Oras ng Expiration</translation> <translation id="8456681095658380701">Di-wastong pangalan</translation> <translation id="8457451314607652708">Mag-import ng mga bookmark</translation> @@ -4914,6 +4902,7 @@ <translation id="855081842937141170">Tab ng pin</translation> <translation id="8551388862522347954">Mga Lisensya</translation> <translation id="8553342806078037065">Pamahalaan ang iba pang mga tao</translation> +<translation id="8554899698005018844">Walang wika</translation> <translation id="855773602626431402">Pinigilan ang isang hindi naka-sandbox na plugin na tumakbo sa page na ito.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Pang-decode ng Larawan</translation> @@ -4951,7 +4940,6 @@ <translation id="862727964348362408">Sinuspinde</translation> <translation id="862750493060684461">CSS cache</translation> <translation id="8627795981664801467">Secure na mga koneksyon lamang</translation> -<translation id="8628085465172583869">Hostname ng server:</translation> <translation id="8630903300770275248">Mag-import ng pinangangasiwaang user</translation> <translation id="8631032106121706562">Bulaklak</translation> <translation id="8637542770513281060">Naglalaman ng secure na module ang iyong computer, na ginagamit upang magpatupad ng maraming mahalagang feature ng seguridad sa Chrome OS. Bisitahin ang Help Center ng Chromebook upang matuto pa: https://support.google.com/chromebook/?p=sm</translation> @@ -5208,7 +5196,6 @@ <translation id="899403249577094719">URL ng Netscape Certificate Base</translation> <translation id="8995603266996330174">Pinamamahalaan ni <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Magdagdag ng account...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Gumagawa ng imahe ng disk.</translation> <translation id="9003647077635673607">Payagan sa lahat ng website</translation> <translation id="9003677638446136377">Suriing muli</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb index 125311e..4e839049 100644 --- a/chrome/app/resources/generated_resources_fr.xtb +++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">Clé PUK</translation> <translation id="1061904396131502319">Il est presque temps de faire une pause</translation> <translation id="1062407476771304334">Remplacer</translation> -<translation id="1064835277883315402">Rejoindre un réseau privé</translation> <translation id="1064912851688322329">Se déconnecter du compte Google</translation> <translation id="1067048845568873861">Date de création</translation> <translation id="1067291318998134776">Linux (version bêta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Recherche en cours…</translation> <translation id="1316495628809031177">La synchronisation est mise en veille</translation> <translation id="1319979322914001937">Application qui présente une liste filtrée d'extensions du Chrome Web Store. Les extensions figurant sur cette liste peuvent être installées directement depuis l'application.</translation> -<translation id="132090119144658135">Correspondance d'objet :</translation> <translation id="1326317727527857210">Connectez-vous à Chrome pour accéder à vos onglets sur vos autres appareils.</translation> <translation id="1327074568633507428">Imprimante connectée à Google Cloud Print</translation> <translation id="1327977588028644528">Passerelle</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Fenêtre de l'application</translation> <translation id="1534389735079119190">ERREUR : Échec du démarrage du conteneur dans la machine virtuelle.</translation> <translation id="15373452373711364">Grand curseur</translation> +<translation id="1540605929960647700">Activer le mode de démonstration</translation> <translation id="1543284117603151572">Importés depuis Edge</translation> <translation id="1545177026077493356">Mode Kiosque automatique</translation> <translation id="1545775234664667895">Thème "<ph name="THEME_NAME" />" installé</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Nous aider à améliorer <ph name="PRODUCT_NAME" /> en envoyant automatiquement les statistiques d'utilisation et les rapports d'erreur à Google</translation> <translation id="1658424621194652532">Cette page a accès à votre micro</translation> <translation id="1660204651932907780">Autoriser l'activation du son des sites (recommandé)</translation> +<translation id="1660938185063657230">Valider votre clé de sécurité</translation> <translation id="1661156625580498328">Appliquer le chiffrement AES (recommandé)</translation> <translation id="1661245713600520330">Cette page répertorie tous les modules chargés dans le processus principal et les modules enregistrés de manière à être chargés ultérieurement.</translation> <translation id="166179487779922818">Mot de passe trop court.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Interdire aux sites de voir le texte et les images copiés dans le presse-papiers</translation> <translation id="1682548588986054654">Nouvelle fenêtre de navigation privée</translation> <translation id="168715261339224929">Activez la synchronisation pour accéder à vos favoris sur tous vos appareils.</translation> +<translation id="1688867105868176567">Effacer les données du site ?</translation> <translation id="1688935057616748272">Saisissez une lettre</translation> <translation id="168991973552362966">Ajouter une imprimante à proximité</translation> <translation id="1689945336726856614">Copier l'&URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Supprimer ce profil utilisateur</translation> <translation id="1706586824377653884">Ajouté par votre administrateur</translation> <translation id="1706625117072057435">Niveaux de zoom</translation> -<translation id="1707463636381878959">Partager ce réseau avec d'autres utilisateurs</translation> <translation id="1708338024780164500">(Inactive)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID : <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (native)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Activer le thème</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Afficher sur le Chrome Web Store</translation> -<translation id="1758831820837444715">Configurer le réseau Ethernet</translation> <translation id="1763046204212875858">Créer des raccourcis vers des applications</translation> <translation id="1763108912552529023">Poursuivre la découverte</translation> <translation id="1763808908432309942">La page s'ouvre dans un nouvel onglet</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Modifiez le mode de partage de ce fichier.</translation> <translation id="1841545962859478868">L'administrateur de cet appareil peut contrôler les éléments suivants :</translation> <translation id="1841705068325380214">L'extension <ph name="EXTENSION_NAME" /> est désactivée</translation> +<translation id="1842766183094193446">Voulez-vous vraiment activer le mode de démonstration ?</translation> <translation id="1844692022597038441">Ce fichier n'est pas disponible hors connexion.</translation> <translation id="1846308012215045257">Cliquez ici en maintenant la touche Ctrl enfoncée pour exécuter <ph name="PLUGIN_NAME" />.</translation> +<translation id="1847880352285315359">Enregistré</translation> <translation id="1848219224579402567">Se déconnecter quand l'écran est rabattu</translation> <translation id="184823282865851239">Bloquer si le site a tendance à afficher des annonces intrusives</translation> <translation id="1849186935225320012">Le contrôle total des appareils MIDI est activé pour cette page</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Vous pourrez toujours modifier cette option plus tard dans les paramètres</translation> <translation id="2006638907958895361">Ouvrir le lien dans <ph name="APP" /></translation> <translation id="2007404777272201486">Signaler un problème...</translation> +<translation id="2016237810978710652">Ouverture des fichiers Linux…</translation> <translation id="2016430552235416146">Traditionnel</translation> <translation id="2017334798163366053">Désactiver la collecte de données relatives aux performances</translation> <translation id="2017836877785168846">Efface l'historique et les saisies semi-automatiques dans la barre d'adresse.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Modifier la carte</translation> <translation id="2154710561487035718">Copier l'URL</translation> <translation id="2155772377859296191">La résolution est de <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Vous pouvez nous aider à améliorer la navigation sécurisée en nous envoyant des informations système et du contenu de page.</translation> <translation id="215753907730220065">Quitter le mode plein écran</translation> <translation id="2157875535253991059">Cette page est maintenant en mode plein écran</translation> <translation id="216169395504480358">Ajouter un réseau Wi-Fi…</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Ajoutez un ID de réquisition sur cet appareil</translation> <translation id="2175042898143291048">Toujours procéder ainsi</translation> <translation id="2175607476662778685">Barre de lancement rapide</translation> +<translation id="2176087259161165020">Autres sources</translation> <translation id="2177950615300672361">Onglet de navigation privée : <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Le plug-in <ph name="PEPPER_PLUGIN_NAME" /> provenant du domaine <ph name="PEPPER_PLUGIN_DOMAIN" /> demande l'accès à votre ordinateur</translation> <translation id="2178614541317717477">Autorité de certification compromise</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Onglet suivant</translation> <translation id="2292848386125228270">Veuillez démarrer <ph name="PRODUCT_NAME" /> en mode utilisateur standard. Si vous devez l'exécuter à la racine dans le cadre du développement, relancez-le avec l'indicateur --no-sandbox.</translation> <translation id="2294358108254308676">Souhaitez-vous installer <ph name="PRODUCT_NAME" /> ?</translation> -<translation id="2296019197782308739">Méthode EAP :</translation> <translation id="2297705863329999812">Rechercher des imprimantes</translation> <translation id="2300383962156589922">Personnaliser et configurer <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Le répertoire racine de l'extension est incorrect.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">ERREUR : Échec de la désinstallation de l'application <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Ajouter un partage de fichiers</translation> <translation id="2367972762794486313">Afficher les applications</translation> +<translation id="2369536625682139252">Toutes les données stockées par <ph name="SITE" /> seront supprimées, sauf les cookies.</translation> <translation id="2371076942591664043">Ouvrir une fois le téléchargement &terminé</translation> <translation id="2377319039870049694">Passer en mode Liste</translation> <translation id="2377667304966270281">Défauts matériels</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Imprimer via la boîte de dialogue du système... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Demander l'autorisation avant d'envoyer (recommandé)</translation> <translation id="2384436799579181135">Une erreur s'est produite. Veuillez vérifier l'imprimante, puis réessayer.</translation> -<translation id="2385700042425247848">Nom du service :</translation> <translation id="2387458720915042159">Type de connexion proxy</translation> <translation id="2391419135980381625">Police standard</translation> <translation id="2391762656119864333">Révoquer</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Partager le contenu audio</translation> <translation id="2480868415629598489">Modifier les données que vous copiez-collez</translation> <translation id="2482878487686419369">Notifications</translation> -<translation id="2485056306054380289">Certificat de l'autorité de certification du serveur :</translation> <translation id="2485422356828889247">Désinstaller</translation> <translation id="2487067538648443797">Ajouter un favori</translation> <translation id="248861575772995840">Impossible de trouver votre téléphone. Assurez-vous que le Bluetooth de votre <ph name="DEVICE_TYPE" /> est activé. <a>En savoir plus</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Effectuez un Powerwash pour rétablir la configuration d'usine de votre appareil <ph name="IDS_SHORT_PRODUCT_NAME" />.</translation> <translation id="2567257616420533738">Mot de passe enregistré. Afficher et gérer les mots de passe enregistrés sur <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Conteneur de barres d'infos</translation> +<translation id="2570454805927264159">Exploitez tout le potentiel de l'Assistant</translation> <translation id="257088987046510401">Thèmes</translation> <translation id="2572032849266859634">L'accès en lecture seule à "<ph name="VOLUME_NAME" />" a été accordé.</translation> <translation id="2573269395582837871">Sélectionner une photo et choisissez un nom</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Valider</translation> <translation id="265390580714150011">Valeur du champ</translation> <translation id="2654166010170466751">Autoriser les sites à installer des gestionnaires de paiement</translation> -<translation id="2655386581175833247">Certificat utilisateur :</translation> <translation id="2660779039299703961">Événement</translation> <translation id="266079277508604648">Impossible de se connecter à l'imprimante. Vérifiez qu'elle est sous tension et connectée à votre Chromebook par Wi-Fi ou USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Aucune donnée sur l'utilisation</translation> <translation id="3007214526293698309">Corriger le format</translation> <translation id="3007771295016901659">Dupliquer l'onglet</translation> +<translation id="3008272652534848354">Réinitialiser les autorisations</translation> <translation id="3009300415590184725">Voulez-vous vraiment annuler la configuration du service Internet mobile ?</translation> <translation id="3009779501245596802">Bases de données indexées</translation> <translation id="3010279545267083280">Mot de passe supprimé</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Modules (<ph name="TOTAL_COUNT" />). Conflits connus : <ph name="BAD_COUNT" />, conflits probables : <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Date et heure</translation> <translation id="310671807099593501">Le site utilise le Bluetooth</translation> -<translation id="3108967419958202225">Sélectionner...</translation> <translation id="3115128645424181617">Impossible de trouver votre téléphone. Assurez-vous qu'il se trouve à proximité et que le Bluetooth est activé.</translation> <translation id="3115147772012638511">En attente de l'affichage du cache</translation> <translation id="3118319026408854581">Aide <ph name="PRODUCT_NAME" /></translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Certains opérateurs peuvent bloquer cette fonctionnalité.</translation> <translation id="316854673539778496">Pour accéder à toutes vos extensions sur tous vos appareils, connectez-vous et activez la synchronisation.</translation> <translation id="3170072451822350649">Vous pouvez également ignorer l'étape de connexion et <ph name="LINK_START" />naviguer en tant qu'invité<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Cliquer pour masquer le mot de passe</translation> <translation id="3177909033752230686">Langue de la page :</translation> <translation id="3181110748548073003">Appuyez sur |<ph name="SHORTCUT" />| pour avancer</translation> <translation id="3182749001423093222">Correcteur orthographique</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">La propriété sera transférée à <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Ouvrir les options d'extension</translation> <translation id="3241680850019875542">Sélectionnez le répertoire racine de l'extension à empaqueter. Pour mettre à jour une extension, sélectionnez également le fichier de clé privée à réutiliser.</translation> -<translation id="3242765319725186192">Clé pré-partagée :</translation> <translation id="3244294424315804309">Ne pas réactiver le son</translation> <translation id="3245321423178950146">Artiste inconnu</translation> <translation id="3246097286174000800">Tester Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Autres actions pour <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Me demander lorsqu'un site essaie d'utiliser un plug-in pour accéder à mon ordinateur</translation> <translation id="3441653493275994384">Écran</translation> -<translation id="3445830502289589282">Authentification phase 2 :</translation> <translation id="344630545793878684">Lire vos données sur plusieurs sites web</translation> <translation id="3449839693241009168">Appuyez sur <ph name="SEARCH_KEY" /> pour envoyer des commandes à <ph name="EXTENSION_NAME" />.</translation> <translation id="3450157232394774192">Taux d'occupation en veille</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> erreurs</translation> <translation id="3495660573538963482">Paramètres de l'Assistant Google</translation> <translation id="3496213124478423963">Zoom arrière</translation> -<translation id="3504135463003295723">Nom du groupe :</translation> <translation id="3505030558724226696">Retirer les droits d'accès aux appareils</translation> <translation id="3507421388498836150">Autorisations actuelles pour <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Supprimer les applications Linux pour Chromebook</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Le certificat de connexion n'est pas valide. Fermeture de la fenêtre dans <ph name="MINUTES" /> et <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Icône de l'extension</translation> <translation id="3665589677786828986">Chrome a détecté que certains de vos paramètres ont été corrompus par un autre programme. Leurs valeurs par défaut ont été rétablies.</translation> -<translation id="3665842570601375360">Sécurité :</translation> <translation id="3668570675727296296">Paramètres linguistiques</translation> <translation id="3668823961463113931">Gestionnaires</translation> <translation id="3670229581627177274">Activer le Bluetooth</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Impossible d'ouvrir ce périphérique, car son système de fichiers n'est pas compatible.</translation> <translation id="3727148787322499904">Les modifications apportées à ce paramètre s'appliquent à tous les réseaux partagés</translation> <translation id="3727187387656390258">Inspecter le pop-up</translation> -<translation id="3728067901555601989">Mot de passe à usage unique :</translation> <translation id="3732078975418297900">Erreur à la ligne <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Serveur SSL avec fonction d'optimisation</translation> <translation id="3737536731758327622">Vos téléchargements s'affichent ici</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Appuyez sur Entrée une fois l'opération terminée</translation> <translation id="3827774300009121996">&Plein écran</translation> <translation id="3828029223314399057">Rechercher dans les favoris</translation> -<translation id="3829932584934971895">Type de fournisseur :</translation> <translation id="3830674330436234648">Aucune lecture disponible</translation> <translation id="3831486154586836914">Mode de présentation de la fenêtre activé</translation> <translation id="383161972796689579">Le propriétaire de cet appareil a désactivé la fonctionnalité d'ajout de nouveaux utilisateurs</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">La mesure de l'utilisation des données a pris fin.</translation> <translation id="3857228364945137633">Testez Smart Lock pour déverrouiller votre <ph name="DEVICE_TYPE" /> sans mot de passe lorsque votre téléphone est à proximité.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" /> : synchronisation désactivée</translation> <translation id="3860381078714302691">Bienvenue dans Hangouts Meet</translation> <translation id="3862134173397075045">Bienvenue dans l'expérience Cast sur Chrome</translation> <translation id="3862788408946266506">L'application dont le fichier manifeste comporte un attribut "kiosk_only" doit être installée en mode Kiosque pour Chrome OS</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Impossible de configurer le réseau</translation> <translation id="3970114302595058915">Identifiant</translation> <translation id="397105322502079400">Calcul en cours…</translation> -<translation id="3974195870082915331">Cliquer pour afficher le mot de passe</translation> <translation id="3975222297214566386">Info-bulle sur les options de saisie</translation> <translation id="397703832102027365">Finalisation en cours…</translation> <translation id="3979395879372752341">Nouvelle extension (<ph name="EXTENSION_NAME" />) ajoutée.</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Saisissez le mot de passe du certificat.</translation> <translation id="404493185430269859">Moteur de recherche par défaut</translation> <translation id="4047112090469382184">Niveau de sécurité</translation> +<translation id="4051049974203704184">Obtenir des informations sur le contenu à l'écran</translation> <translation id="4052120076834320548">Très petite</translation> <translation id="4055023634561256217">Vous devez redémarrer votre appareil avant de pouvoir le réinitialiser avec le Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Accepter pour le groupe</translation> <translation id="4089235344645910861">Paramètres enregistrés. Synchronisation démarrée.</translation> <translation id="4090103403438682346">Activer l'accès validé</translation> +<translation id="4090947011087001172">Réinitialiser les autorisations de site pour <ph name="SITE" /> ?</translation> <translation id="4091434297613116013">feuilles de papier</translation> <translation id="4093955363990068916">Fichier local :</translation> <translation id="4095507791297118304">Affichage principal</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Contrôler la synchronisation, la personnalisation, et plus encore</translation> <translation id="4421932782753506458">Félix</translation> <translation id="4422347585044846479">Modifier le favori de cette page</translation> -<translation id="4423104065312875417">Installer d'autres moteurs de synthèse vocale</translation> <translation id="4423376891418188461">Rétablir les paramètres</translation> <translation id="4423482519432579560">&Vérification orthographique</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, votre administrateur exige que vous changiez votre mot de passe.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Cet onglet lit des fichiers audio.</translation> <translation id="4450974146388585462">Analyser</translation> <translation id="4453946976636652378">Effectuez une recherche sur <ph name="SEARCH_ENGINE_NAME" /> ou saisissez une URL</translation> -<translation id="445923051607553918">Se connecter à un réseau Wi-Fi</translation> <translation id="4462159676511157176">Serveurs de noms personnalisés</translation> <translation id="4467100756425880649">Chrome Web Store Gallery</translation> <translation id="4467101674048705704">Développer le dossier "<ph name="FOLDER_NAME" />"</translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Les fonds d'écran s'affichent sur l'écran de connexion.</translation> <translation id="4684427112815847243">Tout synchroniser</translation> <translation id="4689421377817139245">Synchroniser ce favori sur votre iPhone</translation> +<translation id="4690091457710545971"><Le micrologiciel Wi-Fi d'Intel a généré quatre fichiers : csr.lst, fh_regs.lst, radio_reg.lst et monitor.lst.sysmon. Les trois premiers sont des fichiers binaires qui contiennent des images mémoire de registres. Intel certifie que ces fichiers ne possèdent pas d'informations personnelles ni de données permettant d'identifier les appareils. Le dernier fichier est une trace d'exécution du micrologiciel Intel. Toutes les informations personnelles ainsi que les données permettant d'identifier les appareils qu'il pouvait contenir ont été supprimées. Toutefois, il est trop volumineux pour s'afficher ici. Ces fichiers ont été créés suite aux problèmes que votre appareil a récemment rencontrés avec le Wi-Fi, et seront partagés avec Intel pour qu'une solution soit trouvée.></translation> <translation id="4692302215262324251">Votre <ph name="DEVICE_TYPE" /> a bien été enregistré pour bénéficier de la gestion d'entreprise par <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> S'il s'agit d'une erreur, veuillez contacter le service d'assistance.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Vous devrez peut-être actualiser cette page pour que les nouveaux paramètres soient appliqués.</translation> <translation id="5075131525758602494">Saisir le code de la SIM</translation> <translation id="5078638979202084724">Ajouter tous les onglets aux favoris</translation> +<translation id="5079950360618752063">Utiliser le mot de passe suggéré</translation> <translation id="5084230410268011727">Autoriser les sites à utiliser des capteurs de mouvement et de lumière</translation> <translation id="5085162214018721575">Recherche de mises à jour en cours…</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Supprimer cet article</translation> <translation id="5139955368427980650">&Ouvrir</translation> +<translation id="5142961317498132443">Authentification</translation> <translation id="5143374789336132547">L'extension <ph name="EXTENSION_NAME" /> a modifié la page affichée lorsque vous cliquez sur le bouton Accueil.</translation> <translation id="5143712164865402236">Activer le mode plein écran</translation> <translation id="5145331109270917438">Date de modification</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Maintenez la touche Ctrl, Alt, Maj ou la touche de recherche enfoncée pour afficher le raccourci clavier qui lui est associé.</translation> <translation id="5382591305415226340">Gérer les liens compatibles</translation> <translation id="5384883051496921101">Ce site s'apprête à partager des informations avec une application en dehors du mode navigation privée.</translation> -<translation id="5388588172257446328">Nom d'utilisateur :</translation> <translation id="5388885445722491159">Associé</translation> <translation id="5389237414310520250">Impossible de créer l'utilisateur. Veuillez vérifier l'espace disponible sur votre disque dur et vos autorisations, puis réessayer.</translation> <translation id="5390100381392048184">Autoriser l'activation du son des sites</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Clavier et saisie de texte</translation> <translation id="5553089923092577885">Mappages des stratégies de certificat</translation> <translation id="5554489410841842733">Cette icône s'affiche lorsque l'extension peut agir sur la page active.</translation> -<translation id="5554573843028719904">Autre réseau Wi-Fi...</translation> <translation id="5554720593229208774">Autorité de certification de messagerie</translation> <translation id="5556206011531515970">Cliquez sur "Suivant" pour sélectionner un navigateur par défaut.</translation> <translation id="5556459405103347317">Actualiser</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Passer en mode Appareil photo</translation> <translation id="5612720917913232150"><ph name="URL" /> souhaite avoir accès à la position de votre ordinateur</translation> <translation id="5612734644261457353">Désolé, nous ne pouvons toujours pas valider votre mot de passe. Remarque : si vous l'avez modifié dernièrement, votre nouveau mot de passe ne sera appliqué qu'une fois que vous vous serez déconnecté. Veuillez donc utiliser votre ancien mot de passe.</translation> -<translation id="5613695965848159202">Authentification anonyme :</translation> <translation id="5614190747811328134">Avertissement utilisateur</translation> <translation id="561698261642843490">Quitter Firefox</translation> <translation id="5618075537869101857">Impossible de lancer l'application kiosque.</translation> @@ -3228,7 +3223,6 @@ <translation id="5941343993301164315">Veuillez vous connecter à <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Réduire</translation> <translation id="5946591249682680882">Identifiant de rapport <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Ajouter un réseau privé</translation> <translation id="5949544233750246342">Impossible d'analyser le fichier</translation> <translation id="5955282598396714173">Votre mot de passe est arrivé à expiration. Veuillez vous déconnecter, puis vous reconnecter pour le modifier.</translation> <translation id="5956585768868398362">Est-ce la page de recherche que vous attendiez ?</translation> @@ -3389,11 +3383,13 @@ <translation id="6198102561359457428">Se déconnecter, puis se connecter de nouveau…</translation> <translation id="6198252989419008588">Modifier le code PIN</translation> <translation id="6199801702437275229">En attente d'informations sur l'espace disponible…</translation> +<translation id="6204015976622790023">Recevez des suggestions pertinentes de l'Assistant au sujet du contenu affiché à l'écran.</translation> <translation id="6205710420833115353">Certaines opérations prennent plus longtemps que prévu. Voulez-vous les annuler ?</translation> <translation id="6206311232642889873">Cop&ier l'image</translation> <translation id="6207200176136643843">Réinitialiser le niveau de zoom par défaut</translation> <translation id="620722923698527029">Toujours ouvrir ces types de liens dans l'application associée</translation> <translation id="6207937957461833379">Pays/Région</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" /> : la synchronisation ne fonctionne pas</translation> <translation id="6212039847102026977">Afficher les propriétés de réseau avancées</translation> <translation id="6212168817037875041">Désactiver l'écran</translation> <translation id="6212752530110374741">Envoyer le lien par e-mail</translation> @@ -3431,7 +3427,6 @@ <translation id="6263541650532042179">réinitialiser la synchronisation</translation> <translation id="6264365405983206840">Tout &sélectionner</translation> <translation id="6264422956566238156">Vous avez activé la synchronisation</translation> -<translation id="6265930187414222160">Opération terminée. Le logiciel malveillant a été supprimé.</translation> <translation id="6267166720438879315">Sélectionnez un certificat pour vous authentifier sur <ph name="HOST_NAME" />.</translation> <translation id="6268252012308737255">Ouvrir avec <ph name="APP" /></translation> <translation id="6268747994388690914">Importer les favoris depuis un fichier HTML…</translation> @@ -3538,7 +3533,6 @@ Veuillez cliquer sur "Suivant" pour poursuivre la connexion à votre <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> compte.</translation> <translation id="6419546358665792306">Chargez l'extension non empaquetée</translation> <translation id="642282551015776456">Ce nom ne peut pas être utilisé comme nom de fichier ni de dossier.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Ouvrir les paramètres ChromeVox</translation> <translation id="6429384232893414837">Erreur de mise à jour</translation> <translation id="6430814529589430811">Certificat unique codé Base 64 ASCII</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">Le navigateur Web de Google, pour vous</translation> <translation id="6545665334409411530">Fréquence de répétition</translation> <translation id="6545834809683560467">Utiliser un service de prédiction afin de compléter les requêtes de recherche et les URL saisies dans la barre d'adresse ou dans le champ de recherche du lanceur d'applications</translation> -<translation id="6546686722964485737">Rejoindre le réseau WiMAX</translation> <translation id="6547316139431024316">Ne plus m'avertir pour cette extension</translation> <translation id="6547354035488017500">Si vous ne libérez pas au moins 512 Mo en supprimant des fichiers de l'espace de stockage, votre appareil ne répondra plus.</translation> <translation id="6549689063733911810">Activité récente</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Impossible d'afficher les fichiers Linux</translation> <translation id="720110658997053098">Conserver cet appareil en mode Kiosque de manière permanente</translation> <translation id="7201118060536064622">"<ph name="DELETED_ITEM_NAME" />" supprimé</translation> -<translation id="7205869271332034173">SSID :</translation> <translation id="7206693748120342859">Téléchargement de <ph name="PLUGIN_NAME" /> en cours…</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Quitter la page}one{Quitter la page}other{Quitter les pages}}</translation> <translation id="7216409898977639127">Opérateur de téléphonie mobile</translation> @@ -4516,7 +4508,6 @@ <translation id="7909969815743704077">Téléchargé en mode navigation privée</translation> <translation id="7910768399700579500">&Nouveau dossier</translation> <translation id="7912080627461681647">Votre mot de passe a été modifié sur le serveur. Veuillez vous déconnecter, puis vous reconnecter.</translation> -<translation id="7912883689016444961">Configurer le réseau mobile</translation> <translation id="7915471803647590281">Veuillez nous indiquer ce qu'il se passe avant d'envoyer votre rapport.</translation> <translation id="7916556741383518510">En cas de clic</translation> <translation id="792514962475806987">Niveau de zoom ancré :</translation> @@ -4570,7 +4561,6 @@ <translation id="7988355189918024273">Activer les fonctionnalités d'accessibilité</translation> <translation id="7994702968232966508">Méthode EAP</translation> <translation id="799547531016638432">Supprimer le raccourci</translation> -<translation id="7997479212858899587">Identité :</translation> <translation id="7997826902155442747">Priorité de traitement</translation> <translation id="7999229196265990314">Les fichiers suivants ont été créés : @@ -4654,7 +4644,6 @@ <translation id="8105368624971345109">Désactiver</translation> <translation id="8106045200081704138">Partagés avec moi</translation> <translation id="8107015733319732394">Installation du Google Play Store sur votre <ph name="DEVICE_TYPE" />. Cette opération peut prendre quelques minutes.</translation> -<translation id="8109930990200908494">Connexion obligatoire pour l'identifiant utilisateur.</translation> <translation id="8111155949205007504">Partagez ce mot de passe avec votre iPhone</translation> <translation id="8113043281354018522">Sélectionner un type de licence</translation> <translation id="8116190140324504026">Plus d'informations...</translation> @@ -4665,6 +4654,7 @@ <translation id="8118860139461251237">Gérer vos téléchargements</translation> <translation id="81238879832906896">Fleur jaune et blanche</translation> <translation id="8124313775439841391">ONC géré</translation> +<translation id="8125562866093998907">Le site requiert la validation de votre clé de sécurité pour renforcer la protection de votre compte.</translation> <translation id="813082847718468539">Afficher des informations à propos du site</translation> <translation id="8131740175452115882">Confirmer</translation> <translation id="8133676275609324831">&Afficher dans le dossier</translation> @@ -4775,7 +4765,6 @@ <translation id="8308179586020895837">Demander si l'accès à votre caméra est requis sur <ph name="HOST" /></translation> <translation id="830868413617744215">Bêta</translation> <translation id="8309458809024885768">Ce certificat existe déjà</translation> -<translation id="8309505303672555187">Sélectionnez un réseau :</translation> <translation id="8312871300878166382">Coller dans le dossier</translation> <translation id="8317671367883557781">Ajouter une connexion réseau</translation> <translation id="8319414634934645341">Utilisation étendue de la clé</translation> @@ -4850,7 +4839,6 @@ <translation id="8451512073679317615">assistant</translation> <translation id="8452135315243592079">Carte SIM manquante</translation> <translation id="8453482423012550001">Copie de $1 éléments en cours…</translation> -<translation id="8454288007744638700">Ou sélectionnez un nouveau réseau :</translation> <translation id="845627346958584683">Délai d'expiration</translation> <translation id="8456681095658380701">Ce nom n'est pas valide.</translation> <translation id="8457451314607652708">Importer les favoris</translation> @@ -4914,6 +4902,7 @@ <translation id="855081842937141170">Épingler l'onglet</translation> <translation id="8551388862522347954">Licences</translation> <translation id="8553342806078037065">Gérer d'autres utilisateurs</translation> +<translation id="8554899698005018844">Aucune langue</translation> <translation id="855773602626431402">L'exécution hors bac à sable d'un plug-in n'est pas autorisée sur cette page</translation> <translation id="8557930019681227453">Manifeste</translation> <translation id="8559694214572302298">Décodage d'images</translation> @@ -4951,7 +4940,6 @@ <translation id="862727964348362408">Suspendu</translation> <translation id="862750493060684461">Cache CSS</translation> <translation id="8627795981664801467">Uniquement les connexions sécurisées</translation> -<translation id="8628085465172583869">Nom d'hôte du serveur :</translation> <translation id="8630903300770275248">Importer un utilisateur supervisé</translation> <translation id="8631032106121706562">Fleur</translation> <translation id="8637542770513281060">Votre ordinateur contient un module sécurisé qui permet de mettre en œuvre de nombreuses fonctionnalités de sécurité critiques dans Chrome OS. Consultez le centre d'aide Chromebook pour en savoir plus : https://support.google.com/chromebook/?p=sm.</translation> @@ -5207,7 +5195,6 @@ <translation id="899403249577094719">URL de base du certificat Netscape</translation> <translation id="8995603266996330174">Géré par <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Ajouter un compte…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Création de l'image disque…</translation> <translation id="9003647077635673607">Autoriser sur tous les sites Web</translation> <translation id="9003677638446136377">Revérifier</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index 25a9d5e..a4eda68 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">વિરામનો સમય થવા જ આવ્યો છે</translation> <translation id="1062407476771304334">બદલો</translation> -<translation id="1064835277883315402">ખાનગી નેટવર્કથી જોડાઓ</translation> <translation id="1064912851688322329">તમારું Google એકાઉન્ટ ડિસ્કનેક્ટ કરો</translation> <translation id="1067048845568873861">બનાવ્યું</translation> <translation id="1067291318998134776">Linux (બીટા)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">શોધી રહ્યું છે ...</translation> <translation id="1316495628809031177">સિંક થોભાવ્યું છે</translation> <translation id="1319979322914001937">એક ઍપ્લિકેશન કે જે Chrome વેબ દુકાનથી ફિલ્ટર કરેલ એક્સ્ટેન્શન્સની સૂચિ દર્શાવે છે. સૂચિમાંના એક્સ્ટેન્શન્સ સીધા જ ઍપ્લિકેશનથી ઇન્સ્ટોલ કરી શકાય છે.</translation> -<translation id="132090119144658135">વિષય મેળ:</translation> <translation id="1326317727527857210">તમારા અન્ય ઉપકરણો પરથી તમારા ટૅબ્સ મેળવવા માટે, Chrome માં સાઇન ઇન કરો.</translation> <translation id="1327074568633507428">Google મેઘ મુદ્રણ પર પ્રિન્ટર</translation> <translation id="1327977588028644528">ગેટવે</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">ઍપ્લિકેશન વિંડો</translation> <translation id="1534389735079119190">ભૂલ: VMમાં કન્ટેઇનર શરૂ કરવાનું નિષ્ફ્ળ થયું.</translation> <translation id="15373452373711364">મોટું માઉસ કર્સર</translation> +<translation id="1540605929960647700">ડેમો મોડ ચાલુ કરો</translation> <translation id="1543284117603151572">Edge માંથી આયાત કરેલ</translation> <translation id="1545177026077493356">સ્વચલિત કિઓસ્ક મોડ</translation> <translation id="1545775234664667895">ઇન્સ્ટોલ કરેલી થીમ "<ph name="THEME_NAME" />"</translation> @@ -455,6 +454,7 @@ <translation id="1657406563541664238">ઉપયોગનાં આંકડાઓ અને ક્રેશ રિપોર્ટ્સ આપમેળે Google ને મોકલીને <ph name="PRODUCT_NAME" /> ને વધુ સારુ બનાવવામાં સહાય કરો</translation> <translation id="1658424621194652532">આ પૃષ્ઠ તમારા માઇક્રોફોનને ઍક્સેસ કરી રહ્યું છે.</translation> <translation id="1660204651932907780">સાઇટને અવાજ ચલાવવાની મંજૂરી આપો (સુઝાવ આપેલ)</translation> +<translation id="1660938185063657230">તમારી સુરક્ષા કી ચકાસો</translation> <translation id="1661156625580498328">AES એન્ક્રિપ્શન (ભલામણ કરેલ)ને લાગુ કરો.</translation> <translation id="1661245713600520330">આ પૃષ્ઠ મુખ્ય પ્રક્રિયામાં લોડ થયેલા અને પછીથી લોડ કરવા માટે નોંધવામાં આવેલા બધા મોડ્યૂલ્સને સૂચિબદ્ધ કરે છે.</translation> <translation id="166179487779922818">પાસવર્ડ ખૂબ ટૂંકો છે.</translation> @@ -471,6 +471,7 @@ <translation id="16815041330799488">સાઇટને ક્લિપબોર્ડ પર કૉપિ કરેલ ટેક્સ્ટ અને છબીઓ જોવાની મંજૂરી આપશો નહીં</translation> <translation id="1682548588986054654">નવી છુપી વિંડો</translation> <translation id="168715261339224929">તમારા બધા ઉપકરણો પર તમારા બુકમાર્ક મેળવવા માટે, સિંક કરવાનું ચાલુ કરો.</translation> +<translation id="1688867105868176567">સાઇટનો ડેટા સાફ કરીએ?</translation> <translation id="1688935057616748272">એક અક્ષર લખો</translation> <translation id="168991973552362966">નજીકનું પ્રિન્ટર ઉમેરો</translation> <translation id="1689945336726856614">&URLને કૉપિ કરો</translation> @@ -482,7 +483,6 @@ <translation id="1701062906490865540">આ વ્યક્તિને દૂર કરો</translation> <translation id="1706586824377653884">તમારા વ્યવસ્થાપક દ્વારા ઉમેરાયેલ</translation> <translation id="1706625117072057435">ઝૂમના સ્તર</translation> -<translation id="1707463636381878959">અન્ય વપરાશકર્તાઓ સાથે આ નેટવર્ક શેર કરો</translation> <translation id="1708338024780164500">(નિષ્ક્રિય)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (મૂળ)</translation> @@ -518,7 +518,6 @@ <translation id="175772926354468439">થીમ સક્ષમ કરો</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome વેબ દુકાનમાં જુઓ</translation> -<translation id="1758831820837444715">ઇથરનેટ નેટવર્કને ગોઠવો</translation> <translation id="1763046204212875858">ઍપ્લિકેશન શૉર્ટકટ્સ બનાવો</translation> <translation id="1763108912552529023">અન્વેષણ કરતાં રહો</translation> <translation id="1764226536771329714">બીટા</translation> @@ -576,8 +575,10 @@ <translation id="1839704667838141620">આ ફાઇલ જે રીતે શેર કરેલી છે તે બદલો</translation> <translation id="1841545962859478868">ઉપકરણ વ્યવસ્થાપક નીચે આપેલનું નિરીક્ષણ કરી શકે છે:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" />ને અક્ષમ કરેલ છે</translation> +<translation id="1842766183094193446">શું તમે ખરેખર ડેમો મોડ ચાલુ કરવા માગો છો?</translation> <translation id="1844692022597038441">આ ફાઇલ ઑફલાઇન ઉપલબ્ધ નથી.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" /> ચલાવવા માટે Control-ક્લિક કરો</translation> +<translation id="1847880352285315359">સાચવ્યો</translation> <translation id="1848219224579402567">લિડ બંધ કરવામાં આવે, ત્યારે સાઇન આઉટ કરો</translation> <translation id="184823282865851239">જો સાઇટ ખલેલ પાડતી જાહેરાતો બતાવવાનું વલણ ધરાવતી હોય તેને અવરોધિત કરો</translation> <translation id="1849186935225320012">આ પૃષ્ઠ પાસે MIDI ઉપકરણોનું સંપૂર્ણ નિયંત્રણ છે.</translation> @@ -673,6 +674,7 @@ <translation id="200544492091181894">તમે થોડા સમય પછી સેટિંગમાં જઈને હંમેશાં આને બદલી શકો છો</translation> <translation id="2006638907958895361"><ph name="APP" />માં લિંક ખોલો</translation> <translation id="2007404777272201486">સમસ્યાની જાણ કરો...</translation> +<translation id="2016237810978710652">Linux ફાઇલો ખોલી રહ્યાં છીએ...</translation> <translation id="2016430552235416146">પરંપરાગત</translation> <translation id="2017334798163366053">પ્રદર્શન ડેટા સંગ્રહ અક્ષમ કરો</translation> <translation id="2017836877785168846">ઍડ્રેસ બારમાં ઇતિહાસ અને સ્વતઃપૂર્ણ કરવું સાફ કરો.</translation> @@ -767,6 +769,7 @@ <translation id="2154484045852737596">કાર્ડ સંપાદિત કરો</translation> <translation id="2154710561487035718">URL ની કૉપિ કરો</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> જેવું લાગે છે</translation> +<translation id="2156283799932971644">Googleને અમુક સિસ્ટમ માહિતી અને પેજ કન્ટેન્ટ મોકલીને તમે સલામત બ્રાઉઝિંગ બહેતર બનાવવામાં સહાય કરી શકો છો.</translation> <translation id="215753907730220065">પૂર્ણ સ્ક્રીનથી બહાર નીકળો</translation> <translation id="2157875535253991059">આ પૃષ્ઠ હવે પૂર્ણ સ્ક્રીન છે.</translation> <translation id="216169395504480358">Wi-Fi ઉમેરો...</translation> @@ -776,6 +779,7 @@ <translation id="2173801458090845390">આ ઉપકરણમાં માગણી ID ઉમેરો</translation> <translation id="2175042898143291048">હંમેશાં આ કરો</translation> <translation id="2175607476662778685">ઝડપી લૉંચ બાર</translation> +<translation id="2176087259161165020">અન્ય સ્રોતો</translation> <translation id="2177950615300672361">છુપો ટેબ: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> પરનું <ph name="PEPPER_PLUGIN_NAME" /> તમારા કમ્પ્યુટરને ઍક્સેસ કરવા માગે છે</translation> <translation id="2178614541317717477">CA સમાધાન</translation> @@ -859,7 +863,6 @@ <translation id="2291643155573394834">આગલું ટૅબ</translation> <translation id="2292848386125228270">કૃપા કરીને એક સામાન્ય વપરાશકર્તા તરીકે <ph name="PRODUCT_NAME" /> શરૂ કરો. જો તમને ડેવલપમેન્ટ માટે રૂટ તરીકે ચલાવવાની જરૂર હોય, તો --no-sandbox ચિહ્ન સાથે ફરીથી ચલાવો.</translation> <translation id="2294358108254308676">શું તમે <ph name="PRODUCT_NAME" /> ઇન્સ્ટોલ કરવા માંગો છો?</translation> -<translation id="2296019197782308739">EAP પદ્ધતિ:</translation> <translation id="2297705863329999812">પ્રિન્ટર શોધો</translation> <translation id="2300383962156589922"><ph name="APP_NAME" />ને કસ્ટમાઇઝ કરો અને નિયંત્રિત કરો</translation> <translation id="2301382460326681002">એક્સ્ટેંશન રૂટ ડાયરેક્ટરી અમાન્ય છે.</translation> @@ -907,6 +910,7 @@ <translation id="2366463953911599217">ભૂલ: <ph name="APP_NAME" />ને અનઇન્સ્ટૉલ કરવામાં નિષ્ફળ થયાં.</translation> <translation id="2367199180085172140">ફાઇલ શેર ઉમેરો</translation> <translation id="2367972762794486313">ઍપ્લિકેશનો બતાવો</translation> +<translation id="2369536625682139252"><ph name="SITE" /> દ્વારા સ્ટોર કરેલો કુકી સિવાયનો, બધો ડેટા કાઢી નખાશે,</translation> <translation id="2371076942591664043">&પૂર્ણ થાય ત્યારે ખોલો</translation> <translation id="2377319039870049694">સૂચિ દૃશ્ય પર સ્વિચ કરો</translation> <translation id="2377667304966270281">Hard Faults</translation> @@ -916,7 +920,6 @@ <translation id="2379281330731083556">સિસ્ટમ સંવાદનો ઉપયોગ કરીને છાપો... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">મોકલતાં પહેલાં પૂછો (ભલામણ કરેલ)</translation> <translation id="2384436799579181135">એક ભૂલ આવી છે. કૃપા કરીને તમારું પ્રિન્ટર તપાસો અને ફરી પ્રયાસ કરો.</translation> -<translation id="2385700042425247848">સેવા નામ:</translation> <translation id="2387458720915042159">પ્રૉક્સી કનેક્શનનો પ્રકાર</translation> <translation id="2391419135980381625">માનક ફૉન્ટ</translation> <translation id="2391762656119864333">રદબાતલ કરો</translation> @@ -967,7 +970,6 @@ <translation id="247949520305900375">ઑડિઓ શેર કરો</translation> <translation id="2480868415629598489">તમે કૉપિ અને પેસ્ટ કરો છો તે ડેટાને સંશોધિત કરો</translation> <translation id="2482878487686419369">સૂચનાઓ</translation> -<translation id="2485056306054380289">સર્વર CA પ્રમાણપત્ર:</translation> <translation id="2485422356828889247">અનઇન્સ્ટોલ કરો</translation> <translation id="2487067538648443797">નવું બુકમાર્ક ઉમેરો</translation> <translation id="248861575772995840">તમારો ફોન શોધી શકાતો નથી. ખાતરી કરો કે તમારા <ph name="DEVICE_TYPE" />નું Bluetooth ચાલુ કરેલું છે. <a>વધુ જાણો</a></translation> @@ -1027,6 +1029,7 @@ <translation id="2566124945717127842">તમારા <ph name="IDS_SHORT_PRODUCT_NAME" /> ઉપકરણને નવાની જેમ ફરીથી સેટ કરવા માટે પાવરવૉશ કરો.</translation> <translation id="2567257616420533738">પાસવર્ડ સાચવેલ છે. <ph name="SAVED_PASSWORDS_LINK" /> પર સાચવેલા પાસવર્ડ જુઓ અને મેનેજ કરો</translation> <translation id="2568774940984945469">માહિતી બાર સંગ્રહક</translation> +<translation id="2570454805927264159">તમારા આસિસ્ટંટનો સૌથી વધુ લાભ મેળવો</translation> <translation id="257088987046510401">થીમ્સ</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> ને માત્ર વાંચવાની ઍક્સેસ મંજૂર કરવામાં આવી છે.</translation> <translation id="2573269395582837871">એક ચિત્ર અને નામ પસંદ કરો</translation> @@ -1090,7 +1093,6 @@ <translation id="2653659639078652383">સબમિટ કરો</translation> <translation id="265390580714150011">ફીલ્ડ મૂલ્ય</translation> <translation id="2654166010170466751">સાઇટોને ચુકવણી હૅન્ડલર ઇન્સ્ટૉલ કરવાની મંજૂરી આપે છે</translation> -<translation id="2655386581175833247">વપરાશકર્તા પ્રમાણપત્ર:</translation> <translation id="2660779039299703961">ઇવેન્ટ</translation> <translation id="266079277508604648">પ્રિન્ટર સાથે કનેક્ટ કરી શકાતું નથી. તપાસો કે પ્રિન્ટર ચાલુ કરેલ છે અને વાઇ-ફાઇ અથવા USB દ્વારા તમારી Chromebook સાથે કનેક્ટ કરેલ છે.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1321,6 +1323,7 @@ <translation id="3006881078666935414">કોઈ વપરાશ ડેટા નથી</translation> <translation id="3007214526293698309">ગુણોત્તર ઠીક કરો</translation> <translation id="3007771295016901659">ડુપ્લિકેટ ટૅબ</translation> +<translation id="3008272652534848354">પરવાનગીઓ રીસેટ કરો</translation> <translation id="3009300415590184725">શું તમે ખરેખર મોબાઇલ ડેટા સેવા સેટઅપ પ્રક્રિયાને રદ કરવા માંગો છો?</translation> <translation id="3009779501245596802">અનુક્રમિત ડેટાબેસેસ</translation> <translation id="3010279545267083280">પાસવર્ડ કાઢી નાખ્યો</translation> @@ -1387,7 +1390,6 @@ <translation id="3100609564180505575">મોડ્યુલ્સ(<ph name="TOTAL_COUNT" />) - જાણીતા વિરોધાભાસો: <ph name="BAD_COUNT" />, શંકાસ્પદ: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">તારીખ અને સમય</translation> <translation id="310671807099593501">સાઇટ બ્લૂટૂથનો ઉપયોગ કરી રહી છે</translation> -<translation id="3108967419958202225">પસંદ કરો...</translation> <translation id="3115128645424181617">તમારો ફોન શોધી શકાતો નથી. ખાતરી કરો કે તે હાથવગો છે અને તેનું Bluetooth ચાલુ કરેલું છે.</translation> <translation id="3115147772012638511">કૅશ માટે રાહ જુએ છે...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> સહાય</translation> @@ -1432,7 +1434,6 @@ <translation id="3165390001037658081">કેટલાક કૅરિઅર આ સુવિધાને અવરોધિત કરી શકે છે.</translation> <translation id="316854673539778496">તમારા બધા ઉપકરણો પર તમારા બધા એક્સ્ટેંશન મેળવવા માટે સાઇન ઇન કરો અને સિંક ચાલુ કરો.</translation> <translation id="3170072451822350649">તમે સાઇન ઇન કરવાનું છોડી અને <ph name="LINK_START" />અતિથિ તરીકે બ્રાઉઝ<ph name="LINK_END" /> પણ કરી શકો છો.</translation> -<translation id="3177048931975664371">પાસવર્ડ છુપાવવા માટે ક્લિક કરો</translation> <translation id="3177909033752230686">પૃષ્ઠ ભાષા:</translation> <translation id="3181110748548073003">આગળ જવા માટે |<ph name="SHORTCUT" />| દબાવો</translation> <translation id="3182749001423093222">જોડણી તપાસણી</translation> @@ -1463,7 +1464,6 @@ <translation id="3236289833370040187">માલિકીને <ph name="DESTINATION_DOMAIN" />માં સ્થાનાંતરિત કરવામાં આવશે.</translation> <translation id="323803881985677942">એક્સ્ટેન્શન વિકલ્પો ખોલો</translation> <translation id="3241680850019875542">પૅક કરવા માટે એક્સ્ટેંશનની રૂટ ડાયરેક્ટરી પસંદ કરો. એક્સ્ટેંશનને અપડેટ કરવા માટે, ફરી ઉપયોગ કરવા ખાનગી કી ફાઇલ પણ પસંદ કરો.</translation> -<translation id="3242765319725186192">પૂર્વ-શેર કરેલી કી:</translation> <translation id="3244294424315804309">અવાજ બંધ કરવાનું ચાલુ રાખો</translation> <translation id="3245321423178950146">અજ્ઞાત કલાકાર</translation> <translation id="3246097286174000800">Smart Lock અજમાવી જુઓ</translation> @@ -1596,7 +1596,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> માટે વધુ ક્રિયાઓ</translation> <translation id="3440761377721825626">જ્યારે કોઈ સાઇટ તમારા કમ્પ્યુટરને ઍક્સેસ કરવા માટે પ્લગ-ઇનનો ઉપયોગ કરવા માગે ત્યારે પૂછો</translation> <translation id="3441653493275994384">સ્કિન</translation> -<translation id="3445830502289589282">ફેસ 2 પ્રમાણીકરણ:</translation> <translation id="344630545793878684">ઘણી વેબસાઇટ્સ પર તમારો ડેટા વાંચી શકે છે</translation> <translation id="3449839693241009168">આદેશોને <ph name="EXTENSION_NAME" /> પર મોકલવા માટે <ph name="SEARCH_KEY" /> દબાવો</translation> <translation id="3450157232394774192">નિષ્ક્રિય સ્થિતિ અક્યુપન્સિ ટકા</translation> @@ -1637,7 +1636,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> ભૂલો.</translation> <translation id="3495660573538963482">Google સહાયકની સેટિંગ્સ</translation> <translation id="3496213124478423963">ઝૂમ ઘટાડો</translation> -<translation id="3504135463003295723">જૂથ નામ:</translation> <translation id="3505030558724226696">ઉપકરણ ઍક્સેસ રદબાતલ કરો</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" માટે વર્તમાન પરવાનગીઓ</translation> <translation id="3507547268929739059">Chromebook માટે Linux ઍપને કાઢી નાખો</translation> @@ -1746,7 +1744,6 @@ <translation id="3661054927247347545">સાઇન ઇન પ્રમાણન માન્ય નથી, <ph name="MINUTES" /> : <ph name="SECONDS" />માં વિંડો બંધ થાય છે</translation> <translation id="3664511988987167893">એક્સ્ટેંશન આઇકન</translation> <translation id="3665589677786828986">Chrome ને જાણ થઈ છે કે તમારી કેટલીક સેટિંગ્સ બીજા પ્રોગ્રામ દ્વારા દૂષિત કરવામાં આવેલી અને તેમને તેમના મૂળ ડિફોલ્ટ્સ પર ફરીથી સેટ કરી છે.</translation> -<translation id="3665842570601375360">સુરક્ષા:</translation> <translation id="3668570675727296296">ભાષા સેટિંગ્સ</translation> <translation id="3668823961463113931">હેન્ડલર્સ</translation> <translation id="3670229581627177274">Bluetooth ચાલુ કરો</translation> @@ -1784,7 +1781,6 @@ <translation id="3726463242007121105">આ ઉપકરણ ખોલી શકાતું નથી કારણ કે તેની ફાઇલસિસ્ટમને સપોર્ટ નથી.</translation> <translation id="3727148787322499904">આ સેટિંગને બદલવું તમામ શેર કરેલ નેટવર્કને પ્રભાવિત કરશે</translation> <translation id="3727187387656390258">પૉપ અપની તપાસ કરો</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">લાઇન <ph name="ERROR_LINE" />માં ભૂલ આવી છે</translation> <translation id="3733127536501031542">સ્ટેપ-અપ સાથે SSL સર્વર </translation> <translation id="3737536731758327622">તમારા ડાઉનલોડ્સ અહીં દેખાય છે</translation> @@ -1859,7 +1855,6 @@ <translation id="38275787300541712">પૂર્ણ થવા પર Enter દબાવો</translation> <translation id="3827774300009121996">&પૂર્ણ સ્ક્રીન</translation> <translation id="3828029223314399057">બુકમાર્ક્સ શોધો</translation> -<translation id="3829932584934971895">પ્રદાતા પ્રકાર:</translation> <translation id="3830674330436234648">કોઇ પ્લેબેક ઉપલબ્ધ નથી.</translation> <translation id="3831486154586836914">વિંડો વિહંગાવલોકન મોડમાં દાખલ થયાં</translation> <translation id="383161972796689579">આ ઉપકરણનાં માલિકે નવા વપરાશકર્તાઓને ઉમેરવાથી અક્ષમ કર્યા છે</translation> @@ -1880,6 +1875,7 @@ <translation id="3856921555429624101">ડેટા વપરાશ માપન સમાપ્ત થયું છે</translation> <translation id="3857228364945137633">જ્યારે તમારો ફોન નજીકમાં હોય, ત્યારે તમારા <ph name="DEVICE_TYPE" />ને પાસવર્ડ વિના અનલૉક કરવાનો પ્રયાસ કરો.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: સિંક થોભાવ્યું</translation> <translation id="3860381078714302691">Hangouts Meet પર સ્વાગત છે</translation> <translation id="3862134173397075045">Chrome માં કાસ્ટ અનુભવ પર સ્વાગત છે!</translation> <translation id="3862788408946266506">'Kiosk_only' મેનિફેસ્ટ વિશેષતાવાળી ઍપ Chrome OS કિઓસ્ક મોડમાં ઇન્સ્ટૉલ કરેલી હોવી આવશ્યક છે</translation> @@ -1956,7 +1952,6 @@ <translation id="3968261067169026421">નેટવર્ક સેટ કરી શકાયું નથી</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">ગણના કરી રહ્યું છે...</translation> -<translation id="3974195870082915331">પાસવર્ડ બતાવવા માટે ક્લિક કરો</translation> <translation id="3975222297214566386">ઇનપુટ વિકલ્પો પરપોટો</translation> <translation id="397703832102027365">ફાઇનલ કરી રહ્યું છે...</translation> <translation id="3979395879372752341">નવું એક્સ્ટેંશન ઉમેરાયું (<ph name="EXTENSION_NAME" />)</translation> @@ -1997,6 +1992,7 @@ <translation id="4044612648082411741">તમારો પ્રમાણપત્ર પાસવર્ડ દાખલ કરો</translation> <translation id="404493185430269859">ડિફોલ્ટ શોધ એન્જિન</translation> <translation id="4047112090469382184">આ કેવી રીતે સુરક્ષિત છે</translation> +<translation id="4051049974203704184">સ્ક્રીન પરની વસ્તુઓ વિશે માહિતી મેળવો</translation> <translation id="4052120076834320548">નાનું</translation> <translation id="4055023634561256217">તમારું ઉપકરણ Powerwash સાથે ફરીથી સેટ થઈ શકે તે પહેલા એક પુનર્પ્રારંભ આવશ્યક છે.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2025,6 +2021,7 @@ <translation id="4088095054444612037">જૂથ માટે સ્વીકારો</translation> <translation id="4089235344645910861">સેટિંગ સાચવી. સિંક શરૂ થયું.</translation> <translation id="4090103403438682346">ચકાસાયેલ ઍક્સેસ સક્ષમ કરો</translation> +<translation id="4090947011087001172"><ph name="SITE" /> માટે સાઇટ પરવાનગીને રીસેટ કરીએ?</translation> <translation id="4091434297613116013">કાગળનાં પત્રકો</translation> <translation id="4093955363990068916">સ્થાનિક ફાઇલ:</translation> <translation id="4095507791297118304">પ્રાથમિક પ્રદર્શન</translation> @@ -2058,7 +2055,7 @@ <translation id="4146026355784316281">હંમેશા સિસ્ટમ દર્શક સાથે ખોલો</translation> <translation id="4146785383423576110">રીસેટ કરો અને સાફ કરો</translation> <translation id="4147897805161313378">Google ફોટો</translation> -<translation id="4150201353443180367">પ્રદર્શિત કરો</translation> +<translation id="4150201353443180367">ડિસ્પ્લે</translation> <translation id="4152670763139331043">{NUM_TABS,plural, =1{1 ટેબ}one{# ટેબ્સ}other{# ટેબ્સ}}</translation> <translation id="4154664944169082762">ફિંગરપ્રીંટ્સ</translation> <translation id="4157869833395312646">Microsoft Server Gated Cryptography</translation> @@ -2199,7 +2196,6 @@ <translation id="4419556793104466535">સિંક, વૈયક્તિકરણ અને વધુ બાબતોને નિયંત્રિત કરો</translation> <translation id="4421932782753506458">ફ્લફી</translation> <translation id="4422347585044846479">આ પૃષ્ઠ માટે બુકમાર્ક સંપાદિત કરો</translation> -<translation id="4423104065312875417">વધારાના વાણી એન્જિનો ઇન્સ્ટૉલ કરો</translation> <translation id="4423376891418188461">સેટિંગ્સ પુનઃસ્થાપિત કરો</translation> <translation id="4423482519432579560">&જોડણી તપાસો</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, તમારા વ્યવસ્થાપક માટે આવશ્યક છે કે તમે તમારો પાસવર્ડ બદલો.</translation> @@ -2223,7 +2219,6 @@ <translation id="4449996769074858870">આ ટેબ ઑડિઓ ચલાવી રહ્યું છે.</translation> <translation id="4450974146388585462">તપાસ કરો</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> શોધો અથવા URL ટાઇપ કરો</translation> -<translation id="445923051607553918">Wi-Fi નેટવર્કથી જોડાઓ</translation> <translation id="4462159676511157176">કસ્ટમ નામ સર્વર્સ</translation> <translation id="4467100756425880649">Chrome વેબ દુકાન ગૅલેરી</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" />ને વિસ્તૃત કરો</translation> @@ -2358,6 +2353,7 @@ <translation id="4682551433947286597">વૉલપેપર્સ સાઇન-ઇન સ્ક્રીન પર દેખાય છે.</translation> <translation id="4684427112815847243">દરેક વસ્તુ સમન્વયિત કરો</translation> <translation id="4689421377817139245">તમારા iPhone સાથે આ બુકમાર્કનું સમન્વયન કરો</translation> +<translation id="4690091457710545971"><Intel વાઇ-ફાઇ ફર્મવેયર દ્વારા ચાર ફાઇલ જનરેટ થઈ: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. પહેલી ત્રણ રજિસ્ટર ડમ્પ ધરાવતી બાઇનરી ફાઇલો છો અને Intel દ્વારા ખાતરી આપવામાં આવી છે કે તેમાં વ્યક્તિગત કે ઉપકરણની ઓળખ છતી કરે તેવી કોઈ માહિતી નથી. છેલ્લી ફાઇલ Intel ફર્મવેયરનો અમલ બજાવણી ટ્રેસ છે; જેમાં કોઈપણ વ્યક્તિગત અથવા ઉપકરણની ઓળખ છતી કરતી માહિતીને સ્ક્રબ કરવામાં આવેલ છે, પણ તે અહીં પ્રદર્શિત કરવા માટે ખૂબ મોટી છે. આ ફાઇલો તમારા ઉપકરણમાં તાજેતરની વાઇ-ફાઇ સમસ્યાઓના પ્રતિસાદમાં જનરેટ કરવામાં આવી છે અને આ સમસ્યાઓનું નિવારણ કરવામાં સહાય કરવા માટે તેને Intel સાથે શેર કરવામાં આવી શકે છે.></translation> <translation id="4692302215262324251">તમારા <ph name="DEVICE_TYPE" /> ની <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> દ્વારા એન્ટરપ્રાઇઝ સંચાલન માટે સફળતાપૂર્વક નોંધણી કરવામાં આવી છે. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> જો આ અનપેક્ષિત હોય, તો કૃપા કરીને સમર્થનનો સંપર્ક કરો.</translation> @@ -2464,7 +2460,7 @@ <translation id="4856478137399998590">તમારી મોબાઇલ ડેટા સેવા સક્રિય થઈ છે અને ઉપયોગ માટે તૈયાર છે</translation> <translation id="4857506433977877623">{COUNT,plural, =0{તમામ URLને &છુપી વિંડોમાં ખોલો}=1{&છુપી વિંડોમાં ખોલો}one{તમામ (#) URLને &છુપી વિંડોમાં ખોલો}other{તમામ (#) URLને &છુપી વિંડોમાં ખોલો}}</translation> <translation id="4858913220355269194">Fritz</translation> -<translation id="4862042298115071399"><ph name="WINDOW_TITLE" /> - વીડિઓ ચિત્ર-માં-ચિત્રમાં ચાલી રહ્યો છે</translation> +<translation id="4862042298115071399"><ph name="WINDOW_TITLE" /> - વીડિઓ ચિત્ર-માં-ચિત્ર મોડમાં ચાલી રહ્યો છે</translation> <translation id="4862050643946421924">ઉપકરણ ઉમેરી રહ્યું છે...</translation> <translation id="4862642413395066333">OCSP પ્રતિસાદોને સાઇન ઇન કરે છે</translation> <translation id="4863769717153320198"><ph name="WIDTH" /> x <ph name="HEIGHT" /> જેવું લાગે છે (ડિફૉલ્ટ)</translation> @@ -2615,6 +2611,7 @@ <translation id="5074318175948309511">નવી સેટિંગ્સ પ્રભાવમાં આવે તે પહેલાં આ પૃષ્ઠને ફરીથી લોડ કરવાની જરૂર પડી શકે છે.</translation> <translation id="5075131525758602494">SIM નો PIN દાખલ કરો</translation> <translation id="5078638979202084724">બધા ટૅબ્સ બુકમાર્ક કરો</translation> +<translation id="5079950360618752063">સૂચવેલ પાસવર્ડનો ઉપયોગ કરો</translation> <translation id="5084230410268011727">સાઇટને મોશન અને લાઇટ સેન્સરનો ઉપયોગ કરવાની મંજૂરી આપો</translation> <translation id="5085162214018721575">અપડેટ્સ માટે તપાસી રહ્યું છે</translation> <translation id="5086082738160935172">HID</translation> @@ -2653,6 +2650,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">આ આઇટમ કાઢી નાખો</translation> <translation id="5139955368427980650">&ખોલો</translation> +<translation id="5142961317498132443">પ્રમાણીકરણ</translation> <translation id="5143374789336132547">જ્યારે તમે હોમ બટન ક્લિક કરો છો ત્યારે જે પૃષ્ઠ દર્શાવવામાં આવે છે તે <ph name="EXTENSION_NAME" /> એક્સટેન્શને બદલ્યું છે.</translation> <translation id="5143712164865402236">પૂર્ણ સ્ક્રીનમાં દાખલ થાઓ</translation> <translation id="5145331109270917438">સંશોધિત કર્યાની તારીખ</translation> @@ -2822,7 +2820,6 @@ <translation id="5380103295189760361">તે સંશોધકોનાં કીબોર્ડ શોર્ટકટ્સ જોવા માટે Control, Alt, Shift અથવા શોધને દબાવી રાખો.</translation> <translation id="5382591305415226340">સમર્થિત લિંક્સને સંચાલિત કરો</translation> <translation id="5384883051496921101">આ સાઇટ છુપા મોડની બહારની એક ઍપ્લિકેશન વડે માહિતી શેર કરવા જઈ રહી છે.</translation> -<translation id="5388588172257446328">વપરાશકર્તાનામ:</translation> <translation id="5388885445722491159">જોડી કરેલા</translation> <translation id="5389237414310520250">નવો વપરાશકર્તા બનાવી શકાયો નથી. કૃપા કરીને તમારું હાર્ડ ડ્રાઇવ સ્થાન અને પરવાનગીઓ તપાસો અને ફરી પ્રયાસ કરો.</translation> <translation id="5390100381392048184">સાઇટને અવાજ ચલાવવાની મંજૂરી આપો</translation> @@ -2948,7 +2945,6 @@ <translation id="5551573675707792127">કીબોર્ડ અને ટેક્સ્ટ ઇનપુટ</translation> <translation id="5553089923092577885">પ્રમાણપત્ર નીતિ મેપિંગ્સ</translation> <translation id="5554489410841842733">જ્યારે એક્સટેન્શન ચાલુ પૃષ્ઠ પર કાર્ય કરી શકે ત્યારે આ આયકન દેખાશે.</translation> -<translation id="5554573843028719904">અન્ય Wi-Fi નેટવર્ક...</translation> <translation id="5554720593229208774">ઇમેઇલ પ્રમાણન અધિકારી</translation> <translation id="5556206011531515970">તમારા ડિફૉલ્ટ બ્રાઉઝરને પસંદ કરવા માટે આગલું ક્લિક કરો.</translation> <translation id="5556459405103347317">ફરિથી લોડ કરો</translation> @@ -2989,7 +2985,6 @@ <translation id="5610038042047936818">કૅમેરા મોડ પર સ્વિચ કરો</translation> <translation id="5612720917913232150"><ph name="URL" /> તમારા કમ્પ્યુટરનાં સ્થાનનો ઉપયોગ કરવા માગે છે</translation> <translation id="5612734644261457353">માફ કરશો, તમારો પાસવર્ડ હજી ચકાસી શકાયો નથી. નોંધ: જો તમે તાજેતરમાં તમારો પાસવર્ડ બદલ્યો હોય, તો તમારો નવો પાસવર્ડ તમે એક વાર સાઇન આઉટ કરી લો તે પછી લાગુ થશે, કૃપા કરીને અહીં જૂના પાસવર્ડનો ઉપયોગ કરો.</translation> -<translation id="5613695965848159202">અજ્ઞાત ઓળખાણ:</translation> <translation id="5614190747811328134">વપરાશકર્તા સૂચના</translation> <translation id="561698261642843490">Firefox બંધ કરો</translation> <translation id="5618075537869101857">ડાર્ન, કિઓસ્ક ઍપ્લિકેશન લોંચ કરી શકાઇ નથી.</translation> @@ -3208,7 +3203,6 @@ <translation id="5941343993301164315"><ph name="TOKEN_NAME" /> માટે કૃપા કરીને સાઇન ઇન કરો.</translation> <translation id="5941711191222866238">નાનું કરો</translation> <translation id="5946591249682680882">રીપોર્ટ ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">ખાનગી નેટવર્ક ઉમેરો</translation> <translation id="5949544233750246342">ફાઇલ પાર્સ કરવામાં અસમર્થ</translation> <translation id="5955282598396714173">તમારો પાસવર્ડ સમાપ્ત થઈ ગયો છે. કૃપા કરીને સાઇન આઉટ કરો પછી તેને બદલવા માટે ફરીથી સાઇન ઇન કરો.</translation> <translation id="5956585768868398362">શું આ તમારી અપેક્ષા મુજબનું શોધ પૃષ્ઠ છે?</translation> @@ -3369,11 +3363,13 @@ <translation id="6198102561359457428">સાઇન આઉટ કરો પછી ફરી સાઇન કરો...</translation> <translation id="6198252989419008588">PIN બદલો</translation> <translation id="6199801702437275229">સ્થાન માહિતી માટે રાહ જોઈ રહ્યું છે...</translation> +<translation id="6204015976622790023">તમારા આસિસ્ટંટના તમારી સ્ક્રીન પરની વસ્તુઓથી સંબંધિત સૂચનો જુઓ.</translation> <translation id="6205710420833115353">કેટલાક ઑપરેશન્સમાં અપેક્ષિત કરતાં વધુ સમય લાગી રહ્યો છે. શું તમે તેમને નિરસ્ત કરવા માગો છો?</translation> <translation id="6206311232642889873">છબીની કૉ&પિ બનાવો</translation> <translation id="6207200176136643843">ડિફૉલ્ટ ઝૂમ સ્તર પર રીસેટ કરો</translation> <translation id="620722923698527029">આ પ્રકારની લિંક હંમેશાં સંકળાયેલી ઍપમાં ખોલો</translation> <translation id="6207937957461833379">દેશ/પ્રદેશ</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: સિંક કાર્ય કરી રહ્યું નથી</translation> <translation id="6212039847102026977">વિગતવાર નેટવર્ક ગુણધર્મો બતાવો</translation> <translation id="6212168817037875041">ડિસ્પ્લે બંધ કરો</translation> <translation id="6212752530110374741">લિંક ઇમેઇલ કરો</translation> @@ -3411,7 +3407,6 @@ <translation id="6263541650532042179">સમન્વયન ફરીથી સેટ કરો </translation> <translation id="6264365405983206840">&બધા પસંદ કરો</translation> <translation id="6264422956566238156">તમે સિંક ચાલુ કર્યું છે</translation> -<translation id="6265930187414222160">થઈ ગયું! હાનિકારક સૉફ્ટવેર કાઢી નાખ્યું.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" /> પર પોતાને પ્રમાણિત કરવા માટે એક પ્રમાણપત્ર પસંદ કરો</translation> <translation id="6268252012308737255"><ph name="APP" /> સાથે ખોલો</translation> <translation id="6268747994388690914">HTML ફાઇલમાંથી બુકમાર્ક્સ આયાત કરો...</translation> @@ -3516,7 +3511,6 @@ તમારા <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> એકાઉન્ટમાં સાઇન ઇન કરવાનું ચાલુ રાખવા માટે કૃપા કરીને "આગલું" ક્લિક કરો.</translation> <translation id="6419546358665792306">અનપૅક કરેલ એક્સ્ટેન્શન લોડ કરો</translation> <translation id="642282551015776456">આ નામનો ઉપયોગ ફોલ્ડર નામની કોઈ ફાઇલ તરીકે થઈ શકશે નહીં</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox સેટિંગ્સ ખોલો</translation> <translation id="6429384232893414837">અપડેટમાં ભૂલ</translation> <translation id="6430814529589430811">Base64-encoded ASCII, એકલ પ્રમાણપત્ર</translation> @@ -3597,7 +3591,6 @@ <translation id="6544215763872433504">Google દ્વારા વેબ બ્રાઉઝર, તમારા માટે</translation> <translation id="6545665334409411530">પુનરાવર્તન રેટ</translation> <translation id="6545834809683560467">શોધ અને સરનામાં બાર અથવા એપ લૉન્ચર શોધ બોક્સમાં લખેલા URL ને પૂર્ણ કરવામાં સહાય માટે પૂર્વાનુમાન સેવાનો ઉપયોગ કરો</translation> -<translation id="6546686722964485737">Wimax નેટવર્કથી જોડાઓ</translation> <translation id="6547316139431024316">આ એક્સ્ટેન્શન માટે ફરીથી ચેતવણી આપશો નહીં</translation> <translation id="6547354035488017500">ઓછામાં ઓછું 512 MB સ્થાન ખાલી કરો અથવા તમારું ઉપકરણ પ્રતિભાવવિહીન બની જશે. સ્થાન ખાલી કરવા માટે, ડ્રાઇવ સ્ટોરેજમાંથી ફાઇલો કાઢી નાખો.</translation> <translation id="6549689063733911810">તાજેતરનું</translation> @@ -4013,7 +4006,6 @@ <translation id="7201014958346994077">Linux ફાઇલો જોવામાં અસમર્થ</translation> <translation id="720110658997053098">આ ઉપકરણને કાયમ માટે કિઓસ્ક મોડમાં રાખો</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' ડિલીટ કર્યું</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> ડાઉનલોડ કરી રહ્યું છે...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{પેજમાંથી બહાર નીકળો}one{પેજમાંથી બહાર નીકળો}other{પેજમાંથી બહાર નીકળો}}</translation> <translation id="7216409898977639127">સેલ્યુલર પ્રદાતા</translation> @@ -4486,7 +4478,6 @@ <translation id="7909969815743704077">છૂપા મોડમાં ડાઉનલોડ કર્યું</translation> <translation id="7910768399700579500">&નવું ફોલ્ડર</translation> <translation id="7912080627461681647">સર્વર પર તમારો પાસવર્ડ બદલાઈ ગયો છે. કૃપા કરી સાઇન આઉટ કરો પછી ફરીથી સાઇન ઇન કરો.</translation> -<translation id="7912883689016444961">મોબાઇલ નેટવર્કને ગોઠવો</translation> <translation id="7915471803647590281">કૃપા કરીને પ્રતિસાદ મોકલતા પહેલા શું થઈ રહ્યું છે તે અમને કહો.</translation> <translation id="7916556741383518510">ક્લિક કરવા પર</translation> <translation id="792514962475806987">ડૉક કરેલ ઝૂમ લેવલ:</translation> @@ -4540,7 +4531,6 @@ <translation id="7988355189918024273">ઍક્સેસિબિલિટી સુવિધાઓ સક્ષમ કરો </translation> <translation id="7994702968232966508">EAP પદ્ધતિ</translation> <translation id="799547531016638432">શૉર્ટકટ દૂર કરો</translation> -<translation id="7997479212858899587">ઓળખ:</translation> <translation id="7997826902155442747">પ્રાધાન્યતા પર પ્રક્રિયા કરો</translation> <translation id="7999229196265990314">નીચેની ફાઇલો બનાવાઈ: એક્સટેન્શન: <ph name="EXTENSION_FILE" />કી ફાઇલ: <ph name="KEY_FILE" />તમારી કી ફાઇલને સુરક્ષિત સ્થાન પર મૂકો. તમને તેની જરૂરિયાત તમારા એક્સટેન્શનના નવા સંસ્કરણ બનાવવા માટે પડશે.</translation> <translation id="799923393800005025">જોઇ શકે છે</translation> @@ -4618,7 +4608,6 @@ <translation id="8105368624971345109">બંધ કરો</translation> <translation id="8106045200081704138">મારી સાથે શેર કરેલા</translation> <translation id="8107015733319732394">તમારા <ph name="DEVICE_TYPE" /> પર Google Play સ્ટોર ઇન્સ્ટૉલ કરી રહ્યાં છીએ. આમાં થોડી મિનિટ લાગી શકે છે.</translation> -<translation id="8109930990200908494">વપરાશકર્તા પ્રમાણપત્ર માટે સાઇન-ઇન આવશ્યક.</translation> <translation id="8111155949205007504">તમાર iPhone સાથે આ પાસવર્ડ શેર કરો</translation> <translation id="8113043281354018522">લાઇસન્સનો પ્રકાર પસંદ કરો</translation> <translation id="8116190140324504026">વધુ માહિતી...</translation> @@ -4629,6 +4618,7 @@ <translation id="8118860139461251237">તમારા ડાઉનલોડ્સનું સંચાલન કરો</translation> <translation id="81238879832906896">પીળા અને સફેદ ફૂલ</translation> <translation id="8124313775439841391">સંચાલિત ONC</translation> +<translation id="8125562866093998907">સાઇટ તમારા એકાઉન્ટની વધારાની સુરક્ષા માટે તમારી સુરક્ષા કી ચકાસવા માગે છે.</translation> <translation id="813082847718468539">સ્થાન માહિતી જુઓ</translation> <translation id="8131740175452115882">પુષ્ટિ કરો</translation> <translation id="8133676275609324831">ફોલ્ડરમાં બતાવો</translation> @@ -4739,7 +4729,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> તમારા કૅમેરાને ઍક્સેસ કરવા માંગે છે કે કેમ તે પૂછો</translation> <translation id="830868413617744215">બીટા</translation> <translation id="8309458809024885768">પ્રમાણપત્ર પહેલાંથી અસ્તિત્વમાં છે</translation> -<translation id="8309505303672555187">નેટવર્ક પસંદ કરો:</translation> <translation id="8312871300878166382">ફોલ્ડરમાં પેસ્ટ કરો</translation> <translation id="8317671367883557781">નેટવર્ક કનેક્શન ઉમેરો</translation> <translation id="8319414634934645341">વિસ્તૃત કી ઉપયોગ</translation> @@ -4814,7 +4803,6 @@ <translation id="8451512073679317615">સહાયક</translation> <translation id="8452135315243592079">SIM કાર્ડ ખૂટે છે</translation> <translation id="8453482423012550001">$1 આઇટમ્સ કૉપિ કરી રહ્યું છે...</translation> -<translation id="8454288007744638700">અથવા, એક નવું નેટવર્ક પસંદ કરો:</translation> <translation id="845627346958584683">સમાપ્તિ સમય</translation> <translation id="8456681095658380701">અમાન્ય નામ</translation> <translation id="8457451314607652708">બુકમાર્ક્સ આયાત કરો</translation> @@ -4878,6 +4866,7 @@ <translation id="855081842937141170">ટૅબ પિન કરો</translation> <translation id="8551388862522347954">લાઇસેંસીસ</translation> <translation id="8553342806078037065">અન્ય લોકોને સંચાલિત કરો</translation> +<translation id="8554899698005018844">કોઈ ભાષા નથી</translation> <translation id="855773602626431402">એક અનસેન્ડબૉક્સ્ડ પ્લગિનને આ પૃષ્ઠ પર ચાલવાથી અટકાવવામાં આવ્યું હતું.</translation> <translation id="8557930019681227453">સ્પષ્ટ</translation> <translation id="8559694214572302298">છબી ડીકોડર</translation> @@ -4915,7 +4904,6 @@ <translation id="862727964348362408">સસ્પેન્ડેડ</translation> <translation id="862750493060684461">CSS કેશ</translation> <translation id="8627795981664801467">ફક્ત સુરક્ષિત કનેક્શન્સ</translation> -<translation id="8628085465172583869">સર્વર હોસ્ટનેમ: </translation> <translation id="8630903300770275248">નિરીક્ષિત વપરાશકર્તા આયાત કરો</translation> <translation id="8631032106121706562">પેટલ્સ</translation> <translation id="8637542770513281060">તમારું કમ્પ્યુટર એક સુરક્ષિત મોડ્યુલ ધરાવે છે, કે જેનો ઉપયોગ Chrome OSમાં ઘણી મહત્ત્વપૂર્ણ સુરક્ષા સુવિધાઓ લાગુ પાડવા માટે કરવામાં આવે છે. વધુ જાણવા માટે Chromebook સહાય કેંદ્રની મુલાકાત લો: https://support.google.com/chromebook/?p=sm</translation> @@ -5171,7 +5159,6 @@ <translation id="899403249577094719">નેટસ્કેપ પ્રમાણપત્ર બેઝ URL</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> દ્વારા સંચાલિત</translation> <translation id="8996526648899750015">એકાઉન્ટ ઉમેરો...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">ડિસ્ક છબી બનાવી રહ્યાં છીએ.</translation> <translation id="9003647077635673607">તમામ વેબસાઇટ્સ પર મંજૂરી આપો</translation> <translation id="9003677638446136377">ફરી તપાસો</translation> @@ -5338,7 +5325,7 @@ <translation id="952992212772159698">સક્રિય કરેલું નથી</translation> <translation id="957960681186851048">આ સાઇટે એકથી વધુ ફાઇલોને આપમેળે ડાઉનલોડ કરવાનો પ્રયાસ કર્યો</translation> <translation id="9580706199804957">Google સેવાઓ સાથે કનેક્ટ ન કરી શક્યાં</translation> -<translation id="958416628331784386">આ ટૅબ ચિત્ર-માં-ચિત્રમાં વીડિઓ ચલાવી રહી છે.</translation> +<translation id="958416628331784386">આ ટૅબ ચિત્ર-માં-ચિત્ર મોડમાં વીડિઓ ચલાવી રહી છે.</translation> <translation id="958515377357646513">આગળ જવા માટે ટચ કરો.</translation> <translation id="960719561871045870">ઓપરેટર કોડ</translation> <translation id="960987915827980018">લગભગ 1 કલાક બાકી</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb index 8792a48e..b40c459 100644 --- a/chrome/app/resources/generated_resources_hi.xtb +++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">ब्रेक लेने का समय होने वाला है</translation> <translation id="1062407476771304334">प्रतिस्थापित करें</translation> -<translation id="1064835277883315402">निजी नेटवर्क से जुड़ें</translation> <translation id="1064912851688322329">अपना Google खाता डिस्कनेक्ट करें</translation> <translation id="1067048845568873861">निर्मित</translation> <translation id="1067291318998134776">Linux (बीटा)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">खोज रहा है...</translation> <translation id="1316495628809031177">सिंक रोका हुआ है</translation> <translation id="1319979322914001937">ऐसा ऐप जो Chrome वेब स्टोर से एक्सटेंशन की फ़िल्टर की गई सूची दिखाता है. सूची में मौजूद एक्सटेंशन सीधे ऐप से इंस्टॉल किए गए हो सकते हैं.</translation> -<translation id="132090119144658135">विषय मिलान:</translation> <translation id="1326317727527857210">अपने अन्य डिवाइस से अपने टैब प्राप्त करने के लिए, Chrome में प्रवेश करें.</translation> <translation id="1327074568633507428">Google क्लाउड प्रिंट पर प्रिंटर</translation> <translation id="1327977588028644528">गेटवे</translation> @@ -283,7 +281,7 @@ <translation id="1407489512183974736">मध्य में काटा गया</translation> <translation id="1408504635543854729">डिवाइस की सामग्री फ़ाइल ऐप्लिकेशन में एक्सप्लोर करें. सामग्री किसी व्यवस्थापक ने प्रतिबंधित की है और उसे बदला नहीं जा सकता.</translation> <translation id="1408789165795197664">उन्नत...</translation> -<translation id="1409390508152595145">निगरानी में रखा गया उपयोगकर्ता बनाएं</translation> +<translation id="1409390508152595145">'निगरानी में रखा गया उपयोगकर्ता' बनाएं</translation> <translation id="1410197035576869800">ऐप्लिकेशन आइकॉन</translation> <translation id="1410616244180625362"><ph name="HOST" /> को अपना कैमरा एक्सेस करते रहने दें</translation> <translation id="1411668397053040814">VR में Chrome का इस्तेमाल करने के लिए तिलिस्म कीबोर्ड इंस्टॉल या अपडेट करें</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">ऐप्लिकेशन विंडो</translation> <translation id="1534389735079119190">गड़बड़ी: VM के अंदर मौजूद कंटेनर शुरू नहीं किया जा सका.</translation> <translation id="15373452373711364">बड़ा माउस कर्सर</translation> +<translation id="1540605929960647700">डेमो मोड चालू करें</translation> <translation id="1543284117603151572">Edge से आयात किया गया</translation> <translation id="1545177026077493356">स्वचालित किओस्क मोड</translation> <translation id="1545775234664667895">थीम "<ph name="THEME_NAME" />" स्थापित की गई</translation> @@ -416,7 +415,7 @@ <translation id="1601560923496285236">लागू करें</translation> <translation id="1603914832182249871">(गुप्त)</translation> <translation id="1607139524282324606">प्रविष्टि हटाएं</translation> -<translation id="1608626060424371292">इस उपयोगकर्ता को निकालें</translation> +<translation id="1608626060424371292">इस उपयोगकर्ता को हटाएं</translation> <translation id="1609170755653088773">इस पासवर्ड को अपने iPhone से सिंक करें</translation> <translation id="1609862759711084604">पिछला उपयोगकर्ता</translation> <translation id="1611584202130317952">प्रावधान प्रवाह में रुकावट आई थी. कृपया फिर से कोशिश करें या अपने डिवाइस मालिक या व्यवस्थापक से संपर्क करें.</translation> @@ -444,11 +443,11 @@ <translation id="1643072738649235303">SHA-1 के साथ X9.62 ECDSA हस्ताक्षर</translation> <translation id="1644574205037202324">इतिहास</translation> <translation id="1645516838734033527">आपके <ph name="DEVICE_TYPE" /> को सुरक्षित बनाए रखने के लिए, Smart Lock को आपके फ़ोन पर स्क्रीन लॉक की ज़रूरत होती है.</translation> -<translation id="1646102270785326155">इस उपयोगकर्ता को निकाल दिए जाने पर, इससे संबद्ध सभी फ़ाइलों और स्थानीय डेटा को स्थायी रूप से हटा दिया जाएगा. फिर भी $1 बाद में प्रवेश कर सकता है.</translation> +<translation id="1646102270785326155">इस उपयोगकर्ता को हटाए जाने पर, इससे जुड़ीं सभी फ़ाइलों और स्थानीय डेटा को हमेशा के लिए मिटा दिया जाएगा. फिर भी $1 बाद में साइन इन कर सकता है.</translation> <translation id="1646982517418478057">कृपया इस प्रमाणपत्र को एन्क्रिप्ट करने के लिए पासवर्ड डालें</translation> -<translation id="164814987133974965">निगरानी में रखा गया उपयोगकर्ता आपके मार्गदर्शन में वेब को एक्सप्लोर कर सकता है. निगरानी में रखे गए उपयोगकर्ता के प्रबंधक के रूप में, आप - कुछ वेबसाइट को <ph name="BEGIN_BOLD" />अनुमत या प्रतिबंधित<ph name="END_BOLD" /> कर सकते हैं, - निगरानी में रखे गए उपयोगकर्ता द्वारा देखी गई वेबसाइट की <ph name="BEGIN_BOLD" />समीक्षा<ph name="END_BOLD" /> कर सकते हैं, और +<translation id="164814987133974965">'निगरानी में रखा गया उपयोगकर्ता' आपके दिशा-निर्देशों के साथ वेब के बारे में और ज़्यादा जानकारी हासिल कर सकता है. 'निगरानी में रखे गए उपयोगकर्ता' के प्रबंधक के रूप में, आप + कुछ वेबसाइटों को <ph name="BEGIN_BOLD" />अनुमति दे सकते हैं या रोक लगा<ph name="END_BOLD" /> सकते हैं, + 'निगरानी में रखे गए उपयोगकर्ता' ने जो वेबसाइटें देखी हैं उनकी <ph name="BEGIN_BOLD" />समीक्षा<ph name="END_BOLD" /> कर सकते हैं, और अन्य सेटिंग <ph name="BEGIN_BOLD" />प्रबंधित<ph name="END_BOLD" /> कर सकते हैं.</translation> <translation id="1648528859488547844">स्थान तय करने के लिए वाई-फ़ाई या मोबाइल नेटवर्क का इस्तेमाल करें</translation> <translation id="1648943974594387137">प्रवेश संबंधी विवरण पुराने हैं</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">'इस्तेमाल के आंकड़े' और 'खराबी रिपोर्ट' Google को अपने आप भेजे जाने की अनुमति देकर <ph name="PRODUCT_NAME" /> को बेहतर बनाने में सहायता करें</translation> <translation id="1658424621194652532">यह पेज आपका माइक्रोफ़ोन एक्सेस कर रहा है.</translation> <translation id="1660204651932907780">साइटों को आवाज़ चलाने दें (सुझाया गया)</translation> +<translation id="1660938185063657230">अपनी सुरक्षा चाबी की पुष्टि करें</translation> <translation id="1661156625580498328">AES सुरक्षा लागू करें (सुझाया गया).</translation> <translation id="1661245713600520330">यह पृष्ठ मुख्य प्रक्रिया में लोड किए गए सभी मॉड्यूल और बाद में किसी समय लोड होने के लिए पंजीकृत मॉड्यूल की सूची बनाता है.</translation> <translation id="166179487779922818">पासवर्ड बहुत छोटा है.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">साइटों को क्लिपबोर्ड पर कॉपी किए गए लेख और इमेज न देखने दें</translation> <translation id="1682548588986054654">नई &गुप्त विंडो</translation> <translation id="168715261339224929">अपने सभी डिवाइस पर अपने बुकमार्क पाने के लिए, सिंक चालू करें.</translation> +<translation id="1688867105868176567">साइट डेटा हटाएं?</translation> <translation id="1688935057616748272">कोई अक्षर लिखें</translation> <translation id="168991973552362966">आस-पास का कोई प्रिंटर जोड़ें</translation> <translation id="1689945336726856614">यूआरएल &की कॉपी करें</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">इस व्यक्ति को निकालें</translation> <translation id="1706586824377653884">आपके व्यवस्थापक ने जोड़ा</translation> <translation id="1706625117072057435">ज़ूम स्तर</translation> -<translation id="1707463636381878959">इस नेटवर्क को अन्य उपयोगकर्ताओं के साथ शेयर करें</translation> <translation id="1708338024780164500">(प्रयोग में नहीं)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (आईडी: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (स्थानीय)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">थीम सक्षम करें</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome वेब स्टोर में देखें</translation> -<translation id="1758831820837444715">ईथरनेट नेटवर्क कॉन्फ़िगर करें</translation> <translation id="1763046204212875858">ऐप्स शॉर्टकट बनाएं</translation> <translation id="1763108912552529023">एक्सप्लोर करते रहें</translation> <translation id="1763808908432309942">नए टैब में खुलता है</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">इस फ़ाइल को शेयर करने का तरीका बदलें</translation> <translation id="1841545962859478868">डिवाइस व्यवस्थापक इन चीज़ों की निगरानी कर सकता है:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> अक्षम है</translation> +<translation id="1842766183094193446">क्या आप वाकई डेमो मोड चालू करना चाहते हैं?</translation> <translation id="1844692022597038441">यह फा़इल ऑफ़लाइन उपलब्ध नहीं है.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" /> चलाने के लिए Control दबाए रखते हुए क्लिक करें</translation> +<translation id="1847880352285315359">सेव कर लिया गया है</translation> <translation id="1848219224579402567">लिड बंद होने पर साइन आउट करें</translation> <translation id="184823282865851239">अगर साइट तंग करने वाले विज्ञापन दिखाने के लिए जानी जाती है, तो ब्लॉक करें</translation> <translation id="1849186935225320012">इस पेज के पास MIDI डिवाइस का पूर्ण नियंत्रण है.</translation> @@ -669,7 +670,7 @@ <translation id="1981115145845865539">अपने <ph name="DEVICE_TYPE" /> को अपने आप अनलॉक करें</translation> <translation id="1983959805486816857">आपके द्वारा नया निगरानी में रखा गया उपयोगकर्ता बनाए जाने के बाद, आप <ph name="MANAGEMENT_URL" /> पर कभी भी किसी भी डिवाइस से सेटिंग प्रबंधित कर सकते हैं.</translation> <translation id="1984642098429648350">विंडो को दाईं ओर डॉक करें</translation> -<translation id="1987139229093034863">किसी भिन्न उपयोगकर्ता पर स्विच करें.</translation> +<translation id="1987139229093034863">किसी दूसरे उपयोगकर्ता पर स्विच करें.</translation> <translation id="1987317783729300807">खाते</translation> <translation id="1989112275319619282">ब्राउज़ करें</translation> <translation id="1992397118740194946">सेट नहीं है</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">आप बाद में सेटिंग में जाकर इसे कभी भी बदल सकते हैं</translation> <translation id="2006638907958895361"><ph name="APP" /> में लिंक खोलें</translation> <translation id="2007404777272201486">किसी समस्या की रिपोर्ट करें...</translation> +<translation id="2016237810978710652">'Linux फ़ाइलें' खुल रही हैं...</translation> <translation id="2016430552235416146">परंपरागत</translation> <translation id="2017334798163366053">'परफ़ॉर्मेंस डेटा' इकट्ठा करना बंद करें</translation> <translation id="2017836877785168846">इतिहास साफ़ करता है और पता बार में स्वत: पूर्णता को साफ़ करता है.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">कार्ड संपादित करें</translation> <translation id="2154710561487035718">URL की कॉपी बनाएं</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> जैसा लगता है</translation> +<translation id="2156283799932971644">आप Google को कुछ सिस्टम जानकारी और पेज सामग्री भेजकर सुरक्षित ब्राउज़िंग को बेहतर बना सकते हैं.</translation> <translation id="215753907730220065">पूर्ण स्क्रीन से बाहर निकलें</translation> <translation id="2157875535253991059">यह पेज अब पूर्ण स्क्रीन है.</translation> <translation id="216169395504480358">वाई-फ़ाई जोड़ें...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">इस डिवाइस में मांग आईडी जोड़ें</translation> <translation id="2175042898143291048">हमेशा ऐसा करें</translation> <translation id="2175607476662778685">त्वरित लॉन्च बार</translation> +<translation id="2176087259161165020">'दूसरे स्रोत'</translation> <translation id="2177950615300672361">गुप्त टैब: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> पर <ph name="PEPPER_PLUGIN_NAME" /> आपके कंप्यूटर को एक्सेस करना चाहता है</translation> <translation id="2178614541317717477">CA समझौता</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">अगला टैब</translation> <translation id="2292848386125228270">कृपया <ph name="PRODUCT_NAME" /> को सामान्य उपयोगकर्ता की तरह शुरू करें. अगर आपको डेवलपमेंट के लिए रूट के रूप में चलाना है तो, --no-sandbox फ़्लैग के साथ फिर से चलाएं.</translation> <translation id="2294358108254308676">क्या आप <ph name="PRODUCT_NAME" /> को इंस्टॉल करना चाहते हैं?</translation> -<translation id="2296019197782308739">EAP विधि:</translation> <translation id="2297705863329999812">प्रिंटर खोजें</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> को पसंद के मुताबिक बनाएं और नियंत्रित करें</translation> <translation id="2301382460326681002">एक्सटेंशन मूल निर्देशिका अमान्य है.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">गड़बड़ी: <ph name="APP_NAME" /> अनइंस्टॉल नहीं हो सका.</translation> <translation id="2367199180085172140">File Share जोड़ें</translation> <translation id="2367972762794486313">ऐप्स दिखाएं</translation> +<translation id="2369536625682139252">कुकी को छोड़कर, <ph name="SITE" /> का स्टोर किया हुआ सारा डेटा मिटा दिया जाएगा.</translation> <translation id="2371076942591664043">&पू्र्ण होने पर खोलें</translation> <translation id="2377319039870049694">'सूची की तरह देखें' पर स्विच करें</translation> <translation id="2377667304966270281">हार्ड फ़ॉल्ट</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">सिस्टम डॉयलॉग का उपयोग करके प्रिंट करें… <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">भेजने से पहले पूछें (अनुशंसित)</translation> <translation id="2384436799579181135">कोई गड़बड़ी हुई है. कृपया अपना प्रिंटर देखें और दोबारा कोशिश करें.</translation> -<translation id="2385700042425247848">सेवा नाम:</translation> <translation id="2387458720915042159">प्रॉक्सी कनेक्शन प्रकार</translation> <translation id="2391419135980381625">मानक फ़ॉन्ट</translation> <translation id="2391762656119864333">निरस्त करें</translation> @@ -934,7 +937,7 @@ <translation id="240770291734945588"><ph name="SPACE_AVAILABLE" /> उपलब्ध है</translation> <translation id="2408955596600435184">अपना पिन डालें</translation> <translation id="241082044617551207">अज्ञात प्लग इन</translation> -<translation id="2413749388954403953">बुकमार्क उपयोगकर्ता इंटरफ़ेस बदलें</translation> +<translation id="2413749388954403953">'बुकमार्क यूज़र इंटरफ़ेस' बदलें</translation> <translation id="2419706071571366386">सुरक्षा के लिए, आपका कंप्यूटर इस्तेमाल में नहीं होने पर साइन आउट कर दें.</translation> <translation id="2422426094670600218"><अनाम></translation> <translation id="2423578206845792524">इस रूप में चित्र स&हेजें...</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">ऑडियो शेयर करें</translation> <translation id="2480868415629598489">अपने कॉपी किए हुए और चिपकाए हुए डेटा में बदलाव करें</translation> <translation id="2482878487686419369">अधिसूचनाएं</translation> -<translation id="2485056306054380289">सर्वर CA प्रमाणपत्र:</translation> <translation id="2485422356828889247">विस्थापित करें</translation> <translation id="2487067538648443797">नया बुकमार्क जोड़ें</translation> <translation id="248861575772995840">आपका फ़ोन नहीं मिल पा रहा है. पक्का करें कि आपके <ph name="DEVICE_TYPE" /> का ब्लूटूथ चालू है. <a>अधिक जानें</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">अपने <ph name="IDS_SHORT_PRODUCT_NAME" /> डिवाइस को बिल्कुल नए जैसा रीसेट करने के लिए पावरवॉश करें.</translation> <translation id="2567257616420533738">पासवर्ड सेव किया गया. <ph name="SAVED_PASSWORDS_LINK" /> पर सेव किए गए पासवर्ड देखें और उन्हें संभालें</translation> <translation id="2568774940984945469">जानकारी बार कंटेनर</translation> +<translation id="2570454805927264159">अपनी Assistant सेवा का पूरा फ़ायदा उठाएं</translation> <translation id="257088987046510401">थीम</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> को केवल पढ़ने के लिए ऐक्सेस दे दी गई है.</translation> <translation id="2573269395582837871">कोई फ़ोटो और नाम चुनें</translation> @@ -1050,8 +1053,8 @@ <translation id="2585300050980572691">डिफ़ॉल्ट खोज सेटिंग</translation> <translation id="2586657967955657006">क्लिपबोर्ड</translation> <translation id="2586672484245266891">कृपया थोड़ा छोटा यूआरएल लिखें</translation> -<translation id="2587922270115112871">निगरानी में रखा गया उपयोगकर्ता बनाने से Google खाता नहीं बनता, और उसकी सेटिंग और डेटा - Chrome सिंक के साथ अन्य डिवाइस पर उसका अनुसरण नहीं करेंगे. निगरानी में रखा गया उपयोगकर्ता केवल इस डिवाइस पर लागू होता है.</translation> +<translation id="2587922270115112871">'निगरानी में रखा गया उपयोगकर्ता' बनाने से कोई 'Google खाता' नहीं बनता और उसकी सेटिंग + और डेटा, Chrome सिंक के साथ अन्य डिवाइस पर उसको फ़ॉलो नहीं करेंगे. 'निगरानी में रखा गया उपयोगकर्ता' सिर्फ़ इस डिवाइस पर लागू होता है.</translation> <translation id="258932246702879617"><ph name="BEGIN_BOLD" />टास्कबार में पिन करें<ph name="END_BOLD" /> चुनें</translation> <translation id="259421303766146093">अनावर्धित करें</translation> <translation id="2594999711683503743">Google पर खोजें या यूआरएल डालें</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">सबमिट करें</translation> <translation id="265390580714150011">फ़ील्ड मान</translation> <translation id="2654166010170466751">साइटों को भुगतान हैंडलर इंस्टॉल करने की अनुमति दें</translation> -<translation id="2655386581175833247">उपयोगकर्ता प्रमाणपत्र:</translation> <translation id="2660779039299703961">इवेंट</translation> <translation id="266079277508604648">प्रिंटर से कनेक्ट नहीं किया जा सका. देखें कि प्रिंटर चालू है और वाई-फ़ाई या USB के ज़रिए आपके Chromebook से कनेक्ट किया हुआ है.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1144,7 +1146,7 @@ <translation id="2709516037105925701">ऑटोमैटिक भरना</translation> <translation id="271033894570825754">नया</translation> <translation id="2714393097308983682">Google Play स्टोर</translation> -<translation id="2715751256863167692">इस तरह बेहतर बनाने से आपका Chromebook रीसेट हो जाता है और मौजूदा उपयोगकर्ता डेटा निकल जाता है.</translation> +<translation id="2715751256863167692">यह अपग्रेड (बेहतर बनाना) आपका Chromebook रीसेट कर देता है और मौजूदा 'उपयोगकर्ता डेटा' हटा देता है.</translation> <translation id="2718395828230677721">नाइट लाइट</translation> <translation id="2718998670920917754">एंटी-वायरस सॉफ़्टवेयर ने वायरस का पता लगाया है.</translation> <translation id="2719936478972253983">इन कुकी को ब्लॉक कर दिया गया था</translation> @@ -1160,7 +1162,7 @@ <translation id="273093730430620027">यह पेज आपका कैमरा एक्सेस कर रहा है.</translation> <translation id="2731392572903530958">बंद की गई विंडो पु&न: खोलें</translation> <translation id="2731700343119398978">कृपया प्रतीक्षा करें...</translation> -<translation id="2731710757838467317">आपका निगरानी में रखा गया उपयोगकर्ता बनाया जा रहा है. इसमें कुछ समय लग सकता है.</translation> +<translation id="2731710757838467317">आपका 'निगरानी में रखा गया उपयोगकर्ता' बनाया जा रहा है. इसमें कुछ समय लग सकता है.</translation> <translation id="2735438478659026460">माउस कर्सर के रुक जाने पर अपने आप क्लिक करें</translation> <translation id="2735712963799620190">शेड्यूल</translation> <translation id="2737363922397526254">संक्षिप्त करें...</translation> @@ -1168,7 +1170,7 @@ <translation id="2738771556149464852">बाद में नहीं</translation> <translation id="2739191690716947896">डीबग</translation> <translation id="2739240477418971307">अपनी पहुंच-योग्यता सेटिंग बदलें</translation> -<translation id="2740393541869613458">निगरानी में रखे गए उपयोगकर्ता द्वारा देखी गई वेबसाइटों की समीक्षा करें, और</translation> +<translation id="2740393541869613458">'निगरानी में रखे गए उपयोगकर्ता' ने जो वेबसाइटें देखी हैं उनकी समीक्षा करें, और</translation> <translation id="2743387203779672305">क्लिपबोर्ड में कॉपी करें</translation> <translation id="2745080116229976798">Microsoft Qualified Subordination</translation> <translation id="2749295145042071768">'VM सेवा' शुरू की जा रही है.</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">कोई उपयोग डेटा नहीं</translation> <translation id="3007214526293698309">अनुपात ठीक करें</translation> <translation id="3007771295016901659">डुप्लीकेट टैब</translation> +<translation id="3008272652534848354">'अनुमतियां रीसेट करें'</translation> <translation id="3009300415590184725">क्या आप वाकई मोबाइल डेटा सेवा सेटअप प्रक्रिया को रद्द करना चाहते हैं?</translation> <translation id="3009779501245596802">अनुक्रमित डेटाबेस</translation> <translation id="3010279545267083280">पासवर्ड हटा दिया गया</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">मॉड्यूल (<ph name="TOTAL_COUNT" />) - ज्ञात विरोध: <ph name="BAD_COUNT" />, संदिग्ध: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">दिनांक और समय</translation> <translation id="310671807099593501">साइट ब्लूटूथ का इस्तेमाल कर रही है</translation> -<translation id="3108967419958202225">चुनें...</translation> <translation id="3115128645424181617">आपका फ़ोन नहीं मिल पा रहा है. पक्का करें कि वह पहुंच में है और ब्लूटूथ चालू है.</translation> <translation id="3115147772012638511">संचय की प्रतीक्षा कर रहा है...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" />सहायता</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">कुछ वाहक इस सुविधा को बंद कर सकते हैं.</translation> <translation id="316854673539778496">अपने सभी डिवाइस पर अपने सारे एक्सटेंशन पाने के लिए, साइन इन करें और सिंक चालू करें.</translation> <translation id="3170072451822350649">आप प्रवेश करना छोड़ भी सकते हैं और <ph name="LINK_START" />अतिथि के रूप में ब्राउज़<ph name="LINK_END" /> कर सकते हैं.</translation> -<translation id="3177048931975664371">पासवर्ड छुपाने के लिए क्लिक करें</translation> <translation id="3177909033752230686">पेज की भाषा:</translation> <translation id="3181110748548073003">आगे जाने के लिए |<ph name="SHORTCUT" />| दबाएं</translation> <translation id="3182749001423093222">वर्तनी परीक्षण</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">स्वामित्व <ph name="DESTINATION_DOMAIN" /> को स्थानांतरित कर दिया जाएगा.</translation> <translation id="323803881985677942">एक्सटेंशन के विकल्प खोलें</translation> <translation id="3241680850019875542">पैक के एक्सटेंशनकी मूल निर्देशिका को चुनें. किसी एक्स्टेंशन को अपडेट करने के लिए, पुन: उपयोग के लिए निजी कुंजी फ़ाइल का भी चुनें.</translation> -<translation id="3242765319725186192">पहले से शेयर की गई कुंजी:</translation> <translation id="3244294424315804309">आवाज़ बंद रखें</translation> <translation id="3245321423178950146">अज्ञात कलाकार</translation> <translation id="3246097286174000800">Smart Lock आज़माएं</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> के लिए और कार्रवाइयां</translation> <translation id="3440761377721825626">जब कोई साइट आपका कंप्यूटर एक्सेस करने के लिए किसी प्लग इन का उपयोग करना चाहे, तो पूछें</translation> <translation id="3441653493275994384">स्क्रीन</translation> -<translation id="3445830502289589282">चरण 2 प्रमाणीकरण:</translation> <translation id="344630545793878684">अपना डेटा कई वेबसाइटों पर पढ़ें</translation> <translation id="3449839693241009168">आदेशों को <ph name="EXTENSION_NAME" /> पर भेजने के लिए <ph name="SEARCH_KEY" /> दबाएं</translation> <translation id="3450157232394774192">निष्क्रिय स्थिति उपयोग प्रतिशत</translation> @@ -1625,7 +1624,7 @@ <translation id="3467267818798281173">सुझावों के लिए Google से पूछें</translation> <translation id="3468275649641751422">कोई वीडियो या ऑडियो फ़ाइल स्ट्रीम करें</translation> <translation id="3468522857997926824"><ph name="FILE_COUNT" /> फ़ोटो का <ph name="BEGIN_LINK" />Google डिस्क<ph name="END_LINK" /> में बैक अप लिया गया</translation> -<translation id="3470442499439619530">इस उपयोगकर्ता को निकालें</translation> +<translation id="3470442499439619530">इस उपयोगकर्ता को हटाएं</translation> <translation id="3470502288861289375">कॉपी किया जा रहा है...</translation> <translation id="3473479545200714844">स्क्रीन आवर्द्धक</translation> <translation id="3475447146579922140">Google spreadsheet</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> त्रुटियां.</translation> <translation id="3495660573538963482">Google Assistant सेटिंग</translation> <translation id="3496213124478423963">ज़ूम आउट</translation> -<translation id="3504135463003295723">समूह नाम:</translation> <translation id="3505030558724226696">डिवाइस एक्सेस निरस्त करें</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" के लिए वर्तमान अनुमतियां</translation> <translation id="3507547268929739059">Chromebook के लिए Linux ऐप्लिकेशन हटाएं</translation> @@ -1663,7 +1661,7 @@ <translation id="3514373592552233661">एक से ज़्यादा नेटवर्क उपलब्ध होने पर पसंदीदा नेटवर्क को दूसरे ज्ञात नेटवर्क पर प्राथमिकता दी जाएगी</translation> <translation id="3523642406908660543">जब कोई साइट आपका कंप्यूटर एेक्सेस करने के लिए किसी प्लग इन का उपयोग करना चाहे, तो पूछें (अनुशंसित)</translation> <translation id="3527085408025491307">फ़ोल्डर</translation> -<translation id="3527276236624876118"><ph name="USER_DISPLAY_NAME" /> नाम का एक निगरानी में रखा गया उपयोगकर्ता बनाया गया है.</translation> +<translation id="3527276236624876118"><ph name="USER_DISPLAY_NAME" /> नाम का एक 'निगरानी में रखा गया उपयोगकर्ता' बनाया गया है.</translation> <translation id="3528033729920178817">यह पेज आपकी स्थिति ट्रैक कर रहा है.</translation> <translation id="3528498924003805721">शॉर्टकट लक्ष्य</translation> <translation id="3530305684079447434">अपने सभी डिवाइसों पर अपने बुकमार्क प्राप्त करने के लिए, <ph name="SIGN_IN_LINK" />.</translation> @@ -1715,7 +1713,7 @@ <translation id="3604048165392640554">कोई मोबाइल कनेक्शन नहीं मिला. अपने दूसरे डिवाइसों पर इंस्टैंट टेदरिंग चालू करें और दोबारा कोशिश करें. <a target="_blank" href="<ph name="URL" />">ज़्यादा जानें</a></translation> <translation id="3605780360466892872">बटनडाउन</translation> <translation id="3608454375274108141">F10</translation> -<translation id="3608576286259426129">उपयोगकर्ता चित्र पूर्वावलोकन</translation> +<translation id="3608576286259426129">उपयोगकर्ता के इमेज की झलक</translation> <translation id="3609785682760573515">समन्वयित हो रहा है...</translation> <translation id="3609895557594655134">Android VPN जोड़ें...</translation> <translation id="361106536627977100">फ़्लैश डेटा</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">प्रवेश प्रमाणपत्र मान्य नहीं है, विंडो <ph name="MINUTES" /> : <ph name="SECONDS" /> में बंद हो जाएगी</translation> <translation id="3664511988987167893">एक्सटेंशन आइकॉन</translation> <translation id="3665589677786828986">Chrome को पता चला है कि आपकी कुछ सेटिंग किसी दूसरे प्रोग्राम के द्वारा दूषित कर दी गई हैं और उन्हें उनके मूल डिफ़ॉल्ट पर रीसेट कर दिया गया है.</translation> -<translation id="3665842570601375360">सुरक्षा:</translation> <translation id="3668570675727296296">भाषा सेटिंग</translation> <translation id="3668823961463113931">हैंडलर</translation> <translation id="3670229581627177274">ब्लूटूथ चालू करें</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">यह डिवाइस नहीं खोला जा सकता क्योंकि इसका फ़ाइल सिस्टम समर्थित नहीं है.</translation> <translation id="3727148787322499904">यह सेटिंग बदलने से सभी शेयर नेटवर्क प्रभावित होंगे</translation> <translation id="3727187387656390258">पॉपअप का निरीक्षण करें</translation> -<translation id="3728067901555601989">एक बार इस्तेमाल होने वाला पासवर्ड (ओटीपी):</translation> <translation id="3732078975418297900">लाइन <ph name="ERROR_LINE" /> पर गड़बड़ी</translation> <translation id="3733127536501031542">स्टेप-अप वाला SSL सर्वर</translation> <translation id="3737536731758327622">आपके डाउनलोड यहां दिखाई देंगे</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">पूरा हो जाने पर Enter दबाएं</translation> <translation id="3827774300009121996">&पूर्ण स्क्रीन</translation> <translation id="3828029223314399057">बुकमार्क खोजें</translation> -<translation id="3829932584934971895">प्रदाता प्रकार:</translation> <translation id="3830674330436234648">कोई प्लेबैक उपलब्ध नहीं है</translation> <translation id="3831486154586836914">विंडो संक्षिप्त विवरण मोड में प्रवेश किया</translation> <translation id="383161972796689579">इस डिवाइस के मालिक ने नए उपयोगकर्ता जोड़े जाना अक्षम कर दिया है</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">डेटा उपयोग मापन पूरा हो गया है</translation> <translation id="3857228364945137633">अपना फ़ोन आस-पास होने पर अपने <ph name="DEVICE_TYPE" /> को पासवर्ड के बिना अनलॉक करने के लिए Smart Lock का उपयोग करें.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: सिंक करना रोका गया</translation> <translation id="3860381078714302691">Hangouts Meet में आपका स्वागत है</translation> <translation id="3862134173397075045">Chrome के कास्ट अनुभव में आपका स्वागत है!</translation> <translation id="3862788408946266506">'kiosk_only' मेनिफ़ेस्ट विशेषता वाला ऐप्लिकेशन Chrome OS कियोस्क मोड में इंस्टॉल किया जाना चाहिए</translation> @@ -1903,7 +1899,7 @@ <translation id="3871092408932389764">सबसे कम</translation> <translation id="3872220884670338524">अधिक कार्रवाइयां, <ph name="DOMAIN" /> पर <ph name="USERNAME" /> के लिए सेव किया गया खाता</translation> <translation id="3872991219937722530">डिस्क में स्पेस खाली करें अन्यथा डिवाइस प्रतिक्रिया नहीं देगा.</translation> -<translation id="3878840326289104869">निगरानी में रखा गया उपयोगकर्ता बनाना</translation> +<translation id="3878840326289104869">'निगरानी में रखा गया उपयोगकर्ता' बनाना</translation> <translation id="3879748587602334249">डाउनलोड मैनेजर</translation> <translation id="3888550877729210209"><ph name="LOCK_SCREEN_APP_NAME" /> से नोट लेना</translation> <translation id="3892414795099177503">OpenVPN / L2TP जोड़ें...</translation> @@ -1968,7 +1964,6 @@ <translation id="3968261067169026421">नेटवर्क सेट नहीं किया जा सका</translation> <translation id="3970114302595058915">आईडी</translation> <translation id="397105322502079400">गणना की जा रही है...</translation> -<translation id="3974195870082915331">पासवर्ड दिखाने के लिए क्लिक करें</translation> <translation id="3975222297214566386">इनपुट विकल्पों का बबल</translation> <translation id="397703832102027365">अंतिम रूप दिया जा रहा है...</translation> <translation id="3979395879372752341">नया एक्सटेंशन जोड़ा गया (<ph name="EXTENSION_NAME" />)</translation> @@ -2010,6 +2005,7 @@ <translation id="4044612648082411741">अपना प्रमाणपत्र पासवर्ड डालें</translation> <translation id="404493185430269859">डिफ़ॉल्ट खोज इंजन</translation> <translation id="4047112090469382184">यह कैसे सुरक्षित है</translation> +<translation id="4051049974203704184">स्क्रीन पर मौजूद सामग्री की जानकारी पाएं</translation> <translation id="4052120076834320548">छोटा</translation> <translation id="4055023634561256217">आपके डिवाइस को पॉवरवॉश द्वारा रीसेट किए जाने से पहले पुन:प्रारंभ करना आवश्यक है.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2038,6 +2034,7 @@ <translation id="4088095054444612037">समूह के लिए स्वीकार करें</translation> <translation id="4089235344645910861">सेटिंग सेव की गई. सिंक शुरू हो गया.</translation> <translation id="4090103403438682346">सत्यापित एक्सेस सक्षम करें</translation> +<translation id="4090947011087001172"><ph name="SITE" /> की साइट अनुमतियां रीसेट करें?</translation> <translation id="4091434297613116013">कागज़ की पत्रक</translation> <translation id="4093955363990068916">स्थानीय फ़ाइल:</translation> <translation id="4095507791297118304">प्राथमिक प्रदर्शन</translation> @@ -2149,7 +2146,7 @@ <translation id="428608937826130504">अलमारी आइटम 8</translation> <translation id="4287502004382794929">इस डिवाइस का नामांकन करने के लिए आपके पास पर्याप्त सॉफ़्टवेयर लाइसेंस नहीं हैं. कृपया और अधिक खरीदने के लिए विक्रय विभाग से संपर्क करें. यदि आपको लगता है कि आपको यह संदेश त्रुटिवश दिखाई दे रहा है, तो कृपया सहायता से संपर्क करें.</translation> <translation id="4289540628985791613">संक्षिप्त विवरण</translation> -<translation id="4296575653627536209">निगरानी में रखा गया उपयोगकर्ता जोड़ें</translation> +<translation id="4296575653627536209">'निगरानी में रखा गया उपयोगकर्ता' जोड़ें</translation> <translation id="4297322094678649474">भाषाएं बदलें</translation> <translation id="4300305918532693141">यह सेटिंग बदलने के लिए, <ph name="BEGIN_LINK" />सिंक रीसेट करें<ph name="END_LINK" /></translation> <translation id="4301561945776138921">इस साइट के लिए सेव किया गया कोई पासवर्ड नहीं है.</translation> @@ -2214,7 +2211,6 @@ <translation id="4419556793104466535">'सिंक करें', 'मनमुताबिक बनाएं' वगैरह नियंत्रित करें</translation> <translation id="4421932782753506458">फ्लफ़ी</translation> <translation id="4422347585044846479">इस पेज के लिए बुकमार्क संपादित करें</translation> -<translation id="4423104065312875417">अतिरिक्त बोली इंजन इंस्टॉल करें</translation> <translation id="4423376891418188461">सेटिंग फिर से स्थापित करें</translation> <translation id="4423482519432579560">&वर्तनीजांच</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, आपके व्यवस्थापक के लिए ज़रूरी है कि आप अपना पासवर्ड बदलें.</translation> @@ -2239,7 +2235,6 @@ <translation id="4449996769074858870">यह टैब ऑडियो चला रहा है.</translation> <translation id="4450974146388585462">निदान करें</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> पर खोजें या कोई यूआरएल लिखें</translation> -<translation id="445923051607553918">वाई-फ़ाई नेटवर्क से जुड़ें</translation> <translation id="4462159676511157176">कस्टम नाम सर्वर</translation> <translation id="4467100756425880649">Chrome वेब स्टोर गैलरी</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> विस्तृत करें</translation> @@ -2264,7 +2259,7 @@ <translation id="4508765956121923607">स्रो&त देखें</translation> <translation id="4509823033118379431">इमेज फ़िलहाल उपलब्ध नहीं हैं. संग्रह देखने के लिए कृपया फिर से कनेक्ट करें.</translation> <translation id="451407183922382411"><ph name="COMPANY_NAME" /> के उपयोग से</translation> -<translation id="4514542542275172126">नया निगरानी में रखा गया उपयोगकर्ता सेट करें</translation> +<translation id="4514542542275172126">'निगरानी में रखा गया नया उपयोगकर्ता' सेट करें</translation> <translation id="4514610446763173167">वीडियो को 'चलाएं' या 'रोकें' पर टॉगल करें</translation> <translation id="451515744433878153">निकालें</translation> <translation id="4518677423782794009">क्या Chrome क्रैश हो रहा है, असामान्य स्टार्टअप पृष्ठ, टूलबार या ऐसे अनपेक्षित विज्ञापन दिखा रहा है जिनसे आपको छुटकारा नहीं मिल रहा है या आपके ब्राउज़िंग अनुभव में अन्यथा बदलाव आ रहा है? तो हो सकता है कि आप Chrome सॉफ़्टवेयर सफ़ाई टूल को चलाकर समस्या को ठीक कर पाएं.</translation> @@ -2375,6 +2370,7 @@ <translation id="4682551433947286597">वॉलपेपर साइन-इन स्क्रीन पर दिखाई देते .</translation> <translation id="4684427112815847243">सब कुछ समन्वयित करें</translation> <translation id="4689421377817139245">इस बुकमार्क को अपने iPhone से सिंक करें</translation> +<translation id="4690091457710545971"><Intel वाई-फ़ाई फ़र्मवेयर की जनरेट की हुई चार फ़ाइलें: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. पहली तीन फ़ाइलें बाइनरी हैं जिनमें रजिस्टर डंप शामिल हैं और Intel का दावा है कि इनमें कोई भी निजी या डिवाइस की पहचान करने वाली जानकारी शामिल नहीं है. आखिरी फ़ाइल Intel फ़र्मवेयर का एक एक्ज़ीक्यूशन ट्रेस है जिसमें से किसी भी निजी या डिवाइस की पहचान करने वाली जानकारी को हटा दिया गया है, लेकिन यहां दिखाने के लिए उसका आकार बहुत ही बड़ा है. ये फ़ाइलें आपके डिवाइस में हाल ही में वाई-फ़ाई से जुड़ी समस्याओं के जवाब में जनरेट हुई हैं और इन्हें Intel के साथ शेयर किया जाएगा ताकि इन समस्याओं का हल निकालने में मदद मिल सके.></translation> <translation id="4692302215262324251">आपके डिवाइस को <ph name="DEVICE_TYPE" /><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> द्वारा एंटरप्राइज़ प्रबंधन के लिए सफलतापूर्वक नामांकित कर लिया गया है. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> यदि यह अनपेक्षित है, तो कृपया सहायता से संपर्क करें.</translation> @@ -2415,7 +2411,7 @@ <translation id="4742746985488890273">अलमारी से पिन करें</translation> <translation id="4743260470722568160"><ph name="BEGIN_LINK" />ऐप्लिकेशन अपडेट करने का तरीका जानें<ph name="END_LINK" /></translation> <translation id="4744574733485822359">आपका डाउनलोड पूर्ण हो गया है</translation> -<translation id="4746971725921104503">ऐसा लगता है कि आप पहले से ही उस नाम से उपयोगकर्ता को प्रबंधित कर रहे हैं. क्या आप <ph name="LINK_START" /><ph name="USER_DISPLAY_NAME" /> को इस डिवाइस पर आयात करना चाहते थे<ph name="LINK_END" />?</translation> +<translation id="4746971725921104503">ऐसा लगता है कि आप पहले से ही उस नाम से उपयोगकर्ता को प्रबंधित कर रहे हैं. क्या आप <ph name="LINK_START" /><ph name="USER_DISPLAY_NAME" /> को इस डिवाइस पर लाना<ph name="LINK_END" /> चाहते थे?</translation> <translation id="4748762018725435655">Chrome वेब स्टोर से एक्सटेंशन की आवश्यकता है</translation> <translation id="4750394297954878236">सुझाव</translation> <translation id="475088594373173692">प्रथम उपयोगकर्ता</translation> @@ -2553,7 +2549,7 @@ <translation id="4929386379796360314">प्रिंट करने की जगहें</translation> <translation id="4931132176527519925">स्क्रीन हमेशा शेयर करें</translation> <translation id="4933484234309072027"><ph name="URL" /> पर एम्बेड किया गया</translation> -<translation id="493571969993549666">निगरानी में रखा गया उपयोगकर्ता जोड़ें</translation> +<translation id="493571969993549666">'निगरानी में रखा गया उपयोगकर्ता' जोड़ें</translation> <translation id="4941246025622441835">एंटरप्राइज़ प्रबंधन के लिए डिवाइस को नामांकित करते समय इस डिवाइस अनुरोध का उपयोग करें:</translation> <translation id="4941627891654116707">फ़ॉन्ट का आकार</translation> <translation id="494286511941020793">प्रॉक्सी कॉन्फ़िगरेशन सहायता</translation> @@ -2634,6 +2630,7 @@ <translation id="5074318175948309511">नई सेटिंग के प्रभावी होने से पहले इस पृष्ठ को रीलोड करने की आवश्यकता हो सकती है.</translation> <translation id="5075131525758602494">सिम PIN डालें</translation> <translation id="5078638979202084724">सभी टैब बुकमार्क करें</translation> +<translation id="5079950360618752063">सुझाए गए पासवर्ड का इस्तेमाल करें</translation> <translation id="5084230410268011727">साइटों को गति और लाइट का उपयोग करने की अनुमति दें</translation> <translation id="5085162214018721575">अपडेट जाँच रहा है</translation> <translation id="5086082738160935172">HID</translation> @@ -2672,6 +2669,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">यह आइटम हटाएं</translation> <translation id="5139955368427980650">&खोलें</translation> +<translation id="5142961317498132443">प्रमाणीकरण</translation> <translation id="5143374789336132547">एक्सटेंशन "<ph name="EXTENSION_NAME" />" ने यह बदल दिया है कि जब आप होम बटन क्लिक करते हैं तब कौन सा पेज दिखाया जाए.</translation> <translation id="5143712164865402236">पूर्ण स्क्रीन में प्रवेश करें</translation> <translation id="5145331109270917438">संशोधन दिनांक</translation> @@ -2842,7 +2840,6 @@ <translation id="5380103295189760361">उन कार्रवाई बदलने वाले बटनों के कीबोर्ड शॉर्टकट देखने के लिए Control, Alt, Shift, या Search को दबाए रखें.</translation> <translation id="5382591305415226340">समर्थित लिंक प्रबंधित करें</translation> <translation id="5384883051496921101">यह साइट गुप्त मोड से बाहर के ऐप्लिकेशन के साथ जानकारी शेयर करने वाली है.</translation> -<translation id="5388588172257446328">उपयोगकर्ता नाम:</translation> <translation id="5388885445722491159">युग्मित</translation> <translation id="5389237414310520250">नया उपयोगकर्ता नहीं बनाया जा सका. कृपया अपनी हार्ड डिस्क पर खाली जगह और अनुमतियां देखें और दोबारा कोशिश करें.</translation> <translation id="5390100381392048184">साइटों को आवाज़ चलाने दें</translation> @@ -2932,7 +2929,7 @@ <translation id="5509693895992845810">इस &रूप में सहेजें...</translation> <translation id="5509914365760201064">जारीकर्ता: <ph name="CERTIFICATE_AUTHORITY" /></translation> <translation id="5511823366942919280">क्या आप वाकई इस डिवाइस को "Shark" के रूप में सेट करना चाहते हैं?</translation> -<translation id="5512653252560939721">उपयोगकर्ता प्रमाण-पत्र हार्डवेयर-समर्थित होना चाहिए.</translation> +<translation id="5512653252560939721">उपयोगकर्ता का प्रमाणपत्र हार्डवेयर के समर्थन वाला होना चाहिए.</translation> <translation id="5513242761114685513">प्रसंग मेनू</translation> <translation id="5516183516694518900">अपने बुकमार्क, इतिहास, पासवर्ड और अन्य सेटिंग को अपने सभी डिवाइस पर पाने के लिए अपने Google खाते से Chrome में प्रवेश करें.</translation> <translation id="551752069230578406">अपने खाते में प्रिंटर जोड़ना - इसमें कुछ समय लग सकता है...</translation> @@ -2967,7 +2964,6 @@ <translation id="5551573675707792127">कीबोर्ड और लेख इनपुट</translation> <translation id="5553089923092577885">प्रमाणपत्र नीति मानचित्रण</translation> <translation id="5554489410841842733">यह आइकॉन तब दिखाई देगा जब एक्सटेंशन मौजूदा पेज पर काम कर सकेगा.</translation> -<translation id="5554573843028719904">अन्य वाई-फ़ाई नेटवर्क...</translation> <translation id="5554720593229208774">ईमेल प्रमाणन प्राधिकरण</translation> <translation id="5556206011531515970">अपना डिफ़ॉल्ट ब्राउज़र चुनने के लिए अगला क्लिक करें.</translation> <translation id="5556459405103347317">फिर लोड करें</translation> @@ -3008,7 +3004,6 @@ <translation id="5610038042047936818">कैमरा मोड में स्विच करें</translation> <translation id="5612720917913232150"><ph name="URL" /> आपके कंप्यूटर के स्थान का उपयोग करना चाहता है</translation> <translation id="5612734644261457353">क्षमा करें, आपका पासवर्ड अभी भी सत्यापित नहीं किया जा सकता. ध्यान दें: यदि आपने हाल ही में अपना पासवर्ड बदला है, तो आपके प्रस्थान करते ही आपका नया पासवर्ड लागू हो जाएगा, कृपया यहां पुराने पासवर्ड का उपयोग करें.</translation> -<translation id="5613695965848159202">अनाम पहचान:</translation> <translation id="5614190747811328134">उपयोगकर्ता सूचना</translation> <translation id="561698261642843490">Firefox बंद करें</translation> <translation id="5618075537869101857">अरे नहीं, कियोस्क ऐप्स लॉन्च नहीं किया जा सका.</translation> @@ -3226,7 +3221,6 @@ <translation id="5941343993301164315">कृपया <ph name="TOKEN_NAME" /> में प्रवेश करें.</translation> <translation id="5941711191222866238">छोटा करें</translation> <translation id="5946591249682680882">रिपोर्ट आईडी <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">निजी नेटवर्क जोड़ें</translation> <translation id="5949544233750246342">फ़ाइल को पार्स नहीं किया जा सका</translation> <translation id="5955282598396714173">आपके पासवर्ड की समय-सीमा समाप्त हो गई है. इसे बदलने के लिए कृपया साइन आउट करें उसके बाद फिर से प्रवेश करें.</translation> <translation id="5956585768868398362">क्या यह वही खोज पेज है जिसकी आप अपेक्षा कर रहे थे?</translation> @@ -3370,7 +3364,7 @@ <translation id="6160625263637492097">प्रमाणीकरण के लिए प्रमाणपत्र प्रदान करें</translation> <translation id="6163363155248589649">&सामान्य</translation> <translation id="6163522313638838258">सभी को विस्तृत करें...</translation> -<translation id="6164005077879661055">इस निगरानी में रखे गए उपयोगकर्ता को निकाले जाने के बाद, निगरानी में रखे गए उपयोगकर्ता से संबद्ध सभी फ़ाइलें और स्थानीय डेटा को स्थायी रूप से हटा दिया जाएगा. प्रबंधक द्वारा अब भी इस निगरानी में रखे गए उपयोगकर्ता द्वारा देखी गईं वेबसाइटें और सेटिंग <ph name="MANAGEMENT_URL" /> पर देखी जा सकेंगी.</translation> +<translation id="6164005077879661055">'निगरानी में रखे गए इस उपयोगकर्ता' को हटाने के बाद, निगरानी में रखे गए उपयोगकर्ता से जुड़ीं सभी फ़ाइलें और 'स्थानीय डेटा' हमेशा के लिए मिट जाएंगे. 'निगरानी में रखे गए इस उपयोगकर्ता' की देखी गईं वेबसाइटें और सेटिंग <ph name="MANAGEMENT_URL" /> पर प्रबंधक को अब भी दिखेंगी.</translation> <translation id="6166185671393271715">Chrome में पासवर्ड आयात करें</translation> <translation id="6169040057125497443">कृपया अपना माइक्रोफ़ोन जाँचें.</translation> <translation id="6169666352732958425">डेस्कटॉप कास्ट करने में असमर्थ.</translation> @@ -3387,11 +3381,13 @@ <translation id="6198102561359457428">प्रस्थान करें फिर पुन: प्रवेश करें...</translation> <translation id="6198252989419008588">पिन बदलें</translation> <translation id="6199801702437275229">स्थान जानकारी की प्रतीक्षा कर रहा है...</translation> +<translation id="6204015976622790023">अपनी स्क्रीन पर मौजूद सामग्री के बारे में अपनी Assistant की ओर से मिलने वाले सुझाव देखें.</translation> <translation id="6205710420833115353">कुछ कार्य अपेक्षा से अधिक समय ले रहे हैं. क्या आप उन्हें निरस्त करना चाहते हैं?</translation> <translation id="6206311232642889873">चित्र की प्र&तिलिपि बनाएं</translation> <translation id="6207200176136643843">डिफ़ॉल्ट ज़ूम स्तर पर रीसेट करें</translation> <translation id="620722923698527029">इस प्रकार के लिंक हमेशा उनसे जुड़े ऐप में खोलें</translation> <translation id="6207937957461833379">देश/क्षेत्र</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: सिंक सुविधा काम नहीं कर रही है</translation> <translation id="6212039847102026977">उन्नत नेटवर्क प्रॉपर्टी दिखाएं</translation> <translation id="6212168817037875041">प्रदर्शन बंद करें</translation> <translation id="6212752530110374741">लिंक ईमेल करें</translation> @@ -3429,7 +3425,6 @@ <translation id="6263541650532042179">समन्वयन रीसेट करें</translation> <translation id="6264365405983206840">&सभी को चुनें</translation> <translation id="6264422956566238156">आपने सिंक चालू कर दिया है</translation> -<translation id="6265930187414222160">हो गया! नुकसान पहुंचाने वाला सॉफ़्टवेयर हटाया गया.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" /> पर अपना प्रमाणन करने के लिए किसी प्रमाणपत्र को चुनें</translation> <translation id="6268252012308737255"><ph name="APP" /> में खोलें</translation> <translation id="6268747994388690914">HTML फ़ाइल से बुकमार्क आयात करें...</translation> @@ -3536,7 +3531,6 @@ कृपया अपने <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> खाते में प्रवेश करना जारी रखने के लिए "अगला" क्लिक करें.</translation> <translation id="6419546358665792306">पैक नहीं किया गया एक्सटेंशन लोड करें</translation> <translation id="642282551015776456">यह नाम किसी फ़ाइल या फ़ोल्डर के लिए उपयोग नहीं किया जा सकता</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox सेटिंग खोलें</translation> <translation id="6429384232893414837">अपडेट में गड़बड़ी</translation> <translation id="6430814529589430811">Base64 में एन्कोड किया गया ASCII, सिर्फ़ एक प्रमाणपत्र</translation> @@ -3617,7 +3611,6 @@ <translation id="6544215763872433504">Google का वेब ब्राउज़र, आपके लिए</translation> <translation id="6545665334409411530">दोहराने की दर</translation> <translation id="6545834809683560467">पता बार या ऐप्लिकेशन चलाने के खोज बॉक्स में टाइप किए गए खोज और URL को पूरा करने में मदद के लिए अपने आप अनुमान लगाने की सेवा का इस्तेमाल करें</translation> -<translation id="6546686722964485737">Wimax नेटवर्क में शामिल हों</translation> <translation id="6547316139431024316">इस एक्सटेंशन के लिए फिर से चेतावनी न दें</translation> <translation id="6547354035488017500">डिवाइस की मेमोरी से कम से कम 512 एमबी जगह खाली करें. ऐसा न करने पर आपका डिवाइस काम नहीं करेगा. जगह खाली करने के लिए, डिवाइस की मेमोरी से फ़ाइलें मिटाएं.</translation> <translation id="6549689063733911810">नवीनतम</translation> @@ -3625,7 +3618,7 @@ <translation id="6551508934388063976">निर्देश मौजूद नहीं है. नई विंडों खोलने के लिए control-N दबाएं.</translation> <translation id="655384502888039633"><ph name="USER_COUNT" /> उपयोगकर्ता</translation> <translation id="655483977608336153">दोबारा कोशिश करें</translation> -<translation id="6555432686520421228">सभी उपयोगकर्ता खातों को निकालें और अपने <ph name="IDS_SHORT_PRODUCT_NAME" /> डिवाइस को बिल्कुल नए जैसा बनाने के लिए रीसेट करें.</translation> +<translation id="6555432686520421228">सभी उपयोगकर्ता खातों को हटाएं और अपने <ph name="IDS_SHORT_PRODUCT_NAME" /> डिवाइस को बिल्कुल नया जैसा बनाने के लिए रीसेट करें.</translation> <translation id="6555810572223193255">क्लीनअप अभी उपलब्ध नहीं है</translation> <translation id="6556866813142980365">पुन: करें</translation> <translation id="6558280019477628686">कोई गड़बड़ी हुई है. शायद कुछ आइटम नहीं हटाए गए हैं.</translation> @@ -3714,7 +3707,7 @@ <translation id="6686817083349815241">अपना पासवर्ड सहेजें</translation> <translation id="6690565918367819723"><ph name="PROFILE_NAME" /> व्यक्ति स्विच करें</translation> <translation id="6690659332373509948">इस फ़ाइल को पार्स करने में असमर्थ: <ph name="FILE_NAME" /></translation> -<translation id="6690751852586194791">इस डिवाइस में जोड़ने के लिए कोई निगरानी में रखा गया उपयोगकर्ता चुनें.</translation> +<translation id="6690751852586194791">इस डिवाइस से जोड़ने के लिए कोई 'निगरानी में रखा गया उपयोगकर्ता' चुनें.</translation> <translation id="6691331417640343772">Google डैशबोर्ड पर सिंक किया गया डेटा प्रबंधित करें</translation> <translation id="6691936601825168937">&अग्रेषित करें</translation> <translation id="6697492270171225480">जब कोई पेज मिल नहीं पा रहा हो तो मिलते-जुलते पेज के सुझाव दिखाएं</translation> @@ -3902,7 +3895,7 @@ <translation id="6998793565256476099">डिवाइस को वीडियो कॉन्फ़्रेंसिंग के लिए नामांकित करें</translation> <translation id="7000347579424117903">Ctrl, Alt या Search को शामिल करें</translation> <translation id="7002055706763150362">Chromebook के लिए Smart Lock सेट करने हेतु, Google यह सुनिश्चित करना चाहता है कि यह आप ही हैं—प्रारंभ करने के लिए अपना पासवर्ड लिखें.</translation> -<translation id="7002454948392136538">इस निगरानी में रखे गए उपयोगकर्ता के लिए प्रबंधक चुनें</translation> +<translation id="7002454948392136538">'निगरानी में रखे गए इस उपयोगकर्ता' के लिए प्रबंधक चुनें</translation> <translation id="7003339318920871147">वेब डेटाबेस</translation> <translation id="7003723821785740825">अपना डिवाइस अनलॉक करने के लिए कोई तेज़ तरीका सेट अप करें</translation> <translation id="7004499039102548441">हाल के टैब</translation> @@ -4036,7 +4029,6 @@ <translation id="7201014958346994077">Linux फ़ाइलें नहीं दिखाई जा सकीं</translation> <translation id="720110658997053098">इस डिवाइस को हमेशा के लिए किओस्क मोड में रखें</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' मिटाया गया</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> डाउनलोड हो रहा है...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{पेज से बाहर निकलें}one{पेज से बाहर निकलें}other{पेज से बाहर निकलें}}</translation> <translation id="7216409898977639127">सेल्युलर सेवा देने वाली कंपनी</translation> @@ -4115,7 +4107,7 @@ <translation id="7321545336522791733">सर्वर पहुंच योग्य नहीं है</translation> <translation id="7324297612904500502">बीटा फ़ोरम</translation> <translation id="7325437708553334317">उच्च कंट्रास्ट एक्सटेंशन</translation> -<translation id="7327088014939803293">नया निगरानी में रखा गया उपयोगकर्ता नहीं बनाया जा सका. कृपया सुनिश्चित करें कि आपने ठीक से प्रवेश किया है और पुनः प्रयास करें.</translation> +<translation id="7327088014939803293">'निगरानी में रखा गया नया उपयोगकर्ता' नहीं बनाया जा सका. कृपया पक्का करें कि आपने ठीक से साइन इन किया है और फिर से कोशिश करें.</translation> <translation id="7328867076235380839">गलत संयोजन</translation> <translation id="7329154610228416156">प्रवेश करना विफल रहा क्योंकि उसे गैर-सुरक्षित यूआरएल (<ph name="BLOCKED_URL" />) का उपयोग करने के लिए कॉन्फ़िगर किया गया था. कृपया अपने एडमिन से संपर्क करें.</translation> <translation id="7334190995941642545">Smart Lock वर्तमान में अनुपलब्ध है. कृपया बाद में पुन: प्रयास करें.</translation> @@ -4263,9 +4255,9 @@ <translation id="7556033326131260574">स्मार्ट लॉक आपका खाता सत्यापित नहीं कर सका. प्रवेश करने के लिए अपना पासवर्ड लिखें.</translation> <translation id="7556242789364317684">दुर्भाग्यवश, <ph name="SHORT_PRODUCT_NAME" /> आपकी सेटिंग पुनर्प्राप्त करने में अक्षम है. गड़बड़ी को ठीक करने के लिए, <ph name="SHORT_PRODUCT_NAME" /> को आपके डिवाइस को पावरवॉश के साथ रीसेट करना होगा.</translation> <translation id="7559719679815339381">कृपया प्रतीक्षा करें....कियोस्क ऐप अपडेट होने की प्रक्रिया में है. USB स्टिक ना निकालें.</translation> -<translation id="7563991800558061108">इस गड़बड़ी से बाहर आने के लिए, आपको प्रवेश स्क्रीन से अपने Google खाते में - प्रवेश करना होगा. इसके बाद आप अपने Google खाते से प्रस्थान कर सकते हैं और - फिर से एक निगरानी में रखा गया उपयोगकर्ता बनाकर देख सकते हैं.</translation> +<translation id="7563991800558061108">इस गड़बड़ी से बचने के लिए, आपको साइन इन स्क्रीन के ज़रिए अपने 'Google खाते' में + साइन इन करना होगा. इसके बाद आप 'Google खाते' से साइन आउट कर सकते हैं और + फिर से कोई 'निगरानी में रखा गया उपयोगकर्ता' बना सकते हैं.</translation> <translation id="756445078718366910">ब्राउज़र विंडो खोलें</translation> <translation id="7564847347806291057">प्रक्रिया समाप्त करें</translation> <translation id="7566118625369982896">Play ऐप्लिकेशन के लिंक संभालें</translation> @@ -4316,7 +4308,7 @@ <translation id="7649070708921625228">सहायता</translation> <translation id="7650511557061837441">"<ph name="TRIGGERING_EXTENSION_NAME" />" "<ph name="EXTENSION_NAME" />" को निकालना चाहता है.</translation> <translation id="7652808307838961528">व्यक्ति, <ph name="PROFILE_NAME" /> संपादित करें</translation> -<translation id="765293928828334535">इस वेबसाइट से ऐप्लिकेशन एक्सटेंशन और उपयोगकर्ता स्क्रिप्ट नहीं जोड़े जा सकते हैं</translation> +<translation id="765293928828334535">इस वेबसाइट से ऐप्लिकेशन, एक्सटेंशन और उपयोगकर्ता स्क्रिप्ट नहीं जोड़े जा सकते हैं</translation> <translation id="7654941827281939388">यह खाता पहले से ही इस कंप्यूटर पर उपयोग किया जा रहा है.</translation> <translation id="7658239707568436148">अभी नहीं</translation> <translation id="7659584679870740384">आप इस डिवाइस का उपयोग करने के लिए अधिकृत नहीं हैं. कृपया प्रवेश अनुमति के लिए नियंत्रक से संपर्क करें.</translation> @@ -4365,7 +4357,7 @@ <translation id="7730449930968088409">अपनी स्क्रीन की सामग्री कैप्चर करें</translation> <translation id="7730494089396812859">क्लाउड बैकअप विवरण दिखाएं</translation> <translation id="7732111077498238432">नेटवर्क, नीति से नियंत्रित है</translation> -<translation id="773426152488311044">वर्तमान में केवल आप <ph name="PRODUCT_NAME" /> उपयोगकर्ता हैं.</translation> +<translation id="773426152488311044">फ़िलहाल सिर्फ़ आप <ph name="PRODUCT_NAME" /> के उपयोगकर्ता हैं.</translation> <translation id="7740996059027112821">मानक</translation> <translation id="7748528009589593815">पिछला टैब</translation> <translation id="7748626145866214022">कार्रवाई बार पर और भी विकल्प उपलब्ध हैं. कार्रवाई बार पर फ़ोकस करने के लिए Alt + A दबाएं.</translation> @@ -4387,7 +4379,7 @@ <translation id="7772773261844472235">अपने Chromebook की स्थिति देखें</translation> <translation id="7773726648746946405">सत्र संग्ररण</translation> <translation id="7776701556330691704">कोई आवाज़ नहीं मिली</translation> -<translation id="7781335840981796660">सभी उपयोगकर्ता खाते और स्थानीय डेटा को निकाल दिया जाएगा.</translation> +<translation id="7781335840981796660">सभी 'उपयोगकर्ता खातों' और 'स्थानीय डेटा' को हटा दिया जाएगा.</translation> <translation id="7781540849114045652">VM घटक लोड हो रहा है.</translation> <translation id="7782102568078991263">Google की ओर से कोई और सुझाव नहीं</translation> <translation id="778330624322499012"><ph name="PLUGIN_NAME" /> लोड नहीं कर सके</translation> @@ -4514,7 +4506,6 @@ <translation id="7909969815743704077">गुप्त मोड में डाउनलोड किया गया</translation> <translation id="7910768399700579500">&नया फ़ोल्डर</translation> <translation id="7912080627461681647">सर्वर पर आपका पासवर्ड बदल दिया गया है. कृपया साइन आउट करें उसके बाद फिर से प्रवेश करें.</translation> -<translation id="7912883689016444961">मोबाइल नेटवर्क कॉन्फ़िगर करें</translation> <translation id="7915471803647590281">कृपया फ़ीडबैक भेजने से पहले हमें बताएं कि क्या हो रहा है.</translation> <translation id="7916556741383518510">क्लिक करने पर</translation> <translation id="792514962475806987">डॉक किया गया ज़ूम स्तर:</translation> @@ -4529,7 +4520,7 @@ <translation id="7938594894617528435">वर्तमान में ऑफ़लाइन</translation> <translation id="7939062555109487992">अतिरिक्त सेटिंग</translation> <translation id="7939412583708276221">फिर भी रखें</translation> -<translation id="7939997691108949385">प्रबंधक <ph name="MANAGEMENT_URL" /> पर इस निगरानी में रखे गए उपयोगकर्ता के लिए प्रतिबंध और सेटिंग कॉन्फ़िगर करने के लिए उत्तरदायी होगा.</translation> +<translation id="7939997691108949385"><ph name="MANAGEMENT_URL" /> पर इस 'निगरानी में रखे गए उपयोगकर्ता' के लिए एडमिन पाबंदियों और सेटिंग को कॉन्फ़िगर कर सकेगा.</translation> <translation id="7943837619101191061">स्थान जोड़ें...</translation> <translation id="7945031593909029181">"<ph name="CHROME_EXTENSION_NAME" />" कनेक्ट करना चाहता है</translation> <translation id="794676567536738329">अनुमतियों की दुबारा पूछें</translation> @@ -4568,7 +4559,6 @@ <translation id="7988355189918024273">पहुंच विशेषताएं सक्षम करें</translation> <translation id="7994702968232966508">EAP विधि</translation> <translation id="799547531016638432">शॉर्टकट निकालें</translation> -<translation id="7997479212858899587">पहचान:</translation> <translation id="7997826902155442747">प्राथमिकता संसाधित करें</translation> <translation id="7999229196265990314">निम्न फ़ाइलें बनाई गईं: @@ -4652,7 +4642,6 @@ <translation id="8105368624971345109">बंद करें</translation> <translation id="8106045200081704138">मुझसे शेयर किया गया</translation> <translation id="8107015733319732394">आपके <ph name="DEVICE_TYPE" /> पर Google Play स्टोर इंस्टॉल हो रहा है. इसमें कुछ मिनट लग सकते हैं.</translation> -<translation id="8109930990200908494">उपयोगकर्ता प्रमाणपत्र के लिए प्रवेश करना आवश्यक है.</translation> <translation id="8111155949205007504">इस पासवर्ड को अपने iPhone से शेयर करें</translation> <translation id="8113043281354018522">लाइसेंस का प्रकार चुनें</translation> <translation id="8116190140324504026">अधिक जानकारी...</translation> @@ -4663,6 +4652,7 @@ <translation id="8118860139461251237">अपने डाउनलोड प्रबंधित करें</translation> <translation id="81238879832906896">पीला और सफ़ेद फूल</translation> <translation id="8124313775439841391">प्रबंधित ONC</translation> +<translation id="8125562866093998907">आपके खाते की ज़्यादा सुरक्षा करने के लिए, साइट आपकी सुरक्षा चाबी की पुष्टि करना चाहती है.</translation> <translation id="813082847718468539">साइट जानकारी देखें</translation> <translation id="8131740175452115882">दुबारा पूछें</translation> <translation id="8133676275609324831">खोजकर्ता में &दिखाएं</translation> @@ -4671,11 +4661,11 @@ <translation id="8137559199583651773">एक्सटेंशन प्रबंधित करें</translation> <translation id="8138082791834443598">वैकल्पिक — इस डिवाइस के साथ संबद्ध रहने के लिए नई जानकारी डालें या मौजूदा जानकारी को अपडेट करें.</translation> <translation id="813913629614996137">शुरू हो रहा है...</translation> -<translation id="8140778357236808512">कोई मौजूदा निगरानी में रखा गया उपयोगकर्ता आयात करें</translation> +<translation id="8140778357236808512">'निगरानी में रखा गया कोई मौजूदा उपयोगकर्ता' चुनें</translation> <translation id="8141725884565838206">अपने पासवर्ड प्रबंधित करें</translation> <translation id="8142732521333266922">ठीक, सभी समन्वयित करें</translation> <translation id="8143442547342702591">अमान्य ऐप्लिकेशन</translation> -<translation id="8146177459103116374">यदि आप इस डिवाइस पर पहले से पंजीकृत हैं, तो आप <ph name="LINK2_START" />मौजूदा उपयोगकर्ता के रूप में प्रवेश<ph name="LINK2_END" /> कर सकते हैं.</translation> +<translation id="8146177459103116374">अगर इस डिवाइस पर आपने पहले से रजिस्ट्रेशन किया है तो, आप <ph name="LINK2_START" />मौजूदा उपयोगकर्ता के रूप में साइन इन<ph name="LINK2_END" /> कर सकते हैं.</translation> <translation id="8146793085009540321">प्रवेश करना विफल रहा. कृपया अपने व्यवस्थापक से संपर्क करें या पुन: प्रयास करें.</translation> <translation id="8151185429379586178">डेवलपर टूल</translation> <translation id="8151638057146502721">कॉन्फ़िगर करें</translation> @@ -4710,7 +4700,7 @@ <translation id="8202160505685531999">अपनी <ph name="DEVICE_TYPE" /> प्रोफ़ाइल अपडेट करने के लिए कृपया अपना पासवर्ड पुनः डालें.</translation> <translation id="8206354486702514201">इस सेटिंग को आपके व्यवस्थापक द्वारा लागू किया जाता है.</translation> <translation id="8206745257863499010">ब्लुसी</translation> -<translation id="8209677645716428427">निगरानी में रखा गया उपयोगकर्ता आपके मार्गदर्शन में वेब को एक्सप्लोर कर सकता है. Chrome में निगरानी में रखे गए उपयोगकर्ता के प्रबंधक के रूप में, आप यह कर सकते हैं:</translation> +<translation id="8209677645716428427">'निगरानी में रखा गया उपयोगकर्ता' आपके दिशा-निर्देशों के साथ वेब को एक्सप्लोर कर सकता है. Chrome में 'निगरानी में रखे गए उपयोगकर्ता' के प्रबंधक के रूप में, आप यह कर सकते हैं:</translation> <translation id="8212008074015601248">{NUM_DOWNLOAD,plural, =1{डाउनलोड जारी है}one{डाउनलोड जारी हैं}other{डाउनलोड जारी हैं}}</translation> <translation id="8213449224684199188">आप फ़ोटो मोड में हैं</translation> <translation id="8213577208796878755">एक अन्य उपलब्ध डिवाइस.</translation> @@ -4773,7 +4763,6 @@ <translation id="8308179586020895837">यदि <ph name="HOST" /> आपका कैमरा और माइक्रोफ़ोन एक्सेस करना चाहे, तो पूछें</translation> <translation id="830868413617744215">बीटा</translation> <translation id="8309458809024885768">प्रमाणपत्र पहले से मौजूद है</translation> -<translation id="8309505303672555187">किसी नेटवर्क को चुनें:</translation> <translation id="8312871300878166382">फ़ोल्डर में चिपकाएं</translation> <translation id="8317671367883557781">नेटवर्क कनेक्शन जोड़ें</translation> <translation id="8319414634934645341">विस्तृत कुंजी उपयोग</translation> @@ -4848,7 +4837,6 @@ <translation id="8451512073679317615">assistant</translation> <translation id="8452135315243592079">अनुपलब्ध SIM कार्ड</translation> <translation id="8453482423012550001">$1 आइटम को कॉपी किया जा रहा है...</translation> -<translation id="8454288007744638700">या, कोई नया नेटवर्क चुनें:</translation> <translation id="845627346958584683">समाप्ति समय</translation> <translation id="8456681095658380701">गलत नाम</translation> <translation id="8457451314607652708">बुकमार्क आयात करें</translation> @@ -4901,7 +4889,7 @@ <translation id="8539727552378197395">नहीं (केवल Http)</translation> <translation id="8541166929715485291">सिस्टम डेटा भेजें. निदान और डिवाइस और ऐप्लिकेशन के इस्तेमाल का डेटा Google को अपने आप भेजें. यह सेटिंग डिवाइस के मालिक ने लागू की है. मालिक Google को निदान और इस डिवाइस के इस्तेमाल का डेटा भेजना चुन सकता है. आप इसे <ph name="BEGIN_LINK1" />सेटिंग<ph name="END_LINK1" /> में जाकर देख सकते हैं. अगर आपने अतिरिक्त वेब और ऐप्लिकेशन गतिविधि चालू की है, तो यह जानकारी आपके खाते से संग्रहित की जाएगी, ताकि आप इसे मेरी गतिविधि में प्रबंधित कर सकें. <ph name="BEGIN_LINK2" />अधिक जानें<ph name="END_LINK2" /></translation> <translation id="8545107379349809705">जानकारी छिपाएं...</translation> -<translation id="8545575359873600875">क्षमा करें, आपका पासवर्ड सत्यापित नहीं किया जा सका. हो सकता है इस निगरानी में रखे गए उपयोगकर्ता के प्रबंधक ने हाल ही में पासवर्ड बदल दिया हाे. यदि ऐसा है, तो आपके द्वारा अगली बार प्रवेश करने पर नया पासवर्ड लागू होगा. अपने पुराने पासवर्ड का उपयोग करके देखें.</translation> +<translation id="8545575359873600875">माफ़ करें, आपके पासवर्ड की पुष्टि नहीं हो सकी. हो सकता है कि इस 'निगरानी में रखे गए उपयोगकर्ता' के प्रबंधक ने हाल ही में पासवर्ड बदल दिया हाे. अगर ऐसा है तो, अगली बार जब आप साइन इन करेंगे तो नया पासवर्ड लागू होगा. अपने पुराने पासवर्ड का उपयोग करके देखें.</translation> <translation id="8546186510985480118">डिवाइस में स्पेस कम है</translation> <translation id="8546306075665861288">चित्र संचय</translation> <translation id="8546541260734613940">[*.]example.com</translation> @@ -4912,6 +4900,7 @@ <translation id="855081842937141170">टैब छोटा करें</translation> <translation id="8551388862522347954">लाइसेंस</translation> <translation id="8553342806078037065">अन्य लोगों को प्रबंधित करें</translation> +<translation id="8554899698005018844">कोई भाषा नहीं</translation> <translation id="855773602626431402">एक सैंडबॉक्स नहीं किए गए प्लग इन को इस पृष्ठ पर चलने से रोका गया था.</translation> <translation id="8557930019681227453">मेनिफेस्ट</translation> <translation id="8559694214572302298">चित्र डीकोडर</translation> @@ -4949,7 +4938,6 @@ <translation id="862727964348362408">निलंबित</translation> <translation id="862750493060684461">CSS संचय</translation> <translation id="8627795981664801467">केवल सुरक्षित कनेक्शन</translation> -<translation id="8628085465172583869">सर्वर होस्टनाम:</translation> <translation id="8630903300770275248">'निगरानी में रखे गए उपयोगकर्ता' को यहां लेकर आएं</translation> <translation id="8631032106121706562">पेटल्स</translation> <translation id="8637542770513281060">आपके कंप्यूटर में एक ऐसा सुरक्षित मॉड्यूल है, जिसका उपयोग Chrome OS की कई महत्वपूर्ण सुरक्षा सुविधाओं को लागू करने में किया जाता है. अधिक जानने के लिए Chromebook सहायता केंद्र पर जाएं: https://support.google.com/chromebook/?p=sm</translation> @@ -5205,7 +5193,6 @@ <translation id="899403249577094719">Netscape प्रमाणपत्र आधार URL</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> द्वारा प्रबंधित</translation> <translation id="8996526648899750015">खाता जोड़ें...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">डिस्क इमेज बनाई जा रही है.</translation> <translation id="9003647077635673607">सभी वेबसाइटों पर अनुमति दें</translation> <translation id="9003677638446136377">पुन: जाँचें</translation> @@ -5359,7 +5346,7 @@ <translation id="935490618240037774">आपके बुकमार्क, इतिहास, पासवर्ड और अन्य सेटिंग को आपके Google खाते में समन्वयित किया जाएगा ताकि आप उनका उपयोग अपने सभी डिवाइस पर कर सकें.</translation> <translation id="936801553271523408">सिस्टम का गड़बड़ी संबंधी डेटा</translation> <translation id="93766956588638423">एक्सटेंशन को ठीक करें</translation> -<translation id="938470336146445890">कृपया कोई उपयोगकर्ता प्रमाणपत्र इंस्टॉल करें.</translation> +<translation id="938470336146445890">कृपया कोई 'उपयोगकर्ता प्रमाणपत्र' इंस्टॉल करें.</translation> <translation id="938582441709398163">कीबोर्ड ओवरले</translation> <translation id="939252827960237676">स्क्रीनशॉट सहेजने में विफल</translation> <translation id="939519157834106403">SSID</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb index 703a75b..20b8ad4 100644 --- a/chrome/app/resources/generated_resources_hr.xtb +++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Ubrzo je vrijeme za pauzu</translation> <translation id="1062407476771304334">Zamijeni</translation> -<translation id="1064835277883315402">Pridruži se privatnoj mreži</translation> <translation id="1064912851688322329">Prekidanje veze s Google računom</translation> <translation id="1067048845568873861">Izrađeno</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Pretraživanje...</translation> <translation id="1316495628809031177">Sinkronizacija je pauzirana</translation> <translation id="1319979322914001937">Aplikacija koja prikazuje filtrirani popis proširenja iz Chrome web-trgovine. Proširenja na popisu mogu se instalirati izravno iz te aplikacije.</translation> -<translation id="132090119144658135">Podudaranje predmeta:</translation> <translation id="1326317727527857210">Da bi se prikazale kartice s vaših ostalih uređaja, prijavite se na Chrome.</translation> <translation id="1327074568633507428">Pisač na usluzi Google Cloud Print</translation> <translation id="1327977588028644528">Pristupnik</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Ukloni ovu osobu</translation> <translation id="1706586824377653884">Dodao vaš administrator</translation> <translation id="1706625117072057435">Razine zumiranja</translation> -<translation id="1707463636381878959">Dijeli ovu mrežu s drugim korisnicima</translation> <translation id="1708338024780164500">(Neaktivno)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativno)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Omogućiti temu</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Prikaz u Chrome web-trgovini</translation> -<translation id="1758831820837444715">Konfiguriranje Ethernet mreže</translation> <translation id="1763046204212875858">Stvaranje prečaca aplikacije</translation> <translation id="1763108912552529023">Nastavi istraživati</translation> <translation id="1763808908432309942">Otvara se u novoj kartici</translation> @@ -875,7 +871,6 @@ <translation id="2291643155573394834">Sljedeća kartica</translation> <translation id="2292848386125228270">Pokrenite <ph name="PRODUCT_NAME" /> kao običan korisnik. Ako ga trebate pokrenuti kao korijenski direktorij radi razvoja, pokrenite ga ponovo s oznakom --no-sandbox.</translation> <translation id="2294358108254308676">Želite li instalirati program <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP metoda:</translation> <translation id="2297705863329999812">Pretražite pisače</translation> <translation id="2300383962156589922">Prilagodite i kontrolirajte aplikaciju <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Korijenski direktorij proširenja nije važeći.</translation> @@ -933,7 +928,6 @@ <translation id="2379281330731083556">Ispis pomoću dijaloškog okvira sustava... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Pitanje prije slanja (preporučeno)</translation> <translation id="2384436799579181135">Došlo je do pogreške. Provjerite pisač i pokušajte opet.</translation> -<translation id="2385700042425247848">Naziv usluge:</translation> <translation id="2387458720915042159">Vrsta proxy veze</translation> <translation id="2391419135980381625">Standardni font</translation> <translation id="2391762656119864333">Opozovi</translation> @@ -984,7 +978,6 @@ <translation id="247949520305900375">Podijeli zvuk</translation> <translation id="2480868415629598489">izmjenjivati podatke koje kopirate i lijepite</translation> <translation id="2482878487686419369">Obavijesti</translation> -<translation id="2485056306054380289">CA certifikat poslužitelja:</translation> <translation id="2485422356828889247">Deinstaliraj</translation> <translation id="2487067538648443797">Dodaj novu oznaku</translation> <translation id="248861575772995840">Telefon nije moguće pronaći. Provjerite je li na uređaju <ph name="DEVICE_TYPE" /> uključen Bluetooth. <a>Saznajte više</a></translation> @@ -1109,7 +1102,6 @@ <translation id="2653659639078652383">Pošalji</translation> <translation id="265390580714150011">Vrijednost polja</translation> <translation id="2654166010170466751">Dopusti web-lokacijama instalaciju rukovatelja plaćanjem</translation> -<translation id="2655386581175833247">Korisnički certifikat:</translation> <translation id="2660779039299703961">Događaj</translation> <translation id="266079277508604648">Povezivanje s pisačem nije uspjelo. Provjerite je li pisač uključen i povezan s Chromebookom putem Wi-Fi mreže ili USB-a.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1409,7 +1401,6 @@ <translation id="3100609564180505575">Moduli (<ph name="TOTAL_COUNT" />) - Poznatih konflikata: <ph name="BAD_COUNT" />, mogućih: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Datum i vrijeme</translation> <translation id="310671807099593501">Web-lokacija upotrebljava Bluetooth</translation> -<translation id="3108967419958202225">Odabir...</translation> <translation id="3115128645424181617">Telefon nije moguće pronaći. Provjerite je li vam pri ruci i je li uključen Bluetooth.</translation> <translation id="3115147772012638511">Čekanje predmemorije...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Pomoć</translation> @@ -1454,7 +1445,6 @@ <translation id="3165390001037658081">Neki mobilni operateri mogu blokirati tu značajku.</translation> <translation id="316854673539778496">Da biste imali sva svoja proširenja na svim svojim uređajima, prijavite se i uključite sinkronizaciju.</translation> <translation id="3170072451822350649">Možete također preskočiti prijavu i <ph name="LINK_START" />pregledavati kao gost<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Kliknite za skrivanje zaporke</translation> <translation id="3177909033752230686">Jezik stranice:</translation> <translation id="3181110748548073003">Pritisnite |<ph name="SHORTCUT" />| za pomicanje unaprijed</translation> <translation id="3182749001423093222">Provjera pravopisa</translation> @@ -1485,7 +1475,6 @@ <translation id="3236289833370040187">Vlasništvo će se prenijeti na domenu <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Otvori opcije proširenja</translation> <translation id="3241680850019875542">Odaberite korijenski direktorij proširenja za pakiranje. Da biste ažurirali proširenje, odaberite i datoteku osobnog ključa za ponovnu upotrebu.</translation> -<translation id="3242765319725186192">Unaprijed podijeljen ključ:</translation> <translation id="3244294424315804309">Neka zvuk ostane isključen</translation> <translation id="3245321423178950146">Nepoznati izvođač</translation> <translation id="3246097286174000800">Isprobajte Smart Lock</translation> @@ -1618,7 +1607,6 @@ <translation id="3440663250074896476">Više radnji za oznaku <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Pitaj me kad web-lokacija želi upotrijebiti dodatak za pristup mom računalu</translation> <translation id="3441653493275994384">Zaslon</translation> -<translation id="3445830502289589282">Autentifikacija faze 2:</translation> <translation id="344630545793878684">čitati vaše podatke s raznih web-lokacija</translation> <translation id="3449839693241009168">Pritisnite <ph name="SEARCH_KEY" /> da biste poslali naredbe usluzi <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Postotak zauzetosti u stanju mirovanja</translation> @@ -1659,7 +1647,6 @@ <translation id="3495304270784461826">Broj pogrešaka: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Postavke Google asistenta</translation> <translation id="3496213124478423963">Smanji</translation> -<translation id="3504135463003295723">Naziv grupe:</translation> <translation id="3505030558724226696">Opoziv pristupa uređaju</translation> <translation id="3507421388498836150">Trenutačna dopuštenja za "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Ukloni Linux aplikacije za Chromebook</translation> @@ -1768,7 +1755,6 @@ <translation id="3661054927247347545">Certifikat za prijavu nije važeći, prozor će se zatvoriti za <ph name="MINUTES" />.<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ikona proširenja</translation> <translation id="3665589677786828986">Chrome je otkrio da je neki drugi program promijenio vaše postavke, pa ih je vratio na izvorne zadane vrijednosti.</translation> -<translation id="3665842570601375360">Sigurnost:</translation> <translation id="3668570675727296296">Postavke jezika</translation> <translation id="3668823961463113931">Rukovatelji</translation> <translation id="3670229581627177274">Uključite Bluetooth</translation> @@ -1807,7 +1793,6 @@ <translation id="3726463242007121105">Nije moguće otvoriti ovaj uređaj jer nije podržan njegov datotečni sustav.</translation> <translation id="3727148787322499904">Promjena te postavke utjecat će na sve dijeljene mreže</translation> <translation id="3727187387656390258">Provjeri skočni prozor</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Pogreška u <ph name="ERROR_LINE" />. retku</translation> <translation id="3733127536501031542">SSL poslužitelj s iskorakom</translation> <translation id="3737536731758327622">Ovdje se prikazuju vaša preuzimanja</translation> @@ -1882,7 +1867,6 @@ <translation id="38275787300541712">Na kraju pritisnite Enter</translation> <translation id="3827774300009121996">&Cijeli zaslon</translation> <translation id="3828029223314399057">Pretraži oznake</translation> -<translation id="3829932584934971895">Vrsta davatelja:</translation> <translation id="3830674330436234648">Nema dostupnih reprodukcija</translation> <translation id="3831486154586836914">Otvoren je način pregleda u prozoru</translation> <translation id="383161972796689579">Vlasnik ovog uređaja onemogućio je dodavanje novih korisnika</translation> @@ -1981,7 +1965,6 @@ <translation id="3968261067169026421">Postavljanje mreže nije uspjelo</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Izračun u tijeku…</translation> -<translation id="3974195870082915331">Kliknite za prikaz zaporke</translation> <translation id="3975222297214566386">Oblačić s opcijama unosa</translation> <translation id="397703832102027365">Dovršavanje...</translation> <translation id="3979395879372752341">Dodan je novi nastavak (<ph name="EXTENSION_NAME" />)</translation> @@ -2229,7 +2212,6 @@ <translation id="4419556793104466535">Upravljanje sinkronizacijom, prilagodbom i još mnogo toga</translation> <translation id="4421932782753506458">Pahuljica</translation> <translation id="4422347585044846479">Uredi oznaku za ovu stranicu</translation> -<translation id="4423104065312875417">Instaliraj dodatne alate za pretvaranje teksta u govor</translation> <translation id="4423376891418188461">Vrati postavke</translation> <translation id="4423482519432579560">&Provjera pravopisa</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, vaš administrator traži da promijenite zaporku.</translation> @@ -2254,7 +2236,6 @@ <translation id="4449996769074858870">Ta kartica reproducira zvuk.</translation> <translation id="4450974146388585462">Dijagnosticiranje</translation> <translation id="4453946976636652378">Pretraži <ph name="SEARCH_ENGINE_NAME" /> ili unesi URL</translation> -<translation id="445923051607553918">Spoji se s Wi-Fi mrežom</translation> <translation id="4462159676511157176">Prilagođeni poslužitelji naziva</translation> <translation id="4467100756425880649">Galerija Chrome web-trgovine</translation> <translation id="4467101674048705704">Proširivanje mape <ph name="FOLDER_NAME" /></translation> @@ -2860,7 +2841,6 @@ <translation id="5380103295189760361">Pritisnite Control, Alt, Shift ili Pretraživanje za prikaz tipkovničkih prečaca za te modifikatore.</translation> <translation id="5382591305415226340">Upravljanje podržanim vezama</translation> <translation id="5384883051496921101">Ova će web-lokacija dijeliti podatke s aplikacijom izvan anonimnog načina.</translation> -<translation id="5388588172257446328">Korisničko ime:</translation> <translation id="5388885445722491159">Upareno</translation> <translation id="5389237414310520250">Izrada novog korisnika nije uspjela. Provjerite imate li dovoljno prostora na tvrdom disku i potrebna dopuštenja, pa pokušajte ponovo.</translation> <translation id="5390100381392048184">Dopusti web-lokacijama reprodukciju zvuka</translation> @@ -2985,7 +2965,6 @@ <translation id="5551573675707792127">Tipkovnica i unos teksta</translation> <translation id="5553089923092577885">Mapiranja pravila certifikata</translation> <translation id="5554489410841842733">Ova ikona bit će vidljiva kad na trenutnoj stranici proširenje postane aktivno.</translation> -<translation id="5554573843028719904">Druga Wi-Fi mreža</translation> <translation id="5554720593229208774">Tijelo za izdavanje certifikata za e-poštu</translation> <translation id="5556206011531515970">Kliknite "dalje" da biste odabrali zadani preglednik.</translation> <translation id="5556459405103347317">Ponovno učitaj</translation> @@ -3026,7 +3005,6 @@ <translation id="5610038042047936818">Prijeđi na način fotoaparata</translation> <translation id="5612720917913232150"><ph name="URL" /> želi upotrijebiti lokaciju vašeg računala</translation> <translation id="5612734644261457353">Nažalost, vaša zaporka i dalje nije mogla biti potvrđena. Napomena: ako ste nedavno promijenili zaporku, vaša nova zaporka primjenjivat će se nakon što se odjavite. Ovdje upotrijebite staru zaporku.</translation> -<translation id="5613695965848159202">Anoniman identitet:</translation> <translation id="5614190747811328134">Korisnička obavijest</translation> <translation id="561698261642843490">Zatvaranje Firefoxa</translation> <translation id="5618075537869101857">K vrapcu, aplikacija kioska ne može se pokrenuti.</translation> @@ -3244,7 +3222,6 @@ <translation id="5941343993301164315">Prijavite se na <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimiziraj</translation> <translation id="5946591249682680882">ID izvješća <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Dodaj privatnu mrežu</translation> <translation id="5949544233750246342">Nije moguće analizirati datoteku</translation> <translation id="5955282598396714173">Zaporka je istekla. Odjavite se pa se ponovo prijavite da biste je promijenili.</translation> <translation id="5956585768868398362">Je li to stranica pretraživanja koju ste očekivali?</translation> @@ -3449,7 +3426,6 @@ <translation id="6263541650532042179">Poništi sinkronizaciju</translation> <translation id="6264365405983206840">Odaberi &sve</translation> <translation id="6264422956566238156">Sinkronizacija je uključena</translation> -<translation id="6265930187414222160">Gotovo! Štetni je softver uklonjen.</translation> <translation id="6267166720438879315">Odaberite certifikat za svoju autentikaciju na <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Otvori aplikacijom <ph name="APP" /></translation> <translation id="6268747994388690914">Uvoz oznaka iz HTML datoteke...</translation> @@ -3556,7 +3532,6 @@ Kliknite "Dalje" da biste se nastavili prijavljivati na <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> račun.</translation> <translation id="6419546358665792306">Učitaj raspakirano</translation> <translation id="642282551015776456">To ime ne može se upotrijebiti kao datoteka naziva mape</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Otvori postavke ChromeVoxa</translation> <translation id="6429384232893414837">Pogreška pri ažuriranju</translation> <translation id="6430814529589430811">Base64-šifriran ASCII, jedan certifikat</translation> @@ -3637,7 +3612,6 @@ <translation id="6544215763872433504">Googleov web-preglednik, za vas</translation> <translation id="6545665334409411530">Stopa ponavljanja</translation> <translation id="6545834809683560467">Upotrijebi uslugu predviđanja za dovršavanje pretraživanja i URL-ova upisanih u adresnu traku ili okvir za pretraživanje pokretača aplikacija</translation> -<translation id="6546686722964485737">Pridruživanje mreži WiMAX</translation> <translation id="6547316139431024316">Ne upozoravaj više u vezi s ovim proširenjem</translation> <translation id="6547354035488017500">Oslobodite najmanje 512 MB prostora ili će uređaj prestati reagirati. Da biste oslobodili prostor, izbrišite datoteke iz pohrane uređaja.</translation> <translation id="6549689063733911810">Nedavno</translation> @@ -4056,7 +4030,6 @@ <translation id="7201014958346994077">Nije moguće pregledati Linux datoteke</translation> <translation id="720110658997053098">Trajno zadrži uređaj u načinu kioska</translation> <translation id="7201118060536064622">Izbrisana je stavka "<ph name="DELETED_ITEM_NAME" />"</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Preuzimanje dodatka <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Zatvori stranicu}one{Zatvori stranicu}few{Zatvori stranice}other{Zatvori stranica}}</translation> <translation id="7216409898977639127">Davatelj mobilnih usluga</translation> @@ -4534,7 +4507,6 @@ <translation id="7909969815743704077">Preuzeto u anonimnom načinu</translation> <translation id="7910768399700579500">&Nova mapa</translation> <translation id="7912080627461681647">Zaporka se promijenila na poslužitelju. Odjavite se pa se ponovo prijavite.</translation> -<translation id="7912883689016444961">Konfiguriranje mobilne mreže</translation> <translation id="7915471803647590281">Recite nam što se događa prije nego što nam pošaljete povratnu informaciju.</translation> <translation id="7916556741383518510">Na klik</translation> <translation id="792514962475806987">Razina zumiranja za usidreno povećalo:</translation> @@ -4588,7 +4560,6 @@ <translation id="7988355189918024273">Omogući značajke dostupnosti</translation> <translation id="7994702968232966508">EAP metoda</translation> <translation id="799547531016638432">Uklanjanje prečaca</translation> -<translation id="7997479212858899587">Identitet:</translation> <translation id="7997826902155442747">Prioritet obrade</translation> <translation id="7999229196265990314">Stvorene su sljedeće datoteke: @@ -4672,7 +4643,6 @@ <translation id="8105368624971345109">Isključi</translation> <translation id="8106045200081704138">Dijeljeno sa mnom</translation> <translation id="8107015733319732394">Trgovina Google Play instalira se na vašem uređaju <ph name="DEVICE_TYPE" />. To bi moglo potrajati nekoliko minuta.</translation> -<translation id="8109930990200908494">Potrebna je prijava za korisnički certifikat.</translation> <translation id="8111155949205007504">Dijelite ovu zaporku sa svojim iPhoneom</translation> <translation id="8113043281354018522">Odaberite vrstu licence</translation> <translation id="8116190140324504026">Više informacija...</translation> @@ -4794,7 +4764,6 @@ <translation id="8308179586020895837">Pitaj ako <ph name="HOST" /> želi pristupiti kameri</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certifikat već postoji</translation> -<translation id="8309505303672555187">Odaberite mrežu:</translation> <translation id="8312871300878166382">Zalijepi u mapu</translation> <translation id="8317671367883557781">Dodaj mrežnu vezu</translation> <translation id="8319414634934645341">Produžena upotreba ključa</translation> @@ -4870,7 +4839,6 @@ <translation id="8451512073679317615">asistent</translation> <translation id="8452135315243592079">Nedostaje SIM kartica</translation> <translation id="8453482423012550001">Kopiranje stavki ($1)...</translation> -<translation id="8454288007744638700">Možete i odabrati novu mrežu:</translation> <translation id="845627346958584683">Vrijeme isteka</translation> <translation id="8456681095658380701">Pogrešno ime</translation> <translation id="8457451314607652708">Uvezi oznake</translation> @@ -4972,7 +4940,6 @@ <translation id="862727964348362408">Obustavljeno</translation> <translation id="862750493060684461">CSS predmemorija</translation> <translation id="8627795981664801467">Samo sigurne veze</translation> -<translation id="8628085465172583869">Naziv hosta poslužitelja:</translation> <translation id="8630903300770275248">Uvezi zaštićenog korisnika</translation> <translation id="8631032106121706562">Latica</translation> <translation id="8637542770513281060">Vaše računalo sadrži sigurni modul koji se upotrebljava za primjenu mnogih važnih sigurnosnih značajki u OS-u Chrome. Posjetite Chromebookov centar za pomoć da biste saznali više: https://support.google.com/chromebook/?p=sm</translation> @@ -5228,7 +5195,6 @@ <translation id="899403249577094719">Osnovni URL Netscape certifikata</translation> <translation id="8995603266996330174">Upravlja <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Dodavanje računa...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Izrada slike diska.</translation> <translation id="9003647077635673607">Dopusti na svim web-lokacijama</translation> <translation id="9003677638446136377">Provjeri ponovo</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb index c793ba2..48bdbe3c 100644 --- a/chrome/app/resources/generated_resources_hu.xtb +++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK-kód</translation> <translation id="1061904396131502319">Lassan ideje szünetet tartani</translation> <translation id="1062407476771304334">Csere</translation> -<translation id="1064835277883315402">Csatlakozás magánhálózathoz</translation> <translation id="1064912851688322329">Google-fiók leválasztása</translation> <translation id="1067048845568873861">Létrehozva</translation> <translation id="1067291318998134776">Linux (béta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Keresés...</translation> <translation id="1316495628809031177">A szinkronizálás szünetel</translation> <translation id="1319979322914001937">Olyan alkalmazás, amely a Chrome Internetes áruházból származó bővítmények szűrt listáját jeleníti meg. A listában szereplő alkalmazások közvetlenül telepíthetők az alkalmazásban.</translation> -<translation id="132090119144658135">Tárgyegyeztetés:</translation> <translation id="1326317727527857210">Ha hozzá szeretne férni lapjaihoz a többi eszközéről, jelentkezzen be a Chrome-ba.</translation> <translation id="1327074568633507428">Nyomtató a Google Cloud Printben</translation> <translation id="1327977588028644528">Átjáró</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Alkalmazásablak</translation> <translation id="1534389735079119190">HIBA: Nem sikerült elindítani a tárolót a VM-ben.</translation> <translation id="15373452373711364">Nagy egérmutató</translation> +<translation id="1540605929960647700">Demó mód engedélyezése</translation> <translation id="1543284117603151572">Az Edge böngészőből importálva</translation> <translation id="1545177026077493356">Automatikus kioszk mód</translation> <translation id="1545775234664667895">Telepített téma: "<ph name="THEME_NAME" />"</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Segítsen a <ph name="PRODUCT_NAME" /> fejlesztésében azáltal, hogy automatikusan elküldi a használati statisztikákat és hibajelentéseket a Google részére</translation> <translation id="1658424621194652532">Ez az oldal hozzáfér az Ön mikrofonjához.</translation> <translation id="1660204651932907780">A webhelyek lejátszhatnak hangokat (ajánlott)</translation> +<translation id="1660938185063657230">Igazolja Biztonsági hardverkulcsát</translation> <translation id="1661156625580498328">AES titkosítás kényszerítése (ajánlott).</translation> <translation id="1661245713600520330">Ez az oldal az összes, a fő folyamatba betöltött és a későbbi betöltésre előjegyzett modult felsorolja.</translation> <translation id="166179487779922818">A jelszó túl rövid.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Annak tiltása a webhelyek számára, hogy lássák a vágólapra másolt szövegeket és képeket</translation> <translation id="1682548588986054654">Új &inkognitóablak</translation> <translation id="168715261339224929">Ha az összes eszközén szeretné elérni könyvjelzőit, kapcsolja be a szinkronizálást.</translation> +<translation id="1688867105868176567">Törli a webhelyadatokat?</translation> <translation id="1688935057616748272">Írja be a kívánt karaktert</translation> <translation id="168991973552362966">Közeli nyomtató hozzáadása</translation> <translation id="1689945336726856614">&URL másolása</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Személy eltávolítása</translation> <translation id="1706586824377653884">A rendszergazda által hozzáadva</translation> <translation id="1706625117072057435">Nagyítási/kicsinyítési szintek</translation> -<translation id="1707463636381878959">A hálózat megosztása más felhasználókkal</translation> <translation id="1708338024780164500">(Inaktív)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (azonosító: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> képpont (natív)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Téma engedélyezése</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Megtekintés a Chrome Internetes áruházban</translation> -<translation id="1758831820837444715">Ethernet-hálózat konfigurálása</translation> <translation id="1763046204212875858">Parancsikon létrehozása az alkalmazáshoz</translation> <translation id="1763108912552529023">A felfedezés folytatása</translation> <translation id="1763808908432309942">Új lapon nyílik meg</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Módosítsa a fájl megosztási módját</translation> <translation id="1841545962859478868">Az eszköz rendszergazdája figyelheti a következőket:</translation> <translation id="1841705068325380214">A(z) <ph name="EXTENSION_NAME" /> bővítmény le van tiltva</translation> +<translation id="1842766183094193446">Biztosan engedélyezi a demó módot?</translation> <translation id="1844692022597038441">Ez a fájl nem érhető el offline.</translation> <translation id="1846308012215045257">A Control billentyű lenyomása mellett kattintson ide a(z) <ph name="PLUGIN_NAME" /> futtatásához.</translation> +<translation id="1847880352285315359">Mentve</translation> <translation id="1848219224579402567">Kijelentkezés, ha le van zárva a fedél</translation> <translation id="184823282865851239">Letiltás, ha a webhely jellemzően tolakodó hirdetéseket jelenít meg</translation> <translation id="1849186935225320012">Ez az oldal teljes hozzáféréssel rendelkezik a MIDI-eszközökhöz.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Ezt később módosíthatja a beállítások között</translation> <translation id="2006638907958895361">Link megnyitása a következőben: <ph name="APP" /></translation> <translation id="2007404777272201486">Hibabejelentés...</translation> +<translation id="2016237810978710652">Linux-fájlok megnyitása…</translation> <translation id="2016430552235416146">Hagyományos</translation> <translation id="2017334798163366053">Teljesítményadatok gyűjtésének letiltása</translation> <translation id="2017836877785168846">Törli a címsávban található előzményeket és automatikus kiegészítéseket.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Kártya szerkesztése</translation> <translation id="2154710561487035718">URL másolása</translation> <translation id="2155772377859296191">Megjelenés: <ph name="WIDTH" /> × <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Ön is segíthet a Biztonságos Böngészés fejlesztésében, ha elküld bizonyos rendszer-információkat és oldaltartalmakat a Google-nak.</translation> <translation id="215753907730220065">Kilépés a teljes képernyős módból</translation> <translation id="2157875535253991059">Ez az oldal most teljes képernyős nézetben van.</translation> <translation id="216169395504480358">Wi-Fi hozzáadása...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Igénylésazonosító hozzáadása ehhez az eszközhöz</translation> <translation id="2175042898143291048">Mindig ezt tegye</translation> <translation id="2175607476662778685">Gyorsindító sáv</translation> +<translation id="2176087259161165020">Egyéb források</translation> <translation id="2177950615300672361">Inkognitólap: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">A(z) <ph name="PEPPER_PLUGIN_DOMAIN" /> webhelyen található <ph name="PEPPER_PLUGIN_NAME" /> bővítmény hozzá szeretne férni a számítógéphez</translation> <translation id="2178614541317717477">A tanúsítványkibocsátó veszélyeztetve</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Következő lap</translation> <translation id="2292848386125228270">Indítsa el a <ph name="PRODUCT_NAME" /> alkalmazást normál felhasználóként. Ha a fejlesztéshez rootként kell futtatnia, futtassa a --no-sandbox jelző használatával.</translation> <translation id="2294358108254308676">Biztosan telepíti a <ph name="PRODUCT_NAME" />-ot?</translation> -<translation id="2296019197782308739">EAP-módszer:</translation> <translation id="2297705863329999812">Nyomtatók keresése</translation> <translation id="2300383962156589922">A(z) <ph name="APP_NAME" /> személyre szabása és beállításai</translation> <translation id="2301382460326681002">A bővítmény gyökérkönyvtára érvénytelen.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">HIBA: Nem sikerült a <ph name="APP_NAME" /> eltávolítása.</translation> <translation id="2367199180085172140">Fájlmegosztás hozzáadása</translation> <translation id="2367972762794486313">Alkalmazások megjelenítése</translation> +<translation id="2369536625682139252">A cookie-kat kivéve a(z) <ph name="SITE" /> által tárolt minden adat törlődik.</translation> <translation id="2371076942591664043">Megnyitás, amikor &kész</translation> <translation id="2377319039870049694">Váltás listanézetre</translation> <translation id="2377667304966270281">Súlyos laphiba</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Nyomtatás a rendszer párbeszédablakán keresztül... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Kérdezzen rá küldés előtt (ajánlott)</translation> <translation id="2384436799579181135">Hiba történt. Ellenőrizze a nyomtatót, majd próbálja újra.</translation> -<translation id="2385700042425247848">Szolgáltatás neve:</translation> <translation id="2387458720915042159">Proxykapcsolat típusa</translation> <translation id="2391419135980381625">Alapértelmezett betűtípus</translation> <translation id="2391762656119864333">Visszavonás</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Hang megosztása</translation> <translation id="2480868415629598489">Az Ön által másolt és beillesztett adatok módosítása</translation> <translation id="2482878487686419369">Értesítések</translation> -<translation id="2485056306054380289">Szerver CA tanúsítványa:</translation> <translation id="2485422356828889247">Eltávolítás</translation> <translation id="2487067538648443797">Új könyvjelző hozzáadása</translation> <translation id="248861575772995840">A telefon nem található. Győződjön meg arról, hogy a <ph name="DEVICE_TYPE" /> eszközön a Bluetooth be van kapcsolva. <a>További információ</a>.</translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Végezze el a powerwash műveletet a(z) <ph name="IDS_SHORT_PRODUCT_NAME" /> eszköz visszaállításához, hogy az olyan legyen, mint új korában.</translation> <translation id="2567257616420533738">Sikerült a jelszó mentése. A mentett jelszavakat megtekintheti és kezelheti a következő címen: <ph name="SAVED_PASSWORDS_LINK" />.</translation> <translation id="2568774940984945469">Infósáv tárolója</translation> +<translation id="2570454805927264159">Hozza ki a legtöbbet Segédjéből</translation> <translation id="257088987046510401">Témák</translation> <translation id="2572032849266859634">Csak olvasási hozzáférést kapott a következőhöz: <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Válasszon ki egy képet és nevet</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">Elküldés</translation> <translation id="265390580714150011">Mező értéke</translation> <translation id="2654166010170466751">Fizetéskezelők telepítésének engedélyezése a webhelyek számára</translation> -<translation id="2655386581175833247">Felhasználói tanúsítvány:</translation> <translation id="2660779039299703961">Esemény</translation> <translation id="266079277508604648">Nem sikerült csatlakozni a nyomtatóhoz. Ellenőrizze, hogy be van-e kapcsolva a nyomtató, és hogy csatlakozik-e a Chromebookhoz Wi-Fi-n vagy USB-n keresztül.</translation> <translation id="2661146741306740526">16×9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">Nincsenek használati adatok</translation> <translation id="3007214526293698309">Arány rögzítése</translation> <translation id="3007771295016901659">Másodpéldány készítése</translation> +<translation id="3008272652534848354">Engedélyek visszavonása</translation> <translation id="3009300415590184725">Biztosan meg akarja szakítani a mobil adatátszolgáltatás telepítési folyamatát?</translation> <translation id="3009779501245596802">Indexelt adatbázisok</translation> <translation id="3010279545267083280">A jelszó törölve</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">Modulok (<ph name="TOTAL_COUNT" />) - Ismert ütközések: <ph name="BAD_COUNT" />, feltételezett: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Dátum és idő</translation> <translation id="310671807099593501">A webhely Bluetooth-t használ</translation> -<translation id="3108967419958202225">Válasszon...</translation> <translation id="3115128645424181617">A telefon nem található. Győződjön meg arról, hogy kéznél van, és hogy a Bluetooth be van kapcsolva.</translation> <translation id="3115147772012638511">Betöltés a gyorsítótárból folyamatban...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Súgó</translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">Egyes szolgáltatók letilthatják ezt a funkciót.</translation> <translation id="316854673539778496">Ha az összes eszközén szeretné elérni bővítményeit, jelentkezzen be, és kapcsolja be a szinkronizálást.</translation> <translation id="3170072451822350649">Ki is hagyhatja a bejelentkezést, és <ph name="LINK_START" />böngészhet vendégként<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Kattintson ide a jelszó elrejtéséhez</translation> <translation id="3177909033752230686">Az oldal nyelve</translation> <translation id="3181110748548073003">A továbblépéshez nyomja meg az alábbi billentyűparancsot: |<ph name="SHORTCUT" />|</translation> <translation id="3182749001423093222">Helyesírás-ellenőrzés</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187">A tulajdonjogot átruházza a következőre: <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Bővítmények lehetőségeinek megnyitása</translation> <translation id="3241680850019875542">Válassza ki a bővítmény gyökérkönyvtárát. A bővítmény frissítéséhez meg kell adni az ismét használandó privátkulcs-fájlt is.</translation> -<translation id="3242765319725186192">Előre megosztott kulcs:</translation> <translation id="3244294424315804309">Némítás megtartása</translation> <translation id="3245321423178950146">Ismeretlen előadó</translation> <translation id="3246097286174000800">A Smart Lock kipróbálása</translation> @@ -1608,7 +1608,6 @@ <translation id="3440663250074896476">További műveletek a(z) <ph name="BOOKMARK_NAME" /> könyvjelzőhöz</translation> <translation id="3440761377721825626">Kérdezzen rá, ha egy webhely beépülő modul segítségével akar hozzáférni a számítógéphez</translation> <translation id="3441653493275994384">Képernyő</translation> -<translation id="3445830502289589282">Azonosítás 2. fázisa:</translation> <translation id="344630545793878684">Adatok beolvasása számos webhelyen</translation> <translation id="3449839693241009168">Nyomja meg a(z) <ph name="SEARCH_KEY" /> billentyűt a parancsok elküldéséhez a következőre: <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Tétlenségi állapot lefoglaltsága százalékban</translation> @@ -1649,7 +1648,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> hiba.</translation> <translation id="3495660573538963482">Google Segéd-beállítások</translation> <translation id="3496213124478423963">Kicsinyítés</translation> -<translation id="3504135463003295723">Csoport neve:</translation> <translation id="3505030558724226696">Eszközhozzáférés visszavonása</translation> <translation id="3507421388498836150">Aktuális engedélyek a következőhöz: „<ph name="EXTENSION_NAME" />”</translation> <translation id="3507547268929739059">A Chromebookra telepített linuxos alkalmazások eltávolítása</translation> @@ -1758,7 +1756,6 @@ <translation id="3661054927247347545">A bejelentkezéshez használt tanúsítvány érvénytelen, az ablak bezárásáig hátralévő idő: <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Bővítmény ikonja</translation> <translation id="3665589677786828986">A Chrome azt észlelte, hogy egy másik program miatt megsérült néhány beállítás, ezért visszaállítja őket az eredeti alapértelmezett értékekre.</translation> -<translation id="3665842570601375360">Biztonság:</translation> <translation id="3668570675727296296">Nyelvi beállítások</translation> <translation id="3668823961463113931">Kezelők</translation> <translation id="3670229581627177274">Bluetooth bekapcsolása</translation> @@ -1797,7 +1794,6 @@ <translation id="3726463242007121105">Ezt az eszközt nem lehet megnyitni, mert a fájlrendszere nem támogatott.</translation> <translation id="3727148787322499904">A beállítás módosítása az összes megosztott hálózatot érinti</translation> <translation id="3727187387656390258">Előugró ablak vizsgálata</translation> -<translation id="3728067901555601989">Egyszer használatos jelszó:</translation> <translation id="3732078975418297900">Hiba a következő sorban: <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-szerver Step-up használatával</translation> <translation id="3737536731758327622">Itt jelennek meg a letöltései</translation> @@ -1872,7 +1868,6 @@ <translation id="38275787300541712">Nyomja meg az Enter gombot, ha végzett</translation> <translation id="3827774300009121996">&Teljes képernyő</translation> <translation id="3828029223314399057">Könyvjelzők keresése</translation> -<translation id="3829932584934971895">Szolgáltató típusa:</translation> <translation id="3830674330436234648">Nincs lejátszási lehetőség</translation> <translation id="3831486154586836914">Ablakáttekintési módba lépett</translation> <translation id="383161972796689579">Az eszköz tulajdonosa letiltotta az új felhasználók hozzáadását</translation> @@ -1893,6 +1888,7 @@ <translation id="3856921555429624101">Az adathasználat mérése befejeződött</translation> <translation id="3857228364945137633">Próbálja ki, hogyan oldhatja fel <ph name="DEVICE_TYPE" /> eszközét jelszó használata nélkül a Smart Lock funkció használatával, ha a telefonja a közelében van.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Szinkronizálás szüneteltetve</translation> <translation id="3860381078714302691">Üdvözli a Hangouts Meet!</translation> <translation id="3862134173397075045">Üdvözli a Google Cast-élmény a Chrome-ban!</translation> <translation id="3862788408946266506">A „kiosk_only” jegyzékattribútummal rendelkező alkalmazást kioszk módban kell telepíteni a Chrome OS rendszeren</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Nem sikerült beállítani a hálózatot</translation> <translation id="3970114302595058915">Azonosító</translation> <translation id="397105322502079400">Számítás…</translation> -<translation id="3974195870082915331">Kattintson ide a jelszó megjelenítéséhez</translation> <translation id="3975222297214566386">Beviteli lehetőségek buborékja</translation> <translation id="397703832102027365">Véglegesítés...</translation> <translation id="3979395879372752341">Új bővítmény hozzáadva (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">A tanúsítvány jelszavának megadása</translation> <translation id="404493185430269859">Alapértelmezett keresőmotor</translation> <translation id="4047112090469382184">Miért biztonságos ez?</translation> +<translation id="4051049974203704184">Információkat kaphat a képernyő tartalmáról</translation> <translation id="4052120076834320548">Legkisebb</translation> <translation id="4055023634561256217">Mielőtt a Powerwash segítségével visszaállítaná, újra kell indítania az eszközt.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Elfogadás a csoportra vonatkozóan</translation> <translation id="4089235344645910861">Beállítások mentve, a szinkronizálás megkezdődött.</translation> <translation id="4090103403438682346">Ellenőrzött hozzáférés engedélyezése</translation> +<translation id="4090947011087001172">Visszavonja a(z) <ph name="SITE" /> minden webhelyengedélyét?</translation> <translation id="4091434297613116013">papírlap</translation> <translation id="4093955363990068916">Helyi fájl:</translation> <translation id="4095507791297118304">Elsődleges kijelző</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">A szinkronizálás, személyre szabás és még sok más vezérlése</translation> <translation id="4421932782753506458">Bolyhos</translation> <translation id="4422347585044846479">Könyvjelző szerkesztése ehhez az oldalhoz</translation> -<translation id="4423104065312875417">További beszédmotorok telepítése</translation> <translation id="4423376891418188461">A beállítások visszaállítása</translation> <translation id="4423482519432579560">&Helyesírás-ellenőrzés</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, az Ön rendszergazdája jelszómódosításra kéri.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Ez a lap hangot játszik le.</translation> <translation id="4450974146388585462">Elemzés</translation> <translation id="4453946976636652378">Keressen a(z) <ph name="SEARCH_ENGINE_NAME" /> segítségével, vagy írja be az URL-t</translation> -<translation id="445923051607553918">Belépés Wi-Fi hálózatra</translation> <translation id="4462159676511157176">Egyéni névszerverek</translation> <translation id="4467100756425880649">Chrome Internetes áruház Galéria</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> kibontása</translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">A háttérképek a bejelentkezési képernyőn jelennek meg.</translation> <translation id="4684427112815847243">Minden szinkronizálása</translation> <translation id="4689421377817139245">Szinkronizálja ezt a könyvjelzőt iPhone eszközével</translation> +<translation id="4690091457710545971"><Négy, az Intel Wi-Fi firmware által generált fájl: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Az első három bináris fájl, melyek regisztertartalmakat tárolnak. Az Intel biztosítja, hogy nincs bennük eszköz- és személyes beazonosításra alkalmas adat. Az utolsó fájl végrehajtási lánc az Intel firmware-ből; mentes az eszköz- és személyes beazonosításra alkalmas adatoktól, de túl nagy ahhoz, hogy itt szerepeljen. Ezek a fájlok azért jöttek létre, mert eszközén az elmúlt időszakban Wi-Fi-vel kapcsolatos problémák adódtak. A probléma megoldása érdekében a rendszer megosztja a fájlokat az Intellel.></translation> <translation id="4692302215262324251"><ph name="DEVICE_TYPE" /> vállalati kezelés céljából történő rögzítése a(z) <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> által sikeres volt. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Ha mindez váratlanul történt, forduljon az ügyfélszolgálathoz.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Előfordulhat, hogy az új beállítások életbe lépéséhez az oldal újratöltése szükséges.</translation> <translation id="5075131525758602494">Adja meg a SIM-kártya PIN-kódját</translation> <translation id="5078638979202084724">Összes lap hozzáadása a könyvjelzőkhöz</translation> +<translation id="5079950360618752063">Javasolt jelszó használata</translation> <translation id="5084230410268011727">A mozgás- és fényérzékelők használatnak engedélyezése a webhelyek számára</translation> <translation id="5085162214018721575">Frissítések keresése</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Elem törlése</translation> <translation id="5139955368427980650">&Megnyitás</translation> +<translation id="5142961317498132443">Hitelesítés</translation> <translation id="5143374789336132547">A(z) <ph name="EXTENSION_NAME" /> bővítmény módosította, hogy melyik oldal jelenjen meg a Kezdőlap gombra kattintáskor.</translation> <translation id="5143712164865402236">Teljes képernyő</translation> <translation id="5145331109270917438">Módosítás dátuma</translation> @@ -2844,7 +2842,6 @@ <translation id="5380103295189760361">Tartsa lenyomva a Control, Alt, Shift vagy Keresés gombokat a módosítók billentyűkódjainak megtekintéséhez.</translation> <translation id="5382591305415226340">Támogatott linkek kezelése</translation> <translation id="5384883051496921101">A webhely adatokat kíván megosztani az inkognitómódon kívüli alkalmazással.</translation> -<translation id="5388588172257446328">Felhasználónév:</translation> <translation id="5388885445722491159">Párosítva</translation> <translation id="5389237414310520250">Nem sikerült létrehozni az új felhasználót. Kérjük, ellenőrizze a merevlemezen rendelkezésre álló helyet és az engedélyeket, majd próbálja újra.</translation> <translation id="5390100381392048184">A webhelyek lejátszhatnak hangokat</translation> @@ -2969,7 +2966,6 @@ <translation id="5551573675707792127">Billentyűzet és szövegbevitel</translation> <translation id="5553089923092577885">Tanúsítvány-irányelv leképezések</translation> <translation id="5554489410841842733">Ez az ikon akkor látható, ha a bővítmény tehet valamit az aktuális oldalon.</translation> -<translation id="5554573843028719904">Egyéb Wi-Fi hálózat...</translation> <translation id="5554720593229208774">E-mail tanúsítványkibocsátó</translation> <translation id="5556206011531515970">Kattintson a Tovább gombra az alapértelmezett böngésző kiválasztásához.</translation> <translation id="5556459405103347317">Újratöltés</translation> @@ -3010,7 +3006,6 @@ <translation id="5610038042047936818">Váltás kamera módra</translation> <translation id="5612720917913232150">A(z) <ph name="URL" /> webhely a számítógép helyadatait szeretné használni</translation> <translation id="5612734644261457353">Sajnos a jelszó ellenőrzése még mindig nem sikerült. Megjegyzés: ha a közelmúltban módosította jelszavát, az új jelszó kijelentkezés után kerül beállításra, ezért kérjük, itt a régi jelszót használja.</translation> -<translation id="5613695965848159202">Névtelen azonosító:</translation> <translation id="5614190747811328134">Felhasználói értesítés</translation> <translation id="561698261642843490">Firefox bezárása</translation> <translation id="5618075537869101857">Ejnye, a kiosk-alkalmazást nem lehetett elindítani.</translation> @@ -3229,7 +3224,6 @@ <translation id="5941343993301164315">Kérjük, jelentkezzen be ide: <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Kicsinyítés</translation> <translation id="5946591249682680882">Jelentésazonosító: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Privát hálózat hozzáadása</translation> <translation id="5949544233750246342">A fájl szintaktikai elemzése sikertelen</translation> <translation id="5955282598396714173">A jelszó lejárt. A megváltoztatásához jelentkezzen ki, majd jelentkezzen be újra.</translation> <translation id="5956585768868398362">Erre a keresési oldalra számított?</translation> @@ -3390,11 +3384,13 @@ <translation id="6198102561359457428">Jelentkezzen ki, majd jelentkezzen be újra...</translation> <translation id="6198252989419008588">PIN-kód megváltoztatása</translation> <translation id="6199801702437275229">Várakozás a helyinformációkra...</translation> +<translation id="6204015976622790023">A képernyőn látható tartalmakkal kapcsolatban javaslatokat kaphat Segédjétől.</translation> <translation id="6205710420833115353">Egyes műveletek végrehajtása a vártnál tovább tart. Megszakítja őket?</translation> <translation id="6206311232642889873">Ké&p másolása</translation> <translation id="6207200176136643843">Visszaállítás az alapértelmezett nagyítási szintre</translation> <translation id="620722923698527029">Az ilyen típusú linkeket mindig a társított alkalmazás nyissa meg</translation> <translation id="6207937957461833379">Ország/Régió</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: A szinkronizálás nem működik</translation> <translation id="6212039847102026977">Speciális hálózati tulajdonságok megjelenítése</translation> <translation id="6212168817037875041">A kijelző kikapcsol</translation> <translation id="6212752530110374741">Link küldése e-mailben</translation> @@ -3432,7 +3428,6 @@ <translation id="6263541650532042179">szinkronizálás visszaállítása</translation> <translation id="6264365405983206840">Össz&es kiválasztása</translation> <translation id="6264422956566238156">Bekapcsolta a szinkronizálást</translation> -<translation id="6265930187414222160">Kész. Sikeresen eltávolítottuk a kártékony szoftvert.</translation> <translation id="6267166720438879315">Válasszon tanúsítványt a <ph name="HOST_NAME" /> hitelesítéséhez</translation> <translation id="6268252012308737255">Megnyitás ezzel: <ph name="APP" /></translation> <translation id="6268747994388690914">Könyvjelzők importálása HTML-fájlból...</translation> @@ -3539,7 +3534,6 @@ Kérjük, kattintson a „Tovább” lehetőségre a(z) <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> fiókba való bejelentkezés folytatásához.</translation> <translation id="6419546358665792306">Kicsomagolt elemek betöltése…</translation> <translation id="642282551015776456">Ezt a nevet nem lehet mappa fájlneveként használni</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox-beállítások megnyitása</translation> <translation id="6429384232893414837">Frissítési hiba</translation> <translation id="6430814529589430811">Base64 kódolású ASCII, egyedüli tanúsítvány</translation> @@ -3620,7 +3614,6 @@ <translation id="6544215763872433504">A Google által Önnek készített böngésző</translation> <translation id="6545665334409411530">Ismétlési sebesség</translation> <translation id="6545834809683560467">A várható kifejezés szolgáltatás használata a keresések és URL-címek kiegészítésére a címsávban, illetve az alkalmazásindító keresőmezőjében</translation> -<translation id="6546686722964485737">Csatlakozás WiMAX-hálózathoz</translation> <translation id="6547316139431024316">Nem kérek többé figyelmeztetést ennél a bővítménynél</translation> <translation id="6547354035488017500">Szabadítson fel legalább 512 MB tárhelyet, máskülönben eszköze lefagy. Tárhely felszabadításához töröljön fájlokat az eszköz tárhelyéről.</translation> <translation id="6549689063733911810">Legutóbbiak</translation> @@ -4039,7 +4032,6 @@ <translation id="7201014958346994077">A Linux-fájlok megtekintése nem sikerült</translation> <translation id="720110658997053098">Az eszköz állandó kioszk módban tartása</translation> <translation id="7201118060536064622">„<ph name="DELETED_ITEM_NAME" />” törölve</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">A(z) <ph name="PLUGIN_NAME" /> plug-in letöltése...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Oldal elhagyása}other{Oldalak elhagyása}}</translation> <translation id="7216409898977639127">Mobilszolgáltató</translation> @@ -4517,7 +4509,6 @@ <translation id="7909969815743704077">Letöltve inkognitó módban</translation> <translation id="7910768399700579500">&Új mappa</translation> <translation id="7912080627461681647">A jelszó megváltozott a szerveren. Jelentkezzen ki, majd jelentkezzen be újra.</translation> -<translation id="7912883689016444961">Mobilhálózat beállítása</translation> <translation id="7915471803647590281">Kérjük, mondja el, mi történik, mielőtt elküldené a visszajelzést.</translation> <translation id="7916556741383518510">Kattintásra</translation> <translation id="792514962475806987">Dokkolt állapotú nagyítási szint:</translation> @@ -4571,7 +4562,6 @@ <translation id="7988355189918024273">Kisegítő lehetőségek bekapcsolása</translation> <translation id="7994702968232966508">EAP módszer</translation> <translation id="799547531016638432">Parancsikon eltávolítása</translation> -<translation id="7997479212858899587">Azonosító:</translation> <translation id="7997826902155442747">Folyamatprioritás</translation> <translation id="7999229196265990314">A rendszer a következő fájlokat hozta létre: @@ -4655,7 +4645,6 @@ <translation id="8105368624971345109">Kikapcsolás</translation> <translation id="8106045200081704138">Velem megosztott</translation> <translation id="8107015733319732394">Folyamatban van a Google Play Áruház telepítése a(z) <ph name="DEVICE_TYPE" /> eszközre. Ez eltarthat néhány percig.</translation> -<translation id="8109930990200908494">Bejelentkezés szükséges a felhasználói tanúsítványhoz.</translation> <translation id="8111155949205007504">Ossza meg ezt a jelszót iPhone eszközével</translation> <translation id="8113043281354018522">Válasszon licenctípust</translation> <translation id="8116190140324504026">További információ...</translation> @@ -4666,6 +4655,7 @@ <translation id="8118860139461251237">A letöltések kezelése</translation> <translation id="81238879832906896">Sárga és fehér virág</translation> <translation id="8124313775439841391">Felügyelt ONC</translation> +<translation id="8125562866093998907">A webhely ellenőrizni szeretné az Ön Biztonsági hardverkulcsát, hogy nagyobb védelmet nyújthasson fiókjának.</translation> <translation id="813082847718468539">Az oldalinformációk megtekintése</translation> <translation id="8131740175452115882">Megerősítés</translation> <translation id="8133676275609324831">&Megjelenítés mappában</translation> @@ -4776,7 +4766,6 @@ <translation id="8308179586020895837">Kérdezzen rá, ha a(z) <ph name="HOST" /> hozzá szeretne férni a kamerához</translation> <translation id="830868413617744215">Béta</translation> <translation id="8309458809024885768">A tanúsítvány már létezik</translation> -<translation id="8309505303672555187">Hálózat kiválasztása:</translation> <translation id="8312871300878166382">Beillesztés mappába</translation> <translation id="8317671367883557781">Hálózati kapcsolat hozzáadása</translation> <translation id="8319414634934645341">Bővített kulcshasználat</translation> @@ -4851,7 +4840,6 @@ <translation id="8451512073679317615">segéd</translation> <translation id="8452135315243592079">Hiányzó SIM-kártya</translation> <translation id="8453482423012550001">$1 elem másolása...</translation> -<translation id="8454288007744638700">Vagy válasszon új hálózatot:</translation> <translation id="845627346958584683">Lejárat időpontja</translation> <translation id="8456681095658380701">Érvénytelen név</translation> <translation id="8457451314607652708">Könyvjelzők importálása</translation> @@ -4915,6 +4903,7 @@ <translation id="855081842937141170">Lap rögzítése</translation> <translation id="8551388862522347954">Licencek</translation> <translation id="8553342806078037065">Más személyek kezelése</translation> +<translation id="8554899698005018844">Nincs nyelv</translation> <translation id="855773602626431402">A rendszer megakadályozta egy nem sandbox-technológiát használó beépülő modul futását az oldalon.</translation> <translation id="8557930019681227453">Jegyzék</translation> <translation id="8559694214572302298">Képdekóder</translation> @@ -4952,7 +4941,6 @@ <translation id="862727964348362408">Felfüggesztett</translation> <translation id="862750493060684461">CSS gyorsítótár</translation> <translation id="8627795981664801467">Csak biztonságos kapcsolaton keresztül</translation> -<translation id="8628085465172583869">Szerver gépneve:</translation> <translation id="8630903300770275248">Felügyelt felhasználó importálása</translation> <translation id="8631032106121706562">Virág</translation> <translation id="8637542770513281060">Számítógépe olyan biztonsági modult tartalmaz, amely számos kritikus biztonsági funkció megvalósítására szolgál Chrome OS-en. További információt a Chromebook Súgóban talál: https://support.google.com/chromebook/?p=tpm</translation> @@ -5208,7 +5196,6 @@ <translation id="899403249577094719">Netscape tanúsítvány - alap URL</translation> <translation id="8995603266996330174">Kezelő: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Fiók hozzáadása...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Lemezkép létrehozása.</translation> <translation id="9003647077635673607">Engedélyezés valamennyi webhelyen</translation> <translation id="9003677638446136377">Ellenőrzés újra</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index fed0a7b..74a64bad 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Hampir waktunya istirahat</translation> <translation id="1062407476771304334">Ganti</translation> -<translation id="1064835277883315402">Bergabung dengan jaringan pribadi</translation> <translation id="1064912851688322329">Putuskan kaitan Akun Google Anda</translation> <translation id="1067048845568873861">Dibuat</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Menelusuri...</translation> <translation id="1316495628809031177">Sinkronisasi dijeda</translation> <translation id="1319979322914001937">Aplikasi yang menunjukkan daftar ekstensi yang difilter dari Chrome Webstore. Ekstensi yang ada dalam daftar dapat langsung dipasang dari aplikasi.</translation> -<translation id="132090119144658135">Kecocokan Subjek:</translation> <translation id="1326317727527857210">Untuk mendapatkan tab dari perangkat lainnya, masuk ke Chrome.</translation> <translation id="1327074568633507428">Printer di Google Cloud Print</translation> <translation id="1327977588028644528">Gerbang</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Hapus orang ini</translation> <translation id="1706586824377653884">Ditambahkan oleh administrator Anda</translation> <translation id="1706625117072057435">Tingkat perbesar/perkecil</translation> -<translation id="1707463636381878959">Bagikan jaringan ini dengan pengguna lain</translation> <translation id="1708338024780164500">(Tidak aktif)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Asli)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Aktifkan tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Lihat di Chrome Web Store</translation> -<translation id="1758831820837444715">Konfigurasikan jaringan Ethernet</translation> <translation id="1763046204212875858">Buat pintasan aplikasi</translation> <translation id="1763108912552529023">Terus menjelajah</translation> <translation id="1763808908432309942">Membuka di tab baru</translation> @@ -875,7 +871,6 @@ <translation id="2291643155573394834">Tab berikutnya</translation> <translation id="2292848386125228270">Mulai <ph name="PRODUCT_NAME" /> sebagai pengguna normal. Jika perlu menjalankan sebagai root untuk pengembangan, jalankan ulang dengan tanda tanpa sandbox.</translation> <translation id="2294358108254308676">Apakah Anda ingin memasang <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Metode EAP:</translation> <translation id="2297705863329999812">Telusuri printer</translation> <translation id="2300383962156589922">Sesuaikan dan kontrol <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Direktori akar ekstensi tidak valid.</translation> @@ -933,7 +928,6 @@ <translation id="2379281330731083556">Cetak menggunakan dialog sistem... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Tanyakan sebelum mengirim (disarankan)</translation> <translation id="2384436799579181135">Terjadi error. Harap periksa printer Anda dan coba lagi.</translation> -<translation id="2385700042425247848">Nama layanan:</translation> <translation id="2387458720915042159">Jenis sambungan proxy</translation> <translation id="2391419135980381625">Font standar</translation> <translation id="2391762656119864333">Cabut</translation> @@ -984,7 +978,6 @@ <translation id="247949520305900375">Bagikan audio</translation> <translation id="2480868415629598489">Mengubah data yang Anda copy-paste</translation> <translation id="2482878487686419369">Notifikasi</translation> -<translation id="2485056306054380289">Sertifikat CA server:</translation> <translation id="2485422356828889247">Uninstal</translation> <translation id="2487067538648443797">Tambahkan bookmark baru</translation> <translation id="248861575772995840">Ponsel tidak dapat ditemukan. Pastikan Bluetooth <ph name="DEVICE_TYPE" /> Anda aktif. <a>Pelajari lebih lanjut</a></translation> @@ -1109,7 +1102,6 @@ <translation id="2653659639078652383">Kirim</translation> <translation id="265390580714150011">Nilai Bidang</translation> <translation id="2654166010170466751">Izinkan situs menginstal penangan pembayaran</translation> -<translation id="2655386581175833247">Sertifikat pengguna:</translation> <translation id="2660779039299703961">Acara</translation> <translation id="266079277508604648">Tidak dapat terhubung ke printer. Harap periksa apakah printer sudah diaktifkan dan terhubung ke Chromebook dengan Wi-Fi atau USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1409,7 +1401,6 @@ <translation id="3100609564180505575">Modul (<ph name="TOTAL_COUNT" />) - Konflik yang dikenal: <ph name="BAD_COUNT" />, dicurigai: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Tanggal dan waktu</translation> <translation id="310671807099593501">Situs sedang menggunakan bluetooth</translation> -<translation id="3108967419958202225">Pilih...</translation> <translation id="3115128645424181617">Ponsel tidak dapat ditemukan. Pastikan ponsel ada dalam jangkauan dan Bluetooth diaktifkan.</translation> <translation id="3115147772012638511">Menunggu cache...</translation> <translation id="3118319026408854581">Bantuan <ph name="PRODUCT_NAME" /></translation> @@ -1454,7 +1445,6 @@ <translation id="3165390001037658081">Beberapa operator mungkin memblokir fitur ini.</translation> <translation id="316854673539778496">Untuk mendapatkan semua ekstensi di semua perangkat, login dan aktifkan sinkronisasi.</translation> <translation id="3170072451822350649">Anda juga dapat melewati proses masuk dan <ph name="LINK_START" />menjelajah sebagai tamu<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Klik untuk menyembunyikan sandi</translation> <translation id="3177909033752230686">Bahasa Halaman:</translation> <translation id="3181110748548073003">Tekan |<ph name="SHORTCUT" />| untuk melanjutkan</translation> <translation id="3182749001423093222">Periksa ejaan</translation> @@ -1485,7 +1475,6 @@ <translation id="3236289833370040187">Kepemilikan akan ditransfer ke <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Buka opsi ekstensi</translation> <translation id="3241680850019875542">Pilih direktori akar ekstensi untuk dipaket. Untuk memperbarui ekstensi, pilih juga file kunci pribadi untuk dipakai ulang.</translation> -<translation id="3242765319725186192">Kunci yang dibagikan sebelumnya:</translation> <translation id="3244294424315804309">Lanjutkan mematikan suara</translation> <translation id="3245321423178950146">Artis Tidak Dikenal</translation> <translation id="3246097286174000800">Coba Smart Lock</translation> @@ -1618,7 +1607,6 @@ <translation id="3440663250074896476">Tindakan lainnya untuk <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Tanyakan saat situs ingin menggunakan plugin untuk mengakses komputer</translation> <translation id="3441653493275994384">Layar</translation> -<translation id="3445830502289589282">Autentikasi tahap 2:</translation> <translation id="344630545793878684">Membaca data Anda di sejumlah situs</translation> <translation id="3449839693241009168">Tekan <ph name="SEARCH_KEY" /> untuk mengirimkan perintah ke <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Persentase Pemakaian Status Menganggur</translation> @@ -1659,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> kesalahan.</translation> <translation id="3495660573538963482">Setelan Asisten Google</translation> <translation id="3496213124478423963">Perkecil</translation> -<translation id="3504135463003295723">Nama grup:</translation> <translation id="3505030558724226696">Mencabut akses perangkat</translation> <translation id="3507421388498836150">Izin Saat Ini untuk "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Hapus Aplikasi Linux untuk Chromebook</translation> @@ -1768,7 +1755,6 @@ <translation id="3661054927247347545">Sertifikasi login tidak valid, jendela akan ditutup dalam <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ikon Ekstensi</translation> <translation id="3665589677786828986">Chrome mendeteksi bahwa beberapa setelan Anda dirusak oleh program lain dan menyetelnya ulang ke setelan default aslinya.</translation> -<translation id="3665842570601375360">Keamanan:</translation> <translation id="3668570675727296296">Setelan bahasa</translation> <translation id="3668823961463113931">Penangan</translation> <translation id="3670229581627177274">Aktifkan Bluetooth</translation> @@ -1807,7 +1793,6 @@ <translation id="3726463242007121105">Perangkat ini tidak dapat dibuka karena sistem berkasnya tidak didukung.</translation> <translation id="3727148787322499904">Perubahan pada setelan ini akan berpengaruh pada semua jaringan bersama</translation> <translation id="3727187387656390258">Periksa pop-up</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Error pada saluran <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Server SSL dengan Step-up</translation> <translation id="3737536731758327622">Download Anda muncul di sini</translation> @@ -1882,7 +1867,6 @@ <translation id="38275787300541712">Tekan Enter saat selesai</translation> <translation id="3827774300009121996">Layar &Penuh</translation> <translation id="3828029223314399057">Cari bookmark</translation> -<translation id="3829932584934971895">Jenis penyedia:</translation> <translation id="3830674330436234648">Pemutaran tidak tersedia</translation> <translation id="3831486154586836914">Memasuki mode ikhtisar jendela</translation> <translation id="383161972796689579">Pemilik perangkat ini telah menonaktifkan pengguna baru agar tidak ditambahkan</translation> @@ -1981,7 +1965,6 @@ <translation id="3968261067169026421">Tidak dapat menyiapkan jaringan</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Menghitung...</translation> -<translation id="3974195870082915331">Klik untuk menampilkan sandi</translation> <translation id="3975222297214566386">Balon opsi masukan</translation> <translation id="397703832102027365">Mengakhiri...</translation> <translation id="3979395879372752341">Ekstensi baru ditambahkan (<ph name="EXTENSION_NAME" />)</translation> @@ -2229,7 +2212,6 @@ <translation id="4419556793104466535">Mengontrol sinkronisasi, personalisasi, dan lainnya</translation> <translation id="4421932782753506458">Si Manis</translation> <translation id="4422347585044846479">Edit bookmark untuk halaman ini</translation> -<translation id="4423104065312875417">Instal mesin ucapan tambahan</translation> <translation id="4423376891418188461">Pulihkan Setelan</translation> <translation id="4423482519432579560">&Pemeriksaan Ejaan</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, administrator mewajibkan Anda untuk mengganti sandi.</translation> @@ -2254,7 +2236,6 @@ <translation id="4449996769074858870">Tab ini memutar audio.</translation> <translation id="4450974146388585462">Diagnosis</translation> <translation id="4453946976636652378">Telusuri <ph name="SEARCH_ENGINE_NAME" /> atau ketik URL</translation> -<translation id="445923051607553918">Bergabung dengan jaringan Wi-Fi</translation> <translation id="4462159676511157176">Server nama khusus</translation> <translation id="4467100756425880649">Galeri Chrome Webstore</translation> <translation id="4467101674048705704">Luaskan <ph name="FOLDER_NAME" /></translation> @@ -2860,7 +2841,6 @@ <translation id="5380103295189760361">Tekan Control, Alt, Shift, atau Telusur untuk melihat pintasan keyboard untuk pengubah tersebut.</translation> <translation id="5382591305415226340">Kelola link yang didukung</translation> <translation id="5384883051496921101">Situs ini akan membagikan informasi dengan aplikasi di luar mode penyamaran.</translation> -<translation id="5388588172257446328">Nama Pengguna:</translation> <translation id="5388885445722491159">Disandingkan</translation> <translation id="5389237414310520250">Tidak dapat membuat pengguna baru. Periksa ruang dan izin hard drive Anda, lalu coba lagi.</translation> <translation id="5390100381392048184">Izinkan situs untuk memutar suara</translation> @@ -2985,7 +2965,6 @@ <translation id="5551573675707792127">Input teks dan keyboard</translation> <translation id="5553089923092577885">Pemetaan Kebijakan Sertifikat</translation> <translation id="5554489410841842733">Ikon ini akan kelihatan saat ekstensi dapat bertindak pada halaman saat ini.</translation> -<translation id="5554573843028719904">Jaringan Wi-Fi lainnya...</translation> <translation id="5554720593229208774">Otoritas Sertifikasi Email</translation> <translation id="5556206011531515970">Klik selanjutnya untuk memilih browser default Anda.</translation> <translation id="5556459405103347317">Muat ulang</translation> @@ -3026,7 +3005,6 @@ <translation id="5610038042047936818">Beralih ke mode kamera</translation> <translation id="5612720917913232150"><ph name="URL" /> ingin menggunakan lokasi komputer Anda</translation> <translation id="5612734644261457353">Maaf, sandi Anda masih belum dapat diverifikasi. Catatan: jika Anda baru saja mengubah sandi Anda, sandi yang baru akan diterapkan saat Anda keluar, gunakan sandi lama di sini.</translation> -<translation id="5613695965848159202">Identitas anonim:</translation> <translation id="5614190747811328134">Notifikasi Pengguna</translation> <translation id="561698261642843490">Tutup Firefox</translation> <translation id="5618075537869101857">Waduh, aplikasi kios tidak dapat diluncurkan.</translation> @@ -3244,7 +3222,6 @@ <translation id="5941343993301164315">Harap masuk ke <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Perkecil</translation> <translation id="5946591249682680882">ID Laporan <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Tambahkan jaringan pribadi</translation> <translation id="5949544233750246342">Tidak dapat mengurai file</translation> <translation id="5955282598396714173">Sandi Anda sudah tidak berlaku. Harap logout, lalu login kembali untuk mengubahnya.</translation> <translation id="5956585768868398362">Apakah ini halaman penelusuran yang Anda harapkan?</translation> @@ -3449,7 +3426,6 @@ <translation id="6263541650532042179">setel ulang sinkronisasi</translation> <translation id="6264365405983206840">Pilih Semu&a</translation> <translation id="6264422956566238156">Anda telah mengaktifkan fitur Sinkronisasi</translation> -<translation id="6265930187414222160">Selesai. Software berbahaya telah dihapus.</translation> <translation id="6267166720438879315">Pilih sertifikat untuk membuktikan diri Anda ke <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Buka dengan <ph name="APP" /></translation> <translation id="6268747994388690914">Impor Bookmark dari file HTML...</translation> @@ -3556,7 +3532,6 @@ Klik "Berikutnya" untuk melanjutkan masuk ke akun <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> Anda.</translation> <translation id="6419546358665792306">Muat yang belum dibuka</translation> <translation id="642282551015776456">Nama ini tidak dapat digunakan sebagai nama file atau folder</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Buka setelan ChromeVox</translation> <translation id="6429384232893414837">Error update</translation> <translation id="6430814529589430811">ASCII bersandiaksara Base64, satu sertifikat</translation> @@ -3637,7 +3612,6 @@ <translation id="6544215763872433504">Browser web dari Google, untuk Anda</translation> <translation id="6545665334409411530">Tingkat pengulangan</translation> <translation id="6545834809683560467">Gunakan layanan prediksi untuk membantu melengkapi penelusuran dan URL yang diketik di kolom URL atau kotak penelusuran peluncur aplikasi</translation> -<translation id="6546686722964485737">Gabung dengan jaringan WiMAX</translation> <translation id="6547316139431024316">Jangan peringatkan lagi untuk ekstensi ini</translation> <translation id="6547354035488017500">Kosongkan ruang penyimpanan minimal 512 MB atau perangkat tidak akan merespons. Untuk mengosongkan ruang penyimpanan, hapus file dari penyimpanan perangkat.</translation> <translation id="6549689063733911810">Terkini</translation> @@ -4056,7 +4030,6 @@ <translation id="7201014958346994077">Tidak dapat melihat File Linux</translation> <translation id="720110658997053098">Simpan perangkat ini dalam mode kios secara permanen</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' dihapus</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Mendownload <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Keluar dari halaman}other{Keluar dari halaman}}</translation> <translation id="7216409898977639127">Operator seluler</translation> @@ -4534,7 +4507,6 @@ <translation id="7909969815743704077">Didownload dalam mode Penyamaran</translation> <translation id="7910768399700579500">&Map baru</translation> <translation id="7912080627461681647">Sandi Anda telah diubah di server. Harap logout, lalu login kembali.</translation> -<translation id="7912883689016444961">Konfigurasikan jaringan seluler</translation> <translation id="7915471803647590281">Beri tahu kami apa yang terjadi sebelum mengirim masukan.</translation> <translation id="7916556741383518510">Saat Diklik</translation> <translation id="792514962475806987">Tingkat zoom yang dipasang ke dok:</translation> @@ -4588,7 +4560,6 @@ <translation id="7988355189918024273">Aktifkan fitur aksesibilitas</translation> <translation id="7994702968232966508">Metode EAP</translation> <translation id="799547531016638432">Hapus pintasan</translation> -<translation id="7997479212858899587">Identitas:</translation> <translation id="7997826902155442747">Prioritas Proses</translation> <translation id="7999229196265990314">Membuat file berikut: @@ -4672,7 +4643,6 @@ <translation id="8105368624971345109">Nonaktifkan</translation> <translation id="8106045200081704138">Dibagikan dengan saya</translation> <translation id="8107015733319732394">Menginstal Google Play Store di <ph name="DEVICE_TYPE" />. Tindakan ini dapat memakan waktu beberapa menit.</translation> -<translation id="8109930990200908494">Perlu masuk untuk sertifikat pengguna.</translation> <translation id="8111155949205007504">Bagikan sandi ini dengan iPhone</translation> <translation id="8113043281354018522">Pilih jenis lisensi</translation> <translation id="8116190140324504026">Info selengkapnya...</translation> @@ -4794,7 +4764,6 @@ <translation id="8308179586020895837">Tanyakan jika <ph name="HOST" /> ingin mengakses kamera Anda</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Sertifikat sudah ada</translation> -<translation id="8309505303672555187">Pilih jaringan:</translation> <translation id="8312871300878166382">Tempelkan ke folder</translation> <translation id="8317671367883557781">Tambahkan sambungan jaringan</translation> <translation id="8319414634934645341">Extended Key Usage</translation> @@ -4869,7 +4838,6 @@ <translation id="8451512073679317615">asisten</translation> <translation id="8452135315243592079">Kartu SIM tidak ada</translation> <translation id="8453482423012550001">Menyalin $1 item...</translation> -<translation id="8454288007744638700">Atau, pilih jaringan baru:</translation> <translation id="845627346958584683">Waktu Kedaluwarsa</translation> <translation id="8456681095658380701">Nama tidak valid</translation> <translation id="8457451314607652708">Impor bookmark</translation> @@ -4971,7 +4939,6 @@ <translation id="862727964348362408">Ditangguhkan</translation> <translation id="862750493060684461">Cache CSS</translation> <translation id="8627795981664801467">Hanya sambungan aman</translation> -<translation id="8628085465172583869">Nama host server:</translation> <translation id="8630903300770275248">Impor pengguna yang dilindungi</translation> <translation id="8631032106121706562">Puspa</translation> <translation id="8637542770513281060">Komputer Anda berisi modul aman, yang digunakan untuk menerapkan banyak fitur keamanan kritis di Chrome OS. Buka Pusat Bantuan Chromebook untuk mempelajari lebih lanjut: https://support.google.com/chromebook/?p=sm</translation> @@ -5227,7 +5194,6 @@ <translation id="899403249577094719">Netscape Certificate Base URL</translation> <translation id="8995603266996330174">Dikelola menurut <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Tambahkan akun...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Membuat gambar disk.</translation> <translation id="9003647077635673607">Izinkan di semua situs web</translation> <translation id="9003677638446136377">Periksa lagi</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index 2ad2928..b89749b 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">È quasi ora di fare una pausa</translation> <translation id="1062407476771304334">Sostituisci</translation> -<translation id="1064835277883315402">Connetti a rete privata</translation> <translation id="1064912851688322329">Disconnetti il tuo account Google</translation> <translation id="1067048845568873861">Data creazione</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Ricerca in corso...</translation> <translation id="1316495628809031177">Sincronizzazione in pausa</translation> <translation id="1319979322914001937">Un'app che mostra un elenco filtrato di estensioni del Chrome Web Store. Le estensioni dell'elenco possono essere installate direttamente dall'app.</translation> -<translation id="132090119144658135">Corrispondenza oggetto:</translation> <translation id="1326317727527857210">Accedi a Chrome per trovare le tue schede degli altri dispositivi.</translation> <translation id="1327074568633507428">Stampante su Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Finestra dell'applicazione</translation> <translation id="1534389735079119190">ERRORE: impossibile avviare il container all'interno della VM.</translation> <translation id="15373452373711364">Puntatore del mouse grande</translation> +<translation id="1540605929960647700">Attiva modalità demo</translation> <translation id="1543284117603151572">Importati da Edge</translation> <translation id="1545177026077493356">Modalità kiosk automatica</translation> <translation id="1545775234664667895">Tema "<ph name="THEME_NAME" />" installato</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Aiutaci a migliorare <ph name="PRODUCT_NAME" /> inviando automaticamente a Google le statistiche sull'utilizzo e segnalazioni sugli arresti anomali</translation> <translation id="1658424621194652532">Questa pagina sta accedendo al microfono.</translation> <translation id="1660204651932907780">Consenti ai siti di riprodurre l'audio (opzione consigliata)</translation> +<translation id="1660938185063657230">Verifica token di sicurezza…</translation> <translation id="1661156625580498328">Applica la crittografia AES (consigliato).</translation> <translation id="1661245713600520330">La pagina elenca tutti i moduli caricati nel processo principale e i moduli registrati per il caricamento in una fase successiva.</translation> <translation id="166179487779922818">La password è troppo corta.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Non consentire ai siti di leggere testi e immagini copiati negli appunti</translation> <translation id="1682548588986054654">Nuova finestra di navigazione in incognito</translation> <translation id="168715261339224929">Attiva la sincronizzazione per trovare i tuoi preferiti su tutti i dispositivi.</translation> +<translation id="1688867105868176567">Cancellare i dati del sito?</translation> <translation id="1688935057616748272">Digita una lettera</translation> <translation id="168991973552362966">Aggiungi una stampante vicina</translation> <translation id="1689945336726856614">Copia &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Rimuovi questa persona</translation> <translation id="1706586824377653884">Aggiunta dall'amministratore</translation> <translation id="1706625117072057435">Livelli di zoom</translation> -<translation id="1707463636381878959">Condividi questa rete con altri utenti</translation> <translation id="1708338024780164500">(Non attiva)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (formato nativo)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Attiva tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Visualizza nel Chrome Web Store</translation> -<translation id="1758831820837444715">Configura rete Ethernet</translation> <translation id="1763046204212875858">Creazione di scorciatoie applicazione</translation> <translation id="1763108912552529023">Continua a esplorare</translation> <translation id="1763808908432309942">Si apre in una nuova scheda</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Cambia la modalità di condivisione di questo file</translation> <translation id="1841545962859478868">L'amministratore del dispositivo potrebbe monitorare i seguenti elementi:</translation> <translation id="1841705068325380214">L'estensione <ph name="EXTENSION_NAME" /> è stata disattivata</translation> +<translation id="1842766183094193446">Vuoi attivare questa modalità demo?</translation> <translation id="1844692022597038441">Questo file non è disponibile offline.</translation> <translation id="1846308012215045257">Premi CTRL e fai clic per eseguire <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Modifiche salvate</translation> <translation id="1848219224579402567">Esci alla chiusura del coperchio</translation> <translation id="184823282865851239">Blocca se il sito tende a mostrare annunci invasivi</translation> <translation id="1849186935225320012">Questa pagina ha il controllo totale dei dispositivi MIDI.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Puoi modificare questa scelta in seguito nelle Impostazioni</translation> <translation id="2006638907958895361">Apri link in <ph name="APP" /></translation> <translation id="2007404777272201486">Segnala un problema...</translation> +<translation id="2016237810978710652">Apertura di file Linux…</translation> <translation id="2016430552235416146">Tradizionale</translation> <translation id="2017334798163366053">Disattiva raccolta di dati sul rendimento</translation> <translation id="2017836877785168846">Consente di cancellare la cronologia e i completamenti automatici nella barra degli indirizzi.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Modifica la carta</translation> <translation id="2154710561487035718">Copia URL</translation> <translation id="2155772377859296191">Risoluzione di <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Puoi contribuire a migliorare la Navigazione sicura, grazie all'invio di informazioni di sistema e contenuti delle pagine a Google.</translation> <translation id="215753907730220065">Esci da schermo intero</translation> <translation id="2157875535253991059">Questa pagina ora è a schermo intero.</translation> <translation id="216169395504480358">Aggiungi Wi-Fi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Aggiungi ID richiesta a questo dispositivo</translation> <translation id="2175042898143291048">Traduci sempre</translation> <translation id="2175607476662778685">Barra Avvio veloce</translation> +<translation id="2176087259161165020">Altre fonti</translation> <translation id="2177950615300672361">Scheda di navigazione in incognito: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> su <ph name="PEPPER_PLUGIN_DOMAIN" /> vuole accedere al computer</translation> <translation id="2178614541317717477">Compromesso CA</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Scheda successiva</translation> <translation id="2292848386125228270">Avvia <ph name="PRODUCT_NAME" /> come utente normale. Per eseguirlo come root a fini di sviluppo, esegui di nuovo il flag --no-sandbox.</translation> <translation id="2294358108254308676">Installare <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Metodo EAP:</translation> <translation id="2297705863329999812">Cerca stampanti</translation> <translation id="2300383962156589922">Personalizza e controlla <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Directory principale dell'estensione non valida.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">ERRORE: disinstallazione dell'app <ph name="APP_NAME" /> non riuscita.</translation> <translation id="2367199180085172140">Aggiungi Condivisione file</translation> <translation id="2367972762794486313">Mostra app</translation> +<translation id="2369536625682139252">Tutti dati archiviati dal sito <ph name="SITE" />, eccetto i cookie, verranno eliminati.</translation> <translation id="2371076942591664043">Apri al &termine</translation> <translation id="2377319039870049694">Passa alla visualizzazione elenco</translation> <translation id="2377667304966270281">Errori hardware</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Stampa utilizzando la finestra di dialogo di sistema... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Chiedi prima di inviare (opzione consigliata)</translation> <translation id="2384436799579181135">Si è verificato un errore. Controlla la tua stampante e riprova.</translation> -<translation id="2385700042425247848">Nome servizio:</translation> <translation id="2387458720915042159">Tipo di connessione proxy</translation> <translation id="2391419135980381625">Carattere standard</translation> <translation id="2391762656119864333">Revoca</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Condividi audio</translation> <translation id="2480868415629598489">Modifica dei dati copiati e incollati</translation> <translation id="2482878487686419369">Notifiche</translation> -<translation id="2485056306054380289">Certificato CA del server:</translation> <translation id="2485422356828889247">Disinstalla</translation> <translation id="2487067538648443797">Aggiungi nuovo preferito</translation> <translation id="248861575772995840">Impossibile trovare il telefono. Assicurati che sul dispositivo <ph name="DEVICE_TYPE" /> sia attivo il Bluetooth. <a>Ulteriori informazioni</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Esegui il powerwash per ripristinare il tuo dispositivo <ph name="IDS_SHORT_PRODUCT_NAME" /> e farlo tornare come nuovo.</translation> <translation id="2567257616420533738">Password salvata. Controlla e gestisci le password salvate all'indirizzo <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Infobar Container</translation> +<translation id="2570454805927264159">Utilizza al meglio l'assistente</translation> <translation id="257088987046510401">Temi</translation> <translation id="2572032849266859634">È stato concesso l'accesso in sola lettura a <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Scegli un'immagine e un nome</translation> @@ -1098,7 +1101,6 @@ <translation id="2653659639078652383">Invia</translation> <translation id="265390580714150011">Valore campo</translation> <translation id="2654166010170466751">Consenti ai siti di installare gestori dei pagamenti</translation> -<translation id="2655386581175833247">Certificato utente:</translation> <translation id="2660779039299703961">Evento</translation> <translation id="266079277508604648">Impossibile connettere la stampante. Verifica che sia accesa e collegata al Chromebook tramite Wi-Fi o USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1331,6 +1333,7 @@ <translation id="3006881078666935414">Nessun dato sull'utilizzo</translation> <translation id="3007214526293698309">Correggi proporzioni</translation> <translation id="3007771295016901659">Duplica scheda</translation> +<translation id="3008272652534848354">Reimposta le autorizzazioni</translation> <translation id="3009300415590184725">Annullare la procedura di configurazione del servizio dati mobile?</translation> <translation id="3009779501245596802">Indexed databases</translation> <translation id="3010279545267083280">Password eliminata</translation> @@ -1397,7 +1400,6 @@ <translation id="3100609564180505575">Moduli (<ph name="TOTAL_COUNT" />). Conflitti conosciuti: <ph name="BAD_COUNT" />, sospettati: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Data e ora</translation> <translation id="310671807099593501">Il sito sta usando il Bluetooth</translation> -<translation id="3108967419958202225">Scegli...</translation> <translation id="3115128645424181617">Impossibile trovare il telefono. Assicurati che sia a portata di mano e che il Bluetooth sia attivo.</translation> <translation id="3115147772012638511">In attesa di elaborazione cache...</translation> <translation id="3118319026408854581">Guida di <ph name="PRODUCT_NAME" /></translation> @@ -1442,7 +1444,6 @@ <translation id="3165390001037658081">La funzione potrebbe essere bloccata da alcuni operatori.</translation> <translation id="316854673539778496">Accedi e attiva la sincronizzazione per trovare tutte le tue estensioni su tutti i dispositivi.</translation> <translation id="3170072451822350649">Puoi anche saltare l'accesso e <ph name="LINK_START" />navigare come ospite<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Fai clic per nascondere la password</translation> <translation id="3177909033752230686">Lingua della pagina:</translation> <translation id="3181110748548073003">Premi |<ph name="SHORTCUT" />| per andare avanti</translation> <translation id="3182749001423093222">Controllo ortografico</translation> @@ -1473,7 +1474,6 @@ <translation id="3236289833370040187">La proprietà verrà trasferita a <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Apri opzioni estensione</translation> <translation id="3241680850019875542">Seleziona la directory principale dell'estensione di cui creare il pacchetto. Per aggiornare un'estensione, seleziona anche il file delle chiave privata da riutilizzare.</translation> -<translation id="3242765319725186192">Chiave precondivisa:</translation> <translation id="3244294424315804309">Continua a tenere l'audio disattivato</translation> <translation id="3245321423178950146">Artista sconosciuto</translation> <translation id="3246097286174000800">Prova Smart Lock</translation> @@ -1604,7 +1604,6 @@ <translation id="3440663250074896476">Altre azioni per <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Chiedi conferma quando un sito vuole utilizzare un plug-in per accedere al tuo computer</translation> <translation id="3441653493275994384">Schermo</translation> -<translation id="3445830502289589282">Autenticazione fase 2:</translation> <translation id="344630545793878684">Lettura dei dati su una serie di siti web</translation> <translation id="3449839693241009168">Premi <ph name="SEARCH_KEY" /> per inviare comandi a <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Percentuale di occupazione dello stato di inattività</translation> @@ -1645,7 +1644,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> errori.</translation> <translation id="3495660573538963482">Impostazioni dell'Assistente Google</translation> <translation id="3496213124478423963">Riduci</translation> -<translation id="3504135463003295723">Nome gruppo:</translation> <translation id="3505030558724226696">Revoca accesso ai dispositivi</translation> <translation id="3507421388498836150">Autorizzazioni attuali di "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Rimuovi app Linux per Chromebook</translation> @@ -1754,7 +1752,6 @@ <translation id="3661054927247347545">Certificato di accesso non valido; la finestra verrà chiusa tra <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Icona dell'estensione</translation> <translation id="3665589677786828986">Chrome ha rilevato che alcune impostazioni sono state danneggiate da un altro programma e le ha ripristinate con i valori originali predefiniti.</translation> -<translation id="3665842570601375360">Sicurezza:</translation> <translation id="3668570675727296296">Impostazioni lingua</translation> <translation id="3668823961463113931">Gestori</translation> <translation id="3670229581627177274">Attiva il Bluetooth</translation> @@ -1793,7 +1790,6 @@ <translation id="3726463242007121105">Impossibile aprire il dispositivo perché il suo filesystem non è supportato.</translation> <translation id="3727148787322499904">La modifica di questa impostazione avrà effetto su tutte le reti condivise</translation> <translation id="3727187387656390258">Ispeziona popup</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Errore nella riga <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Server SSL con step-up</translation> <translation id="3737536731758327622">I tuoi download vengono visualizzati qui</translation> @@ -1868,7 +1864,6 @@ <translation id="38275787300541712">Al termine, premi Invio</translation> <translation id="3827774300009121996">&Schermo intero</translation> <translation id="3828029223314399057">Cerca tra i Preferiti</translation> -<translation id="3829932584934971895">Tipo di provider:</translation> <translation id="3830674330436234648">Riproduzione non disponibile</translation> <translation id="3831486154586836914">Modalità panoramica finestre attivata</translation> <translation id="383161972796689579">Il proprietario di questo dispositivo ha disattivato l'aggiunta di nuovi utenti</translation> @@ -1889,6 +1884,7 @@ <translation id="3856921555429624101">La misurazione dell'utilizzo dei dati è terminata</translation> <translation id="3857228364945137633">Prova Smart Lock per sbloccare il tuo dispositivo <ph name="DEVICE_TYPE" /> senza password quando il tuo telefono è nelle vicinanze.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: sincronizzazione in pausa</translation> <translation id="3860381078714302691">Benvenuto in Hangouts Meet</translation> <translation id="3862134173397075045">Benvenuto nell'esperienza Cast di Chrome.</translation> <translation id="3862788408946266506">L'app con l'attributo del file manifest "kiosk_only" deve essere installata in modalità kiosk di Chrome OS</translation> @@ -1966,7 +1962,6 @@ <translation id="3968261067169026421">Impossibile configurare la rete</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Calcolo in corso...</translation> -<translation id="3974195870082915331">Fai clic per visualizzare la password</translation> <translation id="3975222297214566386">Inserisci fumetto di opzioni</translation> <translation id="397703832102027365">Finalizzazione in corso...</translation> <translation id="3979395879372752341">Nuova estensione aggiunta (<ph name="EXTENSION_NAME" />)</translation> @@ -2008,6 +2003,7 @@ <translation id="4044612648082411741">Inserisci la password del certificato</translation> <translation id="404493185430269859">Motore di ricerca predefinito</translation> <translation id="4047112090469382184">Livello di sicurezza della funzione</translation> +<translation id="4051049974203704184">Ricevi informazioni su ciò che è mostrato sullo schermo</translation> <translation id="4052120076834320548">Minuscolo</translation> <translation id="4055023634561256217">È necessario riavviare prima che il dispositivo possa essere reimpostato con Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2036,6 +2032,7 @@ <translation id="4088095054444612037">Accetta per gruppo</translation> <translation id="4089235344645910861">Impostazioni salvate. Sincronizzazione avviata.</translation> <translation id="4090103403438682346">Consente di attivare l'accesso verificato</translation> +<translation id="4090947011087001172">Reimpostare le autorizzazioni per il sito <ph name="SITE" />?</translation> <translation id="4091434297613116013">fogli</translation> <translation id="4093955363990068916">File locale:</translation> <translation id="4095507791297118304">Display principale</translation> @@ -2212,7 +2209,6 @@ <translation id="4419556793104466535">Controlla la sincronizzazione, la personalizzazione e non solo</translation> <translation id="4421932782753506458">Micio</translation> <translation id="4422347585044846479">Modifica Preferito</translation> -<translation id="4423104065312875417">Installa altri motori di riconoscimento vocale</translation> <translation id="4423376891418188461">Ripristina impostazioni</translation> <translation id="4423482519432579560">&Controllo ortografico</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, il tuo amministratore ti chiede di cambiare la password.</translation> @@ -2237,7 +2233,6 @@ <translation id="4449996769074858870">In questa scheda c'è audio in riproduzione.</translation> <translation id="4450974146388585462">Diagnostica</translation> <translation id="4453946976636652378">Cerca su <ph name="SEARCH_ENGINE_NAME" /> o digita un URL</translation> -<translation id="445923051607553918">Connetti a rete Wi-Fi</translation> <translation id="4462159676511157176">Assegna nomi personalizzati a server</translation> <translation id="4467100756425880649">Chrome Web Store Gallery</translation> <translation id="4467101674048705704">Espandi <ph name="FOLDER_NAME" /></translation> @@ -2373,6 +2368,7 @@ <translation id="4682551433947286597">Gli sfondi vengono visualizzati sulla schermata di accesso.</translation> <translation id="4684427112815847243">Sincronizza tutto</translation> <translation id="4689421377817139245">Sincronizza il preferito con l'iPhone</translation> +<translation id="4690091457710545971"><Quattro file generati dal firmware Intel Wi-Fi: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. I primi tre sono file binari che contengono dump di registro e che, secondo quanto dichiarato da Intel, non contengono informazioni personali o di identificazione del dispositivo. L'ultimo file è una traccia di esecuzione dal firmware Intel, privato di ogni informazione personale o di identificazione del dispositivo, ma troppo grande per essere mostrato qui. Questi file sono stati generati in risposta ai recenti problemi del tuo dispositivo con la rete Wi-Fi e verranno condivisi con Intel per agevolare la risoluzione di tali problemi.></translation> <translation id="4692302215262324251">Il dispositivo <ph name="DEVICE_TYPE" /> è stato registrato correttamente per la gestione aziendale da parte di <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Se non era previsto, contatta l'assistenza.</translation> @@ -2632,6 +2628,7 @@ <translation id="5074318175948309511">Potrebbe essere necessario ricaricare la pagina per applicare le nuove impostazioni.</translation> <translation id="5075131525758602494">Inserisci il PIN della SIM</translation> <translation id="5078638979202084724">Aggiungi tutte le schede ai Preferiti</translation> +<translation id="5079950360618752063">Utilizza la password suggerita</translation> <translation id="5084230410268011727">Consenti ai siti di usare i sensori di movimento e della luce</translation> <translation id="5085162214018721575">Verifica disponibilità aggiornamenti</translation> <translation id="5086082738160935172">HID</translation> @@ -2670,6 +2667,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Elimina questa voce</translation> <translation id="5139955368427980650">&Apri</translation> +<translation id="5142961317498132443">Autenticazione</translation> <translation id="5143374789336132547">L'estensione "<ph name="EXTENSION_NAME" />" ha cambiato la pagina mostrata quando fai clic sul pulsante Pagina iniziale.</translation> <translation id="5143712164865402236">Passa a schermo intero</translation> <translation id="5145331109270917438">Data modifica</translation> @@ -2839,7 +2837,6 @@ <translation id="5380103295189760361">Tieni premuto Ctrl, Alt, Maiusc o Cerca per visualizzare le scorciatoie da tastiera per questi tasti di modifica.</translation> <translation id="5382591305415226340">Gestisci i link supportati</translation> <translation id="5384883051496921101">Questo sito sta per condividere informazioni con un'app esterna alla modalità di navigazione in incognito.</translation> -<translation id="5388588172257446328">Nome utente:</translation> <translation id="5388885445722491159">Accoppiato</translation> <translation id="5389237414310520250">Impossibile creare il nuovo utente. Controlla lo spazio disponibile sul disco rigido e le autorizzazioni e riprova.</translation> <translation id="5390100381392048184">Consenti ai siti di riprodurre l'audio</translation> @@ -2964,7 +2961,6 @@ <translation id="5551573675707792127">Tastiera e input di testo</translation> <translation id="5553089923092577885">Mapping dei criteri dei certificati</translation> <translation id="5554489410841842733">Questa icona sarà visibile quando l'estensione potrà interagire nella pagina corrente.</translation> -<translation id="5554573843028719904">Altra rete Wi-Fi...</translation> <translation id="5554720593229208774">Autorità di certificazione email</translation> <translation id="5556206011531515970">Fai clic su Avanti per scegliere il browser predefinito.</translation> <translation id="5556459405103347317">Ricarica</translation> @@ -3005,7 +3001,6 @@ <translation id="5610038042047936818">Passa a modalità Fotocamera</translation> <translation id="5612720917913232150"><ph name="URL" /> vuole usare la posizione del computer</translation> <translation id="5612734644261457353">Spiacenti, la password non è stata ancora verificata. Nota. Se l'hai modificata di recente, la nuova password verrà applicata quando esci, quindi ti invitiamo a utilizzare la tua vecchia password qui.</translation> -<translation id="5613695965848159202">Identità anonima:</translation> <translation id="5614190747811328134">Notifica all'utente</translation> <translation id="561698261642843490">Chiudi Firefox</translation> <translation id="5618075537869101857">Accidenti, non è possibile avviare l'applicazione kiosk.</translation> @@ -3223,7 +3218,6 @@ <translation id="5941343993301164315">Accedi a <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Riduci a icona</translation> <translation id="5946591249682680882">ID rapporto <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Aggiungi rete privata</translation> <translation id="5949544233750246342">Impossibile analizzare il file</translation> <translation id="5955282598396714173">La password è scaduta. Esci e accedi nuovamente per modificarla.</translation> <translation id="5956585768868398362">È la pagina di ricerca prevista?</translation> @@ -3384,11 +3378,13 @@ <translation id="6198102561359457428">Esci e accedi di nuovo...</translation> <translation id="6198252989419008588">Modifica PIN</translation> <translation id="6199801702437275229">In attesa di informazioni sullo spazio...</translation> +<translation id="6204015976622790023">Ricevi dall'assistente suggerimenti attinenti agli elementi sullo schermo.</translation> <translation id="6205710420833115353">Alcune operazioni richiedono più tempo del previsto. Vuoi interromperle?</translation> <translation id="6206311232642889873">Cop&ia immagine</translation> <translation id="6207200176136643843">Ripristina il livello di zoom predefinito</translation> <translation id="620722923698527029">Apri sempre questo tipo di link nell'app associata</translation> <translation id="6207937957461833379">Paese/Regione</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: la sincronizzazione non funziona</translation> <translation id="6212039847102026977">Mostra proprietà di rete avanzate</translation> <translation id="6212168817037875041">Disattiva lo schermo</translation> <translation id="6212752530110374741">Invia link tramite email</translation> @@ -3426,7 +3422,6 @@ <translation id="6263541650532042179">reimpostare la sincronizzazione</translation> <translation id="6264365405983206840">Seleziona &tutto</translation> <translation id="6264422956566238156">Hai attivato la sincronizzazione</translation> -<translation id="6265930187414222160">Fatto! Software dannoso rimosso.</translation> <translation id="6267166720438879315">Seleziona un certificato per autenticarti a <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Apri con <ph name="APP" /></translation> <translation id="6268747994388690914">Importa i preferiti da file HTML...</translation> @@ -3533,7 +3528,6 @@ Fai clic su "Avanti" per continuare ad accedere al tuo account <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Carica estensione non pacchettizzata</translation> <translation id="642282551015776456">Questo nome non può essere utilizzato per un file o una cartella</translation> -<translation id="6423239382391657905">VPN aperta</translation> <translation id="6426200009596957090">Apri le impostazioni ChromeVox</translation> <translation id="6429384232893414837">Errore di aggiornamento</translation> <translation id="6430814529589430811">ASCII con codifica Base64, singolo certificato</translation> @@ -3566,7 +3560,7 @@ <translation id="6466988389784393586">&Apri tutti i Preferiti</translation> <translation id="6468485451923838994">Caratteri</translation> <translation id="6472207088655375767">OTP</translation> -<translation id="6472893788822429178">Mostra pulsante Pagina iniziale</translation> +<translation id="6472893788822429178">Mostra pulsante Home</translation> <translation id="6473842110411557830">Illustrazione Powerwash</translation> <translation id="6474706907372204693">Metodo di immissione precedente</translation> <translation id="6474884162850599008">Scollega account Google Drive</translation> @@ -3614,7 +3608,6 @@ <translation id="6544215763872433504">Il browser web di Google, per te</translation> <translation id="6545665334409411530">Frequenza ripetizione</translation> <translation id="6545834809683560467">Utilizza un servizio di previsione per il completamento delle ricerche e degli URL digitati nella barra degli indirizzi o nella casella di ricerca di Avvio applicazioni</translation> -<translation id="6546686722964485737">Connetti a rete WiMAX</translation> <translation id="6547316139431024316">Non avvisare più per questa estensione</translation> <translation id="6547354035488017500">Libera almeno 512 MB di spazio, altrimenti il tuo dispositivo non risponderà più ai comandi. Per liberare spazio, elimina i file dallo spazio di archiviazione.</translation> <translation id="6549689063733911810">Recenti</translation> @@ -4033,7 +4026,6 @@ <translation id="7201014958346994077">Impossibile visualizzare i file di Linux</translation> <translation id="720110658997053098">Mantieni definitivamente questo dispositivo in modalità kiosk</translation> <translation id="7201118060536064622">"<ph name="DELETED_ITEM_NAME" />" eliminato</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Download di <ph name="PLUGIN_NAME" /> in corso...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Pagina di uscita}other{Pagine di uscita}}</translation> <translation id="7216409898977639127">Fornitore del servizio di telefonia mobile</translation> @@ -4509,7 +4501,6 @@ <translation id="7909969815743704077">Scaricato in modalità in incognito</translation> <translation id="7910768399700579500">&Nuova cartella</translation> <translation id="7912080627461681647">La password è stata modificata sul server. Esci e accedi nuovamente.</translation> -<translation id="7912883689016444961">Configura la rete mobile</translation> <translation id="7915471803647590281">Comunicaci cosa sta accadendo prima di inviare il feedback.</translation> <translation id="7916556741383518510">Al clic</translation> <translation id="792514962475806987">Livello di zoom ancorato:</translation> @@ -4563,7 +4554,6 @@ <translation id="7988355189918024273">Attiva funzioni di accessibilità</translation> <translation id="7994702968232966508">Metodo EAP</translation> <translation id="799547531016638432">Rimuovi scorciatoia</translation> -<translation id="7997479212858899587">Identità:</translation> <translation id="7997826902155442747">Priorità processo</translation> <translation id="7999229196265990314">Sono stati creati i file seguenti: @@ -4647,7 +4637,6 @@ <translation id="8105368624971345109">Disattiva</translation> <translation id="8106045200081704138">Condivisi con me</translation> <translation id="8107015733319732394">Installazione in corso del Google Play Store sul tuo dispositivo <ph name="DEVICE_TYPE" />. L'operazione potrebbe richiedere alcuni minuti.</translation> -<translation id="8109930990200908494">Accesso obbligatorio per il certificato utente.</translation> <translation id="8111155949205007504">Condividi la password con l'iPhone</translation> <translation id="8113043281354018522">Scegli il tipo di licenza</translation> <translation id="8116190140324504026">Ulteriori informazioni...</translation> @@ -4658,6 +4647,7 @@ <translation id="8118860139461251237">Gestione dei download</translation> <translation id="81238879832906896">Fiore bianco e giallo</translation> <translation id="8124313775439841391">ONC gestito</translation> +<translation id="8125562866093998907">Il sito vuole verificare il tuo token di sicurezza per motivi di ulteriore sicurezza del tuo account.</translation> <translation id="813082847718468539">Visualizza informazioni sul sito</translation> <translation id="8131740175452115882">Conferma</translation> <translation id="8133676275609324831">&Mostra nella cartella</translation> @@ -4747,7 +4737,7 @@ <translation id="8263744495942430914"><ph name="FULLSCREEN_ORIGIN" /> ha disattivato il puntatore del mouse.</translation> <translation id="8264718194193514834">"<ph name="EXTENSION_NAME" />" ha attivato lo schermo intero.</translation> <translation id="8270242299912238708">Documenti PDF</translation> -<translation id="827097179112817503">Mostra pulsante Pagina iniziale</translation> +<translation id="827097179112817503">Mostra pulsante Home</translation> <translation id="8271246892936492311">{COUNT,plural, =1{1 preferito eliminato}other{# preferiti eliminati}}</translation> <translation id="8272443605911821513">Gestisci le tue estensioni facendo clic su Estensioni nel menu "Altri strumenti".</translation> <translation id="8274332263553132018">Trasmetti file</translation> @@ -4768,7 +4758,6 @@ <translation id="8308179586020895837">Chiedi conferma se <ph name="HOST" /> vuole accedere alla webcam</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Il certificato esiste già</translation> -<translation id="8309505303672555187">Seleziona una rete:</translation> <translation id="8312871300878166382">Incolla nella cartella</translation> <translation id="8317671367883557781">Aggiungi connesione di rete</translation> <translation id="8319414634934645341">Utilizzo chiave esteso</translation> @@ -4843,7 +4832,6 @@ <translation id="8451512073679317615">assistente</translation> <translation id="8452135315243592079">Scheda SIM mancante</translation> <translation id="8453482423012550001">Copia di $1 elementi...</translation> -<translation id="8454288007744638700">In alternativa, seleziona una nuova rete:</translation> <translation id="845627346958584683">Data di scadenza</translation> <translation id="8456681095658380701">Nome non valido</translation> <translation id="8457451314607652708">Importa Preferiti</translation> @@ -4907,6 +4895,7 @@ <translation id="855081842937141170">Blocca scheda</translation> <translation id="8551388862522347954">Licenze</translation> <translation id="8553342806078037065">Gestisci altre persone</translation> +<translation id="8554899698005018844">Nessuna lingua</translation> <translation id="855773602626431402">È stata impedita l'esecuzione di un plug-in senza sandbox in questa pagina.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Image Decoder</translation> @@ -4944,7 +4933,6 @@ <translation id="862727964348362408">Sospeso</translation> <translation id="862750493060684461">Cache CSS</translation> <translation id="8627795981664801467">Solo connessioni protette</translation> -<translation id="8628085465172583869">Nome host del server:</translation> <translation id="8630903300770275248">Importa utente controllato</translation> <translation id="8631032106121706562">Petalo</translation> <translation id="8637542770513281060">Il computer contiene un modulo per la sicurezza che viene utilizzato per implementare in Chrome OS molte funzionalità di sicurezza fondamentali. Per ulteriori informazioni, visita il Centro assistenza Chromebook all'indirizzo: https://support.google.com/chromebook/?p=sm.</translation> @@ -5200,7 +5188,6 @@ <translation id="899403249577094719">URL di base certificato Netscape</translation> <translation id="8995603266996330174">Gestito da <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Aggiungi account...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Creazione dell'immagine del disco.</translation> <translation id="9003647077635673607">Consenti su tutti i siti web</translation> <translation id="9003677638446136377">Controlla</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index 3e5b82d..e5dee53 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">עוד מעט זמן להפסקה</translation> <translation id="1062407476771304334">החלף</translation> -<translation id="1064835277883315402">הצטרף לרשת פרטית</translation> <translation id="1064912851688322329">נתק את חשבון Google שלך</translation> <translation id="1067048845568873861">נוצר</translation> <translation id="1067291318998134776">Linux (בטא)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">מחפש...</translation> <translation id="1316495628809031177">הסינכרון הושהה</translation> <translation id="1319979322914001937">יישום שמציג רשימה מסוננת של תוספים מחנות האינטרנט של Chrome. ניתן להתקין את התוספים שברשימה ישירות מתוך היישום.</translation> -<translation id="132090119144658135">התאמת נושא:</translation> <translation id="1326317727527857210">כדי לקבל את הכרטיסיות מהמכשירים האחרים שלך, היכנס ל-Chrome.</translation> <translation id="1327074568633507428">מדפסת ב-Google Cloud Print</translation> <translation id="1327977588028644528">שער</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">חלון אפליקציה</translation> <translation id="1534389735079119190">שגיאה: הפעלת הקונטיינר בתוך VM נכשלה.</translation> <translation id="15373452373711364">סמן עכבר גדול</translation> +<translation id="1540605929960647700">הפעלת מצב הדגמה</translation> <translation id="1543284117603151572">מיובא מ-Edge</translation> <translation id="1545177026077493356">מצב קיוסק אוטומטי</translation> <translation id="1545775234664667895">נושא שהותקן "<ph name="THEME_NAME" />"</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">עזור להפוך את <ph name="PRODUCT_NAME" /> לטוב יותר, על ידי שליחה אוטומטית של נתוני שימוש ודוחות קריסה אל Google</translation> <translation id="1658424621194652532">דף זה ניגש למיקרופון שלך.</translation> <translation id="1660204651932907780">מתן הרשאה לאתרים להשמיע צלילים (מומלץ)</translation> +<translation id="1660938185063657230">אימות מפתח האבטחה שלך</translation> <translation id="1661156625580498328">אכיפה של הצפנת AES (מומלץ).</translation> <translation id="1661245713600520330">דף זה מפרט את כל המודולים שנטענו בתהליך הראשי ואת המודולים הרשומים לטעינה בשלב מאוחר יותר.</translation> <translation id="166179487779922818">הסיסמה קצרה מדי.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">אין להתיר לאתרים לגשת לטקסט ותמונות שהועתקו ללוח</translation> <translation id="1682548588986054654">חלון נסתר חדש</translation> <translation id="168715261339224929">כדי שהסימניות שלך יופיעו בכל המכשירים, יש להפעיל סינכרון.</translation> +<translation id="1688867105868176567">למחוק את נתוני האתר?</translation> <translation id="1688935057616748272">צריך להזין אות</translation> <translation id="168991973552362966">הוספת מדפסת קרובה</translation> <translation id="1689945336726856614">העתקת &כתובת אתר</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">הסר משתמש זה</translation> <translation id="1706586824377653884">נוסף על ידי מנהל המערכת שלך</translation> <translation id="1706625117072057435">רמות מרחק מתצוגה</translation> -<translation id="1707463636381878959">שתף רשת זו עם משתמשים אחרים</translation> <translation id="1708338024780164500">(לא פעיל)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (מזהה: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (מקורי)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">הפעל עיצוב</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">הצגה בחנות האינטרנט של Chrome</translation> -<translation id="1758831820837444715">הגדרת רשת אתרנט</translation> <translation id="1763046204212875858">צור קיצורי דרך ליישום</translation> <translation id="1763108912552529023">המשך לחקור</translation> <translation id="1763808908432309942">פתיחה בכרטיסייה חדשה</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">שנה את אופן השיתוף של הקובץ הזה</translation> <translation id="1841545962859478868">ייתכן שמנהל המכשיר עוקב אחרי:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> מושבת</translation> +<translation id="1842766183094193446">להפעיל מצב הדמיה?</translation> <translation id="1844692022597038441">קובץ זו אינו זמין במצב לא מקוון.</translation> <translation id="1846308012215045257">כדי להפעיל את <ph name="PLUGIN_NAME" />, לחץ עליו תוך כדי הקשה על Control</translation> +<translation id="1847880352285315359">נשמר</translation> <translation id="1848219224579402567">יציאה מהחשבון כשמכסה סגור</translation> <translation id="184823282865851239">חסום אם האתר נוטה להציג מודעות שמפריעות</translation> <translation id="1849186935225320012">לדף זה יש שליטה מלאה על מכשירי MIDI.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">ניתן לשנות את האפשרות הזו מאוחר יותר בהגדרות</translation> <translation id="2006638907958895361">פתח את הקישור ב-<ph name="APP" /></translation> <translation id="2007404777272201486">דיווח על בעיה...</translation> +<translation id="2016237810978710652">מתבצעת פתיחה של קובצי Linux...</translation> <translation id="2016430552235416146">מסורתית</translation> <translation id="2017334798163366053">השבת איסוף של נתוני ביצועים</translation> <translation id="2017836877785168846">מנקה את ההיסטוריה וההשלמות האוטומטיות בסרגל הכתובות</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">עריכת כרטיס</translation> <translation id="2154710561487035718">העתק כתובת אתר</translation> <translation id="2155772377859296191">נראה כמו <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">על-ידי שליחה של חלק מפרטי המערכת ותוכן הדפים אל Google אפשר לעזור בשיפור של 'גלישה בטוחה'.</translation> <translation id="215753907730220065">צא ממסך מלא</translation> <translation id="2157875535253991059">דף זה הוא במסך מלא כעת.</translation> <translation id="216169395504480358">הוסף Wi-Fi...</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">הוספת מזהה דרישה למכשיר זה</translation> <translation id="2175042898143291048">עשה זאת תמיד</translation> <translation id="2175607476662778685">סרגל הפעלה מהירה</translation> +<translation id="2176087259161165020">מקורות אחרים</translation> <translation id="2177950615300672361">כרטיסיית גלישה בסתר: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> ב-<ph name="PEPPER_PLUGIN_DOMAIN" /> רוצה גישה למחשב שלך</translation> <translation id="2178614541317717477">רשות האישורים (CA) בסכנה</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">הכרטיסייה הבאה</translation> <translation id="2292848386125228270">הפעל את <ph name="PRODUCT_NAME" /> כמשתמש רגיל. אם תצטרך להפעיל כבסיס לצורך פיתוח, הפעל מחדש עם הסימון --no-sandbox.</translation> <translation id="2294358108254308676">האם ברצונך להתקין את <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">שיטת EAP:</translation> <translation id="2297705863329999812">חפש מדפסות</translation> <translation id="2300383962156589922">התאמה אישית ושליטה ב-<ph name="APP_NAME" /></translation> <translation id="2301382460326681002">ספריית הבסיס של ההרחבה אינה חוקית.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">שגיאה: ההתקנה של <ph name="APP_NAME" /> נכשלה.</translation> <translation id="2367199180085172140">הוספת שיתוף קובץ</translation> <translation id="2367972762794486313">הצג יישומים</translation> +<translation id="2369536625682139252">כל הנתונים שאוחסנו על-ידי <ph name="SITE" /> יימחקו, מלבד קובצי ה-Cookie.</translation> <translation id="2371076942591664043">פתח &בסיום</translation> <translation id="2377319039870049694">מעבר לתצוגת רשימה</translation> <translation id="2377667304966270281">שגיאות חמורות</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">הדפס באמצעות תיבת דו-שיח של המערכת... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">שאל לפני שליחה (מומלץ)</translation> <translation id="2384436799579181135">אירעה שגיאה. יש לבדוק את המדפסת ולנסות שוב.</translation> -<translation id="2385700042425247848">שם השירות:</translation> <translation id="2387458720915042159">סוג חיבור לשרת proxy</translation> <translation id="2391419135980381625">גופן רגיל</translation> <translation id="2391762656119864333">בטל</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">שתף אודיו</translation> <translation id="2480868415629598489">שינוי נתונים שאתה מעתיק ומדביק</translation> <translation id="2482878487686419369">התראות</translation> -<translation id="2485056306054380289">אישור CA של שרת:</translation> <translation id="2485422356828889247">הסר התקנה</translation> <translation id="2487067538648443797">הוספת סימניה חדשה</translation> <translation id="248861575772995840">לא ניתן למצוא את הטלפון שלך. יש לוודא שה-Bluetooth מופעל ב-<ph name="DEVICE_TYPE" />. <a>מידע נוסף</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">בצע פעולת Powerwash כדי לאפס את מכשיר <ph name="IDS_SHORT_PRODUCT_NAME" /> שלך כך שיהיה כמו חדש.</translation> <translation id="2567257616420533738">הסיסמה נשמרה. אפשר להציג ולנהל את הסיסמאות השמורות ב-<ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">גורם מכיל של סרגל המידע</translation> +<translation id="2570454805927264159">איך להפיק את המירב מ-Assistant</translation> <translation id="257088987046510401">ערכות נושא</translation> <translation id="2572032849266859634">ניתנה הרשאה לקריאה בלבד ב-<ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">בחר תמונה ושם</translation> @@ -1096,7 +1099,6 @@ <translation id="2653659639078652383">שלח</translation> <translation id="265390580714150011">ערך שדה </translation> <translation id="2654166010170466751">מתן הרשאה לאתרים להתקין מעבדי handler לתשלומים</translation> -<translation id="2655386581175833247">אישור משתמש:</translation> <translation id="2660779039299703961">אירוע</translation> <translation id="266079277508604648">לא ניתן להתחבר אל המדפסת. יש לוודא שהמדפסת פועלת ומחוברת אל ה-Chromebook דרך רשת ה-Wi-Fi או בחיבור USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1329,6 +1331,7 @@ <translation id="3006881078666935414">אין נתוני שימוש</translation> <translation id="3007214526293698309">תקן את היחס</translation> <translation id="3007771295016901659">שכפל את הכרטיסייה</translation> +<translation id="3008272652534848354">איפוס הרשאות</translation> <translation id="3009300415590184725">האם אתה בטוח שברצונך לבטל את תהליך ההתקנה של שירות הנתונים לנייד?</translation> <translation id="3009779501245596802">מסדי נתונים שנוספו לאינדקס</translation> <translation id="3010279545267083280">הסיסמה נמחקה</translation> @@ -1395,7 +1398,6 @@ <translation id="3100609564180505575">מודולים (<ph name="TOTAL_COUNT" />) - התנגשויות ידועות: <ph name="BAD_COUNT" />, חשודות: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">תאריך ושעה</translation> <translation id="310671807099593501">האתר משתמש ב-Bluetooth</translation> -<translation id="3108967419958202225">בחר...</translation> <translation id="3115128645424181617">לא ניתן למצוא את הטלפון שלך. יש לוודא שהוא נמצא איתך ושהופעל בו Bluetooth.</translation> <translation id="3115147772012638511">ממתין למטמון...</translation> <translation id="3118319026408854581">עזרה של <ph name="PRODUCT_NAME" /></translation> @@ -1440,7 +1442,6 @@ <translation id="3165390001037658081">ייתכן שספקים מסוימים חוסמים את התכונה הזו.</translation> <translation id="316854673539778496">כדי שכל התוספים שלך יהיו זמינים בכל המכשירים שברשותך, צריך להיכנס ולהפעיל את הסינכרון.</translation> <translation id="3170072451822350649">ניתן גם לדלג על הכניסה ו<ph name="LINK_START" />לגלוש כאורח<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">לחץ כדי להסתיר את הסיסמה</translation> <translation id="3177909033752230686">שפת הדף:</translation> <translation id="3181110748548073003">הקש על |<ph name="SHORTCUT" />| כדי להתקדם</translation> <translation id="3182749001423093222">בדיקת איות</translation> @@ -1471,7 +1472,6 @@ <translation id="3236289833370040187">הבעלות תועבר אל <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">פתח אפשרויות תוסף</translation> <translation id="3241680850019875542">בחר את ספריית הבסיס של התוסף שיש לארוז. כדי לעדכן תוסף, בחר גם את קובץ המפתח הפרטי שבו ניתן להשתמש שוב.</translation> -<translation id="3242765319725186192">מפתח משותף מראש:</translation> <translation id="3244294424315804309">המשך השתקת הצלילים</translation> <translation id="3245321423178950146">אמן לא ידוע</translation> <translation id="3246097286174000800">רוצה לנסות את Smart Lock?</translation> @@ -1604,7 +1604,6 @@ <translation id="3440663250074896476">עוד פעולות לסימניה <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">שאל כשאתר רוצה להשתמש בפלאגין כדי לגשת אל המחשב שלך</translation> <translation id="3441653493275994384">מסך</translation> -<translation id="3445830502289589282">אימות שלב 2:</translation> <translation id="344630545793878684">קריאת הנתונים שלך במספר אתרים</translation> <translation id="3449839693241009168">לחץ על <ph name="SEARCH_KEY" /> כדי לשלוח פקודות אל <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">אחוז תפוסה במצב לא פעיל</translation> @@ -1645,7 +1644,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> שגיאות.</translation> <translation id="3495660573538963482">ההגדרות של Google Assistant</translation> <translation id="3496213124478423963">התרחק</translation> -<translation id="3504135463003295723">שם קבוצה:</translation> <translation id="3505030558724226696">בטל גישה למכשירים</translation> <translation id="3507421388498836150">הרשאות נוכחיות של "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">הסרת אפליקציות Linux מה-Chromebook</translation> @@ -1754,7 +1752,6 @@ <translation id="3661054927247347545">אישור הכניסה אינו חוקי. החלון ייסגר בעוד <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">סמל התוסף</translation> <translation id="3665589677786828986">Chrome זיהה שחלק מההגדרות שלך נפגמו על ידי תכנית אחרת ואיפס אותן לברירות המחדל המקוריות.</translation> -<translation id="3665842570601375360">אבטחה:</translation> <translation id="3668570675727296296">הגדרות שפה</translation> <translation id="3668823961463113931">מטפלים</translation> <translation id="3670229581627177274">הפעל Bluetooth</translation> @@ -1793,7 +1790,6 @@ <translation id="3726463242007121105">לא ניתן לפתוח מכשיר זה מאחר שמערכת הקבצים שלו אינה נתמכת.</translation> <translation id="3727148787322499904">שינוי של הגדרה זו ישפיע על כל הרשתות המשותפות</translation> <translation id="3727187387656390258">בדוק חלון מוקפץ</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">שגיאה בשורה <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">שרת SSL עם הגברה</translation> <translation id="3737536731758327622">ההורדות שלך מופיעות כאן</translation> @@ -1868,7 +1864,6 @@ <translation id="38275787300541712">הקש על Enter בסיום</translation> <translation id="3827774300009121996">&מסך מלא</translation> <translation id="3828029223314399057">חפש סימניות</translation> -<translation id="3829932584934971895">סוג ספק:</translation> <translation id="3830674330436234648">לא ניתן להפעיל</translation> <translation id="3831486154586836914">נכנסת למצב סקירת חלון</translation> <translation id="383161972796689579">הבעלים של מכשיר זה השבית את ההוספה של משתמשים חדשים</translation> @@ -1889,6 +1884,7 @@ <translation id="3856921555429624101">מדידת השימוש בנתונים הסתיימה</translation> <translation id="3857228364945137633">כדאי לנסות את Smart Lock כדי לבטל את הנעילה של <ph name="DEVICE_TYPE" /> כשהטלפון בקרבת מקום, בלי להזין סיסמה.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: הסינכרון הושהה</translation> <translation id="3860381078714302691">ברכות על הצטרפותך אל Hangouts Meet</translation> <translation id="3862134173397075045">ברוכים הבאים לחוויה של Cast ב-Chrome!</translation> <translation id="3862788408946266506">במצב קיוסק של Chrome OS, יש להתקין אפליקציות עם מאפיין המניפסט 'kiosk_only'</translation> @@ -1966,7 +1962,6 @@ <translation id="3968261067169026421">לא ניתן היה להגדיר את הרשת</translation> <translation id="3970114302595058915">מזהה</translation> <translation id="397105322502079400">מחשב...</translation> -<translation id="3974195870082915331">לחץ כדי להציג את הסיסמה</translation> <translation id="3975222297214566386">בועת אפשרויות קלט</translation> <translation id="397703832102027365">מסיים...</translation> <translation id="3979395879372752341">תוסף חדש נוסף (<ph name="EXTENSION_NAME" />)</translation> @@ -2008,6 +2003,7 @@ <translation id="4044612648082411741">הזן את סיסמת האישור</translation> <translation id="404493185430269859">מנוע החיפוש המוגדר כברירת מחדל</translation> <translation id="4047112090469382184">כיצד נשמרת האבטחה</translation> +<translation id="4051049974203704184">קבלת מידע על מה שמוצג במסך</translation> <translation id="4052120076834320548">זעיר</translation> <translation id="4055023634561256217">כדי לבצע איפוס באמצעות שחזור הגדרות יצרן, עליך להפעיל תחילה את המכשיר מחדש.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2036,6 +2032,7 @@ <translation id="4088095054444612037">אשר עבור הקבוצה</translation> <translation id="4089235344645910861">ההגדרות נשמרו והסנכרון החל.</translation> <translation id="4090103403438682346">הפעל גישה מאומתת</translation> +<translation id="4090947011087001172">לאפס את ההרשאות של האתר <ph name="SITE" />?</translation> <translation id="4091434297613116013">גליונות נייר</translation> <translation id="4093955363990068916">קובץ מקומי:</translation> <translation id="4095507791297118304">צג ראשי</translation> @@ -2212,7 +2209,6 @@ <translation id="4419556793104466535">שליטה בסינכרון, התאמה אישית ועוד</translation> <translation id="4421932782753506458">לקיק</translation> <translation id="4422347585044846479">ערוך סימניה עבור דף זה</translation> -<translation id="4423104065312875417">התקנה של מנועי דיבור נוספים</translation> <translation id="4423376891418188461">שחזר הגדרות</translation> <translation id="4423482519432579560">&בדיקת איות</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, מנהל המערכת מבקש ממך לשנות את הסיסמה שלך.</translation> @@ -2237,7 +2233,6 @@ <translation id="4449996769074858870">הכרטיסייה הזו מפעילה תוכן אודיו.</translation> <translation id="4450974146388585462">אבחן</translation> <translation id="4453946976636652378">אפשר לחפש ב-<ph name="SEARCH_ENGINE_NAME" /> או להקליד כתובת אתר</translation> -<translation id="445923051607553918">הצטרף לרשת Wi-Fi</translation> <translation id="4462159676511157176">שרתי שמות מותאמים אישית</translation> <translation id="4467100756425880649">הגלריה של חנות האינטרנט של Chrome</translation> <translation id="4467101674048705704">הרחבה של <ph name="FOLDER_NAME" /></translation> @@ -2373,6 +2368,7 @@ <translation id="4682551433947286597">טפטים מופיעים במסך הכניסה.</translation> <translation id="4684427112815847243">סנכרן הכל</translation> <translation id="4689421377817139245">סנכרון הסימניה עם ה-iPhone</translation> +<translation id="4690091457710545971"><קושחת ה-Wi-Fi של Intel יצרה ארבעה קבצים: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. שלושת הקבצים הראשונים הם קובצי Dump בינאריים של המרשם, והמערכת של Intel מטפלת בהם מתוך הנחה שהם לא מכילים מידע שמאפשר זיהוי אישי או זיהוי של המכשיר. הקובץ האחרון הוא מעקב ביצוע מהקושחה של Intel. נמחק ממנו מידע שמאפשר זיהוי אישי או זיהוי של המכשיר, אבל הוא גדול מדי מכדי להציג אותו כאן. הקבצים האלה נוצרו בתגובה לבעיות שאירעו לאחרונה בחיבור ה-Wi-Fi של המכשיר שלך, והם ישותפו עם Intel בניסיון לפתור את הבעיות האלה.></translation> <translation id="4692302215262324251">רישום המכשיר שלך <ph name="DEVICE_TYPE" /> לניהול ארגוני בוצע בהצלחה על ידי <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> אם לא ציפית לרישום כזה, פנה לתמיכה.</translation> @@ -2632,6 +2628,7 @@ <translation id="5074318175948309511">ייתכן שיהיה צורך לטעון מחדש דף זה על מנת שההגדרות החדשות ייכנסו לתוקף.</translation> <translation id="5075131525758602494">הזן את מספר ה-PIN של ה-SIM</translation> <translation id="5078638979202084724">צור סימניה לכל הכרטיסיות</translation> +<translation id="5079950360618752063">שימוש בסיסמה המוצעת</translation> <translation id="5084230410268011727">מתן הרשאה לאתרים להשתמש בחיישני תנועה ואור</translation> <translation id="5085162214018721575">מחפש עדכונים</translation> <translation id="5086082738160935172">HID</translation> @@ -2670,6 +2667,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">מחק את הפריט הזה</translation> <translation id="5139955368427980650">&פתח</translation> +<translation id="5142961317498132443">אימות</translation> <translation id="5143374789336132547">התוסף "<ph name="EXTENSION_NAME" />" שינה את הדף שמוצג כשאתה לוחץ על הלחצן 'דף הבית'.</translation> <translation id="5143712164865402236">עבור למסך מלא</translation> <translation id="5145331109270917438">תאריך שינוי</translation> @@ -2841,7 +2839,6 @@ <translation id="5380103295189760361">החזק את Control, Alt, Shift או 'חפש' כדי לראות מקשי קיצור עבור מקשי הצירוף האלה.</translation> <translation id="5382591305415226340">נהל קישורים נתמכים</translation> <translation id="5384883051496921101">אתר זה עומד לשתף מידע עם אפליקציה מחוץ למצב גלישה בסתר.</translation> -<translation id="5388588172257446328">שם משתמש:</translation> <translation id="5388885445722491159">מתואם</translation> <translation id="5389237414310520250">לא ניתן היה ליצור את המשתמש החדש. בדוק את השטח הפנוי בכונן הקשיח ואת ההרשאות שלך ונסה שוב.</translation> <translation id="5390100381392048184">מתן הרשאה לאתרים להשמיע צלילים</translation> @@ -2966,7 +2963,6 @@ <translation id="5551573675707792127">מקלדת וקלט טקסט</translation> <translation id="5553089923092577885">מיפויי מדיניות אישור </translation> <translation id="5554489410841842733">סמל זה יוצג כאשר ההרחבה תוכל לפעול בדף הנוכחי.</translation> -<translation id="5554573843028719904">רשת Wi-Fi אחרת...</translation> <translation id="5554720593229208774">רשות אישורי אימייל</translation> <translation id="5556206011531515970">לחץ על 'הבא' כדי לבחור את דפדפן ברירת המחדל.</translation> <translation id="5556459405103347317">טען שוב</translation> @@ -3007,7 +3003,6 @@ <translation id="5610038042047936818">מעבר למצב מצלמה</translation> <translation id="5612720917913232150"><ph name="URL" /> רוצה להשתמש במיקום המחשב שלך</translation> <translation id="5612734644261457353">מצטערים, עדיין לא ניתן לאמת את הסיסמה שלך. שים לב: אם שינית את סיסמתך לאחרונה, הסיסמה החדשה תיכנס לתוקף לאחר שתצא. השתמש בסיסמה הישנה כאן.</translation> -<translation id="5613695965848159202">זהות אנונימית:</translation> <translation id="5614190747811328134">הודעת משתמש</translation> <translation id="561698261642843490">סגירת Firefox</translation> <translation id="5618075537869101857">אוף! לא ניתן היה להפעיל את יישום הקיוסק.</translation> @@ -3225,7 +3220,6 @@ <translation id="5941343993301164315">היכנס ל-<ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">מזער</translation> <translation id="5946591249682680882">מזהה דיווח <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">הוסף רשת פרטית</translation> <translation id="5949544233750246342">לא ניתן לנתח את הקובץ</translation> <translation id="5955282598396714173">תוקף הסיסמה פג. כדי לשנות אותה, צא ולאחר מכן היכנס מחדש.</translation> <translation id="5956585768868398362">האם זהו דף החיפוש שציפית לראות?</translation> @@ -3386,11 +3380,13 @@ <translation id="6198102561359457428">צא והיכנס שוב...</translation> <translation id="6198252989419008588">שנה PIN</translation> <translation id="6199801702437275229">מחכה למידע שטח האחסון...</translation> +<translation id="6204015976622790023">הצגת הצעות רלוונטיות מה-Assistant הקשורות למה שמופיע במסך.</translation> <translation id="6205710420833115353">פעולות מסוימות נמשכות זמן רב מהצפוי. האם ברצונך לבטל אותן?</translation> <translation id="6206311232642889873">העת&ק תמונה</translation> <translation id="6207200176136643843">אפס למרחק התצוגה המוגדר כברירת המחדל</translation> <translation id="620722923698527029">פתח תמיד את סוגי הקישורים האלה באפליקציות המשויכות אליהן</translation> <translation id="6207937957461833379">מדינה/אזור</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: הסינכרון לא פועל</translation> <translation id="6212039847102026977">הצג מאפייני רשת מתקדמים</translation> <translation id="6212168817037875041">כבה את הצג</translation> <translation id="6212752530110374741">שליחת קישור באימייל</translation> @@ -3428,7 +3424,6 @@ <translation id="6263541650532042179">אפס סנכרון</translation> <translation id="6264365405983206840">בחר &הכל</translation> <translation id="6264422956566238156">הפעלת את הסינכרון</translation> -<translation id="6265930187414222160">בוצע! התוכנה המזיקה הוסרה.</translation> <translation id="6267166720438879315">בחר אישור כדי לאמת את עצמך מול <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">פתח באמצעות <ph name="APP" /></translation> <translation id="6268747994388690914">יבוא סימניות מקובץ HTML...</translation> @@ -3535,7 +3530,6 @@ לחץ על 'הבא' כדי להמשיך בכניסה אל חשבון <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> שלך.</translation> <translation id="6419546358665792306">טען פריט לא ארוז</translation> <translation id="642282551015776456">ייתכן שלא ניתן להשתמש בשם זה כשם קובץ או תיקייה</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">פתח את הגדרות ChromeVox</translation> <translation id="6429384232893414837">שגיאת עדכון</translation> <translation id="6430814529589430811">ASCII בקידוד Base64, אישור יחיד</translation> @@ -3616,7 +3610,6 @@ <translation id="6544215763872433504">דפדפן האינטרנט של Google, במיוחד בשבילך</translation> <translation id="6545665334409411530">שיעור חזרה</translation> <translation id="6545834809683560467">השתמש בשירות חיזויים כדי להשלים חיפושים וכתובות אתרים שאתה מזין בסרגל הכתובות או בתיבת החיפוש של מפעיל היישומים</translation> -<translation id="6546686722964485737">הצטרפות לרשת WiMAX</translation> <translation id="6547316139431024316">אל תציג שוב אזהרה עבור התוסף הזה</translation> <translation id="6547354035488017500">עליך לפנות 512 MB לפחות משטח האחסון במכשיר, אחרת הוא יפסיק להגיב. כדי לפנות שטח אחסון, מחק קבצים מאחסון המכשיר.</translation> <translation id="6549689063733911810">מהזמן האחרון</translation> @@ -4035,7 +4028,6 @@ <translation id="7201014958346994077">לא ניתן להציג קובצי Linux</translation> <translation id="720110658997053098">השארת המכשיר הזה במצב קיוסק באופן קבוע</translation> <translation id="7201118060536064622">הפריט '<ph name="DELETED_ITEM_NAME" />' נמחק</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">מוריד את <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{יציאה מהדף}two{יציאה מהדפים}many{יציאה מהדפים}other{יציאה מהדפים}}</translation> <translation id="7216409898977639127">ספק שירות סלולרי</translation> @@ -4510,7 +4502,6 @@ <translation id="7909969815743704077">ההורדה בוצעה במצב גלישה בסתר</translation> <translation id="7910768399700579500">&תיקייה חדשה</translation> <translation id="7912080627461681647">הסיסמה שלך שונתה בשרת. צא ולאחר מכן היכנס מחדש.</translation> -<translation id="7912883689016444961">הגדרת רשת סלולרית</translation> <translation id="7915471803647590281">ספר לנו מה קורה לפני שליחת המשוב.</translation> <translation id="7916556741383518510">בזמן לחיצה</translation> <translation id="792514962475806987">רמת זום במצב מעוגן:</translation> @@ -4564,7 +4555,6 @@ <translation id="7988355189918024273">הפוך תכונות נגישות לפעילות</translation> <translation id="7994702968232966508">שיטת EAP</translation> <translation id="799547531016638432">הסר קיצור דרך</translation> -<translation id="7997479212858899587">זהות:</translation> <translation id="7997826902155442747">עדיפות תהליך</translation> <translation id="7999229196265990314">יצר את הקבצים הבאים: @@ -4648,7 +4638,6 @@ <translation id="8105368624971345109">כבה</translation> <translation id="8106045200081704138">בשיתוף איתי</translation> <translation id="8107015733319732394">מתקין את חנות Google Play במכשיר <ph name="DEVICE_TYPE" />. ייתכן שההתקנה תימשך כמה דקות.</translation> -<translation id="8109930990200908494">נדרשת כניסה עבור אישור משתמש.</translation> <translation id="8111155949205007504">שיתוף הסיסמה הזו עם מכשיר ה-iPhone</translation> <translation id="8113043281354018522">בחר סוג רישיון</translation> <translation id="8116190140324504026">עוד מידע...</translation> @@ -4659,6 +4648,7 @@ <translation id="8118860139461251237">לנהל את ההורדות שלך</translation> <translation id="81238879832906896">פרח צהוב ולבן</translation> <translation id="8124313775439841391">ONC מנוהל</translation> +<translation id="8125562866093998907">האתר רוצה לאמת את מפתח האבטחה שלך כדי להגביר את אבטחת החשבון.</translation> <translation id="813082847718468539">הצג נתוני אתר</translation> <translation id="8131740175452115882">אישור</translation> <translation id="8133676275609324831">&הצג בתיקייה</translation> @@ -4769,7 +4759,6 @@ <translation id="8308179586020895837">שאל אם <ph name="HOST" /> רוצה לגשת למצלמה שלך</translation> <translation id="830868413617744215">ביטא</translation> <translation id="8309458809024885768">האישור כבר קיים</translation> -<translation id="8309505303672555187">בחר רשת:</translation> <translation id="8312871300878166382">הדבק בתיקייה</translation> <translation id="8317671367883557781">הוסף חיבור רשת</translation> <translation id="8319414634934645341">שימוש מורחב במפתח</translation> @@ -4844,7 +4833,6 @@ <translation id="8451512073679317615">אסיסטנט</translation> <translation id="8452135315243592079">כרטיס SIM חסר</translation> <translation id="8453482423012550001">מעתיק $1 פריטים...</translation> -<translation id="8454288007744638700">לחלופין, בחר רשת חדשה:</translation> <translation id="845627346958584683">מועד תפוגה</translation> <translation id="8456681095658380701">שם לא חוקי</translation> <translation id="8457451314607652708">יבא סימניות</translation> @@ -4908,6 +4896,7 @@ <translation id="855081842937141170">הצמד כרטיסייה</translation> <translation id="8551388862522347954">רישיונות</translation> <translation id="8553342806078037065">נהל אנשים אחרים</translation> +<translation id="8554899698005018844">לא הוגדרה שפה</translation> <translation id="855773602626431402">בדף הזה נמנעה הפעלה של פלאגין ללא ארגז חול.</translation> <translation id="8557930019681227453">מניפסט</translation> <translation id="8559694214572302298">מפענח התמונות</translation> @@ -4945,7 +4934,6 @@ <translation id="862727964348362408">מושעה</translation> <translation id="862750493060684461">מטמון של CSS</translation> <translation id="8627795981664801467">התחברויות בטוחות בלבד</translation> -<translation id="8628085465172583869">שם מארח של שרת:</translation> <translation id="8630903300770275248">יבא משתמש בפיקוח</translation> <translation id="8631032106121706562">עלי כותרת</translation> <translation id="8637542770513281060">המחשב שלך מכיל מודול מאובטח המשמש ליישום תכונות אבטחה קריטיות רבות ב-Chrome OS. היכנס למרכז העזרה של Chromebook כדי לקבל מידע נוסף: https://support.google.com/chromebook/?p=sm</translation> @@ -5201,7 +5189,6 @@ <translation id="899403249577094719">כתובת אתר בסיסית של אישור Netscape</translation> <translation id="8995603266996330174">מנוהל על ידי <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">הוסף חשבון...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">יצירה של תמונת הדיסק.</translation> <translation id="9003647077635673607">אפשר בכל האתרים</translation> <translation id="9003677638446136377">בדוק שוב</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb index 9eb541a..e40e3a98 100644 --- a/chrome/app/resources/generated_resources_ja.xtb +++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">もうすぐ休憩の時間です</translation> <translation id="1062407476771304334">置換</translation> -<translation id="1064835277883315402">プライベート ネットワークに参加</translation> <translation id="1064912851688322329">Google アカウントを切断</translation> <translation id="1067048845568873861">作成日</translation> <translation id="1067291318998134776">Linux(ベータ版)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">検索しています...</translation> <translation id="1316495628809031177">同期は一時停止中です</translation> <translation id="1319979322914001937">Chrome ウェブストアの拡張機能を絞り込んでリスト表示するアプリです。リストに表示された拡張機能はアプリから直接インストールできます。</translation> -<translation id="132090119144658135">サブジェクトの一致:</translation> <translation id="1326317727527857210">他の端末と同じタブを使用するには、Chrome にログインします。</translation> <translation id="1327074568633507428">Google クラウド プリント上のプリンタ</translation> <translation id="1327977588028644528">ゲートウェイ</translation> @@ -377,6 +375,7 @@ <translation id="1531004739673299060">アプリケーション ウィンドウ</translation> <translation id="1534389735079119190">エラー: VM 内部のコンテナを起動できませんでした。</translation> <translation id="15373452373711364">大きいマウス カーソル</translation> +<translation id="1540605929960647700">デモモードの有効化</translation> <translation id="1543284117603151572">Edge からインポート</translation> <translation id="1545177026077493356">自動キオスク モード</translation> <translation id="1545775234664667895">テーマ「<ph name="THEME_NAME" />」をインストールしました</translation> @@ -460,6 +459,7 @@ <translation id="1657406563541664238">使用統計データや障害レポートを Google に自動送信して <ph name="PRODUCT_NAME" /> の機能向上に役立てる</translation> <translation id="1658424621194652532">このページはマイクにアクセスしています。</translation> <translation id="1660204651932907780">音声の再生をサイトに許可する(推奨)</translation> +<translation id="1660938185063657230">セキュリティ キーの確認</translation> <translation id="1661156625580498328">AES 暗号化を適用します(推奨)。</translation> <translation id="1661245713600520330">このページには、メイン プロセスに読み込まれているすべてのモジュールと、後で読み込むために登録されているモジュールが表示されます。</translation> <translation id="166179487779922818">パスワードが短すぎます。</translation> @@ -477,6 +477,7 @@ <translation id="16815041330799488">クリップボードにコピーされているテキストや画像へのアクセスをサイトに許可しない</translation> <translation id="1682548588986054654">新規シークレット ウインドウ</translation> <translation id="168715261339224929">お使いのどの端末でも同じブックマークを使用するには、同期を有効にします。</translation> +<translation id="1688867105868176567">サイトデータを消去しますか?</translation> <translation id="1688935057616748272">文字を入力してください</translation> <translation id="168991973552362966">近くのプリンタを追加</translation> <translation id="1689945336726856614">URL をコピー(&U)</translation> @@ -488,7 +489,6 @@ <translation id="1701062906490865540">このユーザーを削除</translation> <translation id="1706586824377653884">管理者により追加</translation> <translation id="1706625117072057435">ズームレベル</translation> -<translation id="1707463636381878959">他のユーザーとネットワークを共有</translation> <translation id="1708338024780164500">(無効)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" />(ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" />x<ph name="HEIGHT" />(ネイティブ)</translation> @@ -524,7 +524,6 @@ <translation id="175772926354468439">テーマを有効にする</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome ウェブストアのページに移動</translation> -<translation id="1758831820837444715">イーサネット ネットワークの設定</translation> <translation id="1763046204212875858">アプリケーションのショートカットを作成</translation> <translation id="1763108912552529023">さらに確認</translation> <translation id="1763808908432309942">新しいタブで開きます</translation> @@ -583,8 +582,10 @@ <translation id="1839704667838141620">このファイルの共有方法を変更してください</translation> <translation id="1841545962859478868">デバイス管理者が次の情報を監視している可能性があります。</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> が無効になりました</translation> +<translation id="1842766183094193446">デモモードを有効にしてもよろしいですか?</translation> <translation id="1844692022597038441">このファイルはオフラインでは表示できません。</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" /> を実行するには Control キーを押しながらクリックします</translation> +<translation id="1847880352285315359">保存されました</translation> <translation id="1848219224579402567">ディスプレイを閉じたときにログアウトする</translation> <translation id="184823282865851239">煩わしい広告がよく表示されるサイトの場合にブロック</translation> <translation id="1849186935225320012">このページは MIDI デバイスのフル コントロールが許可されています。</translation> @@ -682,6 +683,7 @@ <translation id="200544492091181894">これは後から [設定] で変更することもできます</translation> <translation id="2006638907958895361"><ph name="APP" /> でリンクを開く</translation> <translation id="2007404777272201486">問題の報告...</translation> +<translation id="2016237810978710652">[Linux ファイル] を開いています...</translation> <translation id="2016430552235416146">通常</translation> <translation id="2017334798163366053">パフォーマンス データの収集を無効にする</translation> <translation id="2017836877785168846">アドレスバーの履歴とオートコンプリート データを削除します。</translation> @@ -776,6 +778,7 @@ <translation id="2154484045852737596">カードを編集</translation> <translation id="2154710561487035718">URL をコピー</translation> <translation id="2155772377859296191">表示上のサイズ: <ph name="WIDTH" />x<ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">一部のシステム情報とページのコンテンツを Google に送信して、セーフ ブラウジングの改善にご協力ください。</translation> <translation id="215753907730220065">全画面表示を終了</translation> <translation id="2157875535253991059">現在このページは全画面表示です。</translation> <translation id="216169395504480358">Wi-Fi を追加...</translation> @@ -785,6 +788,7 @@ <translation id="2173801458090845390">登録 ID をこのデバイスに追加します</translation> <translation id="2175042898143291048">常に翻訳する</translation> <translation id="2175607476662778685">クイック起動バー</translation> +<translation id="2176087259161165020">その他のキャスト元</translation> <translation id="2177950615300672361">シークレット タブ: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> の <ph name="PEPPER_PLUGIN_NAME" /> プラグインから、パソコンへのアクセス許可を求められています</translation> <translation id="2178614541317717477">認証局が侵害された</translation> @@ -868,7 +872,6 @@ <translation id="2291643155573394834">次のタブ</translation> <translation id="2292848386125228270">通常のユーザーとして <ph name="PRODUCT_NAME" /> を起動してください。開発の目的でルートとして実行する必要がある場合は、--no-sandbox フラグを指定して再実行してください。</translation> <translation id="2294358108254308676"><ph name="PRODUCT_NAME" /> をインストールしますか?</translation> -<translation id="2296019197782308739">EAP 方式:</translation> <translation id="2297705863329999812">プリンタを検索</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> のカスタマイズと制御</translation> <translation id="2301382460326681002">拡張機能のルート ディレクトリが無効です。</translation> @@ -916,6 +919,7 @@ <translation id="2366463953911599217">エラー: <ph name="APP_NAME" /> をアンインストールできませんでした。</translation> <translation id="2367199180085172140">ファイル共有を追加</translation> <translation id="2367972762794486313">アプリを表示</translation> +<translation id="2369536625682139252"><ph name="SITE" /> により保存された、Cookie 以外の全データが削除されます。</translation> <translation id="2371076942591664043">ダウンロードしたら開く(&D)</translation> <translation id="2377319039870049694">リスト表示に切り替え</translation> <translation id="2377667304966270281">ハードの障害数</translation> @@ -925,7 +929,6 @@ <translation id="2379281330731083556">システム ダイアログを使用して印刷... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">送信する前に確認する(推奨)</translation> <translation id="2384436799579181135">エラーが発生しました。プリンタを確認してもう一度お試しください。</translation> -<translation id="2385700042425247848">サービス名:</translation> <translation id="2387458720915042159">プロキシ接続タイプ</translation> <translation id="2391419135980381625">標準フォント</translation> <translation id="2391762656119864333">取り消し</translation> @@ -976,7 +979,6 @@ <translation id="247949520305900375">音声を共有する</translation> <translation id="2480868415629598489">コピーして貼り付けるデータの修正</translation> <translation id="2482878487686419369">通知</translation> -<translation id="2485056306054380289">サーバー CA 証明書:</translation> <translation id="2485422356828889247">アンインストール</translation> <translation id="2487067538648443797">新しいブックマークを追加</translation> <translation id="248861575772995840">スマートフォンが見つかりません。<ph name="DEVICE_TYPE" /> で Bluetooth がオンになっていることを確認してください。<a>詳細</a></translation> @@ -1037,6 +1039,7 @@ <translation id="2566124945717127842">お使いの <ph name="IDS_SHORT_PRODUCT_NAME" /> 搭載デバイスを出荷時の状態にリセットするために、Powerwash を実行します。</translation> <translation id="2567257616420533738">パスワードが保存されました。保存パスワードの表示と管理は <ph name="SAVED_PASSWORDS_LINK" /> で行えます。</translation> <translation id="2568774940984945469">情報バー コンテナ</translation> +<translation id="2570454805927264159">アシスタントをもっと活用しましょう</translation> <translation id="257088987046510401">テーマ</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> への読み取り専用アクセスが許可されました。</translation> <translation id="2573269395582837871">画像と名前を選択</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">送信</translation> <translation id="265390580714150011">フィールド値</translation> <translation id="2654166010170466751">サイトに支払いハンドラのインストールを許可</translation> -<translation id="2655386581175833247">ユーザー証明書:</translation> <translation id="2660779039299703961">イベント</translation> <translation id="266079277508604648">プリンタに接続できません。プリンタの電源が入っていて、Wi-Fi または USB 経由で Chromebook に接続されていることを確認してください。</translation> <translation id="2661146741306740526">16×9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">使用状況データはありません</translation> <translation id="3007214526293698309">比率を固定</translation> <translation id="3007771295016901659">タブを複製</translation> +<translation id="3008272652534848354">権限をリセット</translation> <translation id="3009300415590184725">モバイル データ サービスの設定処理をキャンセルしてもよろしいですか?</translation> <translation id="3009779501245596802">Indexed Database</translation> <translation id="3010279545267083280">パスワードを削除しました</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">モジュール(<ph name="TOTAL_COUNT" />) - 既知の競合: <ph name="BAD_COUNT" />、調査中の競合: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">日時</translation> <translation id="310671807099593501">サイトで Bluetooth が使用されています</translation> -<translation id="3108967419958202225">選択...</translation> <translation id="3115128645424181617">スマートフォンが見つかりません。スマートフォンが手の届く範囲にあり、Bluetooth がオンになっていることを確認してください。</translation> <translation id="3115147772012638511">キャッシュを待機しています...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> ヘルプ</translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">携帯通信会社によってはこの機能を利用できない場合があります。</translation> <translation id="316854673539778496">お使いのどの端末でも同じ拡張機能を使用するには、ログインして同期を有効にします。</translation> <translation id="3170072451822350649">ログインせずに<ph name="LINK_START" />ゲストとしてブラウジング<ph name="LINK_END" />することもできます。</translation> -<translation id="3177048931975664371">クリックしてパスワードを隠す</translation> <translation id="3177909033752230686">ページの言語:</translation> <translation id="3181110748548073003">次に進むには |<ph name="SHORTCUT" />| キーを押します</translation> <translation id="3182749001423093222">スペルチェック</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187">所有権が <ph name="DESTINATION_DOMAIN" /> に移ります。</translation> <translation id="323803881985677942">拡張機能のオプションを開きます</translation> <translation id="3241680850019875542">パッケージ化する拡張機能のルート ディレクトリを選択します。拡張機能を更新するには、再使用する秘密鍵ファイルも選択してください。</translation> -<translation id="3242765319725186192">事前共有キー:</translation> <translation id="3244294424315804309">音声のミュートを続行する</translation> <translation id="3245321423178950146">不明なアーティスト</translation> <translation id="3246097286174000800">Smart Lock を使ってみる</translation> @@ -1608,7 +1608,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> に対するその他の操作</translation> <translation id="3440761377721825626">サイトがプラグインを使用してパソコンにアクセスしようとしたときに確認する</translation> <translation id="3441653493275994384">画面</translation> -<translation id="3445830502289589282">フェーズ 2 認証:</translation> <translation id="344630545793878684">多数のウェブサイトでのユーザーデータの読み取り</translation> <translation id="3449839693241009168"><ph name="SEARCH_KEY" /> を押すと <ph name="EXTENSION_NAME" /> にコマンドが送信されます</translation> <translation id="3450157232394774192">アイドル状態の占有率(%)</translation> @@ -1649,7 +1648,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> 件のエラーがあります。</translation> <translation id="3495660573538963482">Google アシスタントの設定</translation> <translation id="3496213124478423963">縮小</translation> -<translation id="3504135463003295723">グループ名:</translation> <translation id="3505030558724226696">デバイスのアクセスを取り消す</translation> <translation id="3507421388498836150">「<ph name="EXTENSION_NAME" />」の現在の権限</translation> <translation id="3507547268929739059">Chromebook から Linux アプリを削除する</translation> @@ -1758,7 +1756,6 @@ <translation id="3661054927247347545">ログインの認証情報が有効ではありません。ウィンドウは <ph name="MINUTES" /> 分 <ph name="SECONDS" /> 秒後に閉じられます</translation> <translation id="3664511988987167893">拡張機能アイコン</translation> <translation id="3665589677786828986">設定の一部が別のプログラムによって変更されていたため、元のデフォルト設定に戻しました。</translation> -<translation id="3665842570601375360">セキュリティ:</translation> <translation id="3668570675727296296">言語設定</translation> <translation id="3668823961463113931">ハンドラ</translation> <translation id="3670229581627177274">Bluetooth を ON にする</translation> @@ -1797,7 +1794,6 @@ <translation id="3726463242007121105">ファイルシステムがサポートされていないため、このデバイスを開くことはできません。</translation> <translation id="3727148787322499904">この設定を変更すると、共有しているすべてのネットワークに影響します</translation> <translation id="3727187387656390258">ポップアップを検証</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900"><ph name="ERROR_LINE" /> 行目にエラーがあります</translation> <translation id="3733127536501031542">International Step-UP 対応の SSL サーバー</translation> <translation id="3737536731758327622">ダウンロードがここに表示されます</translation> @@ -1872,7 +1868,6 @@ <translation id="38275787300541712">終了後は Enter を押します</translation> <translation id="3827774300009121996">全画面表示(&F)</translation> <translation id="3828029223314399057">ブックマークを検索</translation> -<translation id="3829932584934971895">プロバイダの種類:</translation> <translation id="3830674330436234648">再生機能はご利用いただけません</translation> <translation id="3831486154586836914">ウィンドウ概観モードに切り替わりました</translation> <translation id="383161972796689579">このデバイスの所有者は新規ユーザーの追加を無効にしています</translation> @@ -1893,6 +1888,7 @@ <translation id="3856921555429624101">データ使用量の測定が終了しました</translation> <translation id="3857228364945137633">Smart Lock を使用すると、スマートフォンが近くにあるときに、パスワードを入力しなくても <ph name="DEVICE_TYPE" /> のロックを解除できます。</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: 同期が一時停止されています</translation> <translation id="3860381078714302691">ハングアウト Meet へようこそ</translation> <translation id="3862134173397075045">Chrome のキャスト エクスペリエンスへようこそ</translation> <translation id="3862788408946266506">「kiosk_only」のマニフェスト属性が指定されているアプリは、Chrome OS キオスクモードでインストールする必要があります。</translation> @@ -1970,7 +1966,6 @@ <translation id="3968261067169026421">ネットワークを設定できませんでした</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">計算しています...</translation> -<translation id="3974195870082915331">クリックしてパスワードを表示する</translation> <translation id="3975222297214566386">入力オプションのふきだし</translation> <translation id="397703832102027365">最終処理中...</translation> <translation id="3979395879372752341">新しい拡張機能が追加されました(<ph name="EXTENSION_NAME" />)</translation> @@ -2012,6 +2007,7 @@ <translation id="4044612648082411741">証明書のパスワードを入力してください</translation> <translation id="404493185430269859">デフォルトの検索エンジン</translation> <translation id="4047112090469382184">デバイスが保護される仕組み</translation> +<translation id="4051049974203704184">画面上のアイテムの情報を取得</translation> <translation id="4052120076834320548">極小</translation> <translation id="4055023634561256217">デバイスを Powerwash でリセットするには再起動が必要です。</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2040,6 +2036,7 @@ <translation id="4088095054444612037">グループとの共有を許可する</translation> <translation id="4089235344645910861">設定が保存され、同期が始まりました。</translation> <translation id="4090103403438682346">確認済みのアクセスを有効にする</translation> +<translation id="4090947011087001172"><ph name="SITE" /> のサイト権限をリセットしますか?</translation> <translation id="4091434297613116013">枚</translation> <translation id="4093955363990068916">ローカル ファイル:</translation> <translation id="4095507791297118304">メイン ディスプレイ</translation> @@ -2216,7 +2213,6 @@ <translation id="4419556793104466535">同期、カスタマイズ、その他の管理</translation> <translation id="4421932782753506458">フワフワ</translation> <translation id="4422347585044846479">このページのブックマークを編集します</translation> -<translation id="4423104065312875417">追加の読み上げエンジンをインストールする</translation> <translation id="4423376891418188461">設定を元に戻す</translation> <translation id="4423482519432579560">スペルチェック(&S)</translation> <translation id="442397852638519243"><ph name="USER_NAME" /> さん、管理者がパスワードの変更をリクエストしています。</translation> @@ -2241,7 +2237,6 @@ <translation id="4449996769074858870">このタブは音声の再生中です。</translation> <translation id="4450974146388585462">診断</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> で検索するか、URL を入力してください</translation> -<translation id="445923051607553918">Wi-Fi ネットワークへの接続</translation> <translation id="4462159676511157176">カスタム ネーム サーバー</translation> <translation id="4467100756425880649">Chrome ウェブストア ギャラリー</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> を展開します</translation> @@ -2377,6 +2372,7 @@ <translation id="4682551433947286597">壁紙はログイン画面に表示されます。</translation> <translation id="4684427112815847243">すべてを同期する</translation> <translation id="4689421377817139245">このブックマークは iPhone と同期できます</translation> +<translation id="4690091457710545971"><Intel Wi-Fi ファームウェアにより生成された 4 つのファイル: csr.lst、fh_regs.lst、radio_reg.lst、monitor.lst.sysmon。最初の 3 つはレジスタダンプを含むバイナリ ファイルで、個人情報や端末を特定できる情報を一切含まないことが Intel により表明されています。最後の 1 つは Intel ファームウェアからの実行トレースで、個人情報や端末を特定できる情報は除かれていますが、サイズが大きいためここには表示できません。これらのファイルはご使用の端末で最近発生した Wi-Fi の問題への応答として生成されたもので、問題を調査するために Intel と共有されます。></translation> <translation id="4692302215262324251">この <ph name="DEVICE_TYPE" /> は組織の管理対象として登録されました。ドメイン: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />。 <ph name="LINE_BREAK_AND_EMPTY_LINE" /> この動作が想定外の場合は、サポートにお問い合わせください。</translation> @@ -2636,6 +2632,7 @@ <translation id="5074318175948309511">新しい設定を有効にするには、ページの再読み込みが必要な可能性があります。</translation> <translation id="5075131525758602494">SIM PIN を入力</translation> <translation id="5078638979202084724">すべてのタブをブックマークに追加する</translation> +<translation id="5079950360618752063">提案されたパスワードを使用</translation> <translation id="5084230410268011727">サイトによるモーション センサーと光センサーの使用を許可する</translation> <translation id="5085162214018721575">アップデートを確認しています</translation> <translation id="5086082738160935172">HID</translation> @@ -2674,6 +2671,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">このアイテムを削除</translation> <translation id="5139955368427980650">開く(&O)</translation> +<translation id="5142961317498132443">認証</translation> <translation id="5143374789336132547">拡張機能「<ph name="EXTENSION_NAME" />」により、ホームボタンをクリックしたときに表示されるページが変更されました。</translation> <translation id="5143712164865402236">全画面表示にする</translation> <translation id="5145331109270917438">更新日</translation> @@ -2844,7 +2842,6 @@ <translation id="5380103295189760361">Ctrl キー、Alt キー、Shift キー、検索キーを押すと、各キーのキーボード ショートカットが表示されます。</translation> <translation id="5382591305415226340">サポートされているリンクを管理</translation> <translation id="5384883051496921101">このサイトの情報がシークレット モードの外部のアプリに共有されようとしています。</translation> -<translation id="5388588172257446328">ユーザー名:</translation> <translation id="5388885445722491159">ペア設定済み</translation> <translation id="5389237414310520250">新しいユーザーを作成できませんでした。ハードドライブの空き容量と権限を確認し、もう一度お試しください。</translation> <translation id="5390100381392048184">音声の再生をサイトに許可する</translation> @@ -2969,7 +2966,6 @@ <translation id="5551573675707792127">キーボードとテキスト入力</translation> <translation id="5553089923092577885">証明書ポリシーのマッピング</translation> <translation id="5554489410841842733">このアイコンは、ページで拡張機能が使用できる場合に表示されます。</translation> -<translation id="5554573843028719904">他の Wi-Fi ネットワーク....</translation> <translation id="5554720593229208774">メール認証局</translation> <translation id="5556206011531515970">[次へ] をクリックして、既定のブラウザを選択してください。</translation> <translation id="5556459405103347317">再読み込み</translation> @@ -3010,7 +3006,6 @@ <translation id="5610038042047936818">カメラモードに切り替え</translation> <translation id="5612720917913232150"><ph name="URL" /> から、パソコンの現在地情報の使用許可を求められています</translation> <translation id="5612734644261457353">パスワードはまだ確認されていません。注: パスワードを最近変更した場合、新しいパスワードはログアウトした後に適用されます。こちらでは古いパスワードを使用してください。</translation> -<translation id="5613695965848159202">匿名 ID:</translation> <translation id="5614190747811328134">ユーザー通知</translation> <translation id="561698261642843490">Firefox を閉じる</translation> <translation id="5618075537869101857">キオスク アプリケーションを起動できませんでした。</translation> @@ -3228,7 +3223,6 @@ <translation id="5941343993301164315"><ph name="TOKEN_NAME" /> にログインしてください。</translation> <translation id="5941711191222866238">最小化</translation> <translation id="5946591249682680882">レポート ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">プライベート ネットワークを追加</translation> <translation id="5949544233750246342">ファイルを解析できません</translation> <translation id="5955282598396714173">パスワードの有効期限が切れています。パスワードを変更するには、いったんログアウトして再度ログインしてください。</translation> <translation id="5956585768868398362">この検索ページでよろしいですか?</translation> @@ -3389,11 +3383,13 @@ <translation id="6198102561359457428">ログアウトしてから再度ログイン...</translation> <translation id="6198252989419008588">PIN を変更</translation> <translation id="6199801702437275229">空き容量情報を待機中...</translation> +<translation id="6204015976622790023">画面上のアイテムに関連する、アシスタントからのおすすめ情報を確認できます。</translation> <translation id="6205710420833115353">一部の操作に予想より時間がかかっています。中止しますか?</translation> <translation id="6206311232642889873">画像をコピー(&Y)</translation> <translation id="6207200176136643843">リセットしてデフォルトのズームレベルに戻す</translation> <translation id="620722923698527029">このタイプのリンクは常に関連付けられたアプリで開く</translation> <translation id="6207937957461833379">国/地域</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: 同期が機能していません</translation> <translation id="6212039847102026977">ネットワークの詳細プロパティを表示</translation> <translation id="6212168817037875041">画面をオフにする</translation> <translation id="6212752530110374741">リンクをメールで送信</translation> @@ -3431,7 +3427,6 @@ <translation id="6263541650532042179">同期をリセット</translation> <translation id="6264365405983206840">すべて選択(&A)</translation> <translation id="6264422956566238156">同期を有効にしました</translation> -<translation id="6265930187414222160">有害なソフトウェアが削除されました。</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" /> での認証に使用する証明書を選択してください</translation> <translation id="6268252012308737255"><ph name="APP" /> で開く</translation> <translation id="6268747994388690914">HTML ファイルからブックマークをインポート...</translation> @@ -3538,7 +3533,6 @@ このまま <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> アカウントにログインするには [次へ] をクリックしてください。</translation> <translation id="6419546358665792306">パッケージ化されていない拡張機能を読み込む</translation> <translation id="642282551015776456">この名前はフォルダのファイル名として使用できません</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox 設定を開く</translation> <translation id="6429384232893414837">更新エラー</translation> <translation id="6430814529589430811">Base64 エンコード ASCII 形式の単一の証明書</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">Google によるあなたのウェブブラウザ</translation> <translation id="6545665334409411530">リピート回数 / 秒</translation> <translation id="6545834809683560467">予測サービスを使用して、アドレスバーまたはアプリ ランチャーの検索ボックスに入力した検索キーワードや URL を補完する</translation> -<translation id="6546686722964485737">WiMAX ネットワークへの接続</translation> <translation id="6547316139431024316">この拡張機能の警告を表示しない</translation> <translation id="6547354035488017500">端末の空き領域を 512 MB 以上確保してください。空き領域がこれより少なくなると、端末は応答しなくなります。空き領域を確保するために、端末のストレージからファイルを削除してください。</translation> <translation id="6549689063733911810">最近使用したアイテム</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Linux ファイルを表示できません</translation> <translation id="720110658997053098">この端末をキオスクモードに固定する</translation> <translation id="7201118060536064622">「<ph name="DELETED_ITEM_NAME" />」が削除されました</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> をダウンロードしています...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{ページを離れる}other{ページを離れる}}</translation> <translation id="7216409898977639127">モバイル プロバイダ</translation> @@ -4517,7 +4509,6 @@ <translation id="7909969815743704077">シークレット モードでダウンロード</translation> <translation id="7910768399700579500">新しいフォルダ(&N)</translation> <translation id="7912080627461681647">サーバーでパスワードが変更されました。いったんログアウトして再度ログインしてください。</translation> -<translation id="7912883689016444961">モバイル ネットワークを設定</translation> <translation id="7915471803647590281">フィードバックを送信する前に、問題の詳細を入力してください。</translation> <translation id="7916556741383518510">クリックされた場合のみ</translation> <translation id="792514962475806987">ドッキング画面のズームレベル:</translation> @@ -4571,7 +4562,6 @@ <translation id="7988355189918024273">ユーザー補助機能を有効にする</translation> <translation id="7994702968232966508">EAP 方式</translation> <translation id="799547531016638432">ショートカットを削除</translation> -<translation id="7997479212858899587">ID:</translation> <translation id="7997826902155442747">プロセスの優先値</translation> <translation id="7999229196265990314">次のファイルを作成しました: @@ -4655,7 +4645,6 @@ <translation id="8105368624971345109">オフにする</translation> <translation id="8106045200081704138">共有アイテム</translation> <translation id="8107015733319732394"><ph name="DEVICE_TYPE" /> に Google Play ストアをインストールしています。この処理には数分かかる可能性があります。</translation> -<translation id="8109930990200908494">ユーザ証明書にはログインが必要です。</translation> <translation id="8111155949205007504">このパスワードを iPhone と共有</translation> <translation id="8113043281354018522">ライセンスの種類を選択してください</translation> <translation id="8116190140324504026">詳細情報...</translation> @@ -4666,6 +4655,7 @@ <translation id="8118860139461251237">ダウンロードの管理</translation> <translation id="81238879832906896">黄色と白の花</translation> <translation id="8124313775439841391">管理対象 ONC</translation> +<translation id="8125562866093998907">サイトがアカウントのセキュリティ強化のためセキュリティ キーの確認を求めています。</translation> <translation id="813082847718468539">サイト情報を表示</translation> <translation id="8131740175452115882">確認</translation> <translation id="8133676275609324831">フォルダを開く(&S)</translation> @@ -4776,7 +4766,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> がカメラへのアクセスを必要としているときは確認画面を表示する</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">証明書がすでに存在します</translation> -<translation id="8309505303672555187">ネットワークの選択:</translation> <translation id="8312871300878166382">フォルダに貼り付け</translation> <translation id="8317671367883557781">ネットワーク接続を追加</translation> <translation id="8319414634934645341">拡張キーの用途</translation> @@ -4851,7 +4840,6 @@ <translation id="8451512073679317615">アシスタント</translation> <translation id="8452135315243592079">SIM カードがありません</translation> <translation id="8453482423012550001">$1 件の項目をコピーしています...</translation> -<translation id="8454288007744638700">または、新しいネットワークを選択:</translation> <translation id="845627346958584683">有効期限</translation> <translation id="8456681095658380701">名前が無効です</translation> <translation id="8457451314607652708">ブックマークをインポート</translation> @@ -4915,6 +4903,7 @@ <translation id="855081842937141170">タブを固定</translation> <translation id="8551388862522347954">ライセンス</translation> <translation id="8553342806078037065">他のユーザーを管理</translation> +<translation id="8554899698005018844">言語設定なし</translation> <translation id="855773602626431402">このページでのサンドボックスの無効化プラグインの実行がブロックされました。</translation> <translation id="8557930019681227453">マニフェスト</translation> <translation id="8559694214572302298">イメージ デコーダー</translation> @@ -4952,7 +4941,6 @@ <translation id="862727964348362408">停止中</translation> <translation id="862750493060684461">CSS キャッシュ</translation> <translation id="8627795981664801467">セキュリティで保護された接続のみ</translation> -<translation id="8628085465172583869">サーバー ホスト名</translation> <translation id="8630903300770275248">監視対象ユーザーをインポート</translation> <translation id="8631032106121706562">デイジー</translation> <translation id="8637542770513281060">ご使用のパソコンにはセキュア モジュールが組み込まれています。これは Chrome OS の多くの重要なセキュリティ機能を実装するために使用されます。詳しくは Chromebook ヘルプセンター(https://support.google.com/chromebook/?p=sm)をご覧ください。</translation> @@ -5208,7 +5196,6 @@ <translation id="899403249577094719">Netscape 証明書基本 URL</translation> <translation id="8995603266996330174">管理ドメイン: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">アカウントを追加...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />](<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">ディスク イメージを作成しています。</translation> <translation id="9003647077635673607">すべてのウェブサイトで許可する</translation> <translation id="9003677638446136377">もう一度確認</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb index d4cae84..af99abd 100644 --- a/chrome/app/resources/generated_resources_kn.xtb +++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">ಬಹುತೇಕ ವಿರಾಮದ ಸಮಯ</translation> <translation id="1062407476771304334">ಸ್ಥಾನಾಂತರಿಸು</translation> -<translation id="1064835277883315402">ಖಾಸಗಿ ನೆಟ್ವರ್ಕ್ಗೆ ಸೇರ್ಪಡೆಗೊಳ್ಳಿ</translation> <translation id="1064912851688322329">ನಿಮ್ಮ Google ಖಾತೆಯನ್ನು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿ</translation> <translation id="1067048845568873861">ರಚಿಸಲಾಗಿದೆ</translation> <translation id="1067291318998134776">Linux (ಬೀಟಾ)</translation> @@ -223,7 +222,6 @@ <translation id="1316136264406804862">ಹುಡುಕಲಾಗುತ್ತಿದೆ...</translation> <translation id="1316495628809031177">ಸಿಂಕ್ ಅನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ</translation> <translation id="1319979322914001937">Chrome ವೆಬ್ ಅಂಗಡಿಯಿಂದ ವಿಸ್ತರಣೆಗಳ ಫಿಲ್ಟರ್ ಮಾಡಲಾದ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸುವ ಅಪ್ಲಿಕೇಶನ್. ಪಟ್ಟಿಯಲ್ಲಿರುವ ವಿಸ್ತರಣೆಗಳನ್ನು ಅಪ್ಲಿಕೇಶನ್ನಿಂದ ನೇರವಾಗಿ ಸ್ಥಾಪಿಸಬಹುದು.</translation> -<translation id="132090119144658135">ವಿಷಯದ ಹೊಂದಾಣಿಕೆ:</translation> <translation id="1326317727527857210">ನಿಮ್ಮ ಇತರ ಸಾಧನಗಳಿಂದ ನಿಮ್ಮ ಟ್ಯಾಬ್ಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಲು, Chrome ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ.</translation> <translation id="1327074568633507428">Google ಮೇಘ ಮುದ್ರಣದಲ್ಲಿ ಮುದ್ರಕ</translation> <translation id="1327977588028644528">ಗೇಟ್ವೇ</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">ಅಪ್ಲಿಕೇಶನ್ ವಿಂಡೋ</translation> <translation id="1534389735079119190">ದೋಷ: VM ನ ಒಳಗಿರುವ ಕಂಟೇನರ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ.</translation> <translation id="15373452373711364">ದೊಡ್ಡ ಮೌಸ್ ಕರ್ಸರ್</translation> +<translation id="1540605929960647700">ಡೆಮೊ ಮೋಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation> <translation id="1543284117603151572">Edge ನಿಂದ ಆಮದು ಮಾಡಿಕೊಳ್ಳಲಾಗಿದೆ</translation> <translation id="1545177026077493356">ಸ್ವಯಂಚಾಲಿತ ಕಿಯೋಸ್ಕ್ ಮೋಡ್</translation> <translation id="1545775234664667895">ಸ್ಥಾಪಿಸಲಾಗಿರುವ ಥೀಮ್ "<ph name="THEME_NAME" />"</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">Google ಗೆ ಬಳಕೆಯ ಅಂಕಿಅಂಶಗಳು ಮತ್ತು ಕ್ರ್ಯಾಶ್ ವರದಿಯನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕಳುಹಿಸುವ ಮೂಲಕ <ph name="PRODUCT_NAME" /> ಅನ್ನು ಉತ್ತಮಗೊಳಿಸಲು ಸಹಾಯ ಮಾಡಿ</translation> <translation id="1658424621194652532">ಈ ಪುಟವು ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಪ್ರವೇಶಿಸುತ್ತಿದೆ.</translation> <translation id="1660204651932907780">ಧ್ವನಿಯನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿಸಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ)</translation> +<translation id="1660938185063657230">ನಿಮ್ಮ ಸುರಕ್ಷತಾ ಕೀಯನ್ನು ಪರಿಶೀಲಿಸಿ</translation> <translation id="1661156625580498328">AES ಎನ್ಕ್ರಿಪ್ಶನ್ ಅನ್ನು ಜಾರಿಗೊಳಿಸಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ).</translation> <translation id="1661245713600520330">ಮುಖ್ಯ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ ಲೋಡ್ ಮಾಡಲಾದ ಎಲ್ಲ ಮಾಡ್ಯೂಲ್ಗಳು ಮತ್ತು ನಂತರದ ಸ್ಥಿತಿಯಲ್ಲಿ ಲೋಡ್ ಮಾಡಲು ನೋಂದಾಯಿಸಲಾದ ಮಾಡ್ಯೂಲ್ಗಳನ್ನು ಈ ಪುಟವು ಪಟ್ಟಿಮಾಡುತ್ತದೆ.</translation> <translation id="166179487779922818">ಪಾಸ್ವರ್ಡ್ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">ಕ್ಲಿಪ್ಬೋರ್ಡ್ಗೆ ನಕಲಿಸಿರುವ ಪಠ್ಯ ಮತ್ತು ಚಿತ್ರಗಳನ್ನು ನೋಡಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿ ನೀಡಬೇಡಿ</translation> <translation id="1682548588986054654">ಹೊಸ ಅದೃಶ್ಯ ವಿಂಡೋ</translation> <translation id="168715261339224929">ನಿಮ್ಮ ಎಲ್ಲ ಸಾಧನಗಳಲ್ಲಿ ನಿಮ್ಮ ಬುಕ್ಮಾರ್ಕ್ಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಲು, ಸಿಂಕ್ ಆನ್ ಮಾಡಿ.</translation> +<translation id="1688867105868176567">ಸೈಟ್ ಡೇಟಾವನ್ನು ತೆರವುಗೊಳಿಸಬೇಕೇ?</translation> <translation id="1688935057616748272">ಅಕ್ಷರವನ್ನು ಟೈಪ್ ಮಾಡಿ</translation> <translation id="168991973552362966">ಸಮೀಪದಲ್ಲಿರುವ ಪ್ರಿಂಟರ್ ಸೇರಿಸಿ</translation> <translation id="1689945336726856614">&URL ನಕಲಿಸಿ</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">ಈ ವ್ಯಕ್ತಿಯನ್ನು ತೆಗೆದುಹಾಕು</translation> <translation id="1706586824377653884">ನಿಮ್ಮ ನಿರ್ವಾಹಕರ ಮೂಲಕ ಸೇರಿಸಲಾಗಿದೆ</translation> <translation id="1706625117072057435">ಝೂಮ್ ಹಂತಗಳು</translation> -<translation id="1707463636381878959">ಇತರೆ ಬಳಕೆದಾರರೊಂದಿಗೆ ಈ ನೆಟ್ವರ್ಕ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಿ</translation> <translation id="1708338024780164500">(ಸಕ್ರಿಯವಲ್ಲದ)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (ಸ್ಥಳೀಯ)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">ಥೀಮ್ ಸಕ್ರಿಯಗೊಳಿಸು</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome ವೆಬ್ ಸ್ಟೋರ್ನಲ್ಲಿ ವೀಕ್ಷಿಸಿ</translation> -<translation id="1758831820837444715">ಎಥರ್ನೆಟ್ ನೆಟ್ವರ್ಕ್ ಕಾನ್ಫಿಗರ್ ಮಾಡಿ</translation> <translation id="1763046204212875858">ಅಪ್ಲಿಕೇಶನ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ರಚಿಸಿ</translation> <translation id="1763108912552529023">ಅನ್ವೇಷಣೆ ಮುಂದುವರಿಸು</translation> <translation id="1763808908432309942">ಹೊಸ ಟ್ಯಾಬ್ನಲ್ಲಿ ತೆರೆಯುತ್ತದೆ</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">ಈ ಫೈಲ್ ಹಂಚಿಕೆಯಾಗಿರುವ ಬಗೆಯನ್ನು ಬದಲಾಯಿಸಿ</translation> <translation id="1841545962859478868">ಸಾಧನದ ನಿರ್ವಾಹಕರು ಕೆಳಗಿನದನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> ಅವರನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation> +<translation id="1842766183094193446">ನೀವು ಖಚಿತವಾಗಿಯೂ ಡೆಮೊ ಮೋಡ್ ಸಕ್ರಿಯಗೊಳಿಸಲು ಬಯಸುತ್ತೀರಾ?</translation> <translation id="1844692022597038441">ಈ ಫೈಲ್ ಆಫ್ಲೈನ್ನಲ್ಲಿ ಲಭ್ಯವಿಲ್ಲ.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" /> ಅನ್ನು ರನ್ ಮಾಡಲು ಕಂಟ್ರೋಲ್-ಕ್ಲಿಕ್ ಮಾಡಿ</translation> +<translation id="1847880352285315359">ಉಳಿಸಲಾಗಿದೆ</translation> <translation id="1848219224579402567">ಲಿಡ್ ಅನ್ನು ಮುಚ್ಚಿದಾಗ ಸೈನ್ ಔಟ್ ಮಾಡಿ</translation> <translation id="184823282865851239">ಈ ಸೈಟ್ ಸಾಮಾನ್ಯವಾಗಿ ಅತಿಕ್ರಮಣಕಾರಿಯಾಗಿರುವ ಜಾಹೀರಾತುಗಳನ್ನು ತೋರಿಸುತ್ತದೆ ಎಂದಾದರೆ, ಅದನ್ನು ನಿರ್ಬಂಧಿಸಿ</translation> <translation id="1849186935225320012">ಈ ಪುಟಕ್ಕೆ MIDI ಸಾಧನಗಳ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವಿದೆ.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">ನೀವು ಯಾವಾಗಲೂ ಇದನ್ನು ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ನಂತರ ಬದಲಾಯಿಸಬಹುದು</translation> <translation id="2006638907958895361">ಲಿಂಕ್ ಅನ್ನು <ph name="APP" /> ನಲ್ಲಿ ತೆರೆಯಿರಿ</translation> <translation id="2007404777272201486">ಸಮಸ್ಯೆ ವರದಿಮಾಡಿ...</translation> +<translation id="2016237810978710652">Linux ಫೈಲ್ಗಳನ್ನು ತೆರೆಯಲಾಗುತ್ತಿದೆ...</translation> <translation id="2016430552235416146">ಸಾಂಪ್ರದಾಯಿಕ</translation> <translation id="2017334798163366053">ಕಾರ್ಯಕ್ಷಮತೆ ಡೇಟಾ ಸಂಗ್ರಹಣೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation> <translation id="2017836877785168846">ಇತಿಹಾಸವನ್ನು ತೆರವುಗೊಳಿಸಿ ಮತ್ತು ವಿಳಾಸಪಟ್ಟಿಯಲ್ಲಿರುವುದನ್ನು ಸ್ವಯಂಪೂರ್ಣಗೊಳಿಸಿ.</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">ಕಾರ್ಡ್ ಎಡಿಟ್ ಮಾಡಿ</translation> <translation id="2154710561487035718">URL ನಕಲಿಸಿ</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> ನಂತೆ ತೋರುತ್ತಿದೆ</translation> +<translation id="2156283799932971644">ಸಿಸ್ಟಂ ಕುರಿತು ಕೆಲವೊಂದು ಮಾಹಿತಿಯನ್ನು ಮತ್ತು ಪುಟದ ವಿಷಯವನ್ನು Google ಗೆ ಕಳುಹಿಸುವ ಮೂಲಕ, ಸುರಕ್ಷಿತ ಬ್ರೌಸಿಂಗ್ ಅನ್ನು ಸುಧಾರಿಸಲು ನೀವು ಸಹಾಯ ಮಾಡಬಹುದು.</translation> <translation id="215753907730220065">ಪೂರ್ಣಪರದೆಯಿಂದ ನಿರ್ಗಮಿಸಿ</translation> <translation id="2157875535253991059">ಈ ಪುಟವು ಇದೀಗ ಪೂರ್ಣ ಪರದೆಯಾಗಿದೆ.</translation> <translation id="216169395504480358">ವೈ-ಫೈ ಸೇರಿಸಿ...</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">ಈ ಸಾಧನಕ್ಕೆ ನಿಯೋಜನ ಐಡಿ ಅನ್ನು ಸೇರಿಸಿ</translation> <translation id="2175042898143291048">ಯಾವಾಗಲೂ ಹೀಗೆ ಮಾಡಿ</translation> <translation id="2175607476662778685">ಶೀಘ್ರ ಆರಂಭಗೊಳ್ಳುವ ಬಾರ್</translation> +<translation id="2176087259161165020">ಇತರ ಮೂಲಗಳು</translation> <translation id="2177950615300672361">ಅದೃಶ್ಯ ಟ್ಯಾಬ್: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> ನಲ್ಲಿ ಇರುವ <ph name="PEPPER_PLUGIN_DOMAIN" />, ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ಗೆ ಪ್ರವೇಶಿಸಲು ಬಯಸುತ್ತದೆ</translation> <translation id="2178614541317717477">CA ಹೊಂದಾಣಿಕೆ</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">ಮುಂದಿನ ಟ್ಯಾಬ್</translation> <translation id="2292848386125228270">ದಯವಿಟ್ಟು <ph name="PRODUCT_NAME" /> ಅನ್ನು ಸಾಮಾನ್ಯ ಬಳಕೆದಾರನಂತೆ ಪ್ರಾರಂಭಿಸಿ. ನಿಮಗೆ ಅಭಿವೃದ್ಧಿಗೆ ಮೂಲದಂತೆ ಚಾಲನೆಯ ಅಗತ್ಯವಿದ್ದರೆ, --no- ಸ್ಯಾಂಡ್ಬಾಕ್ಸ್ ಫ್ಲ್ಯಾಗ್ ಜೊತೆಗೆ ಮರುಚಾಲನೆ ಮಾಡಿ.</translation> <translation id="2294358108254308676">ನೀವು <ph name="PRODUCT_NAME" /> ಅನ್ನು ಸ್ಥಾಪಿಸಲು ಬಯಸುತ್ತೀರಾ?</translation> -<translation id="2296019197782308739">EAP ವಿಧಾನ:</translation> <translation id="2297705863329999812">ಪ್ರಿಂಟರ್ಗಳನ್ನು ಹುಡುಕಿ</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> ಅನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ</translation> <translation id="2301382460326681002">ವಿಸ್ತರಣೆ ಮೂಲ ಡೈರೆಕ್ಟರಿ ಅಮಾನ್ಯವಾಗಿದೆ.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">ದೋಷ: <ph name="APP_NAME" /> ಅನ್ನು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ.</translation> <translation id="2367199180085172140">ಫೈಲ್ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಸೇರಿಸಿ</translation> <translation id="2367972762794486313">ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ತೋರಿಸು</translation> +<translation id="2369536625682139252">ಕುಕೀಗಳನ್ನು ಹೊರತುಪಡಿಸಿ, <ph name="SITE" /> ಸಂಗ್ರಹಣೆ ಮಾಡಿರುವ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುವುದು.</translation> <translation id="2371076942591664043">&ಮುಗಿಸಿದಾಗ ತೆರೆಯಿರಿ</translation> <translation id="2377319039870049694">ಪಟ್ಟಿ ವೀಕ್ಷಣೆಗೆ ಬದಲಾಯಿಸಿ</translation> <translation id="2377667304966270281">ಹಾರ್ಡ್ ಫಾಲ್ಟ್ಸ್</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">ಸಿಸ್ಟಂ ಸಂವಾದವನ್ನು ಬಳಸಿ ಮುದ್ರಿಸಿ... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">ಕಳುಹಿಸುವ ಮೊದಲು ಕೇಳಿ (ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ)</translation> <translation id="2384436799579181135">ದೋಷ ಸಂಭವಿಸಿದೆ. ನಿಮ್ಮ ಪ್ರಿಂಟರ್ ಪರಿಶೀಲಿಸಿ ಮತ್ತು ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.</translation> -<translation id="2385700042425247848">ಸೇವೆಯ ಹೆಸರು:</translation> <translation id="2387458720915042159">ಪ್ರಾಕ್ಸಿ ಪ್ರಕಾರ ಸಂಪರ್ಕ</translation> <translation id="2391419135980381625">ರೂಢಿಯಲ್ಲಿರುವ ಫಾಂಟ್</translation> <translation id="2391762656119864333">ಹಿಂತೆಗೆದುಕೊ</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">ಆಡಿಯೊ ಹಂಚಿಕೊಳ್ಳಿ</translation> <translation id="2480868415629598489">ನೀವು ನಕಲಿಸಿದ ಮತ್ತು ಅಂಟಿಸಿದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಿ</translation> <translation id="2482878487686419369">ಸೂಚನೆಗಳು</translation> -<translation id="2485056306054380289">ಸರ್ವರ್ CA ಪ್ರಮಾಣಪತ್ರ:</translation> <translation id="2485422356828889247">ಅಸ್ಥಾಪಿಸು</translation> <translation id="2487067538648443797">ಹೊಸ ಬುಕ್ಮಾರ್ಕ್ ಸೇರಿಸಿ</translation> <translation id="248861575772995840">ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಪತ್ತೆ ಮಾಡಲಾಗಲಿಲ್ಲ. ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಸಾಧನಗಳಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ. <a>ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">ಹೊಸದರಂತೆ ಮಾಡುವುದಕ್ಕಾಗಿ ನಿಮ್ಮ <ph name="IDS_SHORT_PRODUCT_NAME" /> ಸಾಧನವನ್ನು ಮರುಹೊಂದಿಸಲು ಪವರ್ವಾಶ್ ಮಾಡಿ.</translation> <translation id="2567257616420533738">ಪಾಸ್ವರ್ಡ್ ಉಳಿಸಲಾಗಿದೆ. ಉಳಿಸಿದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು <ph name="SAVED_PASSWORDS_LINK" /> ನಲ್ಲಿ ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ</translation> <translation id="2568774940984945469">ಮಾಹಿತಿಪಟ್ಟಿಯ ಕಂಟೇನರ್</translation> +<translation id="2570454805927264159">ನಿಮ್ಮ ಅಸಿಸ್ಟೆಂಟ್ನಿಂದ ಹೆಚ್ಚಿನ ಪ್ರಯೋಜನ ಪಡೆಯಿರಿ</translation> <translation id="257088987046510401">ಥೀಮ್ಗಳು</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> ಗೆ ಓದಲು-ಮಾತ್ರ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ.</translation> <translation id="2573269395582837871">ಚಿತ್ರ ಮತ್ತು ಹೆಸರನ್ನು ಆಯ್ಕೆಮಾಡಿ</translation> @@ -1096,7 +1099,6 @@ <translation id="2653659639078652383">ಸಲ್ಲಿಸು</translation> <translation id="265390580714150011">ಕ್ಷೇತ್ರ ಮೌಲ್ಯ</translation> <translation id="2654166010170466751">ಪಾವತಿ ಹ್ಯಾಂಡ್ಲರ್ಗಳನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಸೈಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಅನುಮತಿಸಿ</translation> -<translation id="2655386581175833247">ಬಳಕೆದಾರ ಪ್ರಮಾಣಪತ್ರ:</translation> <translation id="2660779039299703961">ಈವೆಂಟ್</translation> <translation id="266079277508604648">ಪ್ರಿಂಟರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪ್ರಿಂಟರ್ ಆನ್ ಆಗಿದೆಯೇ ಮತ್ತು ಅದು ನಿಮ್ಮ Chromebook ಗೆ ವೈ-ಫೈ ಅಥವಾ USB ಮೂಲಕ ಸಂಪರ್ಕ ಹೊಂದಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1329,6 +1331,7 @@ <translation id="3006881078666935414">ಯಾವುದೇ ಬಳಕೆ ಡೇಟಾ ಇಲ್ಲ</translation> <translation id="3007214526293698309">ಅನುಪಾತ ಹೊಂದಿಸು</translation> <translation id="3007771295016901659">ನಕಲಿ ಟ್ಯಾಬ್</translation> +<translation id="3008272652534848354">ಅನುಮತಿಗಳನ್ನು ಮರುಹೊಂದಿಸಿ</translation> <translation id="3009300415590184725">ಮೊಬೈಲ್ ಡೇಟಾ ಸೇವೆಯ ಪ್ರಕ್ರಿಯೆಯನ್ನು ರದ್ದುಗೊಳಿಸಲು ನೀವು ಖಚಿತವಾಗಿ ಬಯಸುವಿರಾ?</translation> <translation id="3009779501245596802">ಸೂಚ್ಯಂಕಗೊಳಿಸಿದ ಡೇಟಾಬೇಸ್ಗಳು</translation> <translation id="3010279545267083280">ಪಾಸ್ವರ್ಡ್ ಅಳಿಸಲಾಗಿದೆ</translation> @@ -1395,7 +1398,6 @@ <translation id="3100609564180505575">ಮಾಡ್ಯೂಲ್ಗಳು (<ph name="TOTAL_COUNT" />) - ತಿಳಿದ ಘರ್ಷಣೆಗಳು: <ph name="BAD_COUNT" />, ನಿರೀಕ್ಷಿಸಿದ್ದು: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">ದಿನಾಂಕ ಮತ್ತು ಸಮಯ</translation> <translation id="310671807099593501">ಬ್ಲೂಟೂತ್ ಅನ್ನು ಸೈಟ್ ಬಳಸುತ್ತಿದೆ</translation> -<translation id="3108967419958202225">ಆರಿಸಿ...</translation> <translation id="3115128645424181617">ನಿಮ್ಮ ಫೋನ್ ಹುಡುಕಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದು ಸುಲಭವಾಗಿ ಲಭ್ಯವಿರುತ್ತದೆಯೇ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಕೊಳ್ಳಿ.</translation> <translation id="3115147772012638511">ಕ್ಯಾಶ್ಗಾಗಿ ನಿರೀಕ್ಷಿಸುತ್ತಿದೆ...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> ಸಹಾಯ</translation> @@ -1440,7 +1442,6 @@ <translation id="3165390001037658081">ಕೆಲವು ವಾಹಕಗಳು ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ನಿರ್ಬಂಧಿಸಬಹುದು.</translation> <translation id="316854673539778496">ನಿಮ್ಮ ಎಲ್ಲಾ ಸಾಧನಗಳಲ್ಲಿ ನಿಮ್ಮ ಎಲ್ಲಾ ವಿಸ್ತರಣೆಗಳನ್ನು ಪಡೆಯಲು, ಸೈನ್ ಇನ್ ಮಾಡಿ ಮತ್ತು ಸಿಂಕ್ ಆನ್ ಮಾಡಿ.</translation> <translation id="3170072451822350649">ನೀವು ಸೈನ್ ಇನ್ ಮಾಡುವುದನ್ನು ಸ್ಕಿಪ್ ಮಾಡಬಹುದು ಹಾಗೂ <ph name="LINK_START" />ಅತಿಥಿಯಾಗಿ ಬ್ರೌಸ್ ಮಾಡಬಹುದು<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">ಪಾಸ್ವರ್ಡ್ ಮರೆಮಾಡಲು ಕ್ಲಿಕ್ ಮಾಡಿ</translation> <translation id="3177909033752230686">ಪುಟದ ಭಾಷೆ:</translation> <translation id="3181110748548073003">ಮುಂದಕ್ಕೆ ಹೋಗಲು |<ph name="SHORTCUT" />| ಒತ್ತಿರಿ</translation> <translation id="3182749001423093222">ಕಾಗುಣಿತ ಪರಿಶೀಲನೆ</translation> @@ -1471,7 +1472,6 @@ <translation id="3236289833370040187"><ph name="DESTINATION_DOMAIN" /> ಗೆ ಮಾಲೀಕತ್ವವನ್ನು ವರ್ಗಾಯಿಸಲಾಗವುದು.</translation> <translation id="323803881985677942">ವಿಸ್ತರಣೆ ಆಯ್ಕೆಗಳನ್ನು ತೆರೆಯಿರಿ</translation> <translation id="3241680850019875542">ಪ್ಯಾಕ್ ಮಾಡಲು ವಿಸ್ತರಣೆಯ ಮೂಲ ಡೈರೆಕ್ಟರಿಯನ್ನು ಆಯ್ಕೆಮಾಡಿ. ವಿಸ್ತರಣೆಯನ್ನು ನವೀಕರಿಸಲು, ಮರುಬಳಸಲು ಖಾಸಗಿ ಕೀ ಫೈಲ್ ಅನ್ನು ಕೂಡ ಆಯ್ಕೆಮಾಡಿ.</translation> -<translation id="3242765319725186192">ಪೂರ್ವ-ಹಂಚಿಕೆಯ ಕೀಲಿ:</translation> <translation id="3244294424315804309">ಧ್ವನಿ ಮ್ಯೂಟ್ ಮಾಡುವುದನ್ನು ಮುಂದುವರಿಸಿ</translation> <translation id="3245321423178950146">ಅಪರಿಚಿತ ಕಲಾವಿದ</translation> <translation id="3246097286174000800">Smart Lock ಪ್ರಯತ್ನಿಸಿ</translation> @@ -1604,7 +1604,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> ಗಾಗಿ ಇನ್ನಷ್ಟು ಕ್ರಿಯೆಗಳು</translation> <translation id="3440761377721825626">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಪ್ರವೇಶಿಸಲು ಸೈಟ್ ಪ್ಲಗ್ ಇನ್ ಬಳಸಲು ಬಯಸಿದಾಗ ಕೇಳಿ</translation> <translation id="3441653493275994384">ಸ್ಕ್ರೀನ್</translation> -<translation id="3445830502289589282">2ನೇ ಹಂತದ ಪ್ರಮಾಣೀಕರಣ:</translation> <translation id="344630545793878684">ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಹಲವಾರು ವೆಬ್ಸೈಟ್ಗಳಲ್ಲಿ ಓದಿ</translation> <translation id="3449839693241009168"><ph name="EXTENSION_NAME" /> ಗೆ ಆದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು <ph name="SEARCH_KEY" /> ಒತ್ತಿರಿ</translation> <translation id="3450157232394774192">ತಟಸ್ಥ ಸ್ಥಿತಿಯ ನೆಲೆಸುವಿಕೆ ಪ್ರತಿಶತ</translation> @@ -1645,7 +1644,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> ದೋಷಗಳು.</translation> <translation id="3495660573538963482">Google ಸಹಾಯಕ ಸೆಟ್ಟಿಂಗ್ಗಳು</translation> <translation id="3496213124478423963">ಝೂಮ್ ಔಟ್</translation> -<translation id="3504135463003295723">ಗುಂಪು ಹೆಸರು:</translation> <translation id="3505030558724226696">ಸಾಧನ ಪ್ರವೇಶವನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" ಗೆ ಪ್ರಸ್ತುತ ಅನುಮತಿಗಳು</translation> <translation id="3507547268929739059">Chromebook ನಿಂದ Linux ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಿ</translation> @@ -1754,7 +1752,6 @@ <translation id="3661054927247347545">ಸೈನ್ ಇನ್ ಪ್ರಮಾಣೀಕರಣವು ಮಾನ್ಯವಾಗಿಲ್ಲ, <ph name="MINUTES" /> ನಿಮಿಷಗಳಲ್ಲಿ ವಿಂಡೋ ಮುಚ್ಚವುದು : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">ವಿಸ್ತರಣೆ ಐಕಾನ್</translation> <translation id="3665589677786828986">ನಿಮ್ಮ ಕೆಲವು ಸೆಟ್ಟಿಂಗ್ಗಳು ಬೇರೊಂದು ಪ್ರೋಗ್ರಾಂನಿಂದಾಗಿ ಹಾನಿಗೊಳಗಾಗಿರುವುದು Chrome ಗಮನಕ್ಕೆ ಬಂದಿದೆ ಮತ್ತು ಅವುಗಳ ಮೂಲ ಡೀಫಾಲ್ಟ್ಗಳಿಗೆ ಅವುಗಳನ್ನು ಮರುಹೊಂದಿಸಿದೆ.</translation> -<translation id="3665842570601375360">ಭದ್ರತೆ:</translation> <translation id="3668570675727296296">ಭಾಷೆಯ ಸೆಟ್ಟಿಂಗ್ಗಳು</translation> <translation id="3668823961463113931">ಹ್ಯಾಂಡ್ಲರ್ಗಳು</translation> <translation id="3670229581627177274">ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಿ</translation> @@ -1793,7 +1790,6 @@ <translation id="3726463242007121105">ಇದರ ಫೈಲ್ಸಿಸ್ಟಂ ಅನ್ನು ಬೆಂಬಲಿಸದ ಕಾರಣ ಈ ಸಾಧನವನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ.</translation> <translation id="3727148787322499904">ಈ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಬದಲಾಯಿಸುವುದರಿಂದ ಎಲ್ಲಾ ಹಂಚಿತ ನೆಟ್ವರ್ಕ್ಗಳಿಗೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ</translation> <translation id="3727187387656390258">ಪಾಪ್ಅಪ್ ಪರೀಕ್ಷಿಸಿ</translation> -<translation id="3728067901555601989">OTP: </translation> <translation id="3732078975418297900"><ph name="ERROR_LINE" /> ನೇ ಸಾಲಿನಲ್ಲಿ ದೋಷವಿದೆ</translation> <translation id="3733127536501031542">ಹೆಚ್ಚುವಿಕೆಯೊಂದಿಗೆ SSL ಸರ್ವರ್</translation> <translation id="3737536731758327622">ನಿಮ್ಮ ಡೌನ್ಲೋಡ್ಗಳು ಇಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ</translation> @@ -1868,7 +1864,6 @@ <translation id="38275787300541712">ಮುಗಿಸಿದಾಗ ನಮೂದನೆಯನ್ನು ಒತ್ತಿರಿ</translation> <translation id="3827774300009121996">&ಪೂರ್ಣ ಪರದೆ</translation> <translation id="3828029223314399057">ಬುಕ್ಮಾರ್ಕ್ಗಳನ್ನು ಹುಡುಕಿ</translation> -<translation id="3829932584934971895">ಪೂರೈಕೆದಾರರ ಪ್ರಕಾರ:</translation> <translation id="3830674330436234648">ಯಾವುದೇ ಪ್ಲೇಬ್ಯಾಕ್ ಲಭ್ಯವಿಲ್ಲ</translation> <translation id="3831486154586836914">ವಿಂಡೊ ಅವಲೋಕನ ಮೋಡ್ಗೆ ಪ್ರವೇಶಿಸಲಾಗಿದೆ</translation> <translation id="383161972796689579">ಈ ಸಾಧನದ ಮಾಲೀಕರು ಸೇರಿಸುವ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ</translation> @@ -1889,6 +1884,7 @@ <translation id="3856921555429624101">ಡೇಟಾ ಬಳಕೆಯ ಮಾಪನ ಮುಕ್ತಾಯಗೊಂಡಿದೆ</translation> <translation id="3857228364945137633">ನಿಮ್ಮ ಫೋನ್ ಸಮೀಪದಲ್ಲಿರುವಾಗ ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಸಾಧನವನ್ನು ಪಾಸ್ವರ್ಡ್ ಇಲ್ಲದೆಯೇ ಅನ್ಲಾಕ್ ಮಾಡಲು Smart Lock ಅನ್ನು ಪ್ರಯತ್ನಿಸಿ.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: ಸಿಂಕ್ ಮಾಡುವುದನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ</translation> <translation id="3860381078714302691">Hangouts ಸಭೆಗೆ ಸುಸ್ವಾಗತ</translation> <translation id="3862134173397075045">Chrome ನಲ್ಲಿನ ಬಿತ್ತರಿಸು ಅನುಭವಕ್ಕೆ ಸುಸ್ವಾಗತ!</translation> <translation id="3862788408946266506">ChromeOS ಕಿಯೋಸ್ಕ್ ಮೋಡ್ನಲ್ಲಿ 'kiosk_only' ಮ್ಯಾನಿಫೆಸ್ಟ್ ಲಕ್ಷಣವನ್ನು ಹೊಂದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿರಬೇಕು</translation> @@ -1966,7 +1962,6 @@ <translation id="3968261067169026421">ನೆಟ್ವರ್ಕ್ ಹೊಂದಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</translation> <translation id="3970114302595058915">ಐಡಿ</translation> <translation id="397105322502079400">ಎಣಿಸಲಾಗುತ್ತಿದೆ...</translation> -<translation id="3974195870082915331">ಪಾಸ್ವರ್ಡ್ ತೋರಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ</translation> <translation id="3975222297214566386">ಇನ್ಪುಟ್ ಆಯ್ಕೆಗಳ ಬಬಲ್</translation> <translation id="397703832102027365">ಅಂತಿಮಗೊಳಿಸಲಾಗುತ್ತಿದೆ...</translation> <translation id="3979395879372752341">ಹೊಸ ವಿಸ್ತರಣೆಯನ್ನು ಸೇರಿಸಲಾಗಿದೆ (<ph name="EXTENSION_NAME" />)</translation> @@ -2008,6 +2003,7 @@ <translation id="4044612648082411741">ನಿಮ್ಮ ಪ್ರಮಾಣಪತ್ರ ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ</translation> <translation id="404493185430269859">ಡೀಫಾಲ್ಟ್ ಹುಡುಕಾಟ ಎಂಜಿನ್</translation> <translation id="4047112090469382184">ಇದು ಹೇಗೆ ಸುರಕ್ಷಿತವಾಗಿದೆ</translation> +<translation id="4051049974203704184">ಪರದೆಯಲ್ಲಿ ಏನಿದೆ ಎಂಬ ಕುರಿತು ಮಾಹಿತಿ ಪಡೆದುಕೊಳ್ಳಿ</translation> <translation id="4052120076834320548">ಚಿಕ್ಕದು</translation> <translation id="4055023634561256217">ಪವರ್ವಾಶ್ನೊಂದಿಗೆ ನಿಮ್ಮ ಸಾಧನವನ್ನು ಮರುಹೊಂದಿಸುವ ಮೊದಲು ಮರುಪ್ರಾರಂಭಿಸುವ ಅಗತ್ಯವಿದೆ.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2036,6 +2032,7 @@ <translation id="4088095054444612037">ಗುಂಪಿಗಾಗಿ ಸ್ವೀಕರಿಸು</translation> <translation id="4089235344645910861">ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಉಳಿಸಲಾಗಿದೆ. ಸಿಂಕ್ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ.</translation> <translation id="4090103403438682346">ಪರಿಶೀಲಿಸಿದ ಪ್ರವೇಶವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation> +<translation id="4090947011087001172"><ph name="SITE" /> ಗಾಗಿ ಸೈಟ್ ಅನುಮತಿಗಳನ್ನು ಮರುಹೊಂದಿಸುವುದೇ?</translation> <translation id="4091434297613116013">ಕಾಗದದ ಹಾಳೆಗಳು</translation> <translation id="4093955363990068916">ಸ್ಥಳೀಯ ಫೈಲ್:</translation> <translation id="4095507791297118304">ಪ್ರಾಥಮಿಕ ಪ್ರದರ್ಶನ</translation> @@ -2069,7 +2066,7 @@ <translation id="4146026355784316281">ಯಾವಾಗಲೂ ಸಿಸ್ಟಂ ವೀಕ್ಷಕದ ಜೊತೆಗೆ ತೆರೆಯಿರಿ</translation> <translation id="4146785383423576110">ಮರುಹೊಂದಿಸಿ ಮತ್ತು ಸ್ವಚ್ಛಗೊಳಿಸಿ</translation> <translation id="4147897805161313378">Google ಫೋಟೋಗಳು</translation> -<translation id="4150201353443180367">ಪ್ರದರ್ಶನ</translation> +<translation id="4150201353443180367">ಡಿಸ್ಪ್ಲೇ</translation> <translation id="4152670763139331043">{NUM_TABS,plural, =1{1 ಟ್ಯಾಬ್}one{# ಟ್ಯಾಬ್ಗಳು}other{# ಟ್ಯಾಬ್ಗಳು}}</translation> <translation id="4154664944169082762">ಫಿಂಗರ್ಪ್ರಿಂಟ್ಗಳು</translation> <translation id="4157869833395312646">Microsoft Server Gated Cryptography</translation> @@ -2212,7 +2209,6 @@ <translation id="4419556793104466535">ಸಿಂಕ್, ವೈಯಕ್ತೀಕರಣ ಮತ್ತು ಇನ್ನಷ್ಟನ್ನು ನಿಯಂತ್ರಿಸಿ</translation> <translation id="4421932782753506458">ಫ್ಲುಫಿ</translation> <translation id="4422347585044846479">ಈ ಪುಟಕ್ಕಾಗಿ ಬುಕ್ಮಾರ್ಕ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ</translation> -<translation id="4423104065312875417">ಹೆಚ್ಚುವರಿ ಧ್ವನಿ ಎಂಜಿನ್ಗಳನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ</translation> <translation id="4423376891418188461">ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮರುಸ್ಥಾಪಿಸು</translation> <translation id="4423482519432579560">&ಕಾಗುಣಿತಪರೀಕ್ಷೆ</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಗೆ ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನೀವು ಬದಲಾಯಿಸವುದು ಅಗತ್ಯವಿರುತ್ತದೆ.</translation> @@ -2237,7 +2233,6 @@ <translation id="4449996769074858870">ಈ ಟ್ಯಾಬ್ ಆಡಿಯೋ ಪ್ಲೇ ಮಾಡುತ್ತಿದೆ.</translation> <translation id="4450974146388585462">ಪತ್ತೆಹಚ್ಚುವಿಕೆ</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> ಹುಡುಕಿ ಅಥವಾ URL ಟೈಪ್ ಮಾಡಿ</translation> -<translation id="445923051607553918">ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸೇರಿ</translation> <translation id="4462159676511157176">ಕಸ್ಟಮ್ ಹೆಸರು ಸರ್ವರ್ಗಳು</translation> <translation id="4467100756425880649">Chrome ವೆಬ್ ಸ್ಟೋರ್ ಗ್ಯಾಲರಿ</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> ವಿಸ್ತರಿಸಿ</translation> @@ -2373,6 +2368,8 @@ <translation id="4682551433947286597">ಸೈನ್-ಇನ್ ಪರದೆಯ ಮೇಲೆ ವಾಲ್ಪೇಪರ್ಗಳು ಗೋಚರಿಸುತ್ತವೆ.</translation> <translation id="4684427112815847243">ಪ್ರತಿಯೊಂದನ್ನು ಸಿಂಕ್ ಮಾಡಿ</translation> <translation id="4689421377817139245">ನಿಮ್ಮ iPhone ಗೆ ಈ ಬುಕ್ಮಾರ್ಕ್ ಅನ್ನು ಸಿಂಕ್ ಮಾಡಿ</translation> +<translation id="4690091457710545971"><Intel ವೈ-ಫೈ ಫರ್ಮ್ವೇರ್, ನಾಲ್ಕು ಫೈಲ್ಗಳನ್ನು ಉತ್ಪಾದಿಸಿದೆ: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. ಮೊದಲ ಮೂರು ಫೈಲ್ಗಳು, ರಿಜಿಸ್ಟರ್ ಡಂಪ್ಗಳನ್ನು ಹೊಂದಿರುವ ಬೈನರಿ ಫೈಲ್ಗಳಾಗಿವೆ ಮತ್ತು ಇವುಗಳಲ್ಲಿ ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿ ಅಥವಾ ಸಾಧನವನ್ನು-ಗುರುತಿಸುವ ಮಾಹಿತಿ ಇಲ್ಲವೆಂದು Intel ಪ್ರತಿಪಾದಿಸುತ್ತದೆ. ಕೊನೆಯ ಫೈಲ್, Intel ಫರ್ಮ್ವೇರ್ ಒದಗಿಸಿದ ಎಕ್ಸಿಕ್ಯೂಷನ್ ಟ್ರೇಸ್ ಆಗಿದೆ; ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿ ಅಥವಾ ಸಾಧನವನ್ನು-ಗುರುತಿಸುವ ಮಾಹಿತಿಯನ್ನು ಅದರಿಂದ ತೆಗೆದುಹಾಕಲಾಗಿದೆ, ಆದರೆ ಅದು ತೀರಾ ದೊಡ್ಡದಾಗಿರುವುದರಿಂದ ಅದನ್ನು ಇಲ್ಲಿ ಪ್ರದರ್ಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಇತ್ತೀಚೆಗೆ ಉಂಟಾದ ವೈ-ಫೈ ಸಮಸ್ಯೆಗಳಿಗೆ ಪ್ರತಿಯಾಗಿ ಈ ಫೈಲ್ಗಳನ್ನು ಉತ್ಪಾದಿಸಲಾಗಿದೆ +ಮತ್ತು ಈ ಸಮಸ್ಯೆಗಳನ್ನು ನಿವಾರಿಸಲು ನೆರವಾಗುವುದಕ್ಕಾಗಿ, Intel ನೊಂದಿಗೆ ಇವುಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.></translation> <translation id="4692302215262324251"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಡೊಮೇನ್ ಮೂಲಕ ಎಂಟರ್ಪ್ರೈಸ್ ನಿರ್ವಹಣೆಗಾಗಿ ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಅನ್ನು ಯಶಸ್ವಿಯಾಗಿ ದಾಖಲಿಸಲಾಗಿದೆ. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> ಇದು ಅನಿರೀಕ್ಷಿತವಾಗಿದ್ದರೆ, ದಯವಿಟ್ಟು ಬೆಂಬಲಕ್ಕೆ ಸಂಪರ್ಕಿಸಿ.</translation> @@ -2632,6 +2629,7 @@ <translation id="5074318175948309511">ಹೊಸ ಸೆಟ್ಟಿಂಗ್ಗಳು ಪರಿಣಾಮಕಾರಿಯಾಗುವುದಕ್ಕೆ ಮೊದಲು ಈ ಪುಟವನ್ನು ರಿಲೋಡ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.</translation> <translation id="5075131525758602494">ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ</translation> <translation id="5078638979202084724">ಎಲ್ಲಾ ಟ್ಯಾಬ್ಗಳನ್ನು ಬುಕ್ಮಾರ್ಕ್ ಮಾಡಿ</translation> +<translation id="5079950360618752063">ಸೂಚಿಸಿರುವ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಬಳಸಿ</translation> <translation id="5084230410268011727">ಚಲನೆ ಮತ್ತು ಬೆಳಕಿನ ಸೆನ್ಸರ್ಗಳನ್ನು ಬಳಸಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿಸಿ</translation> <translation id="5085162214018721575">ನವೀಕರಣಗಳಿಗಾಗಿ ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</translation> <translation id="5086082738160935172">HID</translation> @@ -2670,6 +2668,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">ಈ ಐಟಂ ಅಳಿಸಿ</translation> <translation id="5139955368427980650">&ತೆರೆ</translation> +<translation id="5142961317498132443">ಪ್ರಮಾಣೀಕರಣ</translation> <translation id="5143374789336132547">ನೀವು ಮುಖಪುಟದ ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ ತೋರಿಸಬೇಕಾದ ಪುಟವನ್ನು "<ph name="EXTENSION_NAME" />" ವಿಸ್ತರಣೆಯು ಬದಲಾಯಿಸಿದೆ.</translation> <translation id="5143712164865402236">ಪೂರ್ಣ ಪರದೆಯನ್ನು ನಮೂದಿಸಿ</translation> <translation id="5145331109270917438">ದಿನಾಂಕ ಮಾರ್ಪಡಿಸಿದೆ</translation> @@ -2842,7 +2841,6 @@ <translation id="5380103295189760361">ಆ ಮಾರ್ಪಾಡುಗಳಿಗಾಗಿ ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ವೀಕ್ಷಿಸಲು Control, Alt, Shift, ಹಿಡಿದುಕೊಳ್ಳಿ ಅಥವಾ ಹುಡುಕಿ.</translation> <translation id="5382591305415226340">ಬೆಂಬಲಿತ ಲಿಂಕ್ಗಳನ್ನು ನಿರ್ವಹಿಸಿ</translation> <translation id="5384883051496921101">ಈ ಸೈಟ್, ಅಜ್ಞಾತ ಮೋಡ್ಗೆ ಹೊರತಾಗಿರುವ ಅಪ್ಲಿಕೇಶನ್ನೊಂದಿಗೆ ಮಾಹಿತಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಿದೆ.</translation> -<translation id="5388588172257446328">ಬಳಕೆದಾರಹೆಸರು:</translation> <translation id="5388885445722491159">ಜೋಡಿಯಾದ</translation> <translation id="5389237414310520250">ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲಾಗಲಿಲ್ಲ. ದಯವಿಟ್ಟು ನಿಮ್ಮ ಹಾರ್ಡ್ ಡ್ರೈವ್ ಸ್ಥಳಾವಕಾಶ ಮತ್ತು ಅನುಮತಿಗಳನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</translation> <translation id="5390100381392048184">ಧ್ವನಿಗಳನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿಸಿ</translation> @@ -2967,7 +2965,6 @@ <translation id="5551573675707792127">ಕೀಬೋರ್ಡ್ ಮತ್ತು ಪಠ್ಯ ಇನ್ಪುಟ್</translation> <translation id="5553089923092577885">ಪ್ರಮಾಣಪತ್ರ ನೀತಿ ಮ್ಯಾಪಿಂಗ್ಗಳು</translation> <translation id="5554489410841842733">ಈ ವಿಸ್ತರಣೆಯು ಪ್ರಸ್ತುತ ಪುಟದಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸಬಹುದಾದಾಗ ಈ ಐಕಾನ್ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ.</translation> -<translation id="5554573843028719904">ಇತರೆ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್...</translation> <translation id="5554720593229208774">ಇಮೇಲ್ ಪ್ರಮಾಣಪತ್ರದ ಪ್ರಾಧಿಕಾರ</translation> <translation id="5556206011531515970">ನಿಮ್ಮ ಡಿಫಾಲ್ಟ್ ಬ್ರೌಸರ್ ಆಯ್ಕೆ ಮಾಡಲು ಮುಂದೆ ಕ್ಲಿಕ್ ಮಾಡಿ.</translation> <translation id="5556459405103347317">ಮರುಲೋಡ್</translation> @@ -3008,7 +3005,6 @@ <translation id="5610038042047936818">ಕ್ಯಾಮರಾ ಮೋಡ್ಗೆ ಬದಲಾಯಿಸಿ</translation> <translation id="5612720917913232150"><ph name="URL" /> ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ನ ಸ್ಥಳವನ್ನು ಬಳಸಲು ಬಯಸುತ್ತದೆ</translation> <translation id="5612734644261457353">ಕ್ಷಮಿಸಿ, ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಇನ್ನೂ ಪರಿಶೀಲಿಸಲಾಗಲಿಲ್ಲ. ಗಮನಿಸಿ: ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನೀವು ಇತ್ತೀಚೆಗೆ ಬದಲಾಯಿಸಿದ್ದರೆ, ನೀವು ಸೈನ್ ಔಟ್ ಮಾಡಿದ ನಂತರ ನಿಮ್ಮ ಹೊಸ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಜಾರಿಗೆ ತರಲಾಗುತ್ತದೆ, ದಯವಿಟ್ಟು ಇಲ್ಲಿ ಹಳೆಯ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಬಳಸಿ.</translation> -<translation id="5613695965848159202">ಅಜ್ಞಾತನಾಮಕ ಗುರುತಿಸುವಿಕೆ:</translation> <translation id="5614190747811328134">ಬಳಕೆದಾರ ಸೂಚನೆ</translation> <translation id="561698261642843490">Firefox ಅನ್ನು ಮುಚ್ಚಿ</translation> <translation id="5618075537869101857">ಓಹ್ ದೇವರೇ, ಕಿಯೋಸ್ಕ್ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗಲಿಲ್ಲ.</translation> @@ -3225,7 +3221,6 @@ <translation id="5941343993301164315">ದಯವಿಟ್ಟು <ph name="TOKEN_NAME" /> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ.</translation> <translation id="5941711191222866238">ಕುಗ್ಗಿಸು</translation> <translation id="5946591249682680882">ವರದಿ ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">ಖಾಸಗಿ ನೆಟ್ವರ್ಕ್ ಸೇರಿಸಿ</translation> <translation id="5949544233750246342">ಫೈಲ್ ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ</translation> <translation id="5955282598396714173">ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅವಧಿ ಮುಗಿದಿದೆ. ಅದನ್ನು ಬದಲಾಯಿಸಲು ಸೈನ್ ಔಟ್ ಮಾಡಿ ಮತ್ತೆ ಸೈನ್ ಇನ್ ಆಗಿರಿ.</translation> <translation id="5956585768868398362">ಇದು ನೀವು ನಿರೀಕ್ಷಿಸುತ್ತಿರುವ ಹುಡುಕಾಟ ಪುಟವೇ?</translation> @@ -3386,11 +3381,13 @@ <translation id="6198102561359457428">ಸೈನ್ ಔಟ್ ಮಾಡಿ ನಂತರ ಮತ್ತೆ ಸೈನ್ ಇನ್ ಮಾಡಿ...</translation> <translation id="6198252989419008588">PIN ಬದಲಾಯಿಸು</translation> <translation id="6199801702437275229">ಅಂತರ ಮಾಹಿತಿಗಾಗಿ ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ...</translation> +<translation id="6204015976622790023">ನಿಮ್ಮ ಪರದೆಯಲ್ಲಿ ಇರುವ ವಿಷಯಕ್ಕೆ ಸಂಬಂಧಿಸಿದಂತೆ, ನಿಮ್ಮ ಅಸಿಸ್ಟೆಂಟ್ನಿಂದ ಸೂಕ್ತ ಸಲಹೆಗಳನ್ನು ನೋಡಿ.</translation> <translation id="6205710420833115353">ಕೆಲವು ಕಾರ್ಯಾಚರಣೆಗಳು ನಿರೀಕ್ಷಿಸಿದ್ದಕ್ಕಿಂತಲೂ ಹೆಚ್ಚಿನ ಸಮಯವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತಿದೆ. ನೀವು ಅವುಗಳನ್ನು ಸ್ಥಗಿತಗೊಳಿಸಲು ಬಯಸುವಿರಾ?</translation> <translation id="6206311232642889873">ಇಮೇಜ್ ಅನ್ನು ನಕ&ಲಿಸಿ</translation> <translation id="6207200176136643843">ಝೂಮ್ ಮಟ್ಟವನ್ನು ಡೀಫಾಲ್ಟ್ಗೆ ಮರುಹೊಂದಿಸಿ</translation> <translation id="620722923698527029">ಸಂಬಂಧಿತ ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ಈ ಪ್ರಕಾರದ ಲಿಂಕ್ಗಳನ್ನು ಯಾವಾಗಲೂ ತೆರೆಯಿರಿ</translation> <translation id="6207937957461833379">ರಾಷ್ಟ್ರ/ಪ್ರದೇಶ</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: ಸಿಂಕ್ ಕೆಲಸ ಮಾಡುತ್ತಿಲ್ಲ</translation> <translation id="6212039847102026977">ಸುಧಾರಿತ ನೆಟ್ವರ್ಕ್ ಗುಣಲಕ್ಷಣಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="6212168817037875041">ಡಿಸ್ಪ್ಲೇ ಅನ್ನು ಆಫ್ ಮಾಡಿ</translation> <translation id="6212752530110374741">ಇಮೇಲ್ ಲಿಂಕ್</translation> @@ -3428,7 +3425,6 @@ <translation id="6263541650532042179">ಸಿಂಕ್ ಮರುಹೊಂದಿಸು</translation> <translation id="6264365405983206840">&ಎಲ್ಲ ಆಯ್ಕೆ ಮಾಡಿ</translation> <translation id="6264422956566238156">ನೀವು ಸಿಂಕ್ ಅನ್ನು ಆನ್ ಮಾಡಿರುವಿರಿ</translation> -<translation id="6265930187414222160">ಮುಗಿದಿದೆ! ಹಾನಿಕಾರಕ ಸಾಫ್ಟ್ವೇರ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" /> ಗೆ ನಿಮ್ಮನ್ನು ಪ್ರಮಾಣೀಕರಿಸಲು ಒಂದು ಪ್ರಮಾಣಪತ್ರವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</translation> <translation id="6268252012308737255"><ph name="APP" /> ರಿಂದ ತೆರೆಯಿರಿ</translation> <translation id="6268747994388690914">HTML ಫೈಲ್ಗಳಿಂದ ಬುಕ್ಮಾರ್ಕ್ಗಳನ್ನು ಆಮದು ಮಾಡಿ......</translation> @@ -3535,7 +3531,6 @@ ನಿಮ್ಮ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಖಾತೆಗೆ ಸೈನ್ ಇನ್ ಮಾಡುವುದನ್ನು ಮುಂದುವರಿಸುವುದಕ್ಕೆ "ಮುಂದೆ" ಕ್ಲಿಕ್ ಮಾಡಿ.</translation> <translation id="6419546358665792306">ಲೋಡ್ ಅನ್ಪ್ಯಾಕ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="642282551015776456">ಈ ಹೆಸರನ್ನು ಫೋಲ್ಡರ್ನ ಫೈಲ್ನಂತೆ ಬಳಸಲಾಗುವುದಿಲ್ಲ</translation> -<translation id="6423239382391657905">VPN ತೆರೆಯಿರಿ</translation> <translation id="6426200009596957090">ChromeVox ಸೆಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ</translation> <translation id="6429384232893414837">ಅಪ್ಡೇಟ್ ದೋಷ</translation> <translation id="6430814529589430811">Base64-ಎನ್ಕೋಡ್ ಮಾಡಿದ ASCII, ಏಕ ಪ್ರಮಾಣಪತ್ರ</translation> @@ -3615,7 +3610,6 @@ <translation id="6544215763872433504">ನಿಮಗಾಗಿ Google ನಿಂದ ವೆಬ್ ಬ್ರೌಸರ್</translation> <translation id="6545665334409411530">ಪುನರಾವರ್ತನೆ ಪ್ರಮಾಣ</translation> <translation id="6545834809683560467">ಹುಡುಕಾಟಗಳನ್ನು ಮತ್ತು ಅಡ್ರೆಸ್ ಬಾರ್ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಲಾಂಚರ್ನಲ್ಲಿನ ಹುಡುಕಾಟ ಪೆಟ್ಟಿಗೆಯಲ್ಲಿ ಟೈಪ್ ಮಾಡಲಾದ URLಗಳನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು ಸಲಹೆ ಸೇವೆಯನ್ನು ಬಳಸು</translation> -<translation id="6546686722964485737">Wimax ನೆಟ್ವರ್ಕ್ ಅನ್ನು ಸೇರಿಸಿ</translation> <translation id="6547316139431024316">ಈ ವಿಸ್ತರಣೆಗಾಗಿ ಮತ್ತೆ ಎಚ್ಚರಿಕೆ ನೀಡದಿರು</translation> <translation id="6547354035488017500">ಕನಿಷ್ಠ 512 MB ಸ್ಥಳಾವಕಾಶವನ್ನು ಮುಕ್ತಗೊಳಿಸಿ ಇಲ್ಲದಿದ್ದರೆ ನಿಮ್ಮ ಸಾಧನವು ಪ್ರತಿಕ್ರಿಯೆ ನೀಡದಂತಾಗುತ್ತದೆ. ಸ್ಥಳಾವಕಾಶವನ್ನು ಮುಕ್ತಗೊಳಿಸಲು, ಸಾಧನದ ಸಂಗ್ರಹಣೆಯಿಂದ ಫೈಲ್ಗಳನ್ನು ಅಳಿಸಿ.</translation> <translation id="6549689063733911810">ಇತ್ತೀಚಿನದು</translation> @@ -4034,7 +4028,6 @@ <translation id="7201014958346994077">Linux ಫೈಲ್ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ</translation> <translation id="720110658997053098">ಈ ಸಾಧನವನ್ನು ಕಿಯೋಸ್ಕ್-ಮೋಡ್ನಲ್ಲಿ ಶಾಶ್ವತವಾಗಿ ಇರಿಸಿಕೊಳ್ಳಿ</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' ಅನ್ನು ಅಳಿಸಲಾಗಿದೆ</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> ಅನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{ನಿರ್ಗಮನ ಪುಟ}one{ನಿರ್ಗಮನ ಪುಟಗಳು}other{ನಿರ್ಗಮನ ಪುಟಗಳು}}</translation> <translation id="7216409898977639127">ಸೆಲ್ಯುಲಾರ್ ಒದಗಿಸುವವರು</translation> @@ -4505,7 +4498,6 @@ <translation id="7909969815743704077">ಅಜ್ಞಾತದಲ್ಲಿ ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="7910768399700579500">&ಹೊಸ ಫೋಲ್ಡರ್</translation> <translation id="7912080627461681647">ಸರ್ವರ್ನಲ್ಲಿ ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಬದಲಾಯಿಸಲಾಗಿದೆ. ಸೈನ್ ಔಟ್ ಮಾಡಿ ಮತ್ತೆ ಸೈನ್ ಇನ್ ಆಗಿರಿ.</translation> -<translation id="7912883689016444961">ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ</translation> <translation id="7915471803647590281">ದಯವಿಟ್ಟು ಪ್ರತಿಕ್ರಿಯೆ ಕಳುಹಿಸುವ ಮುಂಚಿತವಾಗಿ ಏನು ನಡೆಯುತ್ತಿದೆ ಎಂದು ನಮಗೆ ತಿಳಿಸಿ.</translation> <translation id="7916556741383518510">ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ</translation> <translation id="792514962475806987">ಡಾಕ್ ಮಾಡಿರುವುದಕ್ಕೆ ಝೂಮ್ ಮಟ್ಟ:</translation> @@ -4559,7 +4551,6 @@ <translation id="7988355189918024273">ಪ್ರವೇಶದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation> <translation id="7994702968232966508">EAP ವಿಧಾನ</translation> <translation id="799547531016638432">ಶಾರ್ಟ್ಕಟ್ ತೆಗೆದುಹಾಕು</translation> -<translation id="7997479212858899587">ಗುರುತು:</translation> <translation id="7997826902155442747">ಪ್ರಕ್ರಿಯೆಯ ಆದ್ಯತೆ</translation> <translation id="7999229196265990314">ಕೆಳಗಿನ ಫೈಲ್ಗಳನ್ನು ರಚಿಸಲಾಗಿದೆ: @@ -4641,7 +4632,6 @@ <translation id="8105368624971345109">ಆಫ್ ಮಾಡು</translation> <translation id="8106045200081704138">ನನ್ನೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗಿದ್ದು</translation> <translation id="8107015733319732394">ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ನಲ್ಲಿ Google Play ಸ್ಟೋರ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ. ಇದು ಕೆಲವು ನಿಮಿಷಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಹುದು.</translation> -<translation id="8109930990200908494">ಬಳಕೆದಾರರ ಪ್ರಮಾಣಪತ್ರಕ್ಕಾಗಿ ಸೈನ್-ಇನ್ ಅಗತ್ಯವಿದೆ.</translation> <translation id="8111155949205007504">ನಿಮ್ಮ iPhone ಮೂಲಕ ಈ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಿ</translation> <translation id="8113043281354018522">ಪರವಾನಗಿ ಪ್ರಕಾರವನ್ನು ಆರಿಸಿ</translation> <translation id="8116190140324504026">ಇನ್ನಷ್ಟು ಮಾಹಿತಿ...</translation> @@ -4652,6 +4642,7 @@ <translation id="8118860139461251237">ನಿಮ್ಮ ಡೌನ್ಲೋಡ್ಗಳನ್ನು ನಿರ್ವಹಿಸಿ</translation> <translation id="81238879832906896">ಹಳದಿ ಮತ್ತು ಬಿಳಿ ಹೂ</translation> <translation id="8124313775439841391">ನಿರ್ವಹಿಸಲಾದ ONC</translation> +<translation id="8125562866093998907">ನಿಮ್ಮ ಖಾತೆಗೆ ಹೆಚ್ಚಿನ ಸುರಕ್ಷತೆ ಒದಗಿಸುವುದಕ್ಕಾಗಿ, ಸೈಟ್ ನಿಮ್ಮ ಸುರಕ್ಷತಾ ಕೀಯನ್ನು ಪರಿಶೀಲಿಸಲು ಬಯಸುತ್ತದೆ.</translation> <translation id="813082847718468539">ಸೈಟ್ ಮಾಹಿತಿಯನ್ನು ವೀಕ್ಷಿಸಿ</translation> <translation id="8131740175452115882">ದೃಢೀಕರಿಸು</translation> <translation id="8133676275609324831">ಫೋಲ್ಡರ್ನಲ್ಲಿ &ತೋರಿಸಿ</translation> @@ -4762,7 +4753,6 @@ <translation id="8308179586020895837">ನಿಮ್ಮ ಕ್ಯಾಮರಾ ಪ್ರವೇಶಿಸಲು <ph name="HOST" /> ಬಯಸುತ್ತದೆಯೇ ಎಂಬುದನ್ನು ಕೇಳಿ</translation> <translation id="830868413617744215">ಬೀಟಾ</translation> <translation id="8309458809024885768">ಪ್ರಮಾಣಪತ್ರ ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ</translation> -<translation id="8309505303672555187">ನೆಟ್ವರ್ಕ್ ಆಯ್ಕೆ ಮಾಡಿ:</translation> <translation id="8312871300878166382">ಫೋಲ್ಡರ್ಗೆ ಅಂಟಿಸಿ</translation> <translation id="8317671367883557781">ನೆಟ್ವರ್ಕ್ ಸಂಪರ್ಕವನ್ನು ಸೇರಿಸಿ</translation> <translation id="8319414634934645341">ವಿಸ್ತರಿತ ಕೀಲಿ ಬಳಕೆ</translation> @@ -4838,7 +4828,6 @@ <translation id="8451512073679317615">ಸಹಾಯಕ</translation> <translation id="8452135315243592079">ಕಾಣೆಯಾಗಿರುವ ಸಿಮ್ ಕಾರ್ಡ್</translation> <translation id="8453482423012550001">$1 ಐಟಂಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ...</translation> -<translation id="8454288007744638700">ಅಥವಾ, ಹೊಸ ನೆಟ್ವರ್ಕ್ ಆಯ್ಕೆಮಾಡಿ:</translation> <translation id="845627346958584683">ಅವಧಿ ಮೀರುವ ಸಮಯ</translation> <translation id="8456681095658380701">ಅಮಾನ್ಯವಾದ ಹೆಸರು</translation> <translation id="8457451314607652708">ಬುಕ್ಮಾರ್ಕ್ಗಳನ್ನು ಆಮದು ಮಾಡಿ</translation> @@ -4904,6 +4893,7 @@ <translation id="855081842937141170">ಪಿನ್ ಟ್ಯಾಬ್</translation> <translation id="8551388862522347954">ಪರವಾನಗಿಗಳು</translation> <translation id="8553342806078037065">ಇತರ ವ್ಯಕ್ತಿಗಳನ್ನು ನಿರ್ವಹಿಸು</translation> +<translation id="8554899698005018844">ಭಾಷೆ ನಮೂದಿಸಿಲ್ಲ</translation> <translation id="855773602626431402">ಈ ಪುಟದಲ್ಲಿ ಸ್ಯಾಂಡ್ಬಾಕ್ಸ್ ರದ್ದುಗೊಳಿಸಿರುವ ಪ್ಲಗ್-ಇನ್ ಅನ್ನು ಚಾಲನೆ ಮಾಡುವುದರಿಂದ ತಡೆಯಲಾಗಿದೆ.</translation> <translation id="8557930019681227453">ಮ್ಯಾನಿಫೆಸ್ಟ್</translation> <translation id="8559694214572302298">ಚಿತ್ರ ಡಿಕೋಡರ್</translation> @@ -4941,7 +4931,6 @@ <translation id="862727964348362408">ತಡೆಹಿಡಿಯಲಾಗಿದೆ</translation> <translation id="862750493060684461">CSS ಸಂಗ್ರಹ</translation> <translation id="8627795981664801467">ಸುರಕ್ಷಿತ ಸಂಪರ್ಕಗಳು ಮಾತ್ರ</translation> -<translation id="8628085465172583869">ಸರ್ವರ್ ಹೋಸ್ಟ್ ಹೆಸರು:</translation> <translation id="8630903300770275248">ಮೇಲ್ವಿಚಾರಣೆಯ ಬಳಕೆದಾರರನ್ನು ಆಮದು ಮಾಡು</translation> <translation id="8631032106121706562">ಪೆಟಲ್ಸ್</translation> <translation id="8637542770513281060">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್, ಸುಭದ್ರ ಮಾಡ್ಯೂಲ್ ಅನ್ನು ಹೊಂದಿದೆ. Chrome OS ನಲ್ಲಿ ಹಲವು ಪ್ರಮುಖ ಭದ್ರತಾ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಇದನ್ನು ಬಳಸಲಾಗುತ್ತದೆ. ಇದರ ಕುರಿತು ಇನ್ನಷ್ಟು ತಿಳಿದುಕೊಳ್ಳಲು Chromebook ಸಹಾಯ ಕೇಂದ್ರಕ್ಕೆ ಭೇಟಿ ನೀಡಿ: https://support.google.com/chromebook/?p=sm</translation> @@ -5197,7 +5186,6 @@ <translation id="899403249577094719">Netscape ಪ್ರಮಾಣಪತ್ರ ಆಧಾರ URL</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> ನಿಂದ ನಿರ್ವಹಿಸಲಾಗಿದೆ</translation> <translation id="8996526648899750015">ಖಾತೆಯನ್ನು ಸೇರಿಸು...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">ಡಿಸ್ಕ್ ಚಿತ್ರವನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ.</translation> <translation id="9003647077635673607">ಎಲ್ಲ ವೆಬ್ಸೈಟ್ಗಳಲ್ಲಿ ಅನುಮತಿಸಿ</translation> <translation id="9003677638446136377">ಮತ್ತೆ ಪರಿಶೀಲಿಸು</translation> @@ -5345,7 +5333,7 @@ <translation id="9220525904950070496">ಖಾತೆಯನ್ನು ತೆಗೆದುಹಾಕಿ</translation> <translation id="923467487918828349">ಎಲ್ಲಾ ತೋರಿಸಿ</translation> <translation id="930268624053534560">ವಿವರವಾದ ಸಮಯಮೊಹರುಗಳು</translation> -<translation id="932327136139879170">ಮುಖಪುಟ</translation> +<translation id="932327136139879170">Home</translation> <translation id="932508678520956232">ಮುದ್ರಣವನ್ನು ಪ್ರಾರಂಭಿಸುವುದಕ್ಕೆ ಆಗುವುದಿಲ್ಲ.</translation> <translation id="93393615658292258">ಪಾಸ್ವರ್ಡ್ ಮಾತ್ರ</translation> <translation id="934503638756687833">ಅಗತ್ಯವಿದ್ದರೆ, ಇಲ್ಲಿ ಪಟ್ಟಿ ಮಾಡಿರದ ಐಟಂಗಳನ್ನು ಸಹ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ. <a href="<ph name="URL" />">ಅನಪೇಕ್ಷಿತ ಸಾಫ್ಟ್ವೇರ್ನಿಂದ ಸಂರಕ್ಷಣೆ</a> ಕುರಿತು Chrome ಗೌಪ್ಯತೆ ಬಿಳಿ ಹಾಳೆಯಲ್ಲಿ ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ.</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index e1e8d5c..80c90640 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">곧 휴식 시간입니다</translation> <translation id="1062407476771304334">바꾸기</translation> -<translation id="1064835277883315402">사설 네트워크에 연결</translation> <translation id="1064912851688322329">Google 계정 연결 해제</translation> <translation id="1067048845568873861">생성됨</translation> <translation id="1067291318998134776">Linux(베타)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">검색 중...</translation> <translation id="1316495628809031177">동기화 일시중지됨</translation> <translation id="1319979322914001937">Chrome 웹 스토어의 필터링된 확장 프로그램 목록을 보여주는 앱입니다. 앱에서 직접 이 목록에 있는 확장 프로그램을 설치할 수 있습니다.</translation> -<translation id="132090119144658135">주제 일치:</translation> <translation id="1326317727527857210">다른 기기에서 탭을 가져오려면 Chrome에 로그인하세요.</translation> <translation id="1327074568633507428">Google 클라우드 프린트의 프린터</translation> <translation id="1327977588028644528">게이트웨이</translation> @@ -377,6 +375,7 @@ <translation id="1531004739673299060">애플리케이션 창</translation> <translation id="1534389735079119190">오류: VM 내에서 컨테이너를 시작하지 못했습니다.</translation> <translation id="15373452373711364">큰 마우스 커서</translation> +<translation id="1540605929960647700">데모 모드 사용</translation> <translation id="1543284117603151572">Edge에서 가져옴</translation> <translation id="1545177026077493356">자동 키오스크 모드</translation> <translation id="1545775234664667895">테마('<ph name="THEME_NAME" />')를 설치했습니다.</translation> @@ -460,6 +459,7 @@ <translation id="1657406563541664238">사용 통계 및 비정상 종료 보고서가 Google로 자동 전송되게 하여 <ph name="PRODUCT_NAME" /> 개선에 도움 주기</translation> <translation id="1658424621194652532">마이크에 액세스하는 페이지입니다.</translation> <translation id="1660204651932907780">사이트에서 소리를 재생하도록 허용(권장)</translation> +<translation id="1660938185063657230">보안 키 인증</translation> <translation id="1661156625580498328">AES 암호화를 적용합니다(권장).</translation> <translation id="1661245713600520330">이 페이지에는 기본 프로세스에 로드된 모든 모듈과 나중에 로드하도록 등록된 모듈이 표시되어 있습니다.</translation> <translation id="166179487779922818">비밀번호가 너무 짧습니다.</translation> @@ -477,6 +477,7 @@ <translation id="16815041330799488">사이트에서 클립보드에 복사된 텍스트 및 이미지를 확인하도록 허용하지 않음</translation> <translation id="1682548588986054654">새 시크릿 창</translation> <translation id="168715261339224929">어느 기기에서나 북마크를 사용하려면 동기화를 사용 설정하세요.</translation> +<translation id="1688867105868176567">사이트 데이터를 삭제하시겠습니까?</translation> <translation id="1688935057616748272">문자를 입력하세요</translation> <translation id="168991973552362966">근처 프린터 추가</translation> <translation id="1689945336726856614">&URL 복사</translation> @@ -488,7 +489,6 @@ <translation id="1701062906490865540">이 사용자 삭제</translation> <translation id="1706586824377653884">관리자가 추가함</translation> <translation id="1706625117072057435">확대/축소 수준</translation> -<translation id="1707463636381878959">다른 사용자와 네트워크 공유</translation> <translation id="1708338024780164500">(비활성)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" />(ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" />x<ph name="HEIGHT" />(기본)</translation> @@ -524,7 +524,6 @@ <translation id="175772926354468439">테마 사용</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome 웹 스토어에서 보기</translation> -<translation id="1758831820837444715">이더넷 네트워크 설정</translation> <translation id="1763046204212875858">애플리케이션 바로가기 만들기</translation> <translation id="1763108912552529023">계속 살펴보기</translation> <translation id="1763808908432309942">새 탭에서 열기</translation> @@ -583,8 +582,10 @@ <translation id="1839704667838141620">파일 공유 방법을 변경하세요.</translation> <translation id="1841545962859478868">기기 관리자가 다음을 모니터링할 수 있습니다.</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" />이(가) 사용 중지됨</translation> +<translation id="1842766183094193446">데모 모드를 사용하도록 설정하시겠습니까?</translation> <translation id="1844692022597038441">이 파일은 오프라인에서 사용할 수 없습니다.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" />을(를) 실행하려면 Control 키를 누르고 클릭합니다.</translation> +<translation id="1847880352285315359">저장됨</translation> <translation id="1848219224579402567">덮개가 닫히면 로그아웃</translation> <translation id="184823282865851239">사이트에 방해가 되는 광고를 표시하는 경향이 있는 경우 차단</translation> <translation id="1849186935225320012">이 페이지는 MIDI 기기를 완전히 제어할 수 있습니다.</translation> @@ -682,6 +683,7 @@ <translation id="200544492091181894">나중에 언제든지 설정에서 변경 가능</translation> <translation id="2006638907958895361"><ph name="APP" />에서 링크 열기</translation> <translation id="2007404777272201486">문제 신고...</translation> +<translation id="2016237810978710652">Linux 파일을 여는 중...</translation> <translation id="2016430552235416146">기본</translation> <translation id="2017334798163366053">성능 데이터 수집 사용 중지</translation> <translation id="2017836877785168846">검색주소창의 검색 기록 및 자동 완성 항목을 삭제합니다.</translation> @@ -776,6 +778,7 @@ <translation id="2154484045852737596">카드 수정</translation> <translation id="2154710561487035718">URL 복사</translation> <translation id="2155772377859296191"><ph name="WIDTH" />x<ph name="HEIGHT" />처럼 보입니다.</translation> +<translation id="2156283799932971644">일부 시스템 정보와 페이지 콘텐츠를 Google로 전송하여 세이프 브라우징을 개선하도록 도와주세요.</translation> <translation id="215753907730220065">전체화면 종료</translation> <translation id="2157875535253991059">페이지가 현재 전체화면으로 전환되었습니다.</translation> <translation id="216169395504480358">Wi-Fi 추가</translation> @@ -785,6 +788,7 @@ <translation id="2173801458090845390">이 기기에 요청 ID 추가</translation> <translation id="2175042898143291048">항상 번역</translation> <translation id="2175607476662778685">빠른 실행 표시줄</translation> +<translation id="2176087259161165020">기타 소스</translation> <translation id="2177950615300672361">시크릿 탭: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" />의 <ph name="PEPPER_PLUGIN_NAME" />에서 내 컴퓨터에 액세스하려고 합니다</translation> <translation id="2178614541317717477">CA 손상</translation> @@ -868,7 +872,6 @@ <translation id="2291643155573394834">다음 탭</translation> <translation id="2292848386125228270">일반 사용자로 <ph name="PRODUCT_NAME" />을(를) 시작하세요. 개발용 루트로 실행해야 하는 경우 --no-sandbox 플래그를 사용하여 다시 실행하세요.</translation> <translation id="2294358108254308676"><ph name="PRODUCT_NAME" />을(를) 설치하시겠습니까?</translation> -<translation id="2296019197782308739">EAP 방식:</translation> <translation id="2297705863329999812">프린터 검색</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> 맞춤설정 및 제어</translation> <translation id="2301382460326681002">확장 프로그램 루트 디렉토리가 잘못되었습니다.</translation> @@ -916,6 +919,7 @@ <translation id="2366463953911599217">오류: <ph name="APP_NAME" />을(를) 설치하지 못했습니다.</translation> <translation id="2367199180085172140">파일 공유 추가</translation> <translation id="2367972762794486313">앱 표시</translation> +<translation id="2369536625682139252"><ph name="SITE" />에서 저장한 모든 데이터가 삭제됩니다. 쿠키는 삭제되지 않습니다.</translation> <translation id="2371076942591664043">완료되면 열기(&D)</translation> <translation id="2377319039870049694">목록 보기로 전환</translation> <translation id="2377667304966270281">하드 결함</translation> @@ -925,7 +929,6 @@ <translation id="2379281330731083556">시스템 대화상자를 사용하여 인쇄... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">보내기 전에 확인(권장)</translation> <translation id="2384436799579181135">오류가 발생했습니다. 프린터를 확인한 후 다시 시도해 주세요.</translation> -<translation id="2385700042425247848">서비스 이름:</translation> <translation id="2387458720915042159">프록시 연결 유형</translation> <translation id="2391419135980381625">표준 글꼴</translation> <translation id="2391762656119864333">취소</translation> @@ -976,7 +979,6 @@ <translation id="247949520305900375">오디오 공유</translation> <translation id="2480868415629598489">복사하고 붙여넣는 데이터 수정</translation> <translation id="2482878487686419369">알림</translation> -<translation id="2485056306054380289">서버 CA 인증서:</translation> <translation id="2485422356828889247">제거</translation> <translation id="2487067538648443797">새 북마크 추가</translation> <translation id="248861575772995840">휴대전화를 찾을 수 없습니다. <ph name="DEVICE_TYPE" />의 블루투스가 사용 설정되어 있는지 확인하세요. <a>자세히 알아보기</a></translation> @@ -1037,6 +1039,7 @@ <translation id="2566124945717127842">Powerwash는 <ph name="IDS_SHORT_PRODUCT_NAME" /> 기기를 재설정하여 새것처럼 만듭니다.</translation> <translation id="2567257616420533738">비밀번호가 저장되었습니다. <ph name="SAVED_PASSWORDS_LINK" />에 저장된 비밀번호를 보고 관리하세요.</translation> <translation id="2568774940984945469">정보 표시줄 컨테이너</translation> +<translation id="2570454805927264159">어시스턴트 최대한 활용하기</translation> <translation id="257088987046510401">테마</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" />에 대한 읽기 전용 액세스가 허용되었습니다.</translation> <translation id="2573269395582837871">그림과 이름 선택</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">제출</translation> <translation id="265390580714150011">필드 값</translation> <translation id="2654166010170466751">사이트에서 결제 핸들러를 설치하도록 허용</translation> -<translation id="2655386581175833247">사용자 인증서:</translation> <translation id="2660779039299703961">이벤트</translation> <translation id="266079277508604648">프린터에 연결할 수 없습니다. 프린터가 켜져 있으며 Wi-Fi 또는 USB를 통해 Chromebook에 연결되어 있는지 확인하세요.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">사용 데이터 없음</translation> <translation id="3007214526293698309">비율 고정</translation> <translation id="3007771295016901659">탭 복사</translation> +<translation id="3008272652534848354">권한 재설정</translation> <translation id="3009300415590184725">모바일 데이터 서비스 설정 과정을 취소하시겠습니까?</translation> <translation id="3009779501245596802">색인화된 데이터베이스</translation> <translation id="3010279545267083280">비밀번호 삭제됨</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">모듈(<ph name="TOTAL_COUNT" />개) - 알려진 충돌: <ph name="BAD_COUNT" />개, 의심됨: <ph name="SUSPICIOUS_COUNT" />개</translation> <translation id="3101709781009526431">날짜 및 시간</translation> <translation id="310671807099593501">사이트에서 블루투스를 사용하고 있습니다.</translation> -<translation id="3108967419958202225">선택...</translation> <translation id="3115128645424181617">휴대전화를 찾을 수 없습니다. 휴대전화가 가까이 있고 블루투스가 사용 설정되어 있는지 확인하세요.</translation> <translation id="3115147772012638511">캐시를 기다리는 중...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> 도움말</translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">일부 이동통신사는 이 기능을 차단할 수도 있습니다.</translation> <translation id="316854673539778496">어느 기기에서나 내 확장 프로그램을 모두 사용하려면 로그인하여 동기화를 사용 설정하세요.</translation> <translation id="3170072451822350649">로그인을 건너뛰고 <ph name="LINK_START" />손님으로 로그인<ph name="LINK_END" />할 수도 있습니다.</translation> -<translation id="3177048931975664371">비밀번호를 숨기려면 클릭하세요.</translation> <translation id="3177909033752230686">페이지 언어:</translation> <translation id="3181110748548073003">앞으로 이동하려면 |<ph name="SHORTCUT" />| 키를 누르세요.</translation> <translation id="3182749001423093222">맞춤법 검사</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187">소유권이 <ph name="DESTINATION_DOMAIN" />(으)로 이전됩니다.</translation> <translation id="323803881985677942">확장 프로그램 옵션 열기</translation> <translation id="3241680850019875542">압축할 확장 프로그램의 루트 디렉토리를 선택합니다. 확장 프로그램을 업데이트하려면 다시 사용할 비공개 키 파일도 선택합니다.</translation> -<translation id="3242765319725186192">사전 공유 키:</translation> <translation id="3244294424315804309">계속 음소거</translation> <translation id="3245321423178950146">알 수 없는 아티스트</translation> <translation id="3246097286174000800">Smart Lock 사용해보기</translation> @@ -1608,7 +1608,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" />의 작업 메뉴 더보기</translation> <translation id="3440761377721825626">사이트에서 플러그인을 사용하여 내 컴퓨터에 액세스하려 할 때 확인</translation> <translation id="3441653493275994384">차단</translation> -<translation id="3445830502289589282">2단계 인증:</translation> <translation id="344630545793878684">다수의 웹사이트에서 데이터 읽기</translation> <translation id="3449839693241009168"><ph name="SEARCH_KEY" /> 키를 눌러 <ph name="EXTENSION_NAME" />에 명령 보내기</translation> <translation id="3450157232394774192">유휴 상태 점유율</translation> @@ -1649,7 +1648,6 @@ <translation id="3495304270784461826">오류가 <ph name="COUNT" />개 있습니다.</translation> <translation id="3495660573538963482">Google 어시스턴트 설정</translation> <translation id="3496213124478423963">축소</translation> -<translation id="3504135463003295723">그룹 이름:</translation> <translation id="3505030558724226696">기기 액세스 취소</translation> <translation id="3507421388498836150">'<ph name="EXTENSION_NAME" />'의 현재 권한</translation> <translation id="3507547268929739059">Chromebook용 Linux 앱 삭제</translation> @@ -1758,7 +1756,6 @@ <translation id="3661054927247347545">로그인 인증서가 유효하지 않습니다. <ph name="MINUTES" />:<ph name="SECONDS" /> 후에 창이 닫힙니다.</translation> <translation id="3664511988987167893">확장 프로그램 아이콘</translation> <translation id="3665589677786828986">Chrome에서 다른 프로그램이 브라우저 설정을 일부 손상시키고 원래 기본값으로 재설정했음을 감지했습니다.</translation> -<translation id="3665842570601375360">보안:</translation> <translation id="3668570675727296296">언어 설정</translation> <translation id="3668823961463113931">핸들러</translation> <translation id="3670229581627177274">블루투스 켜기</translation> @@ -1797,7 +1794,6 @@ <translation id="3726463242007121105">파일 시스템이 지원되지 않아 이 기기를 열 수 없습니다.</translation> <translation id="3727148787322499904">이 설정을 변경하면 공유한 모든 네트워크에 영향을 줍니다.</translation> <translation id="3727187387656390258">팝업 검사</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900"><ph name="ERROR_LINE" />행에 오류가 있음</translation> <translation id="3733127536501031542">SSL 서버(Step-up 사용)</translation> <translation id="3737536731758327622">다운로드 항목이 여기에 표시됩니다.</translation> @@ -1872,7 +1868,6 @@ <translation id="38275787300541712">완료되면 Enter 키를 누르세요.</translation> <translation id="3827774300009121996">전체화면(&F)</translation> <translation id="3828029223314399057">북마크 검색</translation> -<translation id="3829932584934971895">공급자 유형:</translation> <translation id="3830674330436234648">재생을 사용할 수 없음</translation> <translation id="3831486154586836914">창 개요 모드 시작</translation> <translation id="383161972796689579">이 기기의 소유자가 새로운 사용자를 추가하지 못하도록 설정함</translation> @@ -1893,6 +1888,7 @@ <translation id="3856921555429624101">데이터 사용 측정이 종료됨</translation> <translation id="3857228364945137633">휴대전화가 근처에 있을 때 비밀번호 없이 Smart Lock을 사용하여 <ph name="DEVICE_TYPE" />을(를) 잠금 해제할 수 있습니다.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: 동기화 중지됨</translation> <translation id="3860381078714302691">행아웃 Meet에 오신 것을 환영합니다</translation> <translation id="3862134173397075045">Chrome의 전송 환경에 오신 것을 환영합니다.</translation> <translation id="3862788408946266506">'kiosk_only' 매니페스트 속성을 사용하는 앱은 Chrome OS 키오스크 모드에 설치해야 합니다</translation> @@ -1970,8 +1966,6 @@ <translation id="3968261067169026421">네트워크를 설정할 수 없음</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">계산 중...</translation> -<translation id="3974195870082915331"> -비밀번호를 표시하려면 클릭하세요.</translation> <translation id="3975222297214566386">입력 옵션 도움말 풍선</translation> <translation id="397703832102027365">완료 중...</translation> <translation id="3979395879372752341">새 확장 프로그램이 추가됨(<ph name="EXTENSION_NAME" />)</translation> @@ -2013,6 +2007,7 @@ <translation id="4044612648082411741">인증서 비밀번호를 입력하세요.</translation> <translation id="404493185430269859">기본 검색엔진</translation> <translation id="4047112090469382184">이 기능이 안전한 이유</translation> +<translation id="4051049974203704184">화면에 표시된 내용에 관한 정보 가져오기</translation> <translation id="4052120076834320548">작게</translation> <translation id="4055023634561256217">기기를 Powerwash로 재설정하기 전에 다시 시작해야 합니다.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2034,7 @@ <translation id="4088095054444612037">그룹 공유 승인</translation> <translation id="4089235344645910861">설정이 저장되었으며, 동기화가 시작되었습니다.</translation> <translation id="4090103403438682346">인증 액세스 서비스 사용</translation> +<translation id="4090947011087001172"><ph name="SITE" />의 사이트 권한을 재설정하시겠습니까?</translation> <translation id="4091434297613116013">장</translation> <translation id="4093955363990068916">로컬 파일:</translation> <translation id="4095507791297118304">기본 디스플레이</translation> @@ -2215,7 +2211,6 @@ <translation id="4419556793104466535">동기화, 맞춤설정 등 관리</translation> <translation id="4421932782753506458">복실이</translation> <translation id="4422347585044846479">이 페이지에 대한 북마크 편집</translation> -<translation id="4423104065312875417">추가 음성 엔진 설치</translation> <translation id="4423376891418188461">설정 복원</translation> <translation id="4423482519432579560">맞춤법 검사(&S)</translation> <translation id="442397852638519243"><ph name="USER_NAME" />님, 관리자가 비밀번호 변경을 요청했습니다.</translation> @@ -2240,7 +2235,6 @@ <translation id="4449996769074858870">이 탭은 오디오를 재생합니다.</translation> <translation id="4450974146388585462">진단</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" />에서 검색하거나 URL을 입력하세요.</translation> -<translation id="445923051607553918">WiFi 네트워크 연결</translation> <translation id="4462159676511157176">맞춤 이름 서버</translation> <translation id="4467100756425880649">Chrome 웹 스토어 갤러리</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> 펼치기</translation> @@ -2376,6 +2370,7 @@ <translation id="4682551433947286597">로그인 화면에 배경화면이 표시됩니다.</translation> <translation id="4684427112815847243">모두 동기화</translation> <translation id="4689421377817139245">이 북마크를 내 iPhone에 동기화</translation> +<translation id="4690091457710545971"><Intel Wi-Fi 펌웨어에서 csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon의 4개 파일이 생성되었습니다. 처음 3개 파일은 레지스터 덤프를 포함하는 바이너리 파일로 Intel에서 개인정보나 기기 식별 정보를 포함하지 않도록 선언되었습니다. 4번째 파일은 Intel 펌웨어의 실행 기록으로 모든 개인정보나 기기 식별 정보가 삭제되었지만 너무 커서 여기에 표시할 수 없습니다. 이러한 파일은 최근 생긴 기기의 Wi-Fi 문제로 인해 생성되었으며 관련 문제를 해결하기 위해 Intel과 공유합니다.></translation> <translation id="4692302215262324251"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />에 의해 <ph name="DEVICE_TYPE" />이(가) 기업 관리에 등록되었습니다. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> 이를 예상하지 못한 경우 지원팀에 문의하세요.</translation> @@ -2635,6 +2630,7 @@ <translation id="5074318175948309511">새로운 설정을 적용하기 전에 페이지를 다시 로드해야 할 수도 있습니다.</translation> <translation id="5075131525758602494">SIM PIN 입력</translation> <translation id="5078638979202084724">모든 탭 북마크</translation> +<translation id="5079950360618752063">추천 비밀번호 사용</translation> <translation id="5084230410268011727">사이트에서 모션 및 조도 센서 사용 허용</translation> <translation id="5085162214018721575">업데이트를 확인하는 중</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2669,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">이 항목 삭제</translation> <translation id="5139955368427980650">열기(&O)</translation> +<translation id="5142961317498132443">인증</translation> <translation id="5143374789336132547">홈 버튼을 클릭하면 표시되는 페이지가 '<ph name="EXTENSION_NAME" />' 확장 프로그램으로 인해 변경되었습니다.</translation> <translation id="5143712164865402236">전체화면 열기</translation> <translation id="5145331109270917438">수정된 날짜</translation> @@ -2843,7 +2840,6 @@ <translation id="5380103295189760361">Ctrl, Alt, Shift 또는 Search 키를 길게 누르면 수정자에 대한 단축키를 볼 수 있습니다.</translation> <translation id="5382591305415226340">지원되는 링크 관리</translation> <translation id="5384883051496921101">이 사이트에서 시크릿 모드 외부의 앱을 사용하여 정보를 공유하려고 합니다.</translation> -<translation id="5388588172257446328">사용자 이름:</translation> <translation id="5388885445722491159">페어링됨</translation> <translation id="5389237414310520250">새로운 사용자를 만들지 못했습니다. 하드 드라이브 공간 및 권한을 확인한 다음 다시 시도해 주세요.</translation> <translation id="5390100381392048184">사이트에서 소리를 재생하도록 허용</translation> @@ -2968,7 +2964,6 @@ <translation id="5551573675707792127">키보드 및 텍스트 입력</translation> <translation id="5553089923092577885">인증서 정책 매핑</translation> <translation id="5554489410841842733">현재 페이지에서 확장 프로그램을 실행할 수 있게 되면 아이콘이 표시됩니다.</translation> -<translation id="5554573843028719904">기타 Wi-Fi 네트워크...</translation> <translation id="5554720593229208774">이메일 인증 기관</translation> <translation id="5556206011531515970">다음을 클릭하여 기본 브라우저를 선택하세요.</translation> <translation id="5556459405103347317">새로고침</translation> @@ -3009,7 +3004,6 @@ <translation id="5610038042047936818">카메라 모드로 전환</translation> <translation id="5612720917913232150"><ph name="URL" />에서 내 컴퓨터의 위치에 액세스하려고 합니다</translation> <translation id="5612734644261457353">비밀번호를 여전히 확인할 수 없습니다. 참고: 최근에 비밀번호를 변경한 경우 로그아웃해야 새로운 비밀번호가 적용됩니다. 이전 비밀번호를 사용해 보세요.</translation> -<translation id="5613695965848159202">익명 ID:</translation> <translation id="5614190747811328134">사용자 알림</translation> <translation id="561698261642843490">Firefox 닫기</translation> <translation id="5618075537869101857">키오스크 애플리케이션을 시작할 수 없습니다.</translation> @@ -3227,7 +3221,6 @@ <translation id="5941343993301164315"><ph name="TOKEN_NAME" />에 로그인하세요.</translation> <translation id="5941711191222866238">최소화</translation> <translation id="5946591249682680882">보고서 ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">사설 네트워크 추가</translation> <translation id="5949544233750246342">파일을 파싱할 수 없습니다.</translation> <translation id="5955282598396714173">비밀번호가 만료되었습니다. 로그아웃한 다음 다시 로그인하여 비밀번호를 변경해 주세요.</translation> <translation id="5956585768868398362">설정한 검색 페이지가 맞습니까?</translation> @@ -3388,11 +3381,13 @@ <translation id="6198102561359457428">로그아웃한 후 다시 로그인...</translation> <translation id="6198252989419008588">PIN 변경</translation> <translation id="6199801702437275229">남은 저장 용량을 확인하는 중...</translation> +<translation id="6204015976622790023">화면에 표시된 내용에 관한 어시스턴트의 맞춤 추천 보기</translation> <translation id="6205710420833115353">일부 작업 시간이 예상보다 지연되고 있습니다. 중단하시겠습니까?</translation> <translation id="6206311232642889873">이미지 복사(&Y)</translation> <translation id="6207200176136643843">기본 확대/축소 수준으로 재설정</translation> <translation id="620722923698527029">항상 이러한 유형의 링크를 연결된 앱에서 열기</translation> <translation id="6207937957461833379">국가/지역</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: 동기화가 작동하지 않음</translation> <translation id="6212039847102026977">고급 네트워크 속성 표시</translation> <translation id="6212168817037875041">디스플레이 사용 중지</translation> <translation id="6212752530110374741">이메일 링크</translation> @@ -3430,7 +3425,6 @@ <translation id="6263541650532042179">동기화 재설정</translation> <translation id="6264365405983206840">모두 선택(&A)</translation> <translation id="6264422956566238156">동기화가 사용 설정됨</translation> -<translation id="6265930187414222160">완료되었습니다. 유해한 소프트웨어가 삭제되었습니다.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" />에 대해 인증을 받으려면 인증서를 선택하세요.</translation> <translation id="6268252012308737255"><ph name="APP" />(으)로 열기</translation> <translation id="6268747994388690914">HTML 파일에서 북마크 가져오기...</translation> @@ -3537,7 +3531,6 @@ '다음'을 클릭하여 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 계정에 로그인하세요.</translation> <translation id="6419546358665792306">압축해제된 확장 프로그램을 로드합니다.</translation> <translation id="642282551015776456">폴더 이름의 파일으로 사용할 수 없는 이름입니다.</translation> -<translation id="6423239382391657905">공개 VPN</translation> <translation id="6426200009596957090">ChromeVox 설정 열기</translation> <translation id="6429384232893414837">업데이트 오류</translation> <translation id="6430814529589430811">Base64-인코딩 ASCII, 단일 인증서</translation> @@ -3618,7 +3611,6 @@ <translation id="6544215763872433504">나를 위해 Google이 만든 웹브라우저</translation> <translation id="6545665334409411530">반복 속도</translation> <translation id="6545834809683560467">예상 검색어 서비스를 사용하여 검색주소창 또는 앱 런처 검색창에 입력되는 검색어 및 URL을 더 빠르게 완성</translation> -<translation id="6546686722964485737">Wimax 네트워크에 참여</translation> <translation id="6547316139431024316">이 확장 프로그램에 대해 다시 경고하지 않음</translation> <translation id="6547354035488017500">최소 512MB의 저장 공간을 확보하지 않으면 기기가 응답하지 않을 것입니다. 저장 공간을 확보하려면 기기에서 파일을 삭제하세요.</translation> <translation id="6549689063733911810">최근 문서함</translation> @@ -4037,7 +4029,6 @@ <translation id="7201014958346994077">Linux 파일을 볼 수 없음</translation> <translation id="720110658997053098">이 기기를 키오스크 모드로 영구 고정</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' 삭제됨</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" />을(를) 다운로드 중...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{페이지 나가기}other{페이지 나가기}}</translation> <translation id="7216409898977639127">이동통신사</translation> @@ -4515,7 +4506,6 @@ <translation id="7909969815743704077">시크릿 모드에서 다운로드됨</translation> <translation id="7910768399700579500">새 폴더(&N)</translation> <translation id="7912080627461681647">서버에서 비밀번호가 변경되었습니다. 로그아웃한 다음 다시 로그인해 주세요.</translation> -<translation id="7912883689016444961">모바일 네트워크 설정</translation> <translation id="7915471803647590281">의견을 보내기 전에 현재 상황을 입력해 주세요.</translation> <translation id="7916556741383518510">클릭 시</translation> <translation id="792514962475806987">고정 돋보기 확대/축소 수준:</translation> @@ -4569,7 +4559,6 @@ <translation id="7988355189918024273">접근성 기능 사용</translation> <translation id="7994702968232966508">EAP 방식</translation> <translation id="799547531016638432">바로가기 삭제</translation> -<translation id="7997479212858899587">ID:</translation> <translation id="7997826902155442747">프로세스 우선순위</translation> <translation id="7999229196265990314">생성된 파일: @@ -4653,7 +4642,6 @@ <translation id="8105368624971345109">사용 중지</translation> <translation id="8106045200081704138">공유 문서함</translation> <translation id="8107015733319732394"><ph name="DEVICE_TYPE" />에 Google Play 스토어를 설치합니다. 설치하는 데 몇 분 정도 걸릴 수 있습니다.</translation> -<translation id="8109930990200908494">사용자 인증을 받으려면 로그인해야 합니다.</translation> <translation id="8111155949205007504">이 비밀번호를 iPhone과 공유하기</translation> <translation id="8113043281354018522">라이선스 유형 선택</translation> <translation id="8116190140324504026">추가 정보...</translation> @@ -4664,6 +4652,7 @@ <translation id="8118860139461251237">다운로드 관리</translation> <translation id="81238879832906896">노란색과 흰색 꽃</translation> <translation id="8124313775439841391">관리되는 ONC</translation> +<translation id="8125562866093998907">사이트에서 계정 보안 강화를 위해 보안 키를 인증하려 합니다.</translation> <translation id="813082847718468539">사이트 정보 보기</translation> <translation id="8131740175452115882">확인</translation> <translation id="8133676275609324831">폴더 열기(&S)</translation> @@ -4774,7 +4763,6 @@ <translation id="8308179586020895837"><ph name="HOST" />에서 카메라에 액세스하려는 경우 메시지 표시</translation> <translation id="830868413617744215">베타</translation> <translation id="8309458809024885768">인증서가 이미 존재합니다.</translation> -<translation id="8309505303672555187">네트워크 선택:</translation> <translation id="8312871300878166382">폴더에 붙여넣기</translation> <translation id="8317671367883557781">네트워크 연결 추가</translation> <translation id="8319414634934645341">확장된 키 사용</translation> @@ -4849,7 +4837,6 @@ <translation id="8451512073679317615">어시스턴트</translation> <translation id="8452135315243592079">SIM 카드 없음</translation> <translation id="8453482423012550001">$1개 항목 복사 중...</translation> -<translation id="8454288007744638700">또는 새로운 네트워크 선택</translation> <translation id="845627346958584683">만료 시간</translation> <translation id="8456681095658380701">잘못된 이름입니다.</translation> <translation id="8457451314607652708">북마크 가져오기</translation> @@ -4913,6 +4900,7 @@ <translation id="855081842937141170">탭 고정</translation> <translation id="8551388862522347954">라이선스</translation> <translation id="8553342806078037065">다른 사용자 관리</translation> +<translation id="8554899698005018844">언어가 없음</translation> <translation id="855773602626431402">이 페이지에서 샌드박스 처리되지 않은 플러그인 실행을 차단하였습니다.</translation> <translation id="8557930019681227453">매니페스트</translation> <translation id="8559694214572302298">이미지 디코더</translation> @@ -4950,7 +4938,6 @@ <translation id="862727964348362408">일시중지됨</translation> <translation id="862750493060684461">CSS 캐시</translation> <translation id="8627795981664801467">보안 연결만</translation> -<translation id="8628085465172583869">서버 호스트 이름:</translation> <translation id="8630903300770275248">관리 대상 사용자 가져오기</translation> <translation id="8631032106121706562">꽃잎</translation> <translation id="8637542770513281060">컴퓨터에 보안 모듈이 있습니다. 보안 모듈은 Chrome OS에서 여러 중요한 보안 기능을 구현하는 데 사용됩니다. 자세히 알아보려면 Chromebook 고객센터의 다음 페이지를 방문하세요. https://support.google.com/chromebook/?p=sm</translation> @@ -5206,7 +5193,6 @@ <translation id="899403249577094719">Netscape Certificate Base URL</translation> <translation id="8995603266996330174">관리자: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">계정 추가...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" />[<ph name="ISSUED_TO" />](<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">디스크 이미지를 만드는 중입니다.</translation> <translation id="9003647077635673607">모든 웹사이트에서 허용</translation> <translation id="9003677638446136377">다시 확인</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb index 5e4765e..01006bf 100644 --- a/chrome/app/resources/generated_resources_lt.xtb +++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Beveik atėjo laikas padaryti pertrauką</translation> <translation id="1062407476771304334">Pakeisti</translation> -<translation id="1064835277883315402">Prisijunkite prie privataus tinklo</translation> <translation id="1064912851688322329">Atjunkite „Google“ paskyrą</translation> <translation id="1067048845568873861">Sukurtas</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Ieškoma...</translation> <translation id="1316495628809031177">Sinchronizavimas pristabdytas</translation> <translation id="1319979322914001937">Programa, kuri rodo filtruotą plėtinių iš „Chrome“ internetinės parduotuvės sąrašą. Sąraše rodomus plėtinius galima įdiegti tiesiogiai iš programos.</translation> -<translation id="132090119144658135">Temos atitiktis:</translation> <translation id="1326317727527857210">Prisijunkite prie „Chrome“, kad pasiektumėte skirtukus iš kitų įrenginių.</translation> <translation id="1327074568633507428">„Google“ spausdinimo iš debesies spausdintuvas</translation> <translation id="1327977588028644528">Tinklų sietuvas</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Pašalinti šį asmenį</translation> <translation id="1706586824377653884">Pridėjo jūsų administratorius</translation> <translation id="1706625117072057435">Mastelio keitimo lygiai</translation> -<translation id="1707463636381878959">Bendrinti šį tinklą su kitais naudotojais</translation> <translation id="1708338024780164500">(Neaktyvus)</translation> <translation id="1708713382908678956">„<ph name="NAME_PH" />“ (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (savoji)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Įgalinti temą</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Žr. „Chrome“ internetinėje parduotuvėje</translation> -<translation id="1758831820837444715">Eterneto tinklo konfigūravimas</translation> <translation id="1763046204212875858">Kurti programos sparčiuosius mygtukus</translation> <translation id="1763108912552529023">Toliau tyrinėti</translation> <translation id="1763808908432309942">Atidaromas naujame skirtuke</translation> @@ -875,7 +871,6 @@ <translation id="2291643155573394834">Kitas skirtukas</translation> <translation id="2292848386125228270">Paleiskite „<ph name="PRODUCT_NAME" />“ kaip įprastas naudotojas. Jei norite paleisti kaip pagrindinis naudotojas, kad galėtumėte kurti, iš naujo paleiskite naudodami žymą „--no-sandbox“.</translation> <translation id="2294358108254308676">Ar norite įdiegti „<ph name="PRODUCT_NAME" />“?</translation> -<translation id="2296019197782308739">EAP metodas:</translation> <translation id="2297705863329999812">Ieškoti spausdintuvų</translation> <translation id="2300383962156589922">„<ph name="APP_NAME" />“ tinkinimas ir valdymas</translation> <translation id="2301382460326681002">Plėtinio šakninis katalogas neteisingas.</translation> @@ -933,7 +928,6 @@ <translation id="2379281330731083556">Spausdinti naudojant sistemos dialogo langą... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Klausti prieš siunčiant (rekomenduojama)</translation> <translation id="2384436799579181135">Įvyko klaida. Patikrinkite spausdintuvą ir bandykite dar kartą.</translation> -<translation id="2385700042425247848">Paslaugos pavadinimas:</translation> <translation id="2387458720915042159">Tarpinio serverio ryšio tipas</translation> <translation id="2391419135980381625">Standartinis šriftas</translation> <translation id="2391762656119864333">Anuliuoti</translation> @@ -984,7 +978,6 @@ <translation id="247949520305900375">Bendrinti garsą</translation> <translation id="2480868415629598489">Keisti kopijuojamus ir įklijuojamus duomenis</translation> <translation id="2482878487686419369">Pranešimai</translation> -<translation id="2485056306054380289">Serverio CA sertifikatas:</translation> <translation id="2485422356828889247">Pašalinti</translation> <translation id="2487067538648443797">Pridėti naują žymą</translation> <translation id="248861575772995840">Nepavyksta rasti jūsų telefono. Įsitikinkite, kad „<ph name="DEVICE_TYPE" />“ įrenginyje įjungtas „Bluetooth“. <a>Sužinokite daugiau</a></translation> @@ -1109,7 +1102,6 @@ <translation id="2653659639078652383">Pateikti</translation> <translation id="265390580714150011">Lauko vertė</translation> <translation id="2654166010170466751">Leisti svetainėms diegti mokėjimų dorokles</translation> -<translation id="2655386581175833247">Naudotojo sertifikatas:</translation> <translation id="2660779039299703961">Įvykis</translation> <translation id="266079277508604648">Nepavyko prijungti spausdintuvo. Patikrinkite, ar spausdintuvas yra įjungtas ir prijungtas prie „Chromebook“ naudojant „Wi-Fi“ arba USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1409,7 +1401,6 @@ <translation id="3100609564180505575">Moduliai (<ph name="TOTAL_COUNT" />) – žinomų konfliktų: <ph name="BAD_COUNT" />, įtariamų: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Data ir laikas</translation> <translation id="310671807099593501">Svetainė naudoja „Bluetooth“</translation> -<translation id="3108967419958202225">Pasirinkite...</translation> <translation id="3115128645424181617">Nepavyksta rasti jūsų telefono. Įsitikinkite, kad jis netoliese ir įjungėte „Bluetooth“.</translation> <translation id="3115147772012638511">Laukiama talpyklos...</translation> <translation id="3118319026408854581">„<ph name="PRODUCT_NAME" />“ pagalba</translation> @@ -1454,7 +1445,6 @@ <translation id="3165390001037658081">Kai kurie operatoriai gali blokuoti šią funkciją.</translation> <translation id="316854673539778496">Jei norite gauti visus plėtinius visuose įrenginiuose, prisijunkite ir įjunkite sinchronizavimą.</translation> <translation id="3170072451822350649">Be to, galite praleisti prisijungimo veiksmą ir <ph name="LINK_START" />naršyti kaip svečias<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Jei norite slėpti slaptažodį, spustelėkite.</translation> <translation id="3177909033752230686">Puslapio kalba:</translation> <translation id="3181110748548073003">Paspauskite |<ph name="SHORTCUT" />|, kad eitumėte pirmyn</translation> <translation id="3182749001423093222">Rašybos tikrinimas</translation> @@ -1485,7 +1475,6 @@ <translation id="3236289833370040187">Nuosavybės teisė bus perkelta <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Atidaryti plėtinių parinktis</translation> <translation id="3241680850019875542">Pasirinkite norimo pakuoti plėtinio šakninį katalogą. Norėdami atnaujinti plėtinį, pasirinkite ir asmeninio rakto failą, kuris bus naudojamas iš naujo.</translation> -<translation id="3242765319725186192">Paruoštas bendrinti raktas:</translation> <translation id="3244294424315804309">Tęsti nutildžius garsą</translation> <translation id="3245321423178950146">Nežinomas atlikėjas</translation> <translation id="3246097286174000800">Išbandyti „Smart Lock“</translation> @@ -1618,7 +1607,6 @@ <translation id="3440663250074896476">Daugiau veiksmų („<ph name="BOOKMARK_NAME" />“)</translation> <translation id="3440761377721825626">Klausti, kai svetainė nori naudoti papildinį kompiuteriui pasiekti</translation> <translation id="3441653493275994384">Ekranas</translation> -<translation id="3445830502289589282">2 tapatybės nustatymo etapas:</translation> <translation id="344630545793878684">Skaityti duomenys daugybėje svetainių</translation> <translation id="3449839693241009168">Paspauskite <ph name="SEARCH_KEY" />, kad galėtumėte siųsti komandas į „<ph name="EXTENSION_NAME" />“</translation> <translation id="3450157232394774192">Neveikos būsenos užėmimo procentas</translation> @@ -1659,7 +1647,6 @@ <translation id="3495304270784461826">Klaidų: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">„Google“ padėjėjo nustatymai</translation> <translation id="3496213124478423963">Tolinti</translation> -<translation id="3504135463003295723">Grupės pavadinimas</translation> <translation id="3505030558724226696">Panaikinti įrenginio prieigą</translation> <translation id="3507421388498836150">Dabartiniai „<ph name="EXTENSION_NAME" />“ leidimai</translation> <translation id="3507547268929739059">Pašalinti „Linux“ programas iš „Chromebook“</translation> @@ -1768,7 +1755,6 @@ <translation id="3661054927247347545">Prisijungimo sertifikatas negalioja. Langas bus uždarytas po <ph name="MINUTES" /> min. <ph name="SECONDS" /> sek.</translation> <translation id="3664511988987167893">Plėtinio piktograma</translation> <translation id="3665589677786828986">„Chrome“ aptiko, kad kai kuriuos nustatymus sugadino kita programa, ir nustatė juos iš naujo į pirminius numatytuosius nustatymus.</translation> -<translation id="3665842570601375360">Sauga:</translation> <translation id="3668570675727296296">Kalbos nustatymai</translation> <translation id="3668823961463113931">Apdorojimo programos</translation> <translation id="3670229581627177274">Įjungti „Bluetooth“</translation> @@ -1807,7 +1793,6 @@ <translation id="3726463242007121105">Įrenginio negalima atidaryti, nes nepalaikoma jo failų išdėstymo sistema.</translation> <translation id="3727148787322499904">Šio nustatymo pakeitimas turės įtakos visiems bendrinamiems tinklams</translation> <translation id="3727187387656390258">Tikrinti iššokantįjį langą</translation> -<translation id="3728067901555601989">Vienkartinė slaptafrazė:</translation> <translation id="3732078975418297900">Klaida eilutėje Nr. <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL serveris su sąranka</translation> <translation id="3737536731758327622">Čia rodomi jūsų atsisiuntimai</translation> @@ -1882,7 +1867,6 @@ <translation id="38275787300541712">Paspauskite „Enter“, kai bus atlikta</translation> <translation id="3827774300009121996">&Visas ekranas</translation> <translation id="3828029223314399057">Ieškoti žymėse</translation> -<translation id="3829932584934971895">Teikėjo tipas:</translation> <translation id="3830674330436234648">Atkūrimas nepasiekiamas</translation> <translation id="3831486154586836914">Įjungtas lango apžvalgos režimas</translation> <translation id="383161972796689579">Šio įrenginio savininkas neleido pridėti naujų naudotojų</translation> @@ -1981,7 +1965,6 @@ <translation id="3968261067169026421">Nepavyko nustatyti tinklo</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Skaičiuojama...</translation> -<translation id="3974195870082915331">Spustelėkite, kad slaptažodis būtų parodytas.</translation> <translation id="3975222297214566386">Įvesties parinkčių debesėlis</translation> <translation id="397703832102027365">Užbaigiama...</translation> <translation id="3979395879372752341">Pridėtas naujas plėtinys (<ph name="EXTENSION_NAME" />)</translation> @@ -2229,7 +2212,6 @@ <translation id="4419556793104466535">Valdykite sinchronizavimą, suasmeninimą ir dar daugiau</translation> <translation id="4421932782753506458">Pūkuotasis</translation> <translation id="4422347585044846479">Redaguoti žymę šitam puslapiui</translation> -<translation id="4423104065312875417">Įdiegti papildomų kalbų variklių</translation> <translation id="4423376891418188461">Atkurti nustatymus</translation> <translation id="4423482519432579560">&Rašybos tikrinimas</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, jūsų administratoriui reikia pakeisti jūsų slaptažodį.</translation> @@ -2254,7 +2236,6 @@ <translation id="4449996769074858870">Šiame skirtuko lape leidžiamas garso įrašas.</translation> <translation id="4450974146388585462">Diagnozuoti</translation> <translation id="4453946976636652378">Ieškokite „<ph name="SEARCH_ENGINE_NAME" />“ arba įveskite URL</translation> -<translation id="445923051607553918">Prisijungti prie „Wi-Fi“ tinklo</translation> <translation id="4462159676511157176">Tinkintų pavadinimų serveriai</translation> <translation id="4467100756425880649">„Chrome“ internetinės parduotuvės galerija</translation> <translation id="4467101674048705704">Išskleisti aplanką „<ph name="FOLDER_NAME" />“</translation> @@ -2860,7 +2841,6 @@ <translation id="5380103295189760361">Jei norite matyti šių modifikatorių sparčiuosius klavišus, laikykite paspaudę „Control“, „Alt“, „Shift“ arba „Search“.</translation> <translation id="5382591305415226340">Tvarkyti palaikomas nuorodas</translation> <translation id="5384883051496921101">Šioje svetainėje ketinama bendrinti informaciją su programa ne inkognito režimu.</translation> -<translation id="5388588172257446328">Naudotojo vardas:</translation> <translation id="5388885445722491159">Susieta</translation> <translation id="5389237414310520250">Nepavyko sukurti naujo naudotojo. Patikrinkite, ar standžiajame diske yra vietos, ir leidimus ir bandykite dar kartą.</translation> <translation id="5390100381392048184">Leisti svetainėms leisti garsą</translation> @@ -2985,7 +2965,6 @@ <translation id="5551573675707792127">Klaviatūra ir teksto įvestis</translation> <translation id="5553089923092577885">Sertifikato politikos atvaizdavimas</translation> <translation id="5554489410841842733">Ši piktograma bus matoma, kai plėtinys galės veikti esamame puslapyje.</translation> -<translation id="5554573843028719904">Kitas „Wi-Fi“ tinklas...</translation> <translation id="5554720593229208774">El. pašto sertifikavimo institucija</translation> <translation id="5556206011531515970">Jei norite pasirinkti numatytąją naršyklę, spustelėkite „Kitas“.</translation> <translation id="5556459405103347317">Įkelti iš naujo</translation> @@ -3026,7 +3005,6 @@ <translation id="5610038042047936818">Perjungti į fotoaparato režimą</translation> <translation id="5612720917913232150"><ph name="URL" /> nori naudoti kompiuterio vietovę</translation> <translation id="5612734644261457353">Deja, jūsų slaptažodžio patvirtinti vis tiek nepavyko. Pastaba: jei neseniai pakeitėte slaptažodį, naujas slaptažodis bus taikomas, kai atsijungsite. Čia naudokite senąjį slaptažodį.</translation> -<translation id="5613695965848159202">Anoniminė tapatybė:</translation> <translation id="5614190747811328134">Naudotojo pastaba</translation> <translation id="561698261642843490">„Firefox“ uždarymas</translation> <translation id="5618075537869101857">Deja, nepavyko paleisti viešojo terminalo programos.</translation> @@ -3245,7 +3223,6 @@ <translation id="5941343993301164315">Prisijunkite prie <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Sumažinti</translation> <translation id="5946591249682680882">Ataskaitos ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Pridėti privatųjį tinklą</translation> <translation id="5949544233750246342">Nepavyksta išanalizuoti failo</translation> <translation id="5955282598396714173">Baigėsi slaptažodžio galiojimo laikas. Atsijunkite, tada vėl prisijunkite, kad jį pakeistumėte.</translation> <translation id="5956585768868398362">Ar tai paieškos puslapis, kurį tikėjotės išvysti?</translation> @@ -3450,7 +3427,6 @@ <translation id="6263541650532042179">nustatyti sinchronizavimą iš naujo</translation> <translation id="6264365405983206840">Pasirinkti &viską</translation> <translation id="6264422956566238156">Įjungėt sinchronizavimą</translation> -<translation id="6265930187414222160">Baigta! Žalinga programinė įranga pašalinta.</translation> <translation id="6267166720438879315">Pasirinkite sertifikatą, kad patvirtintumėte savo autentiškumą <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Atidaryti naudojant „<ph name="APP" />“</translation> <translation id="6268747994388690914">Importuoti žymes iš HTML failo...</translation> @@ -3557,7 +3533,6 @@ Spustelėkite „Toliau“, kad tęstumėte prisijungimą prie <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> paskyros.</translation> <translation id="6419546358665792306">Įkelti neišpakuotą</translation> <translation id="642282551015776456">Šio pavadinimo negalima naudoti kaip aplanko pavadinimo</translation> -<translation id="6423239382391657905">Atidaryti virtualųjį privatųjį tinklą</translation> <translation id="6426200009596957090">Atidaryti „ChromeVox“ nustatymus</translation> <translation id="6429384232893414837">Atnaujinimo klaida</translation> <translation id="6430814529589430811">„Base64“ užkoduotas ASCII, vienas sertifikatas</translation> @@ -3638,7 +3613,6 @@ <translation id="6544215763872433504">Jums skirta žiniatinklio naršyklė, sukurta „Google“</translation> <translation id="6545665334409411530">Kartojimo dažnis</translation> <translation id="6545834809683560467">Naudoti numatymo paslaugą, padėsiančią užbaigti adreso juostoje arba programų paleidimo priemonės paieškos laukelyje įvedamus paieškos terminus ir URL adresus</translation> -<translation id="6546686722964485737">Prisijungimas prie „Wimax“ tinklo</translation> <translation id="6547316139431024316">Daugiau nebeįspėti apie šį plėtinį</translation> <translation id="6547354035488017500">Atlaisvinkite bent 512 MB vietos arba jūsų įrenginys nebeatsakys. Norėdami atlaisvinti vietos, ištrinkite failus iš įrenginio saugyklos.</translation> <translation id="6549689063733911810">Naujausi</translation> @@ -4057,7 +4031,6 @@ <translation id="7201014958346994077">Nepavyko peržiūrėti „Linux“ failų</translation> <translation id="720110658997053098">Įgalinti nuolatinį šio įrenginio veikimą viešojo terminalo režimu</translation> <translation id="7201118060536064622">„<ph name="DELETED_ITEM_NAME" />“ ištrintas (-a)</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Atsisiunčiamas „<ph name="PLUGIN_NAME" />“...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Išeiti iš puslapio}one{Išeiti iš puslapių}few{Išeiti iš puslapių}many{Išeiti iš puslapių}other{Išeiti iš puslapių}}</translation> <translation id="7216409898977639127">Mobiliojo ryšio teikėjas</translation> @@ -4535,7 +4508,6 @@ <translation id="7909969815743704077">Atsisiųsta inkognito režimu</translation> <translation id="7910768399700579500">&Naujas aplankas</translation> <translation id="7912080627461681647">Slaptažodis pakeistas serveryje. Atsijunkite, tada vėl prisijunkite.</translation> -<translation id="7912883689016444961">Konfigūruoti mobiliojo ryšio tinklą</translation> <translation id="7915471803647590281">Prieš atsiųsdami atsiliepimą, aprašykite problemą.</translation> <translation id="7916556741383518510">Spustelėjus</translation> <translation id="792514962475806987">Prie doko prijungto didintuvo mastelio keitimo lygis:</translation> @@ -4589,7 +4561,6 @@ <translation id="7988355189918024273">Įgalinti pasiekiamumo funkcijas</translation> <translation id="7994702968232966508">EAP metodas</translation> <translation id="799547531016638432">Pašalinti spartųjį klavišą</translation> -<translation id="7997479212858899587">Tapatybė:</translation> <translation id="7997826902155442747">Apdorojimo pirmumas</translation> <translation id="7999229196265990314">Sukurti šie failai: @@ -4673,7 +4644,6 @@ <translation id="8105368624971345109">Išjungti</translation> <translation id="8106045200081704138">Bendrinama su manimi</translation> <translation id="8107015733319732394">Įdiegiama „Google Play“ parduotuvė jūsų „<ph name="DEVICE_TYPE" />“ įrenginyje. Tai gali šiek tiek užtrukti.</translation> -<translation id="8109930990200908494">Norint gauti naudotojo sertifikatą reikia prisijungti.</translation> <translation id="8111155949205007504">Bendrinkite šį slaptažodį su „iPhone“</translation> <translation id="8113043281354018522">Pasirinkite licencijos tipą</translation> <translation id="8116190140324504026">Daugiau informacijos...</translation> @@ -4795,7 +4765,6 @@ <translation id="8308179586020895837">Klausti, jei <ph name="HOST" /> nori pasiekti fotoaparatą</translation> <translation id="830868413617744215">Beta versija</translation> <translation id="8309458809024885768">Sertifikatas jau yra</translation> -<translation id="8309505303672555187">Pasirinkti tinklą:</translation> <translation id="8312871300878166382">Įklijuoti į aplanką</translation> <translation id="8317671367883557781">Pridėti tinklo ryšį</translation> <translation id="8319414634934645341">Išplėstinis rakto naudojimas</translation> @@ -4870,7 +4839,6 @@ <translation id="8451512073679317615">Padėjėjas</translation> <translation id="8452135315243592079">Nėra SIM kortelės</translation> <translation id="8453482423012550001">Kopijuojama elementų: $1...</translation> -<translation id="8454288007744638700">Arba pasirinkite naują tinklą:</translation> <translation id="845627346958584683">Galiojimo laikas</translation> <translation id="8456681095658380701">Netinkamas pavadinimas</translation> <translation id="8457451314607652708">Importuoti žymes</translation> @@ -4972,7 +4940,6 @@ <translation id="862727964348362408">Laikinai sustabdyta</translation> <translation id="862750493060684461">CSS talpykla</translation> <translation id="8627795981664801467">Tik saugus ryšys</translation> -<translation id="8628085465172583869">Prieglobos serverio pavadinimas:</translation> <translation id="8630903300770275248">Importuoti prižiūrimą naudotoją</translation> <translation id="8631032106121706562">Vainiklapiai</translation> <translation id="8637542770513281060">Jūsų kompiuteryje yra saugus modulis, kuris naudojamas „Chrome“ OS įdiegiant daug svarbių saugos funkcijų. Jei norite sužinoti daugiau, apsilankykite „Chromebook“ pagalbos centre adresu https://support.google.com/chromebook/?p=sm</translation> @@ -5228,7 +5195,6 @@ <translation id="899403249577094719">„Netscape“ sertifikatų bazės URL</translation> <translation id="8995603266996330174">Valdoma „<ph name="DOMAIN" />“</translation> <translation id="8996526648899750015">Pridėti paskyrą...</translation> -<translation id="8997135628821231">„<ph name="ISSUED_BY" />“ [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Kuriamas disko vaizdas.</translation> <translation id="9003647077635673607">Leisti visose svetainėse</translation> <translation id="9003677638446136377">Tikrinti dar kartą</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb index 8310107..15d7a62 100644 --- a/chrome/app/resources/generated_resources_lv.xtb +++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Tūlīt būs pārtraukums</translation> <translation id="1062407476771304334">Aizstāt</translation> -<translation id="1064835277883315402">Pievienoties privātam tīklam</translation> <translation id="1064912851688322329">Atvienot savu Google kontu</translation> <translation id="1067048845568873861">Izveidots</translation> <translation id="1067291318998134776">Linux (Beta versija)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Notiek meklēšana...</translation> <translation id="1316495628809031177">Sinhronizācija ir apturēta</translation> <translation id="1319979322914001937">Lietotne, kurā tiek rādīts filtrēts saraksts ar Chrome interneta veikalā pieejamiem paplašinājumiem. Sarakstā esošos paplašinājumus var instalēt tieši no lietotnes.</translation> -<translation id="132090119144658135">Temata atbilstība:</translation> <translation id="1326317727527857210">Pierakstieties pārlūkā Chrome, lai būtu pieejamas cilnes no citām jūsu ierīcēm.</translation> <translation id="1327074568633507428">Printeris Google mākoņdrukā</translation> <translation id="1327977588028644528">Vārteja</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Lietojumprogrammas logs</translation> <translation id="1534389735079119190">KĻŪDA: neizdevās palaist VM konteineru.</translation> <translation id="15373452373711364">Liels peles kursors</translation> +<translation id="1540605929960647700">Demonstrācijas režīma iespējošana</translation> <translation id="1543284117603151572">Importētas no pārlūkprogrammas Edge</translation> <translation id="1545177026077493356">Automātiskais kioska režīms</translation> <translation id="1545775234664667895">Instalēts motīvs “<ph name="THEME_NAME" />”</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Palīdziet uzlabot programmu <ph name="PRODUCT_NAME" />, automātiski nosūtot lietošanas statistiku un avārijas pārskatus uzņēmumam Google</translation> <translation id="1658424621194652532">Šī lapa piekļūst jūsu mikrofonam.</translation> <translation id="1660204651932907780">Atļaut vietnēm atskaņot skaņu (ieteicams)</translation> +<translation id="1660938185063657230">Drošības atslēgas verifikācija</translation> <translation id="1661156625580498328">Piemērot AES šifrēšanu (ieteicams).</translation> <translation id="1661245713600520330">Šajā lapā ir uzskaitīti visi moduļi, kas ielādēti galvenajā procesā, un moduļi, kas reģistrēti, lai to ielādi veiktu vēlāk.</translation> <translation id="166179487779922818">Parole ir pārāk īsa.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Neļaut vietnēm skatīt starpliktuvē kopēto tekstu un attēlus</translation> <translation id="1682548588986054654">Jauns inkognito režīma logs</translation> <translation id="168715261339224929">Lai grāmatzīmes būtu pieejamas visās jūsu ierīcēs, ieslēdziet sinhronizāciju.</translation> +<translation id="1688867105868176567">Vai notīrīt vietnes datus?</translation> <translation id="1688935057616748272">Ierakstiet kādu burtu.</translation> <translation id="168991973552362966">Tuvumā esoša printera pievienošana</translation> <translation id="1689945336726856614">Kopēt &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Noņemt šo lietotāju</translation> <translation id="1706586824377653884">Pievienoja administrators</translation> <translation id="1706625117072057435">Tālummaiņas līmeņi</translation> -<translation id="1707463636381878959">Kopīgot šo tīklu ar citiem lietotājiem</translation> <translation id="1708338024780164500">(Neaktīva)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (sākotnējā)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Iespējot motīvu</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Skatīt Chrome interneta veikalā</translation> -<translation id="1758831820837444715">Ethernet tīkla konfigurēšana</translation> <translation id="1763046204212875858">Izveidot lietojumprogrammu saīsnes</translation> <translation id="1763108912552529023">Turpināt izpēti</translation> <translation id="1763808908432309942">Tiks atvērta jaunā cilnē</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Mainīt, kā tiek kopīgots šis fails</translation> <translation id="1841545962859478868">Ierīces administrators var uzraudzīt šo:</translation> <translation id="1841705068325380214">“<ph name="EXTENSION_NAME" />” ir atspējots</translation> +<translation id="1842766183094193446">Vai tiešām vēlaties iespējot demonstrācijas režīmu?</translation> <translation id="1844692022597038441">Šis fails nav pieejams bezsaistē.</translation> <translation id="1846308012215045257">Lai palaistu spraudni <ph name="PLUGIN_NAME" />, nospiediet taustiņu Ctrl un noklikšķiniet</translation> +<translation id="1847880352285315359">Saglabāts</translation> <translation id="1848219224579402567">Izrakstīties, kad vāks tiek aizvērts</translation> <translation id="184823282865851239">Bloķēt, ja vietnē tiek rādītas traucējošas reklāmas</translation> <translation id="1849186935225320012">Šai lapai ir pieejama MIDI ierīču pilnīga pārvaldība.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Vēlāk varēsiet to mainīt iestatījumos.</translation> <translation id="2006638907958895361">Atvērt saiti lietotnē <ph name="APP" /></translation> <translation id="2007404777272201486">Ziņot par problēmu...</translation> +<translation id="2016237810978710652">Notiek Linux failu atvēršana…</translation> <translation id="2016430552235416146">Tradicionālā</translation> <translation id="2017334798163366053">Atspējot veiktspējas datu apkopošanu</translation> <translation id="2017836877785168846">Notīra vēsturi un automātiskās pabeigšanas ierakstus adreses joslā.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Kartes informācijas rediģēšana</translation> <translation id="2154710561487035718">Kopēt URL</translation> <translation id="2155772377859296191">Noteiktā izšķirtspēja: <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Varat palīdzēt uzlabot Drošo pārlūkošanu, nosūtot noteiktu sistēmas informāciju un lapas saturu Google serveriem.</translation> <translation id="215753907730220065">Iziet no pilnekrāna režīma</translation> <translation id="2157875535253991059">Šī lapa tagad ir redzama pilnekrāna režīmā.</translation> <translation id="216169395504480358">Pievienot Wi-Fi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Pievienot pieprasījuma ID šai ierīcei</translation> <translation id="2175042898143291048">Vienmēr</translation> <translation id="2175607476662778685">Ātrās darbības josla</translation> +<translation id="2176087259161165020">Citi avoti</translation> <translation id="2177950615300672361">Inkognito režīma cilne: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Spraudnim <ph name="PEPPER_PLUGIN_NAME" /> domēnā <ph name="PEPPER_PLUGIN_DOMAIN" /> ir nepieciešama piekļuve jūsu datoram.</translation> <translation id="2178614541317717477">CA drošības politikas apdraudējums</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Nākamā cilne</translation> <translation id="2292848386125228270">Startējiet pārlūku <ph name="PRODUCT_NAME" /> kā parasts lietotājs. Ja vēlaties to palaist izstrādei kā sakni, veiciet atkārtotu palaišanu, izmantojot atzīmi --no-sandbox.</translation> <translation id="2294358108254308676">Vai vēlaties instalēt <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP metode:</translation> <translation id="2297705863329999812">Meklēt printerus</translation> <translation id="2300383962156589922">Pielāgot un kontrolēt lietotni <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Paplašinājuma saknes direktorijs nav derīgs.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">Kļūda: neizdevās atinstalēt lietotni <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Pievienot failu kopīgošanu</translation> <translation id="2367972762794486313">Rādīt lietotnes</translation> +<translation id="2369536625682139252">Tiks izdzēsti visi vietnes <ph name="SITE" /> saglabātie dati, izņemot sīkfailus.</translation> <translation id="2371076942591664043">Atvērt, kad esat beidzis</translation> <translation id="2377319039870049694">Pāriet uz saraksta skatījumu</translation> <translation id="2377667304966270281">Nopietnas kļūdas</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Drukāt, izmantojot sistēmas dialoglodziņu... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Jautāt pirms sūtīšanas (ieteicams)</translation> <translation id="2384436799579181135">Radās kļūda. Lūdzu, pārbaudiet printeri un mēģiniet vēlreiz.</translation> -<translation id="2385700042425247848">Pakalpojuma nosaukums:</translation> <translation id="2387458720915042159">Starpniekservera savienojuma veids</translation> <translation id="2391419135980381625">Standarta fonts</translation> <translation id="2391762656119864333">Atsaukt</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Kopīgot audio</translation> <translation id="2480868415629598489">Modificēt datus, kurus jūs kopējat un ielīmējat</translation> <translation id="2482878487686419369">Paziņojumi</translation> -<translation id="2485056306054380289">Servera CA sertifikāts:</translation> <translation id="2485422356828889247">Atinstalēt</translation> <translation id="2487067538648443797">Pievienot jaunu grāmatzīmi</translation> <translation id="248861575772995840">Nevar atrast tālruni. Jūsu ierīcē (<ph name="DEVICE_TYPE" />) jābūt iespējotam Bluetooth savienojumam. <a>Uzziniet vairāk</a>.</translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Izmantojiet funkciju Powerwash un atiestatiet savā <ph name="IDS_SHORT_PRODUCT_NAME" /> ierīcē sākotnējos rūpnīcas iestatījumus.</translation> <translation id="2567257616420533738">Parole ir saglabāta. Skatiet un pārvaldiet saglabātās paroles vietnē <ph name="SAVED_PASSWORDS_LINK" />.</translation> <translation id="2568774940984945469">Informācijas joslas konteiners</translation> +<translation id="2570454805927264159">Visu Asistenta iespēju izmantošana</translation> <translation id="257088987046510401">Motīvi</translation> <translation id="2572032849266859634">Tika piešķirta tikai lasīšanas piekļuve krātuvei <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Izvēlieties attēlu un vārdu</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Iesniegt</translation> <translation id="265390580714150011">Lauka vērtība</translation> <translation id="2654166010170466751">Atļaut vietnēm instalēt maksājumu apdarinātājus</translation> -<translation id="2655386581175833247">Lietotāja sertifikāts:</translation> <translation id="2660779039299703961">Notikums</translation> <translation id="266079277508604648">Nevar izveidot savienojumu ar printeri. Pārbaudiet, vai printeris ir ieslēgts un vai printerim ir izveidots savienojums ar Chromebook datoru Wi-Fi tīklā vai izmantojot USB savienojumu.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Nav lietojuma datu</translation> <translation id="3007214526293698309">Fiksēt malu attiecību</translation> <translation id="3007771295016901659">Dublēt cilni</translation> +<translation id="3008272652534848354">Atiestatīt atļaujas</translation> <translation id="3009300415590184725">Vai tiešām vēlaties atcelt mobilo datu pakalpojumu iestatīšanas procesu?</translation> <translation id="3009779501245596802">Rādītājā iekļautās datu bāzes</translation> <translation id="3010279545267083280">Parole dzēsta</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Moduļi (<ph name="TOTAL_COUNT" />) — zināmie konflikti: <ph name="BAD_COUNT" />; aizdomīgie: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Datums un laiks</translation> <translation id="310671807099593501">Vietne izmanto Bluetooth savienojumu.</translation> -<translation id="3108967419958202225">Izvēlēties...</translation> <translation id="3115128645424181617">Nevar atrast tālruni. Tam ir jābūt rokas stiepiena attālumā, un Bluetooth savienojumam jābūt ieslēgtam.</translation> <translation id="3115147772012638511">Gaida krtuvi...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> palīdzība</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Daļa mobilo sakaru operatoru var bloķēt šo funkciju.</translation> <translation id="316854673539778496">Lai paplašinājumi būtu pieejami visās jūsu ierīcēs, pierakstieties un ieslēdziet sinhronizāciju.</translation> <translation id="3170072451822350649">Varat arī izlaist pierakstīšanos un <ph name="LINK_START" />veikt pārlūkošanu kā viesis<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Noklikšķiniet, lai slēptu paroli</translation> <translation id="3177909033752230686">Lapas valoda:</translation> <translation id="3181110748548073003">Nospiediet |<ph name="SHORTCUT" />|, lai pārietu uz priekšu.</translation> <translation id="3182749001423093222">Pareizrakstības pārbaude</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Īpašumtiesības tiks nodotas domēnam <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Atvērt paplašinājumu opcijas</translation> <translation id="3241680850019875542">Atlasiet pakojamā paplašinājuma saknes direktoriju. Lai atjauninātu paplašinājumu, atlasiet arī privātās atslēgas failu atkārtotai izmantošanai.</translation> -<translation id="3242765319725186192">Iepriekš koplietots kods:</translation> <translation id="3244294424315804309">Turpināt ar izslēgtu skaņu</translation> <translation id="3245321423178950146">Nezināms izpildītājs</translation> <translation id="3246097286174000800">Izmēģināt Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Citas darbības ar grāmatzīmi <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Vaicāt, ja vietne vēlas izmantot spraudni, lai piekļūtu datoram</translation> <translation id="3441653493275994384">Ekrāns</translation> -<translation id="3445830502289589282">2. fāzes autentifikācija:</translation> <translation id="344630545793878684">Lasīt jūsu datus vairākās vietnēs</translation> <translation id="3449839693241009168">Nospiediet <ph name="SEARCH_KEY" />, lai nosūtītu komandas uz <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Neaktīvs stāvoklis — noslogojuma procentuālais daudzums</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> kļūdas.</translation> <translation id="3495660573538963482">Google asistenta iestatījumi</translation> <translation id="3496213124478423963">Tālināt</translation> -<translation id="3504135463003295723">Grupas nosaukums:</translation> <translation id="3505030558724226696">Atsaukt piekļuvi ierīcei</translation> <translation id="3507421388498836150">“<ph name="EXTENSION_NAME" />” pašreizējās atļaujas</translation> <translation id="3507547268929739059">Noņemt Linux lietotnes no Chromebook datora</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Pierakstīšanās sertifikāts nav derīgs. Logs tiks aizvērts pēc <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Paplašinājuma ikona</translation> <translation id="3665589677786828986">Pārlūkā Chrome tika konstatēts, ka daži jūsu iestatījumi tika bojāti citā programmā, tāpēc šie iestatījumi tika atiestatīti uz sākotnējiem noklusējuma iestatījumiem.</translation> -<translation id="3665842570601375360">Drošība:</translation> <translation id="3668570675727296296">Valodas iestatījumi</translation> <translation id="3668823961463113931">Apdarinātāji</translation> <translation id="3670229581627177274">Ieslēgt Bluetooth</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Šo ierīci nevar atvērt, jo tās failu sistēma netiek atbalstīta.</translation> <translation id="3727148787322499904">Nomainot šo iestatījumu, tiks ietekmēti visi koplietotie tīkli.</translation> <translation id="3727187387656390258">Pārbaudīt uznirstošo elementu</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Kļūda rindiņā <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL serveris ar palielināšanu</translation> <translation id="3737536731758327622">Jūsu lejupielādes ir redzamas šeit.</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Kad pabeigts, nospiediet Enter</translation> <translation id="3827774300009121996">Pil&nekrāna režīms</translation> <translation id="3828029223314399057">Meklēt grāmatzīmes</translation> -<translation id="3829932584934971895">Sniedzēja veids:</translation> <translation id="3830674330436234648">Atskaņošana nav pieejama</translation> <translation id="3831486154586836914">Tika atvērts logu kopsavilkuma režīms.</translation> <translation id="383161972796689579">Šīs ierīces īpašnieks ir atspējojis jauno lietotāju pievienošanu.</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Datu lietojuma mērīšana ir pabeigta.</translation> <translation id="3857228364945137633">Izmēģiniet Smart Lock, lai atbloķētu savu ierīci (<ph name="DEVICE_TYPE" />) bez paroles, kad tuvumā atrodas tālrunis.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: sinhronizācija ir apturēta</translation> <translation id="3860381078714302691">Laipni lūdzam pakalpojumā Hangouts Meet</translation> <translation id="3862134173397075045">Iepazīstiet Cast iespējas pārlūkā Chrome!</translation> <translation id="3862788408946266506">Lai instalētu lietotni ar manifesta atribūtu kiosk_only, ir jāizmanto Chrome OS kioska režīms.</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Nevarēja iestatīt tīklu</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Aprēķina...</translation> -<translation id="3974195870082915331">Noklikšķiniet, lai rādītu paroli</translation> <translation id="3975222297214566386">Ievades opciju burbulis</translation> <translation id="397703832102027365">Notiek pabeigšana...</translation> <translation id="3979395879372752341">Ir pievienots jauns paplašinājums (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Ievadiet sertifikāta paroli</translation> <translation id="404493185430269859">Noklusējuma meklētājprogramma</translation> <translation id="4047112090469382184">Drošības aspekti</translation> +<translation id="4051049974203704184">Saņemt informāciju par ekrānā parādīto saturu</translation> <translation id="4052120076834320548">Niecīgs</translation> <translation id="4055023634561256217">Lai ierīces atiestatīšanai izmantotu funkciju Powerwash, ierīci ir nepieciešams restartēt.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Pieņemt grupai</translation> <translation id="4089235344645910861">Iestatījumi saglabāti. Sākta sinhronizācija.</translation> <translation id="4090103403438682346">Iespējot verificētu piekļuvi</translation> +<translation id="4090947011087001172">Vai atiestatīt vietnes <ph name="SITE" /> atļaujas?</translation> <translation id="4091434297613116013">papīra lapas</translation> <translation id="4093955363990068916">Lokālais fails:</translation> <translation id="4095507791297118304">Galvenais displejs</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Sinhronizāciju, personalizācijas un citu iespēju pārvaldība</translation> <translation id="4421932782753506458">Minka</translation> <translation id="4422347585044846479">Rediģēt šīs lapas grāmatzīmes</translation> -<translation id="4423104065312875417">Instalēt papildu runas programmas</translation> <translation id="4423376891418188461">Atjaunot iestatījumus</translation> <translation id="4423482519432579560">&Pareizrakstības pārbaudītājs</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, jūsu administrators pieprasa paroles maiņu.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Šī cilne atskaņo audio.</translation> <translation id="4450974146388585462">Diagnosticēt</translation> <translation id="4453946976636652378">Meklējiet <ph name="SEARCH_ENGINE_NAME" /> meklētājprogrammā vai ierakstiet URL</translation> -<translation id="445923051607553918">Pievienoties Wi-Fi tīklam</translation> <translation id="4462159676511157176">Pielāgoti nosaukumu serveri</translation> <translation id="4467100756425880649">Chrome interneta veikala galerija</translation> <translation id="4467101674048705704">Izvērst mapi <ph name="FOLDER_NAME" /></translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Fona tapetes tiek rādītas pierakstīšanās ekrānā.</translation> <translation id="4684427112815847243">Sinhronizēt visu</translation> <translation id="4689421377817139245">Sinhronizējiet šo grāmatzīmi savā iPhone tālrunī</translation> +<translation id="4690091457710545971"><Četri Intel Wi-Fi aparātprogrammatūras ģenerēti faili: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Pirmie trīs ir binārie faili, kas ietver reģistra izmetes; Intel apliecina, ka tie neietver personas informāciju vai ierīci identificējošu informāciju. Pēdējais fails ir Intel programmaparatūras izpildes trasējums; no tā ir noņemta personas informācija un ierīci identificējoša informācija, taču to nevar parādīt šeit, jo fails ir pārāk liels. Šie faili tika ģenerēti, reaģējot uz nesenām Wi-Fi problēmām jūsu ierīcē, un tie tiks kopīgoti ar Intel, lai palīdzētu novērst šīs problēmas.></translation> <translation id="4692302215262324251">Jūsu <ph name="DEVICE_TYPE" /> ierīce ir sekmīgi reģistrēta uzņēmuma pārvaldībai domēnā <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Ja šī darbība nav paredzēta, lūdzu, sazinieties ar atbalsta dienestu.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Lai jaunie iestatījumi tiktu piemēroti, iespējams, šī lapa būs jāielādē atkārtoti.</translation> <translation id="5075131525758602494">SIM kartes PIN ievadīšana</translation> <translation id="5078638979202084724">Saglabāt visas cilnes kā grāmatzīmes</translation> +<translation id="5079950360618752063">Izmantojiet ieteikto paroli</translation> <translation id="5084230410268011727">Atļaut vietnēm izmantot kustību un gaismas sensorus</translation> <translation id="5085162214018721575">Notiek pārbaude, vai ir pieejami atjauninājumi.</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Dzēst šo vienumu</translation> <translation id="5139955368427980650">Atvērt</translation> +<translation id="5142961317498132443">Autentifikācija</translation> <translation id="5143374789336132547">Paplašinājums “<ph name="EXTENSION_NAME" />” mainīja iestatījumu, kura lapa tiek parādīta, noklikšķinot uz pogas Sākums.</translation> <translation id="5143712164865402236">Ieiet pilnekrāna režīmā</translation> <translation id="5145331109270917438">Modificēšanas datums</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Turiet nospiestu taustiņu Control, Alt, Shift vai Search, lai skatītu šo modificētāju īsinājumtaustiņus.</translation> <translation id="5382591305415226340">Pārvaldīt atbalstītās saites</translation> <translation id="5384883051496921101">Šī vietne kopīgos informāciju ar lietotni, kas nav inkognito režīmā.</translation> -<translation id="5388588172257446328">Lietotājvārds:</translation> <translation id="5388885445722491159">Sapārots</translation> <translation id="5389237414310520250">Nevarēja izveidot jaunu lietotāju. Lūdzu, pārbaudiet vietu cietajā diskā un atļaujas un mēģiniet vēlreiz.</translation> <translation id="5390100381392048184">Atļaut vietnēm atskaņot skaņu</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Tastatūra un teksta ievade</translation> <translation id="5553089923092577885">Sertifikāta politikas kartējumi</translation> <translation id="5554489410841842733">Šī ikona tiks parādīta, ja paplašinājums varēs veikt darbības apmeklētajā lapā.</translation> -<translation id="5554573843028719904">Citi Wi-Fi tīkli...</translation> <translation id="5554720593229208774">E-pasta sertifikāta izdevējiestāde</translation> <translation id="5556206011531515970">Noklikšķiniet blakus, lai izvēlētos noklusējuma pārlūkprogrammu.</translation> <translation id="5556459405103347317">Pārlādēt</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Pārslēgt uz kameras režīmu</translation> <translation id="5612720917913232150">Vietnē <ph name="URL" /> tiek pieprasīta atļauja izmantot jūsu datora atrašanās vietu.</translation> <translation id="5612734644261457353">Diemžēl jūsu paroli joprojām nevarēja verificēt. Piezīme. Ja nesen mainījāt paroli, jaunā parole tiks lietota pēc izrakstīšanās. Lūdzu, šeit izmantojiet iepriekšējo paroli.</translation> -<translation id="5613695965848159202">Anonīma indentitāte:</translation> <translation id="5614190747811328134">Paziņojums lietotājam</translation> <translation id="561698261642843490">Firefox aizvēršana</translation> <translation id="5618075537869101857">Diemžēl kioska lietojumprogrammu nevarēja palaist.</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">Pierakstieties ierīcē <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimizēt</translation> <translation id="5946591249682680882">Pārskata ID: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Pievienot privātu tīklu</translation> <translation id="5949544233750246342">Nevar parsēt failu.</translation> <translation id="5955282598396714173">Paroles derīguma termiņš ir beidzies. Lai mainītu paroli, izrakstieties un vēlreiz pierakstieties.</translation> <translation id="5956585768868398362">Vai šī ir meklēšanas lapa, ko bijāt gaidījis?</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">Izrakstīties un tad pierakstīties vēlreiz</translation> <translation id="6198252989419008588">Mainīt PIN</translation> <translation id="6199801702437275229">Gaida informāciju par brīvo vietu...</translation> +<translation id="6204015976622790023">Skatiet atbilstošus Asistenta ieteikumus par ekrānā redzamo saturu.</translation> <translation id="6205710420833115353">Dažas darbības aizņem vairāk laika, nekā paredzēts. Vai vēlaties tās priekšlaikus pārtraukt?</translation> <translation id="6206311232642889873">Kopēt &attēlu</translation> <translation id="6207200176136643843">Atiestatīt noklusējuma tālummaiņas līmeni</translation> <translation id="620722923698527029">Vienmēr atvērt šo veidu saites saistītajā lietotnē</translation> <translation id="6207937957461833379">Valsts/reģions</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: sinhronizācija nedarbojas</translation> <translation id="6212039847102026977">Rādīt tīkla papildu rekvizītus</translation> <translation id="6212168817037875041">Izslēgt displeju</translation> <translation id="6212752530110374741">Sūtīt saiti e-pasta ziņojumā</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">Atiestatīt sinhronizāciju</translation> <translation id="6264365405983206840">&Atlasīt visu</translation> <translation id="6264422956566238156">Jūs esat ieslēdzis sinhronizēšanu</translation> -<translation id="6265930187414222160">Gatavs! Kaitīgā programmatūra ir noņemta.</translation> <translation id="6267166720438879315">Atlasiet sertifikātu, lai autentificētu sevi vietnē <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Atvērt lietotnē <ph name="APP" /></translation> <translation id="6268747994388690914">Importēt grāmatzīmes no HTML faila...</translation> @@ -3537,7 +3532,6 @@ Lai turpinātu pierakstīšanos <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> kontā, noklikšķiniet uz Tālāk.</translation> <translation id="6419546358665792306">Ielādēt atpakotu</translation> <translation id="642282551015776456">Šo nosaukumu nedrīkst izmantot kā mapes nosaukuma failu</translation> -<translation id="6423239382391657905">Atvērt VPN</translation> <translation id="6426200009596957090">Atvērt ChromeVox iestatījumus</translation> <translation id="6429384232893414837">Atjaunināšanas kļūda</translation> <translation id="6430814529589430811">Base64 kodēts ASCII, viens sertifikāts</translation> @@ -3618,7 +3612,6 @@ <translation id="6544215763872433504">Google izstrādātā tīmekļa pārlūkprogramma tieši jums</translation> <translation id="6545665334409411530">Atkārtošanas ātrums</translation> <translation id="6545834809683560467">Izmantot ieteikumus, lai ātrāk ievadītu meklēšanas frāzes un vietrāžus URL adreses joslā vai lietotņu palaidēja meklēšanas lodziņā.</translation> -<translation id="6546686722964485737">Savienojuma izveide ar WiMAX tīklu</translation> <translation id="6547316139431024316">Vairs nebrīdināt par šo paplašinājumu</translation> <translation id="6547354035488017500">Atbrīvojiet vismaz 512 MB vietas ierīcē, pretējā gadījumā tā nereaģēs. Lai atbrīvotu vietu, izdzēsiet failus no ierīces krātuves.</translation> <translation id="6549689063733911810">Pēdējie</translation> @@ -4037,7 +4030,6 @@ <translation id="7201014958346994077">Nevar skatīt Linux failus</translation> <translation id="720110658997053098">Pastāvīgi turēt ierīcei ieslēgtu kioska režīmu</translation> <translation id="7201118060536064622">Vienums “<ph name="DELETED_ITEM_NAME" />” ir izdzēsts.</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Notiek spraudņa <ph name="PLUGIN_NAME" /> lejupielāde...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Izejas lapa}zero{Izejas lapas}one{Izejas lapas}other{Izejas lapas}}</translation> <translation id="7216409898977639127">Mobilo sakaru operators</translation> @@ -4514,7 +4506,6 @@ <translation id="7909969815743704077">Lejupielādēts inkognito režīmā</translation> <translation id="7910768399700579500">Jauna mape</translation> <translation id="7912080627461681647">Jūsu parole serverī ir mainīta. Lūdzu, izrakstieties un vēlreiz pierakstieties.</translation> -<translation id="7912883689016444961">Konfigurēt mobilo tīklu</translation> <translation id="7915471803647590281">Pirms atsauksmes nosūtīšanas lūdzam jūs pastāstīt, kas notiek.</translation> <translation id="7916556741383518510">Noklikšķinot</translation> <translation id="792514962475806987">Dokotās tālummaiņas līmenis:</translation> @@ -4568,7 +4559,6 @@ <translation id="7988355189918024273">Iespējot pieejamības funkcijas</translation> <translation id="7994702968232966508">EAP metode</translation> <translation id="799547531016638432">Noņemt saīsni</translation> -<translation id="7997479212858899587">Identitāte:</translation> <translation id="7997826902155442747">Procesa prioritāte</translation> <translation id="7999229196265990314">Tika izveidoti šādi faili: @@ -4652,7 +4642,6 @@ <translation id="8105368624971345109">Izslēgt</translation> <translation id="8106045200081704138">Kopīgots ar mani</translation> <translation id="8107015733319732394">Notiek Google Play veikala instalēšana jūsu ierīcē (<ph name="DEVICE_TYPE" />). Tas var ilgt dažas minūtes.</translation> -<translation id="8109930990200908494">Lai saņemtu lietotāja sertifikātu, ir jāpierakstās.</translation> <translation id="8111155949205007504">Kopīgojiet šo paroli ar savu iPhone tālruni</translation> <translation id="8113043281354018522">Izvēlieties licences veidu</translation> <translation id="8116190140324504026">Plašāka informācija...</translation> @@ -4663,6 +4652,7 @@ <translation id="8118860139461251237">Pārvaldīt lejupielādes</translation> <translation id="81238879832906896">Dzeltens un balts zieds</translation> <translation id="8124313775439841391">Pārvaldītais ONC</translation> +<translation id="8125562866093998907">Vietne vēlas verificēt jūsu drošības atslēgu, lai uzlabotu jūsu konta drošību.</translation> <translation id="813082847718468539">Skatīt informāciju par vietni</translation> <translation id="8131740175452115882">Apstiprināt</translation> <translation id="8133676275609324831">Rādīt ma&pē</translation> @@ -4773,7 +4763,6 @@ <translation id="8308179586020895837">Vaicāt, vai vietne <ph name="HOST" /> vēlas piekļūt kamerai</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Sertifikāts jau pastāv.</translation> -<translation id="8309505303672555187">Atlasīt tīklu:</translation> <translation id="8312871300878166382">Ielīmēt mapē</translation> <translation id="8317671367883557781">Pievienot tīkla savienojumu</translation> <translation id="8319414634934645341">Paplašināta atslēgas lietošana</translation> @@ -4849,7 +4838,6 @@ <translation id="8451512073679317615">asistents</translation> <translation id="8452135315243592079">Nav SIM kartes.</translation> <translation id="8453482423012550001">Notiek $1 vienumu kopēšana...</translation> -<translation id="8454288007744638700">Vai atlasiet jaunu tīklu:</translation> <translation id="845627346958584683">Termiņa beigu laiks</translation> <translation id="8456681095658380701">Nederīgs nosaukums</translation> <translation id="8457451314607652708">Importēt grāmatzīmes</translation> @@ -4913,6 +4901,7 @@ <translation id="855081842937141170">Piespraust cilni</translation> <translation id="8551388862522347954">Licences</translation> <translation id="8553342806078037065">Pārvaldīt citas personas</translation> +<translation id="8554899698005018844">Nav valodas</translation> <translation id="855773602626431402">Šajā lapā tika novērsta tāda spraudņa darbība, kas nav ievietots smilškastē.</translation> <translation id="8557930019681227453">Manifests</translation> <translation id="8559694214572302298">Attēlu dekodētājs</translation> @@ -4950,7 +4939,6 @@ <translation id="862727964348362408">Atlikts</translation> <translation id="862750493060684461">CSS kešatmiņa</translation> <translation id="8627795981664801467">Tikai droši savienojumi</translation> -<translation id="8628085465172583869">Servera nosaukums:</translation> <translation id="8630903300770275248">Importēt uzraudzīto lietotāju</translation> <translation id="8631032106121706562">Puķīte</translation> <translation id="8637542770513281060">Jūsu datorā ir ietverts drošības modulis, kas tiek izmantots, lai operētājsistēmā Chrome OS ieviestu daudz svarīgu drošības funkciju. Lai uzzinātu vairāk, apmeklējiet Chromebook palīdzības centru: https://support.google.com/chromebook/?p=sm.</translation> @@ -5206,7 +5194,6 @@ <translation id="899403249577094719">Netscape sertifikāta Base URL</translation> <translation id="8995603266996330174">Pārvalda domēnu <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Pievienot kontu...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Notiek diska attēla izveide.</translation> <translation id="9003647077635673607">Atļaut visās vietnēs</translation> <translation id="9003677638446136377">Pārbaudīt vēlreiz</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb index dee6c127..4947625 100644 --- a/chrome/app/resources/generated_resources_ml.xtb +++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">ഇടവേളയ്ക്കുള്ള സമയം ആകാറായിരിക്കുന്നു</translation> <translation id="1062407476771304334">മാറ്റിസ്ഥാപിക്കുക</translation> -<translation id="1064835277883315402">സ്വകാര്യ നെറ്റ്വർക്കിൽ ചേരുക</translation> <translation id="1064912851688322329">നിങ്ങളുടെ Google അക്കൗണ്ട് വിച്ഛേദിക്കുക</translation> <translation id="1067048845568873861">സൃഷ്ടിച്ചു</translation> <translation id="1067291318998134776">Linux (ബീറ്റ)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">തിരയുന്നു...</translation> <translation id="1316495628809031177">സമന്വയം താൽക്കാലികമായി നിർത്തി</translation> <translation id="1319979322914001937">ഒരു ആപ്പ് Chrome വെബ് സ്റ്റോറിൽ നിന്നുള്ള ഫിൽട്ടർ ചെയ്ത വിപുലീകരണങ്ങളുടെ ലിസ്റ്റ് കാണിക്കുന്നു. ലിസ്റ്റിലെ വിപുലീകരണങ്ങൾ ആപ്പിൽ നിന്ന് നേരിട്ട് ഇൻസ്റ്റാൾ ചെയ്യാനാകും.</translation> -<translation id="132090119144658135">പൊരുത്തപ്പെടുന്ന വിഷയം:</translation> <translation id="1326317727527857210">നിങ്ങളുടെ മറ്റ് ഉപകരണങ്ങളിൽ നിന്നുള്ള ടാബുകൾ ലഭിക്കാൻ, Chrome-ൽ സൈൻ ഇൻ ചെയ്യുക.</translation> <translation id="1327074568633507428">Google ക്ലൗഡ് പ്രിന്റിലെ പ്രിന്റർ</translation> <translation id="1327977588028644528">ഗേറ്റ്വേ</translation> @@ -374,6 +372,7 @@ <translation id="1531004739673299060">അപ്ലിക്കേഷൻ വിൻഡോ</translation> <translation id="1534389735079119190">പിശക്: VM-ന് ഉള്ളിലെ കണ്ടെയിനർ ആരംഭിക്കാനായില്ല.</translation> <translation id="15373452373711364">വലിയ മൗസ് കഴ്സർ</translation> +<translation id="1540605929960647700">ഡെമോ മോഡ് പ്രവർത്തനക്ഷമമാക്കുക</translation> <translation id="1543284117603151572">Edge-ൽ നിന്നും ഇമ്പോർട്ടുചെയ്തത്</translation> <translation id="1545177026077493356">യാന്ത്രിക കിയോസ്ക് മോഡ്</translation> <translation id="1545775234664667895">"<ph name="THEME_NAME" />" തീം ഇന്സ്റ്റാള് ചെയ്തു</translation> @@ -457,6 +456,7 @@ <translation id="1657406563541664238">Google ലേക്ക് ഉപയോഗ സ്ഥിതിവിവരകണക്കുകളും ക്രാഷ് റിപ്പോര്ട്ടുകളും സ്വപ്രേരിതമായി അയച്ചുകൊണ്ട് <ph name="PRODUCT_NAME" /> മെച്ചപ്പെട്ട രീതിയില് നിര്മ്മിക്കാന് സഹായിക്കുക</translation> <translation id="1658424621194652532">ഈ പേജ് നിങ്ങളുടെ മൈക്രോഫോൺ ആക്സസ്സുചെയ്യുന്നു.</translation> <translation id="1660204651932907780">ശബ്ദം പ്ലേ ചെയ്യാൻ സൈറ്റുകളെ അനുവദിക്കുക (ശുപാർശ ചെയ്യുന്നു)</translation> +<translation id="1660938185063657230">നിങ്ങളുടെ സുരക്ഷാ കീ പരിശോധിച്ചുറപ്പിക്കുക</translation> <translation id="1661156625580498328">AES എൻക്രിപ്ഷൻ നടപ്പിലാക്കുക (ശുപാർശ ചെയ്തത്).</translation> <translation id="1661245713600520330">പിന്നീടുള്ള ഒരു ഘട്ടത്തില് ലോഡുചെയ്യുന്നതിനായി രജിസ്റ്റര് ചെയ്തിരിക്കുന്ന പ്രധാന പ്രോസസ്സിലേക്കും മൊഡ്യൂളുകളിലേക്കും ലോഡുചെയ്തിരിക്കുന്ന എല്ലാ മൊഡ്യൂളുകളും ഈ പേജ് ലിസ്റ്റുചെയ്യുന്നു.</translation> <translation id="166179487779922818">പാസ്വേഡ് വളരെ ചെറുതാണ്.</translation> @@ -474,6 +474,7 @@ <translation id="16815041330799488">ക്ലിപ്പ്ബോർഡിലേക്ക് പകർത്തിയിട്ടുള്ള ടെക്സ്റ്റുകളും ചിത്രങ്ങളും കാണാൻ സൈറ്റുകളെ അനുവദിക്കരുത്</translation> <translation id="1682548588986054654">പുതിയ വേഷ പ്രച്ഛന്ന വിന്ഡോ</translation> <translation id="168715261339224929">എല്ലാ ഉപകരണങ്ങളിലും നിങ്ങളുടെ ബുക്ക്മാർക്കുകൾ ലഭിക്കാൻ, 'സമന്വയം' ഓണാക്കുക.</translation> +<translation id="1688867105868176567">സൈറ്റ് ഡാറ്റ മായ്ക്കണോ?</translation> <translation id="1688935057616748272">ഒരു അക്ഷരം ടൈപ്പ് ചെയ്യുക</translation> <translation id="168991973552362966">സമീപത്തുള്ള ഒരു പ്രിന്റർ ചേർക്കുക</translation> <translation id="1689945336726856614">&URL പകർത്തുക</translation> @@ -485,7 +486,6 @@ <translation id="1701062906490865540">ഈ ഉപയോക്താവിനെ നീക്കംചെയ്യുക</translation> <translation id="1706586824377653884">നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ ചേർത്തത്</translation> <translation id="1706625117072057435">സൂം നിലകൾ</translation> -<translation id="1707463636381878959">മറ്റ് ഉപയോക്താക്കളുമായി ഈ നെറ്റ്വര്ക്ക് പങ്കിടുക</translation> <translation id="1708338024780164500">(നിഷ്ക്രിയം)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ഐഡി: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (പ്രാദേശികം)</translation> @@ -521,7 +521,6 @@ <translation id="175772926354468439">തീം പ്രാപ്തമാക്കുക</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome വെബ് സ്റ്റോറിൽ കാണുക</translation> -<translation id="1758831820837444715">എതെർനെറ്റ് നെറ്റ്വർക്ക് കോൺഫിഗർ ചെയ്യുക</translation> <translation id="1763046204212875858">അപ്ലിക്കേഷന് കുറുക്കുവഴികള് സൃഷ്ടിക്കുക</translation> <translation id="1763108912552529023">പര്യവേക്ഷണം ചെയ്യുന്നത് തുടരുക</translation> <translation id="1763808908432309942">പുതിയൊരു ടാബിൽ തുറക്കുന്നു</translation> @@ -580,8 +579,10 @@ <translation id="1839704667838141620">ഈ ഫയൽ പങ്കിട്ട രീതി മാറ്റുക</translation> <translation id="1841545962859478868">ഉപകരണ അഡ്മിൻ ഇനിപ്പറയുന്നവ നിരീക്ഷിച്ചേക്കാം:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> പ്രവർത്തനരഹിതമാക്കി</translation> +<translation id="1842766183094193446">ഡൊമോ മോഡ് പ്രവർത്തനക്ഷമമാക്കണമെന്ന് ഉറപ്പാണോ?</translation> <translation id="1844692022597038441">ഈ ഫയൽ ഓഫ്ലൈനിൽ ലഭ്യമാകില്ല.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" /> റൺ ചെയ്യാൻ കൺട്രോൾ-ക്ലിക്ക്</translation> +<translation id="1847880352285315359">സംരക്ഷിച്ചു</translation> <translation id="1848219224579402567">ലിഡ് അടഞ്ഞിരിക്കുമ്പോൾ സൈൻ ഔട്ട് ചെയ്യുക</translation> <translation id="184823282865851239">അനാവശ്യമായ പരസ്യങ്ങൾ സൈറ്റ് കാണിക്കുന്നുവെങ്കിൽ ബ്ലോക്കുചെയ്യുക</translation> <translation id="1849186935225320012">ഈ പേജിന് MIDI ഉപകരണങ്ങളുടെ പൂർണ്ണ നിയന്ത്രണമുണ്ട്.</translation> @@ -679,6 +680,7 @@ <translation id="200544492091181894">നിങ്ങൾക്കിത് എപ്പോൾ വേണമെങ്കിലും ക്രമീകരണത്തിൽ മാറ്റാം</translation> <translation id="2006638907958895361"><ph name="APP" /> ആപ്പില് ലിങ്ക് തുറക്കുക</translation> <translation id="2007404777272201486">ഒരു പ്രശ്നം റിപ്പോര്ട്ടുചെയ്യുക...</translation> +<translation id="2016237810978710652">Linux ഫയലുകൾ തുറക്കുന്നു ...</translation> <translation id="2016430552235416146">പരമ്പരാഗതം</translation> <translation id="2017334798163366053">പ്രകടന ഡാറ്റ ശേഖരണം പ്രവർത്തനരഹിതമാക്കുക</translation> <translation id="2017836877785168846">വിലാസ ബാറിലെ ചരിത്രവും സ്വയം പൂർത്തീകരണങ്ങളും മായ്ക്കുന്നു.</translation> @@ -773,6 +775,7 @@ <translation id="2154484045852737596">കാർഡ് എഡിറ്റുചെയ്യുക</translation> <translation id="2154710561487035718">URL പകര്ത്തുക</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> പോലെ തോന്നുന്നു</translation> +<translation id="2156283799932971644">ചില സിസ്റ്റം വിവരങ്ങളും പേജ് ഉള്ളടക്കവും Google-ന് അയച്ച്, സുരക്ഷിത ബ്രൗസിംഗ് മെച്ചപ്പെടുത്താൻ നിങ്ങൾക്ക് സഹായിക്കാനാകും.</translation> <translation id="215753907730220065">പൂര്ണ്ണ സ്ക്രീനില് നിന്ന് പുറത്തുകടക്കുക</translation> <translation id="2157875535253991059">ഈ പേജ് ഇപ്പോൾ പൂർണ്ണമായ സ്ക്രീനിലാണ്.</translation> <translation id="216169395504480358">Wi-Fi ചേർക്കുക...</translation> @@ -782,6 +785,7 @@ <translation id="2173801458090845390">ഈ ഉപകരണത്തിൽ അഭ്യർത്ഥന ഐഡി ചേർക്കുക</translation> <translation id="2175042898143291048">എല്ലായ്പ്പോഴും ഇങ്ങനെ ചെയ്യുക</translation> <translation id="2175607476662778685">ക്വിക്ക് ലോഞ്ച് ബാര്</translation> +<translation id="2176087259161165020">മറ്റ് ഉറവിടങ്ങൾ</translation> <translation id="2177950615300672361">ആൾമാറാട്ട ടാബ്: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">നിങ്ങളുടെ കമ്പ്യൂട്ടർ ആക്സസ് ചെയ്യാൻ <ph name="PEPPER_PLUGIN_DOMAIN" /> എന്നതിലെ <ph name="PEPPER_PLUGIN_NAME" /> ആഗ്രഹിക്കുന്നു</translation> <translation id="2178614541317717477">CA കോംപ്രമൈസ്</translation> @@ -865,7 +869,6 @@ <translation id="2291643155573394834">അടുത്ത ടാബ്</translation> <translation id="2292848386125228270"><ph name="PRODUCT_NAME" /> ഉപകരണത്തെ സാധാരണ ഉപയോക്താവിനെ പോലെ ഉപയോഗിച്ചുതുടങ്ങൂ. കൂടുതൽ വിപുലമാക്കാൻ ഒരു റൂട്ടായി റൺ ചെയ്യണമെങ്കിൽ, --no-sandbox ഫ്ലാഗ് ഉപയോഗിച്ച് വീണ്ടും റൺ ചെയ്യുക.</translation> <translation id="2294358108254308676">നിങ്ങള് <ph name="PRODUCT_NAME" /> ഇന്സ്റ്റാള് ചെയ്യാന് താല്പ്പര്യപ്പെടുന്നുണ്ടോ?</translation> -<translation id="2296019197782308739">EAP രീതി:</translation> <translation id="2297705863329999812">പ്രിന്ററുകൾ തിരയുക</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> ഇഷ്ടാനുസൃതമാക്കുകയും നിയന്ത്രിക്കുകയും ചെയ്യുക</translation> <translation id="2301382460326681002">വിപുലീകരണ റൂട്ട് ഡയറക്ടറി അസാധുവാണ്.</translation> @@ -913,6 +916,7 @@ <translation id="2366463953911599217">പിശക്: <ph name="APP_NAME" /> അൺഇൻസ്റ്റാൾ ചെയ്യുന്നത് പരാജയപ്പെട്ടു.</translation> <translation id="2367199180085172140">ഫയൽ പങ്കിടൽ ചേർക്കുക</translation> <translation id="2367972762794486313">അപ്ലിക്കേഷനുകൾ കാണിക്കുക</translation> +<translation id="2369536625682139252">കുക്കികൾ ഒഴികെ, <ph name="SITE" /> സംഭരിച്ച മുഴുവൻ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും.</translation> <translation id="2371076942591664043">ചെയ്തുകഴിയുമ്പോള് &തുറക്കുക</translation> <translation id="2377319039870049694">ലിസ്റ്റ് കാഴ്ചയിലേക്ക് മാറുക</translation> <translation id="2377667304966270281">ഹാർഡ് ഫോൾട്ടുകൾ</translation> @@ -922,7 +926,6 @@ <translation id="2379281330731083556">സിസ്റ്റം ഡയലോഗ് ഉപയോഗിച്ച് പ്രിന്റ് ചെയ്യുക... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">അയയ്ക്കുന്നതിന് മുമ്പ് ചോദിക്കുക (ശുപാർശചെയ്തത്)</translation> <translation id="2384436799579181135">ഒരു പിശക് സംഭവിച്ചു. നിങ്ങളുടെ പ്രിന്റർ പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക.</translation> -<translation id="2385700042425247848">സേവന നാമം:</translation> <translation id="2387458720915042159">പ്രോക്സി കണക്ഷൻ തരം</translation> <translation id="2391419135980381625">സാധാരണ ഫോണ്ട്</translation> <translation id="2391762656119864333">റദ്ദാക്കുക</translation> @@ -973,7 +976,6 @@ <translation id="247949520305900375">ഓഡിയോ പങ്കിടുക</translation> <translation id="2480868415629598489">നിങ്ങൾ പകർത്തി ഒട്ടിക്കുന്ന വിവരത്തിൽ മാറ്റം വരുത്തുക</translation> <translation id="2482878487686419369">വിജ്ഞാപനങ്ങള്</translation> -<translation id="2485056306054380289">സെര്വര് CA സര്ട്ടിഫിക്കറ്റ്:</translation> <translation id="2485422356828889247">അണ്ഇന്സ്റ്റാള് ചെയ്യുക</translation> <translation id="2487067538648443797">പുതിയ ബുക്ക്മാർക്ക് ചേർക്കുക</translation> <translation id="248861575772995840">നിങ്ങളുടെ ഫോൺ കണ്ടെത്താനായില്ല. <ph name="DEVICE_TYPE" /> ഉപകരണത്തിന്റെ Bluetooth ഓണാണെന്ന് ഉറപ്പുവരുത്തുക. <a>കൂടുതലറിയുക</a></translation> @@ -1034,6 +1036,7 @@ <translation id="2566124945717127842">നിങ്ങളുടെ <ph name="IDS_SHORT_PRODUCT_NAME" /> ഉപകരണം പുതിയതുപോലാക്കാൻ പുനഃസജ്ജമാക്കുന്നതിന് പവർവാഷുചെയ്യുക.</translation> <translation id="2567257616420533738">പാസ്വേഡ് സംരക്ഷിച്ചു. <ph name="SAVED_PASSWORDS_LINK" /> എന്നതിൽ സംരക്ഷിച്ച പാസ്വേഡുകൾ കാണുക, നിയന്ത്രിക്കുക</translation> <translation id="2568774940984945469">വിവരബാര് കണ്ടെയ്നര്</translation> +<translation id="2570454805927264159">നിങ്ങളുടെ Assistant-നെ പരമാവധി പ്രയോജനപ്പെടുത്തുക</translation> <translation id="257088987046510401">തീമുകള്</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> എന്നതിലേക്ക് റീഡ് ഒൺലി ആക്സസ്സ് അനുവദിച്ചു.</translation> <translation id="2573269395582837871">ഒരു ചിത്രവും പേരും തിരഞ്ഞെടുക്കുക</translation> @@ -1097,7 +1100,6 @@ <translation id="2653659639078652383">സമര്പ്പിക്കൂ</translation> <translation id="265390580714150011">ഫീല്ഡ് മൂല്യം</translation> <translation id="2654166010170466751">പേയ്മെന്റ് ഹാൻഡ്ലറുകളെ ഇൻസ്റ്റാൾ ചെയ്യാൻ സൈറ്റുകളെ അനുവദിക്കുന്നു</translation> -<translation id="2655386581175833247">ഉപയോക്തൃ സര്ട്ടിഫിക്കറ്റ്:</translation> <translation id="2660779039299703961">ഇവന്റ്</translation> <translation id="266079277508604648">പ്രിന്റർ കണക്റ്റ് ചെയ്യാനാവുന്നില്ല. പ്രിന്റർ ഓണാണോ എന്നും വൈഫൈയോ USB-യോ ഉപയോഗിച്ച് Chromebook-ലേക്ക് കണക്റ്റ് ചെയ്തിട്ടുണ്ടോ എന്നും പരിശോധിക്കുക.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1330,6 +1332,7 @@ <translation id="3006881078666935414">ഉപയോഗ ഡാറ്റ ഇല്ല</translation> <translation id="3007214526293698309">അനുപാതം ക്രമീകരിക്കുക</translation> <translation id="3007771295016901659">ഡ്യൂപ്ലിക്കേറ്റ് ടാബ്</translation> +<translation id="3008272652534848354">അനുമതികൾ പുനഃസജ്ജീകരിക്കുക</translation> <translation id="3009300415590184725">മൊബൈൽ ഡാറ്റാ സേവന സജ്ജീകരണ പ്രോസസ്സ് റദ്ദാക്കാൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുവെന്ന് തീർച്ചയാണോ?</translation> <translation id="3009779501245596802">ഇൻഡെക്സ് ചെയ്ത ഡാറ്റബേസുകള്</translation> <translation id="3010279545267083280">പാസ്വേഡ് ഇല്ലാതാക്കി</translation> @@ -1396,7 +1399,6 @@ <translation id="3100609564180505575">മൊഡ്യൂളുകള് (<ph name="TOTAL_COUNT" />) - അറിഞ്ഞ പൊരുത്തക്കേടുകള്: <ph name="BAD_COUNT" />, സംശയിക്കുന്നവ: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">തീയതിയും സമയവും</translation> <translation id="310671807099593501">സൈറ്റ്, bluetooth ഉപയോഗിക്കുന്നു</translation> -<translation id="3108967419958202225">തിരഞ്ഞെടുക്കുക...</translation> <translation id="3115128645424181617">നിങ്ങളുടെ ഫോൺ കണ്ടെത്താനാകുന്നില്ല. Bluetooth ഓണാണെന്നും ഫോൺ കൈയ്യിലുണ്ടെന്നും ഉറപ്പാക്കുക.</translation> <translation id="3115147772012638511">കാഷെയ്ക്കായി കാത്തിരിക്കുന്നു...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> സഹായം</translation> @@ -1441,7 +1443,6 @@ <translation id="3165390001037658081">ചില സേവനദായകർ ഈ ഫീച്ചർ ബ്ലോക്കുചെയ്തേക്കും.</translation> <translation id="316854673539778496">നിങ്ങളുടെ വിപുലീകരണങ്ങൾ എല്ലാ ഉപകരണങ്ങളിലും ലഭിക്കാൻ, സൈൻ ഇൻ ചെയ്ത്, 'സമന്വയിപ്പിക്കൽ' ഓണാക്കുക.</translation> <translation id="3170072451822350649">നിങ്ങൾക്ക് സൈൻ ഇൻ ചെയ്യുന്നത് ഒഴിവാക്കി <ph name="LINK_START" />അതിഥിയായി ബ്രൗസുചെയ്യാനുമാകും<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">പാസ്വേഡ് മറയ്ക്കുന്നതിനായി ക്ലിക്ക് ചെയ്യുക</translation> <translation id="3177909033752230686">പേജ് ഭാഷ:</translation> <translation id="3181110748548073003">മുന്നോട്ട് പോകാൻ |<ph name="SHORTCUT" />| അമർത്തുക</translation> <translation id="3182749001423093222">അക്ഷരത്തെറ്റ് പരിശോധന</translation> @@ -1472,7 +1473,6 @@ <translation id="3236289833370040187">ഉടമസ്ഥാവകാശം <ph name="DESTINATION_DOMAIN" /> എന്നതിലേക്ക് കൈമാറ്റം ചെയ്യുന്നതാണ്.</translation> <translation id="323803881985677942">വിപുലീകരണ ഓപ്ഷനുകൾ തുറക്കുക</translation> <translation id="3241680850019875542">പാക്ക് ചെയ്യുന്നതിന് വിപുലീകരണത്തിന്റെ റൂട്ട് ഡയറക്ടറി തിരഞ്ഞെടുക്കുക. ഒരു വിപുലീകരണം അപ്ഡേറ്റ് ചെയ്യുന്നതിന്, വീണ്ടും ഉപയോഗിക്കുന്നതിന് സ്വകാര്യ കീ ഫയലും തിരഞ്ഞെടുക്കുക.</translation> -<translation id="3242765319725186192">മുമ്പേ പങ്കുവച്ച കീ:</translation> <translation id="3244294424315804309">ശബ്ദം മ്യൂട്ട് ചെയ്യുന്നത് തുടരുക</translation> <translation id="3245321423178950146">അറിയപ്പെടാത്ത കലാകാരൻ</translation> <translation id="3246097286174000800">Smart Lock പരീക്ഷിക്കുക</translation> @@ -1605,7 +1605,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> എന്നതിനുള്ള കൂടുതൽ പ്രവർത്തനങ്ങൾ</translation> <translation id="3440761377721825626">നിങ്ങളുടെ കമ്പ്യൂട്ടർ ആക്സസ് ചെയ്യാൻ ഒരു സൈറ്റ്, പ്ലഗ് ഇൻ ഉപയോഗിക്കാൻ താൽപ്പര്യപ്പെടുമ്പോൾ ആവശ്യപ്പെടുക</translation> <translation id="3441653493275994384">സ്ക്രീന്</translation> -<translation id="3445830502289589282">ഘട്ടം 2 പ്രാമാണീകരണം:</translation> <translation id="344630545793878684">നിരവധി വെബ്സൈറ്റുകളിലെ നിങ്ങളുടെ വിവരം വായിക്കുക</translation> <translation id="3449839693241009168"><ph name="EXTENSION_NAME" /> ലേക്ക് കമാന്റുകള് അയയ്ക്കുന്നതിന് <ph name="SEARCH_KEY" /> അമര്ത്തുക</translation> <translation id="3450157232394774192">നിഷ്ക്രിയ നില ഒക്യുപ്പൻസി ശതമാനം</translation> @@ -1646,7 +1645,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> പിശകുകൾ.</translation> <translation id="3495660573538963482">Google അസിസ്റ്റന്റ് ക്രമീകരണം</translation> <translation id="3496213124478423963">സൂം ഔട്ട്</translation> -<translation id="3504135463003295723">ഗ്രൂപ്പ് നാമം:</translation> <translation id="3505030558724226696">ഉപകരണ ആക്സസ്സ് റദ്ദാക്കുക</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" എന്നതിനായുള്ള നിലവിലെ അനുമതികൾ</translation> <translation id="3507547268929739059">Chromebook-നായുള്ള Linux ആപ്പുകൾ നീക്കം ചെയ്യുക</translation> @@ -1755,7 +1753,6 @@ <translation id="3661054927247347545">സൈൻ ഇൻ സർട്ടിഫിക്കറ്റ് ശരിയല്ല, <ph name="MINUTES" /> : <ph name="SECONDS" />-നുള്ളിൽ വിൻഡോ അടയ്ക്കുന്നു</translation> <translation id="3664511988987167893">വിപുലീകരണ ഐക്കൺ</translation> <translation id="3665589677786828986">മറ്റൊരു പ്രോഗ്രാം നിങ്ങളുടെ ചില ക്രമീകരണങ്ങൾക്ക് കേടുവരുത്തി അവയുടെ യഥാർത്ഥ സ്ഥിര ക്രമീകരണങ്ങളിലേക്ക് അവ പുനഃസജ്ജമാക്കിയതായി Chrome കണ്ടെത്തി.</translation> -<translation id="3665842570601375360">സുരക്ഷ:</translation> <translation id="3668570675727296296">ഭാഷാ ക്രമീകരണങ്ങൾ</translation> <translation id="3668823961463113931">ഹാന്ഡ്ലറുകള്</translation> <translation id="3670229581627177274">Bluetooth ഓണാക്കുക</translation> @@ -1794,7 +1791,6 @@ <translation id="3726463242007121105">ഈ ഉപകരണത്തിന്റെ ഫയൽസിസ്റ്റം പിന്തുണയ്ക്കാത്തതിനാൽ ഇത് തുറക്കാനായില്ല.</translation> <translation id="3727148787322499904">ഈ ക്രമീകരണം മാറ്റുന്നത് എല്ലാ പങ്കിട്ട നെറ്റ്വർക്കുകളെയും ബാധിക്കാനിടയാക്കും</translation> <translation id="3727187387656390258">പോപ്പ്അപ്പ് പരിശോധിക്കുക</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900"><ph name="ERROR_LINE" />-മത്തെ വരിയിൽ പിശക്</translation> <translation id="3733127536501031542">സ്റ്റെപ്പ്-അപ്പ് ഉള്ള SSL സെര്വര് </translation> <translation id="3737536731758327622">നിങ്ങളുടെ ഡൗൺലോഡുകൾ ഇവിടെ ദൃശ്യമാകും</translation> @@ -1869,7 +1865,6 @@ <translation id="38275787300541712">ചെയ്തുകഴിയുമ്പോൾ Enter അമർത്തുക</translation> <translation id="3827774300009121996">&പൂര്ണ്ണ സ്ക്രീന്</translation> <translation id="3828029223314399057">ബുക്ക്മാര്ക്കുകള് തിരയുക</translation> -<translation id="3829932584934971895">പ്രൊവൈഡര് തരം:</translation> <translation id="3830674330436234648">പ്ലേബാക്ക് ലഭ്യമല്ല</translation> <translation id="3831486154586836914">വിൻഡോ ചുരുക്കവിവരണ മോഡ് നൽകി</translation> <translation id="383161972796689579">പുതിയ ഉപയോക്താക്കളെ ചേരുന്നതിൽ നിന്ന് ഈ ഉപകരണത്തിന്റെ ഉടമ അപ്രാപ്തമാക്കി</translation> @@ -1890,6 +1885,7 @@ <translation id="3856921555429624101">ഡാറ്റ ഉപയോഗം കണക്കാക്കുന്നത് അവസാനിച്ചു</translation> <translation id="3857228364945137633">നിങ്ങളുടെ ഫോൺ സമീപത്തുള്ളപ്പോൾ, പാസ്വേഡ് ഇല്ലാതെ <ph name="DEVICE_TYPE" /> അൺലോക്കുചെയ്യുന്നതിന് Smart Lock പരീക്ഷിക്കുക.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: സമന്വയം താൽക്കാലികമായി നിർത്തി</translation> <translation id="3860381078714302691">Hangouts Meet-ലേക്ക് സ്വാഗതം</translation> <translation id="3862134173397075045">Chrome-ലെ Cast അനുഭവത്തിലേക്ക് സ്വാഗതം!</translation> <translation id="3862788408946266506">Chrome OS കിയോസ്ക് മോഡിൽ, 'kiosk_only' മാനിഫെസ്റ്റ് ആട്രിബ്യൂട്ട് ഉള്ള അപ്ലിക്കേഷൻ ഇൻസ്റ്റാൾ ചെയ്യണം</translation> @@ -1966,7 +1962,6 @@ <translation id="3968261067169026421">നെറ്റ്വർക്ക് സജ്ജമാക്കാനായില്ല</translation> <translation id="3970114302595058915">ഐഡി</translation> <translation id="397105322502079400">കണക്കാക്കുന്നു...</translation> -<translation id="3974195870082915331">പാസ്വേഡ് കാണിക്കുന്നതിനായി ക്ലിക്ക് ചെയ്യുക</translation> <translation id="3975222297214566386">ഇൻപുട്ട് ഓപ്ഷൻ ബബിൾ</translation> <translation id="397703832102027365">തീര്ച്ചപ്പെടുത്തുന്നു...</translation> <translation id="3979395879372752341">പുതിയ വിപുലീകരണം ചേർത്തു (<ph name="EXTENSION_NAME" />)</translation> @@ -2008,6 +2003,7 @@ <translation id="4044612648082411741">നിങ്ങളുടെ സർട്ടിഫിക്കറ്റ് പാസ്വേഡ് നൽകുക</translation> <translation id="404493185430269859">സ്ഥിര തിരയൽ എൻജിൻ</translation> <translation id="4047112090469382184">ഇതെങ്ങനെ സുരക്ഷിതമാകും</translation> +<translation id="4051049974203704184">സ്ക്രീനിൽ എന്താണുള്ളതെന്ന വിവരം നേടുക</translation> <translation id="4052120076834320548">ചെറുത്</translation> <translation id="4055023634561256217">പവർവാഷ് ഉപയോഗിച്ച് നിങ്ങളുടെ ഉപകരണം പുനസജ്ജമാക്കുന്നതിനുമുമ്പ് പുനരാരംഭിക്കേണ്ടതുണ്ട്.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2036,6 +2032,7 @@ <translation id="4088095054444612037">ഗ്രൂപ്പിനായി അംഗീകരിക്കുക</translation> <translation id="4089235344645910861">ക്രമീകരണം സംരക്ഷിച്ചു. സമന്വയം ആരംഭിച്ചു.</translation> <translation id="4090103403438682346">പരിശോധിച്ചുറപ്പിച്ച ആക്സസ്സ് പ്രവർത്തനക്ഷമമാക്കുക</translation> +<translation id="4090947011087001172"><ph name="SITE" />-നുള്ള സൈറ്റ് അനുമതികൾ പുനഃസജ്ജീകരിക്കണോ?</translation> <translation id="4091434297613116013">പേപ്പര് പാളികള്</translation> <translation id="4093955363990068916">പ്രാദേശിക ഫയൽ:</translation> <translation id="4095507791297118304">പ്രാഥമിക ഡിസ്പ്ലേ</translation> @@ -2212,7 +2209,6 @@ <translation id="4419556793104466535">സമന്വയം, വ്യക്തിപരമാക്കൽ എന്നിവയും മറ്റും നിയന്ത്രിക്കുക</translation> <translation id="4421932782753506458">ഫ്ലഫി</translation> <translation id="4422347585044846479">ഈ പേജിനായി ബുക്മാര്ക്ക് എഡിറ്റ് ചെയ്യുക</translation> -<translation id="4423104065312875417">അധിക സ്പീച്ച് എഞ്ചിൻ ഇൻസ്റ്റാൾ ചെയ്യുക</translation> <translation id="4423376891418188461">ക്രമീകരണം പുനഃസ്ഥാപിക്കുക</translation> <translation id="4423482519432579560">&അക്ഷരത്തെറ്റ് പരിശോധന</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, അഡ്മിനിസ്ട്രേറ്റർ നിങ്ങളുടെ പാസ്വേഡ് മാറ്റാൻ ആവശ്യപ്പെടുന്നു.</translation> @@ -2237,7 +2233,6 @@ <translation id="4449996769074858870">ഈ ടാബ് ഓഡിയോ പ്ലേ ചെയ്യുന്നു.</translation> <translation id="4450974146388585462">പ്രശ്നം നിർണ്ണയിക്കുക</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> തിരയുക അല്ലെങ്കിൽ ഒരു URL ടൈപ്പ് ചെയ്യുക</translation> -<translation id="445923051607553918">Wi-Fi നെറ്റ്വര്ക്കില് അംഗമാകുക</translation> <translation id="4462159676511157176">ഇഷ്ടാനുസൃത നാമ സെർവറുകൾ</translation> <translation id="4467100756425880649">Chrome വെബ് സ്റ്റോർ ഗാലറി</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> വികസിപ്പിക്കുക</translation> @@ -2373,6 +2368,7 @@ <translation id="4682551433947286597">സൈൻ-ഇൻ സ്ക്രീനിൽ ദൃശ്യമാകേണ്ട വാൾപേപ്പറുകൾ.</translation> <translation id="4684427112815847243">എല്ലാം സമന്വയിപ്പിക്കുക</translation> <translation id="4689421377817139245">ഈ ബുക്ക്മാർക്ക് നിങ്ങളുടെ iPhone-ൽ സമന്വയിപ്പിക്കുക</translation> +<translation id="4690091457710545971"><Intel വൈഫൈ ഫേംവെയർ നാല് ഫയലുകൾ സൃഷ്ടിച്ചു: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. ആദ്യത്തെ മൂന്നെണ്ണം രജിസ്റ്റർ ഡമ്പുകൾ അടങ്ങുന്ന ബൈനറി ഫയലുകളാണ്, വ്യക്തിഗത വിവരങ്ങളോ ഉപകരണത്തെ തിരിച്ചറിയാനാകുന്ന വിവരങ്ങളോ ഉൾപ്പെടാതിരിക്കാൻ Intel സ്ഥാപിച്ചവയാണവ. അവസാനത്തേത് Intel ഫേംവെയറിൽ നിന്നുള്ള ഒരു എക്സിക്യൂഷൻ ട്രെയ്സ് ആണ്; അതിലുള്ള മുഴുവൻ വ്യക്തിഗത വിവരങ്ങളോ ഉപകരണത്തെ തിരിച്ചറിയാനാകുന്ന വിവരങ്ങളോ മായ്ച്ചുകളഞ്ഞിട്ടുണ്ടാകും, എങ്കിലും അത് ഇവിടെ പ്രദർശിപ്പിക്കാൻ കഴിയുന്നതിലും വലുതാണ്. നിങ്ങളുടെ ഉപകരണത്തിൽ അടുത്തിടെയുണ്ടായ വൈഫൈ പ്രശ്നങ്ങളുടെ അടിസ്ഥാനത്തിൽ സൃഷ്ടിക്കപ്പെട്ടവയാണ് ഈ ഫയലുകൾ, ഈ പ്രശ്നങ്ങൾ പരിഹരിക്കാനായി ഇവ Intel-മായി പങ്കിടുന്നതാണ്.></translation> <translation id="4692302215262324251"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ഡൊമെയ്നിന്റെ എന്റർപ്രൈസ് മാനേജ്മെന്റിന് വേണ്ടി നിങ്ങളുടെ <ph name="DEVICE_TYPE" /> എൻറോൾ ചെയ്തു. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> ഇത് അപ്രതീക്ഷിത പ്രവർത്തനമായിരുന്നെങ്കിൽ, പിന്തുണാവിഭാഗത്തെ ബന്ധപ്പെടുക.</translation> @@ -2632,6 +2628,7 @@ <translation id="5074318175948309511">പുതിയ ക്രമീകരണങ്ങൾ പ്രയോഗത്തിൽ വരുന്നതിന് മുമ്പ് ഈ പേജ് വീണ്ടും ലോഡുചെയ്യേണ്ടതായി വരാം.</translation> <translation id="5075131525758602494">സിം പിൻ നൽകുക</translation> <translation id="5078638979202084724">എല്ലാ ടാബുകളും ബുക്ക്മാര്ക്ക് ചെയ്യുക</translation> +<translation id="5079950360618752063">നിർദ്ദേശിച്ച പാസ്വേഡ് ഉപയോഗിക്കുക</translation> <translation id="5084230410268011727">ചലന സെൻസറുകളും വെളിച്ച സെൻസറുകളും ഉപയോഗിക്കാൻ സൈറ്റുകളെ അനുവദിക്കുക</translation> <translation id="5085162214018721575">അപ്ഡേറ്റുകൾക്കായി പരിശോധിക്കുന്നു</translation> <translation id="5086082738160935172">HID</translation> @@ -2670,6 +2667,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">ഈ ഇനം ഇല്ലാതാക്കുക</translation> <translation id="5139955368427980650">&തുറക്കൂ</translation> +<translation id="5142961317498132443">പരിശോധിച്ചുറപ്പിക്കൽ</translation> <translation id="5143374789336132547">നിങ്ങൾ ഹോം ബട്ടൺ ക്ലിക്കുചെയ്യുമ്പോൾ ദൃശ്യമാകുന്ന പേജിനെ "<ph name="EXTENSION_NAME" />" വിപുലീകരണം മാറ്റി.</translation> <translation id="5143712164865402236">പൂര്ണ്ണ സ്ക്രീനില് പ്രവേശിക്കുക</translation> <translation id="5145331109270917438">പരിഷ്ക്കരിച്ചത്</translation> @@ -2840,7 +2838,6 @@ <translation id="5380103295189760361">ആ മോഡിഫയറുകൾക്കുള്ള കീബോർഡ് കുറുക്കുവഴികൾ കാണുന്നതിന് Control, Alt, Shift അമർത്തിപ്പിടിക്കുക അല്ലെങ്കിൽ തിരയുക.</translation> <translation id="5382591305415226340">പിന്തുണയ്ക്കുന്ന ലിങ്കുകൾ മാനേജുചെയ്യുക</translation> <translation id="5384883051496921101">അദൃശ്യതാ സംവിധാനത്തിനു പുറത്തുള്ള ഒരു ആപ്പുമായി ഈ സൈറ്റ് വിവരങ്ങൾ പങ്കിടാൻ പോകുന്നു.</translation> -<translation id="5388588172257446328">ഉപയോക്തൃനാമം:</translation> <translation id="5388885445722491159">ജോഡിയായ</translation> <translation id="5389237414310520250">പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കാനായില്ല. നിങ്ങളുടെ ഹാർഡ് ഡ്രൈവിലെ ഇടവും അനുമതികളും പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക.</translation> <translation id="5390100381392048184">ശബ്ദം പ്ലേ ചെയ്യാൻ സൈറ്റുകളെ അനുവദിക്കുക</translation> @@ -2965,7 +2962,6 @@ <translation id="5551573675707792127">കീബോർഡും ടെക്സ്റ്റ് ഇൻപുട്ടും</translation> <translation id="5553089923092577885">സര്ട്ടിഫിക്കറ്റ് നയ മാപ്പിംഗുകള്</translation> <translation id="5554489410841842733">വിപുലീകരണത്തിന് നിലവിലുള്ള പേജില് പ്രവര്ത്തിക്കാന് കഴിയുമ്പോള്, ഈ ഐക്കണ് കാണാനാകും.</translation> -<translation id="5554573843028719904">മറ്റ് Wi-Fi നെറ്റ്വര്ക്ക്...</translation> <translation id="5554720593229208774">ഇമെയില് സര്ട്ടിഫിക്കേഷന് അതോറിറ്റി</translation> <translation id="5556206011531515970">നിങ്ങളുടെ സ്ഥിരം ബ്രൗസർ തിരഞ്ഞെടുക്കാൻ അടുത്തത് ക്ലിക്കുചെയ്യുക.</translation> <translation id="5556459405103347317">വീണ്ടും ലോഡുചെയ്യുക</translation> @@ -3006,7 +3002,6 @@ <translation id="5610038042047936818">ക്യാമറ മോഡിലേക്ക് മാറുക</translation> <translation id="5612720917913232150">നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ ലൊക്കേഷൻ ഉപയോഗിക്കാൻ <ph name="URL" /> ആഗ്രഹിക്കുന്നു</translation> <translation id="5612734644261457353">ക്ഷമിക്കണം, ഇപ്പോഴും നിങ്ങളുടെ പാസ്വേഡ് സ്ഥിരീകരിക്കാൻ കഴിഞ്ഞില്ല. ശ്രദ്ധിക്കുക: സമീപകാലത്ത് നിങ്ങൾ പാസ്വേഡ് മാറ്റിയിട്ടുണ്ടെങ്കിൽ, പുതിയ പാസ്വേഡ് സൈൻ ഔട്ട് ചെയ്തുകഴിഞ്ഞാൽ ബാധകമാകും, പഴയ പാസ്വേഡ് ഇവിടെ ഉപയോഗിക്കുക.</translation> -<translation id="5613695965848159202">അജ്ഞാത ഐഡന്റിറ്റി:</translation> <translation id="5614190747811328134">ഉപയോക്തൃ അറിയിപ്പ്</translation> <translation id="561698261642843490">Firefox അടയ്ക്കുക</translation> <translation id="5618075537869101857">ക്ഷമിക്കണം, കിയോസ്ക് അപ്ലിക്കേഷൻ സമാരംഭിക്കാനായില്ല.</translation> @@ -3224,7 +3219,6 @@ <translation id="5941343993301164315"><ph name="TOKEN_NAME" /> എന്നതിലേക്ക് ദയവായി പ്രവേശിക്കുക.</translation> <translation id="5941711191222866238">ചെറുതാക്കുക</translation> <translation id="5946591249682680882">റിപ്പോർട്ട് ഐഡി <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">സ്വകാര്യ നെറ്റ്വര്ക്ക് ചേര്ക്കുക</translation> <translation id="5949544233750246342">ഫയലിനെ വിശകലനം ചെയ്യാനായില്ല</translation> <translation id="5955282598396714173">നിങ്ങളുടെ പാസ്വേഡ് കാലഹരണപ്പെട്ടിരിക്കുന്നു. അത് മാറ്റുന്നതിന്, സൈൻ ഔട്ട് ചെയ്യുക, തുടർന്ന് സൈൻ ഇൻ ചെയ്യുക.</translation> <translation id="5956585768868398362">നിങ്ങൾ പ്രതീക്ഷിക്കുന്ന തിരയൽ പേജ് ഇതാണോ?</translation> @@ -3386,11 +3380,13 @@ <translation id="6198102561359457428">സൈൻ ഔട്ട് ചെയ്ത് വീണ്ടും സൈൻ ഇൻ ചെയ്യുക...</translation> <translation id="6198252989419008588">PIN മാറ്റുക</translation> <translation id="6199801702437275229">സ്പെയ്സ് വിവരത്തിനായി കാത്തിരിക്കുന്നു...</translation> +<translation id="6204015976622790023">നിങ്ങളുടെ സ്ക്രീനിൽ എന്താണുള്ളതെന്നതുമായി ബന്ധപ്പെട്ട്, Assistant-ൽ നിന്നുള്ള പ്രസക്തമായ നിർദ്ദേശങ്ങൾ കാണുക.</translation> <translation id="6205710420833115353">ചില പ്രവർത്തനങ്ങൾ പ്രതീക്ഷിച്ചതിലും സമയമെടുക്കുന്നു. നിങ്ങൾക്ക് അവ അവസാനിപ്പിക്കണോ?</translation> <translation id="6206311232642889873">ചിത്രം പകര്ത്തു&ക</translation> <translation id="6207200176136643843">ഡിഫോൾട്ട് സൂം ലെവലിലേക്ക് റീസെറ്റുചെയ്യുക</translation> <translation id="620722923698527029">ഇത്തരം ലിങ്കുകൾ എല്ലായ്പ്പോഴും ബന്ധപ്പെട്ട ആപ്പിൽ തുറക്കുക</translation> <translation id="6207937957461833379">രാജ്യം/പ്രവിശ്യ</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: സമന്വയം പ്രവർത്തിക്കുന്നില്ല</translation> <translation id="6212039847102026977">വിപുലമായ നെറ്റ്വർക്ക് പ്രോപ്പർട്ടികൾ കാണിക്കുക</translation> <translation id="6212168817037875041">ഡിസ്പ്ലേ ഓഫാക്കുക</translation> <translation id="6212752530110374741">ലിങ്ക് ഇമെയിൽ ചെയ്യുക</translation> @@ -3428,7 +3424,6 @@ <translation id="6263541650532042179">സമന്വയം പുനഃസജ്ജമാക്കുക</translation> <translation id="6264365405983206840">എല്ലാം &തിരഞ്ഞെടുക്കുക</translation> <translation id="6264422956566238156">നിങ്ങൾ സമന്വയിപ്പിക്കൽ ഓണാക്കി</translation> -<translation id="6265930187414222160">പൂർത്തിയായി! ദോഷകരമായ സോഫ്റ്റ്വെയർ നീക്കം ചെയ്തു.</translation> <translation id="6267166720438879315">നിങ്ങളെ <ph name="HOST_NAME" /> ലേക്ക് ആധാരീകരിക്കാന് ഒരു സര്ട്ടിഫിക്കറ്റ് തിരഞ്ഞെടുക്കുക</translation> <translation id="6268252012308737255"><ph name="APP" /> ഉപയോഗിച്ച് തുറക്കുക</translation> <translation id="6268747994388690914">HTML ഫയലിൽ നിന്ന് ബുക്ക്മാർക്കുകൾ ഇംപോർട്ടുചെയ്യുക...</translation> @@ -3535,7 +3530,6 @@ നിങ്ങളുടെ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> അക്കൗണ്ടിലേക്ക് സൈൻ ഇൻ ചെയ്യുന്നത് തുടരാൻ "അടുത്തത്" ക്ലിക്കുചെയ്യുക.</translation> <translation id="6419546358665792306">അൺപായ്ക്കുചെയ്തവ ലോഡുചെയ്യുക</translation> <translation id="642282551015776456">ഈ നാമം ഒരു ഫോൾഡർ നാമത്തിന്റെ ഫയൽ ആയി ഉപയോഗിക്കരുത്</translation> -<translation id="6423239382391657905">VPNതുറക്കുക</translation> <translation id="6426200009596957090">ChromeVox ക്രമീകരണം തുറക്കുക</translation> <translation id="6429384232893414837">അപ്ഡേറ്റ് ചെയ്യുന്നതിൽ പിശക്</translation> <translation id="6430814529589430811">Base64-എന്കോഡുചെയ്ത ASCII, ഒറ്റ സര്ട്ടിഫിക്കറ്റ്</translation> @@ -3617,7 +3611,6 @@ <translation id="6544215763872433504">Google-ൽ നിന്ന് നിങ്ങൾക്കുള്ള വെബ് ബ്രൗസർ</translation> <translation id="6545665334409411530">ആവർത്തന നിരക്ക്</translation> <translation id="6545834809683560467">തിരയലുകളും ഒരു വിലാസ ബാറിലോ അപ്ലിക്കേഷൻ ലോഞ്ചർ തിരയൽ ബോക്സിലോ ടൈപ്പുചെയ്തിരിക്കുന്ന URL കളും പൂര്ത്തിയാക്കാൻ ഒരു പ്രവചന സേവനം ഉപയോഗിക്കുക</translation> -<translation id="6546686722964485737">Wimax നെറ്റ്വർക്കിൽ ചേരുക</translation> <translation id="6547316139431024316">ഈ വിപുലീകരണത്തിന് വീണ്ടും മുന്നറിപ്പ് നൽകരുത്</translation> <translation id="6547354035488017500">512 MB ഇടമെങ്കിലും സൃഷ്ടിച്ചില്ലെങ്കിൽ നിങ്ങളുടെ ഉപകരണം പ്രതികരിക്കില്ല. ഇടം സൃഷ്ടിക്കാൻ, ഉപകരണ സ്റ്റോറേജിൽ നിന്ന് ഫയലുകൾ ഇല്ലാതാക്കുക.</translation> <translation id="6549689063733911810">പുതിയവ</translation> @@ -4036,7 +4029,6 @@ <translation id="7201014958346994077">Linux ഫയലുകൾ കാണാനാകുന്നില്ല</translation> <translation id="720110658997053098">ഈ ഉപകരണം ശാശ്വതമായി കിയോസ്ക് മോഡിൽ നിലനിർത്തുക</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' ഇല്ലാതാക്കി</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> ഡൗൺലോഡുചെയ്യുന്നു...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{പേജിൽ നിന്ന് പുറത്തുകടക്കുക}other{പേജുകളിൽ നിന്ന് പുറത്തുകടക്കുക}}</translation> <translation id="7216409898977639127">സെല്ലുലാര് സേവനദാതാവ്</translation> @@ -4514,7 +4506,6 @@ <translation id="7909969815743704077">ആൾമാറാട്ട മോഡിൽ ഡൗൺലോഡുചെയ്തു</translation> <translation id="7910768399700579500">&പുതിയ ഫോള്ഡര്</translation> <translation id="7912080627461681647">സെർവറിൽ നിങ്ങളുടെ പാസ്വേഡ് മാറ്റിയിരിക്കുന്നു. സൈൻ ഔട്ട് ചെയ്യുക, തുടർന്ന് വീണ്ടും സൈൻ ഇൻ ചെയ്യുക.</translation> -<translation id="7912883689016444961">മൊബൈൽ നെറ്റ്വർക്ക് കോൺഫിഗർ ചെയ്യുക</translation> <translation id="7915471803647590281">ഫീഡ്ബാക്ക് അയയ്ക്കുന്നതിന് മുമ്പ് എന്തുസംഭവിക്കുന്നുവെന്ന് ഞങ്ങളോട് ദയവായി പറയുക.</translation> <translation id="7916556741383518510">ക്ലിക്കിൽ</translation> <translation id="792514962475806987">ഡോക്ക് ചെയ്ത സൂം നില:</translation> @@ -4568,7 +4559,6 @@ <translation id="7988355189918024273">ഉപയോഗസഹായി സവിശേഷതകള് സാദ്ധ്യമാക്കുക </translation> <translation id="7994702968232966508">EAP രീതി</translation> <translation id="799547531016638432">കുറുക്കുവഴി നീക്കംചെയ്യുക</translation> -<translation id="7997479212858899587">ഐഡന്റിറ്റി:</translation> <translation id="7997826902155442747">പ്രോസസ്സ് മുൻഗണന</translation> <translation id="7999229196265990314">ഇനിപ്പറയുന്ന ഫയലുകള് സൃഷ്ടിച്ചു: @@ -4652,7 +4642,6 @@ <translation id="8105368624971345109">ഓഫാക്കുക</translation> <translation id="8106045200081704138">ഞാനുമായി പങ്കിട്ടവ</translation> <translation id="8107015733319732394">നിങ്ങളുടെ <ph name="DEVICE_TYPE" />-ൽ Google Play Store ഇൻസ്റ്റാൾ ചെയ്യുന്നു. ഇതിന് കുറച്ച് മിനിറ്റുകളെടുക്കാം.</translation> -<translation id="8109930990200908494">ഉപയോക്തൃ സർട്ടിഫിക്കറ്റിനായി സൈൻ ഇൻ ചെയ്യേണ്ടത് ആവശ്യമാണ്.</translation> <translation id="8111155949205007504">നിങ്ങളുടെ iPhone-മായി ഈ പാസ്വേഡ് പങ്കിടുക</translation> <translation id="8113043281354018522">ലൈസൻസ് തരം തിരഞ്ഞെടുക്കുക</translation> <translation id="8116190140324504026">കൂടുതൽ വിവരങ്ങള്...</translation> @@ -4663,6 +4652,7 @@ <translation id="8118860139461251237">നിങ്ങളുടെ ഡൗൺലോഡുകൾ നിയന്ത്രിക്കുക</translation> <translation id="81238879832906896">മഞ്ഞയും വെളുപ്പും നിറത്തിലുള്ള പൂവ്</translation> <translation id="8124313775439841391">നിയന്ത്രിത ONC</translation> +<translation id="8125562866093998907">നിങ്ങളുടെ അക്കൗണ്ടിനുള്ള അധിക സുരക്ഷയ്ക്കായി സൈറ്റിന് സുരക്ഷാ കീ സ്ഥിരീകരിക്കേണ്ടതുണ്ട്.</translation> <translation id="813082847718468539">സൈറ്റ് വിവരങ്ങള് കാണുക</translation> <translation id="8131740175452115882">സ്ഥിരീകരിക്കുക</translation> <translation id="8133676275609324831">&ഫോള്ഡറില് കാണിക്കുക</translation> @@ -4773,7 +4763,6 @@ <translation id="8308179586020895837"><ph name="HOST" />-ന് നിങ്ങളുടെ ക്യാമറ ആക്സസ്സുചെയ്യാൻ താൽപ്പര്യമുണ്ടോ എന്ന് ചോദിക്കുക</translation> <translation id="830868413617744215">ബീറ്റ</translation> <translation id="8309458809024885768">സർട്ടിഫിക്കറ്റ് നിലവിലുണ്ട്</translation> -<translation id="8309505303672555187">ഒരു നെറ്റ്വര്ക്ക് തിരഞ്ഞെടുക്കുക:</translation> <translation id="8312871300878166382">ഫോൾഡറിൽ ഒട്ടിക്കുക</translation> <translation id="8317671367883557781">നെറ്റ്വർക്ക് കണക്ഷൻ ചേർക്കുക</translation> <translation id="8319414634934645341">വിപുലീകരിച്ച കീ ഉപയോഗം</translation> @@ -4848,7 +4837,6 @@ <translation id="8451512073679317615">അസിസ്റ്റന്റ്</translation> <translation id="8452135315243592079">സിം കാർഡ് കാണുന്നില്ല</translation> <translation id="8453482423012550001">$1 ഇനങ്ങൾ പകർത്തുന്നു...</translation> -<translation id="8454288007744638700">അല്ലെങ്കിൽ, ഒരു പുതിയ നെറ്റ്വർക്ക് തിരഞ്ഞെടുക്കുക:</translation> <translation id="845627346958584683">കാലഹരണപ്പെടല് സമയം</translation> <translation id="8456681095658380701">അസാധുവായ പേര്</translation> <translation id="8457451314607652708">ബുക്ക്മാർക്കുകൾ ഇമ്പോർട്ടുചെയ്യുക</translation> @@ -4912,6 +4900,7 @@ <translation id="855081842937141170">ടാബ് പിൻ ചെയ്യുക</translation> <translation id="8551388862522347954">ലൈസന്സുകള്</translation> <translation id="8553342806078037065">മറ്റുള്ളവരെ മാനേജുചെയ്യുക</translation> +<translation id="8554899698005018844">ഭാഷയില്ല</translation> <translation id="855773602626431402">ഈ പേജിൽ പ്രവർത്തിക്കുന്നതിൽ നിന്നും ഒരു അൺസാൻഡ്ബോക്സ് ചെയ്ത പ്ലഗ്-ഇൻ തടഞ്ഞു.</translation> <translation id="8557930019681227453">മാനിഫെസ്റ്റ്</translation> <translation id="8559694214572302298">ഇമേജ് ഡീകോഡർ</translation> @@ -4949,7 +4938,6 @@ <translation id="862727964348362408">താൽക്കാലികമായി നിർത്തി</translation> <translation id="862750493060684461">CSS കാഷേ</translation> <translation id="8627795981664801467">കണക്ഷനുകള് മാത്രം സുരക്ഷിതമാക്കുക</translation> -<translation id="8628085465172583869">സെര്വര് അതിഥിനാമം:</translation> <translation id="8630903300770275248">സൂപ്പർവൈസുചെയ്ത ഉപയോക്താവിനെ ഇമ്പോർട്ടുചെയ്യുക</translation> <translation id="8631032106121706562">പെറ്റൽസ്</translation> <translation id="8637542770513281060">നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ, Chrome OS-ലെ നിർണ്ണായകമായ നിരവധി സുരക്ഷാ ഫീച്ചറുകൾ നടപ്പിലാക്കാൻ ഉപയോഗിക്കുന്ന സുരക്ഷാ മൊഡ്യൂൾ അടങ്ങിയിരിക്കുന്നു. കൂടുതലറിയാൻ Chromebook സഹായകേന്ദ്രം സന്ദർശിക്കുക: https://support.google.com/chromebook/?p=sm</translation> @@ -5204,7 +5192,6 @@ <translation id="899403249577094719">നെറ്റ്സ്കേപ്പ് സര്ട്ടിഫിക്കറ്റ് ബേസ് URL</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> എന്നത് കൈകാര്യം ചെയ്യുന്നു</translation> <translation id="8996526648899750015">അക്കൗണ്ട് ചേർക്കുക...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">ഡിസ്ക്ക് ചിത്രം സൃഷ്ടിക്കുന്നു.</translation> <translation id="9003647077635673607">എല്ലാ വെബ്സൈറ്റുകളിലും അനുവദിക്കുക</translation> <translation id="9003677638446136377">വീണ്ടും പരിശോധിക്കുക</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb index 5d829d3..a1d2b93 100644 --- a/chrome/app/resources/generated_resources_mr.xtb +++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">विश्रांतीची वेळ झाली आहे</translation> <translation id="1062407476771304334">पुनर्स्थित करा</translation> -<translation id="1064835277883315402">खाजगी नेटवर्कवर रुजू व्हा</translation> <translation id="1064912851688322329">आपले Google खाते डिसकनेक्ट करा</translation> <translation id="1067048845568873861">तयार केले</translation> <translation id="1067291318998134776">Linux (बीटा)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">शोधत आहे...</translation> <translation id="1316495628809031177">सिंक थांबवले आहे</translation> <translation id="1319979322914001937">Chrome वेब स्टोअरमधील विस्ताराची फिल्टर केलेली सूची दर्शविणारा अॅप. सूचीमधील विस्तार अॅपवरून थेट इंस्टॉल केले जाऊ शकतात.</translation> -<translation id="132090119144658135">जुळणारा विषय:</translation> <translation id="1326317727527857210">आपल्या इतर डिव्हाइसेसवरील आपले टॅब प्राप्त करण्यासाठी, Chrome मध्ये साइन इन करा.</translation> <translation id="1327074568633507428">Google क्लाउड प्रिंट वरील प्रिंटर</translation> <translation id="1327977588028644528">गेटवे</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">अॅप्लिकेशन विंडो</translation> <translation id="1534389735079119190">एरर: VM मध्ये कंटेनर सुरू करता आले नाही.</translation> <translation id="15373452373711364">मोठा माउस कर्सर</translation> +<translation id="1540605929960647700">डेमो मोड सुरू करा</translation> <translation id="1543284117603151572">Edge वरून आयात केले</translation> <translation id="1545177026077493356">स्वयंचलित कियोस्क मोड</translation> <translation id="1545775234664667895">"<ph name="THEME_NAME" />" थीम इंस्टॉल केली</translation> @@ -458,6 +457,7 @@ <translation id="1657406563541664238">वापर आकडेवारी आणि क्रॅश अहवाल स्वयंचलितपणे Google कडे पाठवून <ph name="PRODUCT_NAME" /> ला अधिक चांगले करण्यास मदत करा</translation> <translation id="1658424621194652532">हे पृष्ठ आपल्या मायक्रोफोनवर प्रवेश करत आहे.</translation> <translation id="1660204651932907780">साइटना ध्वनी प्ले करण्याची परवानगी द्या (शिफारस केलेले)</translation> +<translation id="1660938185063657230">तुमची सिक्युरिटी की पडताळा</translation> <translation id="1661156625580498328">AES एंक्रिप्शन लागू करा (शिफारस केलेले).</translation> <translation id="1661245713600520330">हे पृष्ठ मुख्य प्रक्रियेत लोड केलेली आणि नंतर लोड करण्यासाठी नोंदविलेली सर्व मॉड्यूल्स सूचीबद्ध करते.</translation> <translation id="166179487779922818">पासवर्ड खूप लहान आहे.</translation> @@ -475,6 +475,7 @@ <translation id="16815041330799488">क्लिपबोर्डवर कॉपी केलेला मजकूर आणि इमेज पाहण्याची अनुमती साइटना देऊ नका</translation> <translation id="1682548588986054654">नवीन गुप्त विंडो</translation> <translation id="168715261339224929">तुमच्या सर्व डिव्हाइसवर तुमचे बुकमार्क मिळवण्यासाठी, सिंक चालू करा.</translation> +<translation id="1688867105868176567">साइट डेटा साफ करायचा?</translation> <translation id="1688935057616748272">एखादे अक्षर टाइप करा</translation> <translation id="168991973552362966">एक जवळपासचे प्रिंटर जोडा</translation> <translation id="1689945336726856614">URL कॉपी करा</translation> @@ -486,7 +487,6 @@ <translation id="1701062906490865540">या व्यक्तीस काढा</translation> <translation id="1706586824377653884">आपल्या प्रशासकाने जोडले</translation> <translation id="1706625117072057435">झूम स्तर</translation> -<translation id="1707463636381878959">अन्य वापरकर्त्यांसह हा नेटवर्क शेअर करा</translation> <translation id="1708338024780164500">(निष्क्रिय)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (आयडी: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (मूळ)</translation> @@ -522,7 +522,6 @@ <translation id="175772926354468439">थीम सक्षम करा</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome वेब स्टोअरमध्ये पहा</translation> -<translation id="1758831820837444715">इथरनेट नेटवर्क कॉन्फिगर करा</translation> <translation id="1763046204212875858">अॅप्लिकेशन शॉर्टकट तयार करा</translation> <translation id="1763108912552529023">एक्सप्लोर करत रहा</translation> <translation id="1763808908432309942">नवीन टॅबमध्ये उघडते</translation> @@ -581,8 +580,10 @@ <translation id="1839704667838141620">ही फाईल सामायिक कशी केली जाते ते बदला</translation> <translation id="1841545962859478868">डिव्हाइस प्रशासक कदाचित खालील गोष्टींचे परीक्षण करू शकतो:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> बंद केला आहे</translation> +<translation id="1842766183094193446">तुम्हाला खरंच डेमो मोड सुरू करायचा आहे का?</translation> <translation id="1844692022597038441">ही फाइल ऑफलाइन उपलब्ध नाही.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" /> चालविण्यासाठी Control-क्लिक करा</translation> +<translation id="1847880352285315359">सेव्ह केले</translation> <translation id="1848219224579402567">लिड बंद असताना साइन आउट करा</translation> <translation id="184823282865851239">साइटने अनाहूत जाहिराती दाखवणे सुरू ठेवल्यास ब्लॉक करा</translation> <translation id="1849186935225320012">या पृष्ठास MIDI डिव्हाइसचे पूर्ण नियंत्रण आहे.</translation> @@ -680,6 +681,7 @@ <translation id="200544492091181894">तुम्ही हे नंतर कधीही सेटिंग्ज मध्ये बदलू शकता.</translation> <translation id="2006638907958895361">लिंक <ph name="APP" /> मध्ये उघडा</translation> <translation id="2007404777272201486">समस्या नोंदवा...</translation> +<translation id="2016237810978710652">Linux फायली उघडत आहे...</translation> <translation id="2016430552235416146">पारंपारिक</translation> <translation id="2017334798163366053">कार्यप्रदर्शन डेटा संकलन अक्षम करा</translation> <translation id="2017836877785168846">अॅड्रेस बारमधील इतिहास आणि आपोआप पूर्ण केलेले साफ करते.</translation> @@ -774,6 +776,7 @@ <translation id="2154484045852737596">कार्ड संपादित करा</translation> <translation id="2154710561487035718">URL कॉपी करा</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> सारखे दिसते</translation> +<translation id="2156283799932971644">सुरक्षित ब्राउझिंगमध्ये सुधारणा करण्यासाठी तुम्ही Google ला काही सिस्टम माहिती आणि पेज आशय पाठवून मदत करू शकता.</translation> <translation id="215753907730220065">पूर्ण स्क्रीनमधून निर्गमन करा</translation> <translation id="2157875535253991059">हे पृष्ठ आता फुल स्क्रीन असेल.</translation> <translation id="216169395504480358">वाय-फाय जोडा...</translation> @@ -783,6 +786,7 @@ <translation id="2173801458090845390">या डीव्हाइसवर मागणी आयडी जोडा</translation> <translation id="2175042898143291048">हे नेहमी करा</translation> <translation id="2175607476662778685">द्रुत लाँच बार</translation> +<translation id="2176087259161165020">इतर स्रोत</translation> <translation id="2177950615300672361">गुप्त टॅब: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> वरील <ph name="PEPPER_PLUGIN_NAME" /> ला तुमचा काँप्युटर अॅक्सेस करायचा आहे</translation> <translation id="2178614541317717477">CA तडजोड</translation> @@ -866,7 +870,6 @@ <translation id="2291643155573394834">पुढील टॅब</translation> <translation id="2292848386125228270">कृपया <ph name="PRODUCT_NAME" /> चा सामान्य वापरकर्ता म्हणून प्रारंभ करा. आपल्याला विकासासाठी मूळ म्हणून चालविणे आवश्यक असल्यास, सॅन्डबॉक्स ध्वजांकन नाही -- सह पुन्हा चालवा.</translation> <translation id="2294358108254308676">आपण <ph name="PRODUCT_NAME" /> स्थापित करू इच्छिता?</translation> -<translation id="2296019197782308739">EAP पद्धत:</translation> <translation id="2297705863329999812">प्रिंटर शोधा</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> ला कस्टमाइझ आणि नियंत्रित करा</translation> <translation id="2301382460326681002">विस्तार मूळ निर्देशिका अवैध आहे.</translation> @@ -914,6 +917,7 @@ <translation id="2366463953911599217">एरर: <ph name="APP_NAME" /> अनइंस्टॉल करता आले नाही.</translation> <translation id="2367199180085172140">फाइल शेअर जोडा</translation> <translation id="2367972762794486313">अॅप्स दर्शवा</translation> +<translation id="2369536625682139252">कुकीज वगळता <ph name="SITE" /> द्वारे स्टोअर केलेला सर्व डेटा हटवला जाईल.</translation> <translation id="2371076942591664043">&पूर्ण झाल्यानंतर उघडा</translation> <translation id="2377319039870049694">सूची व्ह्यूवर स्विच करा</translation> <translation id="2377667304966270281">हार्ड फॉल्ट</translation> @@ -923,7 +927,6 @@ <translation id="2379281330731083556">सिस्टम संवाद वापरून प्रिंट करा… <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">पाठविण्यापूर्वी विचारा (शिफारस केलेले)</translation> <translation id="2384436799579181135">एक एरर आली आहे. कृपया तुमचा प्रिंटर तपासा आणि पुन्हा प्रयत्न करा.</translation> -<translation id="2385700042425247848">सेवेचे नाव:</translation> <translation id="2387458720915042159">प्रॉक्सी कनेक्शन प्रकार</translation> <translation id="2391419135980381625">मानक फॉन्ट</translation> <translation id="2391762656119864333">मागे घ्या</translation> @@ -974,7 +977,6 @@ <translation id="247949520305900375">ऑडिओ शेअर करा</translation> <translation id="2480868415629598489">आपण कॉपी आणि पेस्ट करता तो डेटा सुधारित करा</translation> <translation id="2482878487686419369">सूचना</translation> -<translation id="2485056306054380289">सर्व्हर CA प्रमाणपत्र:</translation> <translation id="2485422356828889247">अनइन्स्टॉल करणे</translation> <translation id="2487067538648443797">नवीन बुकमार्क जोडा</translation> <translation id="248861575772995840">तुमचा फोन आढळला नाही. तुमच्या <ph name="DEVICE_TYPE" /> चे ब्लुटूथ चालू असल्याची खात्री करा. <a>आणखी जाणून घ्या</a></translation> @@ -1035,6 +1037,7 @@ <translation id="2566124945717127842">आपला <ph name="IDS_SHORT_PRODUCT_NAME" /> डिव्हाइस अगदी नवीन सारखे रीसेट करण्यासाठी Powerwash करा.</translation> <translation id="2567257616420533738">पासवर्ड सेव्ह केला. सेव्ह केलेले पासवर्ड <ph name="SAVED_PASSWORDS_LINK" /> येथे पहा आणि व्यवस्थापित करा</translation> <translation id="2568774940984945469">इंफोबार कंटेनर</translation> +<translation id="2570454805927264159">तुमच्या असिस्टंटकडून सर्वाधिक मिळवा</translation> <translation id="257088987046510401">थीम</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> साठी केवळ-वाचनीय प्रवेश मंजूर केला गेला आहे.</translation> <translation id="2573269395582837871">एक चित्र आणि नाव निवडा</translation> @@ -1098,7 +1101,6 @@ <translation id="2653659639078652383">सबमिट करा</translation> <translation id="265390580714150011">फील्ड मूल्य</translation> <translation id="2654166010170466751">पेमेंट हँडलर इंस्टॉल करण्यासाठी साइटना अनुमती द्या</translation> -<translation id="2655386581175833247">वापरकर्ता प्रमाणपत्र:</translation> <translation id="2660779039299703961">इव्हेंट</translation> <translation id="266079277508604648">प्रिंटरशी कनेक्ट करू शकत नाही. प्रिंटर चालू आहे का आणि तो वाय-फाय किंवा USB ने तुमच्या Chromebook शी कनेक्ट केला आहे का ते तपासा.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1331,6 +1333,7 @@ <translation id="3006881078666935414">वापराचा कोणताही डेटा नाही</translation> <translation id="3007214526293698309">गुणोत्तराचे निराकरण करा</translation> <translation id="3007771295016901659">डुप्लिकेट टॅब</translation> +<translation id="3008272652534848354">परवानग्या रीसेट करा</translation> <translation id="3009300415590184725">मोबाइल डेटा सेट अप प्रक्रिया रद्द करु इच्छित आहात याबद्दल आपल्याला खात्री आहे?</translation> <translation id="3009779501245596802">अनुक्रमित डेटाबेस</translation> <translation id="3010279545267083280">पासवर्ड हटवला</translation> @@ -1397,7 +1400,6 @@ <translation id="3100609564180505575">मॉड्यूल (<ph name="TOTAL_COUNT" />) - ज्ञात संघर्ष: <ph name="BAD_COUNT" />, संशयित: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">तारीख आणि वेळ</translation> <translation id="310671807099593501">साइट ब्लूटूथ वापरत आहे</translation> -<translation id="3108967419958202225">निवडा...</translation> <translation id="3115128645424181617">तुमचा फोन आढळला नाही. तो सोयीस्कर असल्याची आणि ब्लुटूथ चालू असल्याची खात्री करा.</translation> <translation id="3115147772012638511">कॅशेसाठी प्रतीक्षा करीत आहे...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> मदत</translation> @@ -1442,7 +1444,6 @@ <translation id="3165390001037658081">काही वाहक हे वैशिष्ट्य अवरोधित शकतात.</translation> <translation id="316854673539778496">तुमच्या सर्व डिव्हाइसवर तुमचे सर्व एक्स्टेंशन मिळवण्यासाठी, साइन इन करा आणि सिंंक करणे चालू करा.</translation> <translation id="3170072451822350649">आपण साइन इन वगळुन <ph name="LINK_START" />अतिथी म्हणून ब्राउझ<ph name="LINK_END" /> देखील करू शकता.</translation> -<translation id="3177048931975664371">पासवर्ड लपविण्यासाठी क्लिक करा</translation> <translation id="3177909033752230686">पृष्ठ भाषा:</translation> <translation id="3181110748548073003">पुढे जाण्यासाठी |<ph name="SHORTCUT" />| दाबा</translation> <translation id="3182749001423093222">शब्दलेखन तपासणी</translation> @@ -1473,7 +1474,6 @@ <translation id="3236289833370040187">मालकी <ph name="DESTINATION_DOMAIN" /> कडे हस्तांतरित केली जाईल.</translation> <translation id="323803881985677942">विस्तार पर्याय उघडा</translation> <translation id="3241680850019875542">पॅक करण्यासाठी विस्ताराची मूळ निर्देशिका निवडा. एक विस्तार अपडेट करण्याकरिता, पुनर्वापरासाठी खाजगी की फाइल देखील निवडा.</translation> -<translation id="3242765319725186192">पूर्व-सामायिक की:</translation> <translation id="3244294424315804309">आवाज म्यूट करणे सुरू ठेवा</translation> <translation id="3245321423178950146">अज्ञात कलाकार</translation> <translation id="3246097286174000800">Smart Lock वापरून पहा</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> साठी अधिक क्रिया</translation> <translation id="3440761377721825626">एखादी साइट आपल्या संगणकावर प्रवेश करण्यासाठी प्लगिन वापरू इच्छिते तेव्हा विचारा</translation> <translation id="3441653493275994384">तपासा</translation> -<translation id="3445830502289589282">टप्पा 2 प्रमाणीकरण:</translation> <translation id="344630545793878684">अनेक वेबसाइटवर आपला डेटा वाचा</translation> <translation id="3449839693241009168"><ph name="EXTENSION_NAME" /> कडे कमांड पाठविण्यासाठी <ph name="SEARCH_KEY" /> दाबा</translation> <translation id="3450157232394774192">निष्क्रिय स्थिती कब्जा टक्केवारी</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> एरर.</translation> <translation id="3495660573538963482">Google साहाय्यक सेटिंग्ज</translation> <translation id="3496213124478423963">झूम कमी करा</translation> -<translation id="3504135463003295723">गट नाव:</translation> <translation id="3505030558724226696">डिव्हाइस प्रवेश रद्द करा</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" साठी वर्तमान परवानग्या</translation> <translation id="3507547268929739059">Chromebook साठी Linux अॅप्स काढा</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">साइन इन प्रमाणपत्र अवैध आहे, विंडो <ph name="MINUTES" /> : <ph name="SECONDS" /> मध्ये बंद होत आहे</translation> <translation id="3664511988987167893">एक्स्टेंशन आयकन</translation> <translation id="3665589677786828986">Chrome ला आढळले आहे की आपल्या काही सेटिंग्ज दुसर्या प्रोग्रामद्वारे दूषित झाल्या होत्या आणि त्यांच्या मूळ डीफॉल्टवर त्या रीसेट केल्या.</translation> -<translation id="3665842570601375360">सुरक्षितता:</translation> <translation id="3668570675727296296">भाषा सेटिंग्ज</translation> <translation id="3668823961463113931">हँडलर</translation> <translation id="3670229581627177274">Bluetooth चालू करा</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">हे डिव्हाइस उघडले जाऊ शकत नाही कारण त्याचे फाइलसिस्टम समर्थित नाही.</translation> <translation id="3727148787322499904">हे सेटिंग बदलल्याने सर्व सामायिक केलेले नेटवर्क प्रभावित होतील</translation> <translation id="3727187387656390258">पॉपअपची तपासणी करा</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">रेषा <ph name="ERROR_LINE" /> वर एरर</translation> <translation id="3733127536501031542">स्टेप-अप सह SSL सर्व्हर</translation> <translation id="3737536731758327622">आपले डाउनलोड येथे दिसतील</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">पूर्ण झाल्यानंतर एंटर दाबा</translation> <translation id="3827774300009121996">&पूर्ण स्क्रीन</translation> <translation id="3828029223314399057">बुकमार्क शोधणे</translation> -<translation id="3829932584934971895">प्रदाता प्रकार:</translation> <translation id="3830674330436234648">प्लेबॅक उपलब्ध नाही</translation> <translation id="3831486154586836914">विंडो विहंगावलोकन मोड एंटर केला</translation> <translation id="383161972796689579">या डिव्हाइसच्या मालकाने नवीन वापरकर्त्यांना जोडले जाण्यापासून अक्षम केले आहे</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">डेटा वापर मापन समाप्त झाले</translation> <translation id="3857228364945137633">तुमचा फोन जवळपास असताना पासवर्डशिवाय तुमचे <ph name="DEVICE_TYPE" /> अनलॉक करण्यासाठी Smart Lock वापरून पहा.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: सिंक करणे थांबवले</translation> <translation id="3860381078714302691">Hangouts Meetमध्ये तुमचे स्वागत आहे</translation> <translation id="3862134173397075045">Chrome मधील कास्ट अनुभवावर आपले स्वागत आहे!</translation> <translation id="3862788408946266506">'kiosk_only' मॅनिफेस्ट विशेषता असलेले अॅप Chrome OS कियोस्क मोडमध्ये इंस्टॉल केले जाणे आवश्यक आहे</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">नेटवर्क सेट करणे शक्य झाले नाही</translation> <translation id="3970114302595058915">आयडी</translation> <translation id="397105322502079400">गणना करत आहे...</translation> -<translation id="3974195870082915331">पासवर्ड दर्शविण्यासाठी क्लिक करा</translation> <translation id="3975222297214566386">इनपुट पर्याय फुगा</translation> <translation id="397703832102027365">पूर्ण करीत आहे...</translation> <translation id="3979395879372752341">नवीन विस्तार जोडला (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">आपला प्रमाणपत्र पासवर्ड एंटर करा</translation> <translation id="404493185430269859">डीफॉल्ट शोध इंजिन</translation> <translation id="4047112090469382184">हे कसे सुरक्षित आहे</translation> +<translation id="4051049974203704184">स्क्रीनवर काय आहे याबाबत माहिती मिळवा</translation> <translation id="4052120076834320548"> लघु</translation> <translation id="4055023634561256217">Powerwash सह आपला डिव्हाइस रीसेट केला जाण्यापूर्वी रीस्टार्ट करणे आवश्यक आहे.</translation> @@ -2038,6 +2034,7 @@ <translation id="4088095054444612037">गटासाठी स्वीकारा</translation> <translation id="4089235344645910861">सेटिंग्ज सेव्ह केल्या. सिंक सुरू केले.</translation> <translation id="4090103403438682346">सत्यापित केलेला प्रवेश सक्षम करा</translation> +<translation id="4090947011087001172"><ph name="SITE" /> साठी साइट परवानग्या रीसेट करायच्या?</translation> <translation id="4091434297613116013">कागदी पत्रके</translation> <translation id="4093955363990068916">स्थानिक फाईल:</translation> <translation id="4095507791297118304">प्राथमिक प्रदर्शन</translation> @@ -2214,7 +2211,6 @@ <translation id="4419556793104466535">सिंक, पर्सनलायझेशन आणि बरेच काही नियंत्रित करा</translation> <translation id="4421932782753506458">Fluffy</translation> <translation id="4422347585044846479">या पृष्ठासाठी बुकमार्क संपादित करा</translation> -<translation id="4423104065312875417">अतिरिक्त स्पीच इंजिन इंस्टॉल करा</translation> <translation id="4423376891418188461">सेटिंग्ज पुनर्संचयित करा</translation> <translation id="4423482519432579560">&शब्दलेखन तपासणी</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, आपण आपला पासवर्ड बदलणे आपल्या प्रशासकासाठी आवश्यक आहे.</translation> @@ -2239,7 +2235,6 @@ <translation id="4449996769074858870">हा टॅब ऑडिओ प्ले करत आहे.</translation> <translation id="4450974146388585462">निदान करा</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> वर शोधा किंवा URL टाइप करा</translation> -<translation id="445923051607553918">वाय-फाय नेटवर्कमध्ये सामील व्हा</translation> <translation id="4462159676511157176">सानुकूल नाव सर्व्हर</translation> <translation id="4467100756425880649">Chrome वेब स्टोअर गॅलरी</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> विस्तारित करा</translation> @@ -2375,6 +2370,7 @@ <translation id="4682551433947286597">साइन-इन स्क्रीनवर दिसणारे वॉलपेपर.</translation> <translation id="4684427112815847243">सर्वकाही संंकालित करा</translation> <translation id="4689421377817139245">आपल्या iPhone सह हा बुकमार्क संकालित करा</translation> +<translation id="4690091457710545971"><Intel वाय-फाय फर्मवेयरद्वारे चार फायली निर्माण करण्यात आल्या: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. पहिल्या तीन बायनरी फायली अशा आहेत ज्यामध्ये रजिस्टर डंप आहेत आणि त्यामध्ये कोणतीही वैयक्तिक किंवा डिव्हाइसची ओळख स्पष्ट करणारी माहिती नसेल याची Intel द्वारे खात्री करण्यात आली आहे. शेवटची फाइल म्हणजे Intel फर्मवेयरने काढलेला माग आहे; त्यामधून कोणतीही वैयक्तिक किंवा डिव्हाइसची ओळख स्पष्ट करणारी माहिती काढून टाकण्यात आली आहे, पण ही फाइल इथे दर्शवण्यासाठी खूप मोठी आहे. तुमच्या डिव्हाइसवर नुकत्याच उद्भवलेल्या वाय-फाय समस्यांच्या प्रतिसादातून या फायली तयार करण्यात आल्या आहेत आणि या समस्यांवर मार्ग काढण्यासाठी त्या Intel सह शेअर केल्या जातील.></translation> <translation id="4692302215262324251">एंटरप्राइझ व्यवस्थापनासाठी <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ने आपल्या <ph name="DEVICE_TYPE" /> ची यशस्वीरित्या नोंदणी केली आहे. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> हे अनपेक्षित असल्यास, कृपया समर्थनाशी संपर्क करा.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">नवीन सेटिंग्ज प्रभावी होण्यापूर्वी या पृष्ठास रीलोड करण्याची आवश्यकता असू शकते.</translation> <translation id="5075131525758602494">सिम पिन एंटर करा</translation> <translation id="5078638979202084724">सर्व टॅब बुकमार्क करा</translation> +<translation id="5079950360618752063">सुचवलेला पासवर्ड वापरा</translation> <translation id="5084230410268011727">साइटना गती आणि प्रकाश सेन्सर वापरू द्या</translation> <translation id="5085162214018721575">अद्यतनांसाठी तपासत आहे</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">हा आयटम हटवा</translation> <translation id="5139955368427980650">&उघडा</translation> +<translation id="5142961317498132443">ऑथेंटिकेशन</translation> <translation id="5143374789336132547">आपण होम बटण क्लिक करता तेव्हा कोणते पृष्ठ दर्शविले जाते हे "<ph name="EXTENSION_NAME" />" विस्ताराने बदलले आहे.</translation> <translation id="5143712164865402236">पूर्ण स्क्रीनमध्ये जा</translation> <translation id="5145331109270917438">सुधारणा तारीख</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">अशा सुधारकांचे कीबोर्ड शॉर्टकट पाहण्यासाठी Control, Alt, Shift, किंवा शोध दाबून ठेवा.</translation> <translation id="5382591305415226340">समर्थित दुवे व्यवस्थापित करा</translation> <translation id="5384883051496921101">ही साइट गुप्त मोडच्या बाहेरील एखाद्या अॅपबरोबर ही माहिती शेअर करणार आहे.</translation> -<translation id="5388588172257446328">वापरकर्तानाव:</translation> <translation id="5388885445722491159">जोडलेले</translation> <translation id="5389237414310520250">नवीन वापरकर्ता तयार करणे शक्य झाले नाही. कृपया तुमची हार्ड ड्राइव्ह जागा आणि परवानग्या तपासा आणि पुन्हा प्रयत्न करा.</translation> <translation id="5390100381392048184">साइटना ध्वनी प्ले करण्याची परवानगी द्या</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">कीबोर्ड आणि मजकूर इनपुट</translation> <translation id="5553089923092577885">प्रमाणपत्र धोरण मॅपिंग</translation> <translation id="5554489410841842733">जेव्हा विस्तार वर्तमान पृष्ठावर कार्य करेल तेव्हा हे प्रतीक दृश्यमान होईल.</translation> -<translation id="5554573843028719904">इतर वाय-फाय नेटवर्क...</translation> <translation id="5554720593229208774">ईमेल प्रमाणन अधिकृतता</translation> <translation id="5556206011531515970">आपले डीफॉल्ट ब्राउझर निवडण्यासाठी पुढील क्लिक करा.</translation> <translation id="5556459405103347317">रीलोड करा</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">कॅमेरा मोडवर स्विच करा</translation> <translation id="5612720917913232150"><ph name="URL" /> ला तुमच्या काँप्युटरचे स्थान वापरायचे आहे</translation> <translation id="5612734644261457353">क्षमस्व, आपला पासवर्ड अद्याप सत्यापित होऊ शकला नाही. टीप: आपण अलीकडेच आपला पासवर्ड बदलला असल्यास, एकदा आपण साइन आउट केल्यानंतर आपला नवीन पासवर्ड लागू केला जाईल, कृपया येथे जुना पासवर्ड वापरा.</translation> -<translation id="5613695965848159202">अनामित ओळख:</translation> <translation id="5614190747811328134">वापरकर्ता सूचना</translation> <translation id="561698261642843490">Firefox बंद करा</translation> <translation id="5618075537869101857">अरेरे, कियोस्क अॅप्लिकेशन लाँच केला जाऊ शकला नाही.</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">कृपया <ph name="TOKEN_NAME" /> मध्ये साइन इन करा.</translation> <translation id="5941711191222866238">लहान करा</translation> <translation id="5946591249682680882">अहवाल आयडी <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">खाजगी नेटवर्क जोडा</translation> <translation id="5949544233750246342">फाइल विश्लेषित करण्यात अक्षम</translation> <translation id="5955282598396714173">तुमचा पासवर्ड एक्सपायर झाला आहे. तो बदलण्यासाठी कृपया साइन आऊट करा आणि पुन्हा साइन इन करा.</translation> <translation id="5956585768868398362">आपण अपेक्षा करत होता हे तेच शोध पृष्ठ आहे?</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">साइन आउट करा नंतर पुन्हा साइन इन करा...</translation> <translation id="6198252989419008588">पिन बदला</translation> <translation id="6199801702437275229">स्थान माहितीसाठी प्रतीक्षा करत आहे...</translation> +<translation id="6204015976622790023">तुमच्या स्क्रीनवर काय आहे यासंबंधित तुमच्या असिस्टंटकडील उपयुक्त सूचना पाहा.</translation> <translation id="6205710420833115353">काही ऑपरेशनला अपेक्षेपेक्षा जास्त वेळ लागत आहे. आपण त्यांना निरस्त करू इच्छिता?</translation> <translation id="6206311232642889873">इमेज कॉ&पी करा</translation> <translation id="6207200176136643843">झूम स्तर डीफॉल्टवर रीसेट करा</translation> <translation id="620722923698527029">या प्रकारच्या लिंक नेहमी संबद्ध अॅपमध्ये उघडा</translation> <translation id="6207937957461833379">देश/प्रदेश</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: सिंक करणे कार्यरत नाही</translation> <translation id="6212039847102026977">प्रगत नेटवर्क वैशिष्ट्ये दर्शवा</translation> <translation id="6212168817037875041">डिस्प्ले बंद करा</translation> <translation id="6212752530110374741">ईमेल लिंक</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">समक्रमण रीसेट करा</translation> <translation id="6264365405983206840">&सर्व निवडा</translation> <translation id="6264422956566238156">तुम्ही सिंक सुरू केले आहे</translation> -<translation id="6265930187414222160">पूर्ण झाले! धोकादायक सॉफ्टवेअर काढून टाकले.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" /> वर आपल्या स्वतःस प्रमाणीकृत करण्यासाठी एक प्रमाणपत्र निवडा</translation> <translation id="6268252012308737255"><ph name="APP" /> सह उघडा</translation> <translation id="6268747994388690914">HTML फायलीवरुन बुकमार्क आयात करा...</translation> @@ -3537,7 +3532,6 @@ कृपया आपल्या <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> खात्यामध्ये साइन इन करणे सुरु ठेवण्यासाठी "पुढील" क्लिक करा.</translation> <translation id="6419546358665792306">अनपॅक केलेले लोड करा</translation> <translation id="642282551015776456">हे नाव एखाद्या फाइल किंवा फोल्डरचे नाव म्हणून वापरले जाऊ शकत नाही</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox सेटिंग्ज उघडा</translation> <translation id="6429384232893414837">अपडेट एरर</translation> <translation id="6430814529589430811">Base64-encoded ASCII, एकल प्रमाणपत्र</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">तुमच्यासाठी, Google द्वारे वेब ब्राउझर</translation> <translation id="6545665334409411530">पुनरावृत्ती दर</translation> <translation id="6545834809683560467">अॅड्रेस बारमध्ये किंवा अॅप लाँचरमध्ये टाइप केलेले शोध आणि URL पूर्ण करण्यात मदतीसाठी पूर्वानुमान सेवा वापरा</translation> -<translation id="6546686722964485737">WiMAX नेटवर्कमध्ये सामील व्हा</translation> <translation id="6547316139431024316">या विस्तारासाठी पुन्हा चेतावणी देऊ नका</translation> <translation id="6547354035488017500">किमान 512 MB स्थान मोकळे करा किंवा आपले डिव्हाइस अप्रतिसादात्मक बनेल. स्थान मोकळे करण्यासाठी, डिव्हाइस संचयामधून फायली हटवा.</translation> <translation id="6549689063733911810">अलीकडील</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Linux फायली बघू शकत नाही</translation> <translation id="720110658997053098">हे डिव्हाइस कायमचे कियोस्क मोडमध्ये ठेवा</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' हटवले</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> डाउनलोड करीत आहे...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{पेजमधून बाहेर या}one{पेजमधून बाहेर या}other{पेजमधून बाहेर या}}</translation> <translation id="7216409898977639127">सेल्युलर सेवा देणारा</translation> @@ -4513,7 +4505,6 @@ <translation id="7909969815743704077">गुप्त मध्ये डाउनलोड केले</translation> <translation id="7910768399700579500">&नवीन फोल्डर</translation> <translation id="7912080627461681647">तुमचा पासवर्ड सर्व्हरवर बदलला आहे. कृपया साइन आऊट करा आणि पुन्हा साइन इन करा.</translation> -<translation id="7912883689016444961">मोबाईल नेटवर्क कॉन्फिगर करा</translation> <translation id="7915471803647590281">कृपया अभिप्राय पाठविण्यापूर्वी काय होत आहे ते आम्हाला सांगा.</translation> <translation id="7916556741383518510">क्लिकवर</translation> <translation id="792514962475806987">डॉक केलेली झूम पातळी:</translation> @@ -4567,7 +4558,6 @@ <translation id="7988355189918024273">प्रवेश वैशिष्ट्ये सक्षम करा</translation> <translation id="7994702968232966508">EAP पद्धत</translation> <translation id="799547531016638432">शॉर्टकट काढा</translation> -<translation id="7997479212858899587">ओळख:</translation> <translation id="7997826902155442747">प्रक्रिया प्राधान्य</translation> <translation id="7999229196265990314">निम्न फायली तयार केल्या: @@ -4651,7 +4641,6 @@ <translation id="8105368624971345109">बंद करा</translation> <translation id="8106045200081704138">माझ्याशी सामायिक केलेले</translation> <translation id="8107015733319732394">तुमच्या <ph name="DEVICE_TYPE" /> वर Google Play स्टोअर इंस्टॉल करत आहे. यासाठी काही मिनिटे लागतील.</translation> -<translation id="8109930990200908494">वापरकर्ता प्रमाणपत्रासाठी साइन इन आवश्यक.</translation> <translation id="8111155949205007504">आपल्या iPhone सह हा पासवर्ड शेअर करा</translation> <translation id="8113043281354018522">परवाना प्रकार निवडा</translation> <translation id="8116190140324504026">अधिक माहिती...</translation> @@ -4662,6 +4651,7 @@ <translation id="8118860139461251237">आपले डाउनलोड व्यवस्थापित करा</translation> <translation id="81238879832906896">पिवळे आणि पांढरे फूल</translation> <translation id="8124313775439841391">व्यवस्थापित ONC</translation> +<translation id="8125562866093998907">तुमच्या खात्याला अधिक सुरक्षितता जोडण्यासाठी या साइटला तुमची सिक्युरिटी की पडताळायची आहे.</translation> <translation id="813082847718468539">साइटची माहिती पहा</translation> <translation id="8131740175452115882">पुष्टी करा</translation> <translation id="8133676275609324831">फोल्डरमध्ये &दर्शवा</translation> @@ -4772,7 +4762,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> आपल्या कॅमेर्यावर प्रवेश करू इच्छित असल्यास विचारा</translation> <translation id="830868413617744215">बीटा</translation> <translation id="8309458809024885768">प्रमाणपत्र आधीपासूनच विद्यमान आहे</translation> -<translation id="8309505303672555187">एखादे नेटवर्क निवडा:</translation> <translation id="8312871300878166382">फोल्डरमध्ये पेस्ट करा</translation> <translation id="8317671367883557781">नेटवर्क कनेक्शन जोडा</translation> <translation id="8319414634934645341">विस्तारित की वापर</translation> @@ -4847,7 +4836,6 @@ <translation id="8451512073679317615">साहाय्यक</translation> <translation id="8452135315243592079">गहाळ सिम कार्ड</translation> <translation id="8453482423012550001">$1 आयटम कॉपी करत आहे...</translation> -<translation id="8454288007744638700">किंवा, एक नवीन नेटवर्क निवडा:</translation> <translation id="845627346958584683">कालावधी समाप्ती वेळ</translation> <translation id="8456681095658380701">अवैध नाव</translation> <translation id="8457451314607652708">बुकमार्क आयात करा</translation> @@ -4911,6 +4899,7 @@ <translation id="855081842937141170">टॅब पिन करा</translation> <translation id="8551388862522347954">परवाने</translation> <translation id="8553342806078037065">इतर लोक व्यवस्थापित करा</translation> +<translation id="8554899698005018844">कोणतीही भाषा नाही</translation> <translation id="855773602626431402">या पृष्ठावर चालण्यापासून सॅन्डबॉक्स न केलेल्या प्लगिनला प्रतिबंधित करण्यात आले.</translation> <translation id="8557930019681227453">मॅनिफेस्ट</translation> <translation id="8559694214572302298">इमेज डीकोडर</translation> @@ -4948,7 +4937,6 @@ <translation id="862727964348362408">निलंबित</translation> <translation id="862750493060684461">CSS कॅश </translation> <translation id="8627795981664801467">केवळ सुरक्षित कनेक्शन</translation> -<translation id="8628085465172583869">सर्व्हर होस्टनाव:</translation> <translation id="8630903300770275248">पर्यवेक्षी वापरकर्ता आयात करा</translation> <translation id="8631032106121706562">पाकळ्या</translation> <translation id="8637542770513281060">तुमच्या काँप्युटरमध्ये एक सुरक्षित मॉड्यूल आहे, जे Chrome OSमध्ये अनेक गंभीर सुरक्षितता वैशिष्ट्ये अंमलात आणण्यासाठी वापरले जाते. आणखी जाणून घेण्यासाठी Chromebook मदत केंद्राला भेट द्या: https://support.google.com/chromebook/?p=sm</translation> @@ -5205,7 +5193,6 @@ <translation id="899403249577094719">Netscape प्रमाणपत्र मूळ URL</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> द्वारे व्यवस्थापित</translation> <translation id="8996526648899750015">खाते जोडा...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">डिस्क इमेज तयार करत आहे.</translation> <translation id="9003647077635673607">सर्व वेबसाइटवर अनुमती द्या</translation> <translation id="9003677638446136377">पुन्हा तपासा</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb index fdaf86c..54b8375 100644 --- a/chrome/app/resources/generated_resources_ms.xtb +++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Masa rehat hampir tiba</translation> <translation id="1062407476771304334">Gantikan</translation> -<translation id="1064835277883315402">Sertai rangkaian persendirian</translation> <translation id="1064912851688322329">Putuskan sambungan Akaun Google anda</translation> <translation id="1067048845568873861">Dibuat</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Mencari...</translation> <translation id="1316495628809031177">Penyegerakan dijeda</translation> <translation id="1319979322914001937">Apl yang menunjukkan senarai ditapis bagi sambungan daripada Gedung Web Chrome. Sambungan dalam senarai boleh dipasang terus daripada apl.</translation> -<translation id="132090119144658135">Padanan Subjek:</translation> <translation id="1326317727527857210">Log masuk ke Chrome untuk mendapatkan tab daripada peranti anda yang lain.</translation> <translation id="1327074568633507428">Pencetak di Cetakan Awan Google</translation> <translation id="1327977588028644528">Get Laluan</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Tetingkap Aplikasi</translation> <translation id="1534389735079119190">RALAT: Gagal memulakan bekas dalam VM.</translation> <translation id="15373452373711364">Kursor tetikus besar</translation> +<translation id="1540605929960647700">Dayakan mod tunjuk cara</translation> <translation id="1543284117603151572">Diimport Daripada Edge</translation> <translation id="1545177026077493356">Mod Kios Automatik</translation> <translation id="1545775234664667895">Tema yang dipasang "<ph name="THEME_NAME" />"</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Bantu jadikan <ph name="PRODUCT_NAME" /> lebih baik dengan menghantar statistik dan laporan nahas secara automatik kepada Google</translation> <translation id="1658424621194652532">Halaman ini mengakses mikrofon anda.</translation> <translation id="1660204651932907780">Benarkan tapak untuk memainkan bunyi (disyorkan)</translation> +<translation id="1660938185063657230">Sahkan Kunci Keselamatan anda</translation> <translation id="1661156625580498328">Kuat kuasakan penyulitan AES (disyorkan).</translation> <translation id="1661245713600520330">Halaman ini menyenaraikan semua modul yang dimuatkan ke proses utama dan modul yang didaftarkan pada titik kemudian.</translation> <translation id="166179487779922818">Kata laluan terlalu pendek.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Jangan benarkan tapak melihat teks dan imej yang disalin ke papan keratan</translation> <translation id="1682548588986054654">Tetingkap Inkognito Baharu</translation> <translation id="168715261339224929">Hidupkan penyegerakan untuk mendapatkan penanda halaman pada semua peranti anda.</translation> +<translation id="1688867105868176567">Kosongkan data tapak?</translation> <translation id="1688935057616748272">Taip huruf</translation> <translation id="168991973552362966">Tambahkan pencetak berdekatan</translation> <translation id="1689945336726856614">Salin &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Alih keluar orang ini</translation> <translation id="1706586824377653884">Ditambahkan oleh pentadbir anda</translation> <translation id="1706625117072057435">Tahap zum</translation> -<translation id="1707463636381878959">Kongsi rangkaian ini dengan pengguna lain</translation> <translation id="1708338024780164500">(Tidak Aktif)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Natif)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Dayakan tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Lihat di Gedung Web Chrome</translation> -<translation id="1758831820837444715">Konfigurasikan rangkaian Ethernet</translation> <translation id="1763046204212875858">Cipta pintasan aplikasi</translation> <translation id="1763108912552529023">Teruskan meneroka</translation> <translation id="1763808908432309942">Membuka dalam tab baharu</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Tukar cara fail ini dikongsi.</translation> <translation id="1841545962859478868">Pentadbir peranti boleh memantau perkara berikut:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> dilumpuhkan</translation> +<translation id="1842766183094193446">Adakah anda pasti mahu mendayakan mod tunjuk cara?</translation> <translation id="1844692022597038441">Fail ini tidak boleh didapati di luar talian.</translation> <translation id="1846308012215045257">Tekan Ctrl dan klik untuk menjalankan <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Disimpan</translation> <translation id="1848219224579402567">Log keluar apabila penutup ditutup</translation> <translation id="184823282865851239">Sekat jika tapak cenderung menyiarkan iklan yang mengganggu</translation> <translation id="1849186935225320012">Halaman ini mengawal sepenuhnya peranti MIDI.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Anda boleh menukar ciri ini dalam tetapan pada bila-bila masa</translation> <translation id="2006638907958895361">Buka Pautan dalam <ph name="APP" /></translation> <translation id="2007404777272201486">Laporkan Isu...</translation> +<translation id="2016237810978710652">Membuka Fail Linux...</translation> <translation id="2016430552235416146">Tradisional</translation> <translation id="2017334798163366053">Lumpuhkan pengumpulan data prestasi</translation> <translation id="2017836877785168846">Kosongkan sejarah dan pelengkapan automatik dalam bar alamat.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Edit kad</translation> <translation id="2154710561487035718">Salin URL</translation> <translation id="2155772377859296191">Kelihatan seperti <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Anda boleh membantu dalam meningkatkan Penyemakan Imbas Selamat dengan menghantar beberapa maklumat sistem dan kandungan halaman kepada Google.</translation> <translation id="215753907730220065">Keluar Daripada Skrin Penuh</translation> <translation id="2157875535253991059">Halaman ini kini dalam skrin penuh.</translation> <translation id="216169395504480358">Tambah Wi-Fi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Tambahkan ID permintaan pada peranti ini</translation> <translation id="2175042898143291048">Sentiasa terjemahkan</translation> <translation id="2175607476662778685">Bar lancar cepat</translation> +<translation id="2176087259161165020">Sumber lain</translation> <translation id="2177950615300672361">Tab Inkognito: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Pemalam <ph name="PEPPER_PLUGIN_NAME" /> di <ph name="PEPPER_PLUGIN_DOMAIN" /> ingin mengakses komputer anda</translation> <translation id="2178614541317717477">Tolak ansur CA</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Tab seterusnya</translation> <translation id="2292848386125228270">Sila mulakan <ph name="PRODUCT_NAME" /> sebagai pengguna biasa. Jika anda perlu menjalankan apl sebagai akar untuk pembangunan, jalankan semula dengan --bendera tanpa kotak pasir.</translation> <translation id="2294358108254308676">Adakah anda mahu memasang <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Kaedah EAP:</translation> <translation id="2297705863329999812">Cari pencetak</translation> <translation id="2300383962156589922">Sesuaikan dan kawal <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Direktori akar sambungan adalah tidak sah.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">RALAT: Gagal menyahpasang <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Tambah Perkongsian Fail</translation> <translation id="2367972762794486313">Paparkan apl</translation> +<translation id="2369536625682139252">Semua data yang disimpan oleh <ph name="SITE" /> akan dipadamkan, kecuali kuki.</translation> <translation id="2371076942591664043">Buka apabila &selesai</translation> <translation id="2377319039870049694">Tukar kepada paparan senarai</translation> <translation id="2377667304966270281">Kesalahan Keras</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Cetak menggunakan dialog sistem... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Tanya sebelum menghantar (disyorkan)</translation> <translation id="2384436799579181135">Ralat telah berlaku. Sila periksa pencetak anda dan cuba lagi.</translation> -<translation id="2385700042425247848">Nama perkhidmatan:</translation> <translation id="2387458720915042159">Jenis sambungan proksi</translation> <translation id="2391419135980381625">Fon standard</translation> <translation id="2391762656119864333">Batalkan</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Kongsi audio</translation> <translation id="2480868415629598489">Ubah suai data yang anda salin dan tampal</translation> <translation id="2482878487686419369">Pemberitahuan</translation> -<translation id="2485056306054380289">Sijil CA pelayan:</translation> <translation id="2485422356828889247">Nyahpasang</translation> <translation id="2487067538648443797">Tambahkan penanda halaman baharu</translation> <translation id="248861575772995840">Tidak dapat mencari telefon anda. Pastikan Bluetooth <ph name="DEVICE_TYPE" /> anda dihidupkan. <a>Ketahui lebih lanjut</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Powerwash untuk menetapkan semula peranti <ph name="IDS_SHORT_PRODUCT_NAME" /> anda supaya seperti baharu.</translation> <translation id="2567257616420533738">Kata laluan disimpan. Lihat dan urus kata laluan yang disimpan di <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Bekas Bar Maklumat</translation> +<translation id="2570454805927264159">Manfaatkan Assistant anda sepenuhnya</translation> <translation id="257088987046510401">Tema</translation> <translation id="2572032849266859634">Akses baca sahaja kepada <ph name="VOLUME_NAME" /> telah diberikan.</translation> <translation id="2573269395582837871">Pilih gambar dan nama</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">Serah</translation> <translation id="265390580714150011">Nilai Medan</translation> <translation id="2654166010170466751">Benarkan tapak untuk memasang pengendali pembayaran</translation> -<translation id="2655386581175833247">Sijil pengguna:</translation> <translation id="2660779039299703961">Acara</translation> <translation id="266079277508604648">Tidak dapat menyambungkan pencetak. Pastikan pencetak dihidupkan dan disambungkan kepada Chromebook anda melalui Wi-Fi atau USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">Tiada data penggunaan</translation> <translation id="3007214526293698309">Betulkan nisbah</translation> <translation id="3007771295016901659">Tab Pendua</translation> +<translation id="3008272652534848354">Tetapkan semula kebenaran</translation> <translation id="3009300415590184725">Adakah anda pasti mahu membatalkan proses penyediaan perkhidmatan data mudah alih?</translation> <translation id="3009779501245596802">Pangkalan data berindeks</translation> <translation id="3010279545267083280">Kata laluan dipadamkan</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">Modul (<ph name="TOTAL_COUNT" />) - Konflik dikenali: <ph name="BAD_COUNT" />, disyaki: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Tarikh dan masa</translation> <translation id="310671807099593501">Tapak sedang menggunakan bluetooth</translation> -<translation id="3108967419958202225">Pilih...</translation> <translation id="3115128645424181617">Tidak dapat mencari telefon anda. Pastikan telefon tersebut ada bersama anda dan Bluetooth dihidupkan.</translation> <translation id="3115147772012638511">Menunggu cache...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Bantuan</translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">Sesetengah pembawa mungkin menyekat ciri ini.</translation> <translation id="316854673539778496">Log masuk dan hidupkan penyegerakan untuk mendapatkan semua sambungan pada semua peranti anda.</translation> <translation id="3170072451822350649">Anda juga boleh melangkau log masuk dan <ph name="LINK_START" />menyemak imbas sebagai tetamu<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Klik untuk sembunyikan kata laluan</translation> <translation id="3177909033752230686">Bahasa Halaman:</translation> <translation id="3181110748548073003">Tekan |<ph name="SHORTCUT" />| untuk beralih ke hadapan</translation> <translation id="3182749001423093222">Semakan ejaan</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187">Pemilikan akan dipindahkan ke <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Buka pilihan sambungan</translation> <translation id="3241680850019875542">Pilih direktori akar bagi sambungan untuk pek. Untuk mengemas kini sambungan, pilih kunci persendirian untuk gunakan semula juga.</translation> -<translation id="3242765319725186192">Kekunci prakongsi:</translation> <translation id="3244294424315804309">Teruskan meredam bunyi</translation> <translation id="3245321423178950146">Artis Tidak Dikenali</translation> <translation id="3246097286174000800">Cuba Smart Lock</translation> @@ -1608,7 +1608,6 @@ <translation id="3440663250074896476">Lagi tindakan untuk <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Tanya apabila tapak ingin menggunakan pemalam untuk mengakses komputer anda</translation> <translation id="3441653493275994384">Skrin</translation> -<translation id="3445830502289589282">Pengesahan fasa 2:</translation> <translation id="344630545793878684">Baca data anda di beberapa tapak web</translation> <translation id="3449839693241009168">Tekan <ph name="SEARCH_KEY" /> untuk menghantar perintah kepada <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Peratusan Penggunaan Keadaan Melahu</translation> @@ -1649,7 +1648,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> ralat.</translation> <translation id="3495660573538963482">Tetapan Google Assistant</translation> <translation id="3496213124478423963">Zum Keluar</translation> -<translation id="3504135463003295723">Nama kumpulan:</translation> <translation id="3505030558724226696">Batalkan akses peranti</translation> <translation id="3507421388498836150">Kebenaran Semasa untuk "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Alih keluar Apl Linux untuk Chromebook</translation> @@ -1758,7 +1756,6 @@ <translation id="3661054927247347545">Pensijilan log masuk tidak sah, tetingkap akan ditutup dalam <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ikon Sambungan</translation> <translation id="3665589677786828986">Chrome mengesan bahawa sesetengah tetapan anda telah terganggu oleh program lain dan menetapkannya semula kepada tetapan lalainya yang asal.</translation> -<translation id="3665842570601375360">Keselamatan:</translation> <translation id="3668570675727296296">Tetapan bahasa</translation> <translation id="3668823961463113931">Pengendali</translation> <translation id="3670229581627177274">Hidupkan Bluetooth</translation> @@ -1797,7 +1794,6 @@ <translation id="3726463242007121105">Peranti ini tidak boleh dibuka kerana sistem failnya tidak disokong.</translation> <translation id="3727148787322499904">Tindakan menukar tetapan ini akan menjejaskan semua rangkaian yang dikongsi</translation> <translation id="3727187387656390258">Periksa pop muncul</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Ralat pada baris <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Pelayan SSL dengan Peningkatan</translation> <translation id="3737536731758327622">Muat turun anda dipaparkan di sini</translation> @@ -1872,7 +1868,6 @@ <translation id="38275787300541712">Tekan Enter apabila selesai</translation> <translation id="3827774300009121996">&Skrin Penuh</translation> <translation id="3828029223314399057">Cari penanda halaman</translation> -<translation id="3829932584934971895">Jenis pembekal:</translation> <translation id="3830674330436234648">Main balik tidak tersedia</translation> <translation id="3831486154586836914">Memasuki mod gambaran keseluruhan tetingkap</translation> <translation id="383161972796689579">Pemilik peranti ini telah melumpuhkan pengguna baharu daripada ditambah</translation> @@ -1893,6 +1888,7 @@ <translation id="3856921555429624101">Pengukuran penggunaan data telah tamat</translation> <translation id="3857228364945137633">Cuba Smart Lock untuk membuka kunci <ph name="DEVICE_TYPE" /> anda tanpa kata laluan semasa telefon ada berdekatan.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elir.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Penyegerakan dijeda</translation> <translation id="3860381078714302691">Selamat datang ke Hangout Meet</translation> <translation id="3862134173397075045">Selamat datang ke pengalaman Cast dalam Chrome!</translation> <translation id="3862788408946266506">Apl dengan atribut manifes 'kiosk_only' mesti dipasang dalam mod kios OS Chrome OS</translation> @@ -1970,7 +1966,6 @@ <translation id="3968261067169026421">Tidak dapat menyediakan rangkaian</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Mengira...</translation> -<translation id="3974195870082915331">Klik untuk menunjukkan kata laluan</translation> <translation id="3975222297214566386">Gelembung pilihan input</translation> <translation id="397703832102027365">Menyelesaikan...</translation> <translation id="3979395879372752341">Sambungan baharu ditambah (<ph name="EXTENSION_NAME" />)</translation> @@ -2012,6 +2007,7 @@ <translation id="4044612648082411741">Masukkan kata laluan sijil anda</translation> <translation id="404493185430269859">Enjin carian lalai</translation> <translation id="4047112090469382184">Bagaimana ini selamat</translation> +<translation id="4051049974203704184">Dapatkan maklumat untuk item yang dipaparkan pada skrin</translation> <translation id="4052120076834320548">Sangat Kecil</translation> <translation id="4055023634561256217">Mula semula diperlukan sebelum peranti anda boleh ditetapkan semula dengan Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2040,6 +2036,7 @@ <translation id="4088095054444612037">Terima untuk kumpulan</translation> <translation id="4089235344645910861">Tetapan disimpan. Penyegerakan bermula.</translation> <translation id="4090103403438682346">Dayakan Akses Disahkan</translation> +<translation id="4090947011087001172">Tetapkan semula kebenaran tapak untuk <ph name="SITE" />?</translation> <translation id="4091434297613116013">helai kertas</translation> <translation id="4093955363990068916">Fail setempat:</translation> <translation id="4095507791297118304">Paparan utama</translation> @@ -2216,7 +2213,6 @@ <translation id="4419556793104466535">Kawal penyegerakan, pemperibadian dan pelbagai lagi</translation> <translation id="4421932782753506458">Gebu</translation> <translation id="4422347585044846479">Edit penanda halaman untuk halaman ini</translation> -<translation id="4423104065312875417">Pasang enjin pertuturan tambahan</translation> <translation id="4423376891418188461">Pulihkan Tetapan</translation> <translation id="4423482519432579560">&Semakan ejaan</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, pentadbir anda memerlukan anda untuk menukar kata laluan.</translation> @@ -2241,7 +2237,6 @@ <translation id="4449996769074858870">Tab ini sedang memainkan audio.</translation> <translation id="4450974146388585462">Diagnosis</translation> <translation id="4453946976636652378">Cari <ph name="SEARCH_ENGINE_NAME" /> atau taipkan URL</translation> -<translation id="445923051607553918">Sertai rangkaian Wi-Fi</translation> <translation id="4462159676511157176">Nama pelayan tersuai</translation> <translation id="4467100756425880649">Galeri Gedung Web Chrome</translation> <translation id="4467101674048705704">Kembangkan <ph name="FOLDER_NAME" /></translation> @@ -2377,6 +2372,7 @@ <translation id="4682551433947286597">Kertas dinding dipaparkan pada Skrin Log Masuk.</translation> <translation id="4684427112815847243">Segerakkan semua</translation> <translation id="4689421377817139245">Segerakkan penanda halaman ini ke iPhone anda</translation> +<translation id="4690091457710545971"><Empat fail dihasilkan oleh perisian tegar Wi-Fi Intel: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Tiga fail yang pertama ialah fail perduaan yang mengandungi longgokan pendaftaran dan Intel menegaskan bahawa fail ini tidak mengandungi maklumat peribadi atau yang mengenal pasti peranti. Fail terakhir ialah surih pelaksanaan daripada perisian tegar Intel; fail ini telah dibersihkan supaya tidak mengandungi sebarang maklumat peribadi atau yang mengenal pasti peranti, tetapi terlalu besar untuk dipaparkan di sini. Fail ini dihasilkan sebagai tindak balas terhadap masalah Wi-Fi pada peranti anda baru-baru ini dan akan dikongsi dengan Intel untuk membantu dalam menyelesaikan masalah ini.></translation> <translation id="4692302215262324251"><ph name="DEVICE_TYPE" /> berjaya didaftarkan untuk pengurusan perusahaan oleh <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Jika perkara ini tidak dijangka, sila hubungi sokongan.</translation> @@ -2636,6 +2632,7 @@ <translation id="5074318175948309511">Halaman ini mungkin perlu dimuat semula sebelum tetapan baru berkesan.</translation> <translation id="5075131525758602494">Masukkan PIN SIM</translation> <translation id="5078638979202084724">Tanda halaman semua tab</translation> +<translation id="5079950360618752063">Gunakan kata laluan yang disyorkan</translation> <translation id="5084230410268011727">Benarkan tapak menggunakan penderia gerakan dan cahaya</translation> <translation id="5085162214018721575">Menyemak kemas kini</translation> <translation id="5086082738160935172">HID</translation> @@ -2674,6 +2671,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Padam item ini</translation> <translation id="5139955368427980650">&Buka</translation> +<translation id="5142961317498132443">Pengesahan</translation> <translation id="5143374789336132547">Sambungan "<ph name="EXTENSION_NAME" />" telah menukar halaman yang ditunjukkan apabila anda mengklik butang Laman Utama.</translation> <translation id="5143712164865402236">Memasuki Skrin Penuh</translation> <translation id="5145331109270917438">Tarikh diubah suai</translation> @@ -2844,7 +2842,6 @@ <translation id="5380103295189760361">Tahan Control, Alt, Shift, atau Search untuk melihat pintasan papan kekunci bagi pengubah suai tersebut.</translation> <translation id="5382591305415226340">Urus pautan yang disokong</translation> <translation id="5384883051496921101">Tapak ini akan berkongsi maklumat dengan apl di luar daripada mod inkognito.</translation> -<translation id="5388588172257446328">Nama pengguna:</translation> <translation id="5388885445722491159">Dipasangkan</translation> <translation id="5389237414310520250">Pengguna baharu tidak dapat dibuat. Sila semak ruang cakera keras serta kebenaran anda dan cuba lagi.</translation> <translation id="5390100381392048184">Benarkan tapak untuk memainkan bunyi</translation> @@ -2969,7 +2966,6 @@ <translation id="5551573675707792127">Papan kekunci dan masukan teks</translation> <translation id="5553089923092577885">Pemetaan Dasar Sijil</translation> <translation id="5554489410841842733">Ikon ini akan kelihatan apabila sambungan boleh bertindak pada halaman semasa.</translation> -<translation id="5554573843028719904">Rangkaian Wi-Fi Yang Lain...</translation> <translation id="5554720593229208774">Pihak Berkuasa Pensijilan E-mel</translation> <translation id="5556206011531515970">Klik seterusnya untuk memilih penyemak imbas lalai anda.</translation> <translation id="5556459405103347317">Muat Semula</translation> @@ -3010,7 +3006,6 @@ <translation id="5610038042047936818">Beralih ke mod kamera</translation> <translation id="5612720917913232150"><ph name="URL" /> mahu menggunakan lokasi komputer anda</translation> <translation id="5612734644261457353">Maaf, kata laluan anda masih tidak dapat disahkan. Perhatian: jika anda menukar kata laluan anda baru-baru ini, kata laluan baharu anda akan digunakan apabila anda log keluar, sila gunakan kata laluan yang lama di sini.</translation> -<translation id="5613695965848159202">Identiti tanpa nama:</translation> <translation id="5614190747811328134">Notis Pengguna</translation> <translation id="561698261642843490">Tutup Firefox</translation> <translation id="5618075537869101857">Alamak, aplikasi kios tidak dapat dilancarkan.</translation> @@ -3228,7 +3223,6 @@ <translation id="5941343993301164315">Sila log masuk ke <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimumkan</translation> <translation id="5946591249682680882">ID Laporan <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Tambah rangkaian persendirian</translation> <translation id="5949544233750246342">Tidak dapat menghurai fail</translation> <translation id="5955282598396714173">Kata laluan anda telah tamat tempoh. Sila log keluar, kemudian log masuk semula untuk menukarnya.</translation> <translation id="5956585768868398362">Adakah ini halaman carian yang anda jangkakan?</translation> @@ -3389,11 +3383,13 @@ <translation id="6198102561359457428">Log keluar kemudian log masuk semula...</translation> <translation id="6198252989419008588">Tukar PIN</translation> <translation id="6199801702437275229">Menunggu maklumat ruang...</translation> +<translation id="6204015976622790023">Lihat cadangan yang berkaitan daripada Assistant anda, yang berkaitan dengan item yang dipaparkan pada skrin anda.</translation> <translation id="6205710420833115353">Sesetengah operasi mengambil masa lebih lama daripada yang dijangkakan. Adakah anda ingin menghenti paksanya?</translation> <translation id="6206311232642889873">Sal&in Imej</translation> <translation id="6207200176136643843">Tetapkan semula kepada tahap zum lalai</translation> <translation id="620722923698527029">Sentiasa buka jenis pautan ini dalam apl yang berkaitan</translation> <translation id="6207937957461833379">Negara/Rantau</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Penyegerakan tidak berfungsi</translation> <translation id="6212039847102026977">Tunjukkan sifat rangkaian terperinci</translation> <translation id="6212168817037875041">Matikan paparan</translation> <translation id="6212752530110374741">E-melkan Pautan</translation> @@ -3431,7 +3427,6 @@ <translation id="6263541650532042179">tetapkan semula segerak</translation> <translation id="6264365405983206840">Pilih &Semua</translation> <translation id="6264422956566238156">Anda telah menghidupkan Penyegerakan</translation> -<translation id="6265930187414222160">Selesai! Perisian berbahaya dialih keluar.</translation> <translation id="6267166720438879315">Pilih sijil untuk mengesahkan dengan sendiri pada <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Buka menggunakan <ph name="APP" /></translation> <translation id="6268747994388690914">Import Penanda Halaman dari Fail HTML...</translation> @@ -3538,7 +3533,6 @@ Sila klik "Seterusnya" untuk terus mengelog masuk ke akaun <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> anda.</translation> <translation id="6419546358665792306">Muatkan sambungan dinyahpek</translation> <translation id="642282551015776456">Nama ini tidak boleh digunakan sebagai nama fail atau folder</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Buka tetapan ChromeVox</translation> <translation id="6429384232893414837">Ralat kemas kini</translation> <translation id="6430814529589430811">Base64 terkod ASCII, sijil tunggal</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">Penyemak imbas web oleh Google, untuk anda</translation> <translation id="6545665334409411530">Kadar pengulangan</translation> <translation id="6545834809683560467">Gunakan perkhidmatan ramalan untuk membantu menyelesaikan carian dan URL yang ditaip dalam bar alamat atau kotak carian pelancar apl</translation> -<translation id="6546686722964485737">Sertai rangkaian WIMAX</translation> <translation id="6547316139431024316">Jangan berikan amaran untuk sambungan ini lagi</translation> <translation id="6547354035488017500">Kosongkan sekurang-kurangnya 512 MB ruang, jika tidak peranti anda akan menjadi tidak responsif. Untuk mengosongkan ruang, padamkan fail daripada storan peranti.</translation> <translation id="6549689063733911810">Terbaharu</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Tidak dapat melihat Fail Linux</translation> <translation id="720110658997053098">Pastikan peranti ini kekal dalam mod kios</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' dipadamkan</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Memuat turun <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Keluar daripada halaman}other{Keluar daripada halaman}}</translation> <translation id="7216409898977639127">Penyedia selular</translation> @@ -4516,7 +4508,6 @@ <translation id="7909969815743704077">Dimuat turun dalam Inkognito</translation> <translation id="7910768399700579500">&Folder baharu</translation> <translation id="7912080627461681647">Kata laluan anda telah ditukar pada pelayan. Sila log keluar, kemudian log masuk semula.</translation> -<translation id="7912883689016444961">Konfigurasi rangkaian mudah alih</translation> <translation id="7915471803647590281">Sila beritahu kami kejadian yang berlaku sebelum menghantar maklum balas.</translation> <translation id="7916556741383518510">Apabila Diklik</translation> <translation id="792514962475806987">Tahap zum dok:</translation> @@ -4570,7 +4561,6 @@ <translation id="7988355189918024273">Dayakan ciri kebolehcapaian</translation> <translation id="7994702968232966508">Kaedah EAP</translation> <translation id="799547531016638432">Alih keluar pintasan</translation> -<translation id="7997479212858899587">Identiti:</translation> <translation id="7997826902155442747">Keutamaan Proses</translation> <translation id="7999229196265990314">Mencipta fail berikut: @@ -4654,7 +4644,6 @@ <translation id="8105368624971345109">Matikan</translation> <translation id="8106045200081704138">Dikongsi dengan saya</translation> <translation id="8107015733319732394">Memasang Gedung Google Play pada <ph name="DEVICE_TYPE" /> anda. Proses ini mungkin mengambil masa beberapa minit.</translation> -<translation id="8109930990200908494">Log masuk diperlukan untuk sijil pengguna.</translation> <translation id="8111155949205007504">Kongsi kata laluan ini dengan iPhone anda</translation> <translation id="8113043281354018522">Pilih jenis lesen</translation> <translation id="8116190140324504026">Maklumat lanjut...</translation> @@ -4665,6 +4654,7 @@ <translation id="8118860139461251237">Urus muat turun anda</translation> <translation id="81238879832906896">Bunga kuning dan putih</translation> <translation id="8124313775439841391">ONC Terurus</translation> +<translation id="8125562866093998907">Tapak ini mahu mengesahkan Kunci Keselamatan anda untuk meningkatkan keselamatan akaun anda.</translation> <translation id="813082847718468539">Lihat maklumat tapak</translation> <translation id="8131740175452115882">Sahkan</translation> <translation id="8133676275609324831">&Paparkan dalam folder</translation> @@ -4775,7 +4765,6 @@ <translation id="8308179586020895837">Tanya jika <ph name="HOST" /> mahu mengakses kamera anda</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Sijil sudah wujud</translation> -<translation id="8309505303672555187">Pilih rangkaian:</translation> <translation id="8312871300878166382">Tampal ke folder</translation> <translation id="8317671367883557781">Tambahkan sambungan rangkaian</translation> <translation id="8319414634934645341">Penggunaan Penting Dilanjutkan</translation> @@ -4851,7 +4840,6 @@ <translation id="8451512073679317615">assistant</translation> <translation id="8452135315243592079">Kad SIM tiada</translation> <translation id="8453482423012550001">Menyalin $1 item...</translation> -<translation id="8454288007744638700">Selain itu, pilih rangkaian baharu:</translation> <translation id="845627346958584683">Masa Tamat Tempoh</translation> <translation id="8456681095658380701">Nama tidak sah</translation> <translation id="8457451314607652708">Import penanda halaman</translation> @@ -4915,6 +4903,7 @@ <translation id="855081842937141170">Pin tab</translation> <translation id="8551388862522347954">Lesen</translation> <translation id="8553342806078037065">Urus orang lain</translation> +<translation id="8554899698005018844">Tiada bahasa</translation> <translation id="855773602626431402">Pemalam tanpa kotak pasir telah dihalang daripada dijalankan di halaman ini.</translation> <translation id="8557930019681227453">Manifes</translation> <translation id="8559694214572302298">Penyahkod Imej</translation> @@ -4952,7 +4941,6 @@ <translation id="862727964348362408">Digantung</translation> <translation id="862750493060684461">Cache CSS</translation> <translation id="8627795981664801467">Sambungan selamat sahaja</translation> -<translation id="8628085465172583869">Nama hos pelayan:</translation> <translation id="8630903300770275248">Import pengguna diselia</translation> <translation id="8631032106121706562">Kelopak</translation> <translation id="8637542770513281060">Komputer anda mengandungi modul selamat, yang digunakan untuk melaksanakan banyak ciri keselamatan penting dalam OS Chrome. Lawati Pusat Bantuan Chromebook untuk mengetahui lebih lanjut: https://support.google.com/chromebook/?p=sm</translation> @@ -5208,7 +5196,6 @@ <translation id="899403249577094719">URL Tapak Sijil Netscape</translation> <translation id="8995603266996330174">Diuruskan oleh <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Tambahkan akaun…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Membuat imej cakera.</translation> <translation id="9003647077635673607">Benarkan pada semua laman web</translation> <translation id="9003677638446136377">Semak sekali lagi</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb index 926d10d..b5fb07d 100644 --- a/chrome/app/resources/generated_resources_nl.xtb +++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">Pukcode</translation> <translation id="1061904396131502319">Bijna tijd voor pauze</translation> <translation id="1062407476771304334">Vervangen</translation> -<translation id="1064835277883315402">Aanmelden bij privénetwerk</translation> <translation id="1064912851688322329">Je Google-account ontkoppelen</translation> <translation id="1067048845568873861">Gemaakt</translation> <translation id="1067291318998134776">Linux (bèta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Zoeken...</translation> <translation id="1316495628809031177">Synchronisatie is onderbroken</translation> <translation id="1319979322914001937">Een app waarin een gefilterde lijst wordt weergegeven met extensies uit de Chrome Web Store. Extensies in de lijst kunnen rechtstreeks vanuit de app worden geïnstalleerd.</translation> -<translation id="132090119144658135">Overeenkomst van onderwerp:</translation> <translation id="1326317727527857210">Log in bij Chrome om de tabbladen van je andere apparaten te bekijken.</translation> <translation id="1327074568633507428">Printer op Google Cloudprinter</translation> <translation id="1327977588028644528">Gateway</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">App-venster</translation> <translation id="1534389735079119190">FOUT: Kan de container niet starten binnen de VM.</translation> <translation id="15373452373711364">Grote muisaanwijzer</translation> +<translation id="1540605929960647700">Demomodus inschakelen</translation> <translation id="1543284117603151572">Geïmporteerd uit Edge</translation> <translation id="1545177026077493356">Automatische kioskmodus</translation> <translation id="1545775234664667895">Geïnstalleerd thema: '<ph name="THEME_NAME" />'</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Help <ph name="PRODUCT_NAME" /> beter te maken door automatisch gebruiksstatistieken en crashmeldingen naar Google te verzenden</translation> <translation id="1658424621194652532">Deze pagina heeft toegang tot je microfoon.</translation> <translation id="1660204651932907780">Toestaan dat sites geluid afspelen (aanbevolen)</translation> +<translation id="1660938185063657230">Je beveiligingssleutel verifiëren</translation> <translation id="1661156625580498328">AES-encryptie afdwingen (aanbevolen).</translation> <translation id="1661245713600520330">Op deze pagina staan alle modules die in het hoofdproces zijn geladen, en alle modules waarvan is vastgesteld dat deze op een later moment worden geladen.</translation> <translation id="166179487779922818">Wachtwoord is te kort.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Niet toestaan dat sites tekst en afbeeldingen kunnen zien die naar het klembord zijn gekopieerd</translation> <translation id="1682548588986054654">Nieuw incognitovenster</translation> <translation id="168715261339224929">Schakel synchronisatie in om al je bladwijzers op al je apparaten te bekijken.</translation> +<translation id="1688867105868176567">Sitegegevens wissen?</translation> <translation id="1688935057616748272">Typ een letter</translation> <translation id="168991973552362966">Een printer in de buurt toevoegen</translation> <translation id="1689945336726856614">&URL kopiëren</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Deze persoon verwijderen</translation> <translation id="1706586824377653884">Toegevoegd door je beheerder</translation> <translation id="1706625117072057435">Zoomniveaus</translation> -<translation id="1707463636381878959">Dit netwerk delen met andere gebruikers</translation> <translation id="1708338024780164500">(Inactief)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (native)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Thema inschakelen</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Bekijken in de Chrome Web Store</translation> -<translation id="1758831820837444715">Ethernet-netwerk configureren</translation> <translation id="1763046204212875858">Applicatiesnelkoppelingen maken</translation> <translation id="1763108912552529023">Blijf ontdekken</translation> <translation id="1763808908432309942">Wordt op een nieuw tabblad geopend</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Wijzig de manier waarop dit bestand wordt gedeeld</translation> <translation id="1841545962859478868">De apparaatbeheerder kan het volgende controleren:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> is uitgeschakeld</translation> +<translation id="1842766183094193446">Weet je zeker dat je de demomodus wilt inschakelen?</translation> <translation id="1844692022597038441">Dit bestand is offline niet beschikbaar.</translation> <translation id="1846308012215045257">Ctrl-klik om <ph name="PLUGIN_NAME" /> uit te voeren</translation> +<translation id="1847880352285315359">Opgeslagen</translation> <translation id="1848219224579402567">Uitloggen wanneer de klep wordt gesloten</translation> <translation id="184823282865851239">Blokkeren als de site opdringerige advertenties vertoont</translation> <translation id="1849186935225320012">Deze pagina heeft volledig beheer van MIDI-apparaten.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Je kunt dit later altijd wijzigen via de instellingen</translation> <translation id="2006638907958895361">Link openen in <ph name="APP" /></translation> <translation id="2007404777272201486">Een probleem melden...</translation> +<translation id="2016237810978710652">Linux-bestanden openen…</translation> <translation id="2016430552235416146">Traditioneel</translation> <translation id="2017334798163366053">Het verzamelen van prestatiegegevens uitschakelen</translation> <translation id="2017836877785168846">Wist de geschiedenis en automatische aanvullingen in de adresbalk.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Kaart bewerken</translation> <translation id="2154710561487035718">URL kopiëren</translation> <translation id="2155772377859296191">Ziet eruit als <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Je kunt helpen Safe Browsing te verbeteren door bepaalde systeeminformatie en paginacontent naar Google te verzenden.</translation> <translation id="215753907730220065">Volledig scherm sluiten</translation> <translation id="2157875535253991059">Deze pagina wordt nu op volledig scherm weergegeven.</translation> <translation id="216169395504480358">Wifi toevoegen...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Aanvraag-ID toevoegen aan dit apparaat</translation> <translation id="2175042898143291048">Dit altijd doen</translation> <translation id="2175607476662778685">Balk Snelstarten</translation> +<translation id="2176087259161165020">Andere bronnen</translation> <translation id="2177950615300672361">Incognitotabblad: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> op <ph name="PEPPER_PLUGIN_DOMAIN" /> vraagt om toegang tot je computer</translation> <translation id="2178614541317717477">Inbreuk op CA</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Volgend tabblad</translation> <translation id="2292848386125228270">Start <ph name="PRODUCT_NAME" /> als een normale gebruiker. Als je voor ontwikkelingsdoeleinden moet uitvoeren als root, voer je opnieuw uit met de markering '--no-sandbox'.</translation> <translation id="2294358108254308676">Wil je <ph name="PRODUCT_NAME" /> installeren?</translation> -<translation id="2296019197782308739">EAP-methode:</translation> <translation id="2297705863329999812">Printers zoeken</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> aanpassen en beheren</translation> <translation id="2301382460326681002">Hoofddirectory van extensie is ongeldig.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">FOUT: kan <ph name="APP_NAME" /> niet verwijderen.</translation> <translation id="2367199180085172140">File Share toevoegen</translation> <translation id="2367972762794486313">Apps weergeven</translation> +<translation id="2369536625682139252">Alle gegevens die zijn opgeslagen door <ph name="SITE" /> worden verwijderd, behalve cookies.</translation> <translation id="2371076942591664043">Openen wanneer geree&d</translation> <translation id="2377319039870049694">Overschakelen naar lijstweergave</translation> <translation id="2377667304966270281">Harde fouten</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Afdrukken via systeemdialoogvenster... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Vragen vóór verzenden (aanbevolen)</translation> <translation id="2384436799579181135">Er is een fout opgetreden. Controleer je printer en probeer het opnieuw.</translation> -<translation id="2385700042425247848">Naam van service:</translation> <translation id="2387458720915042159">Proxyverbindingstype</translation> <translation id="2391419135980381625">Standaard lettertype</translation> <translation id="2391762656119864333">Intrekken</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Audio delen</translation> <translation id="2480868415629598489">Gegevens aanpassen die je kopieert en plakt</translation> <translation id="2482878487686419369">Meldingen</translation> -<translation id="2485056306054380289">CA-certificaat van server:</translation> <translation id="2485422356828889247">Installatie ongedaan maken</translation> <translation id="2487067538648443797">Nieuwe bladwijzer toevoegen</translation> <translation id="248861575772995840">Kan je telefoon niet vinden. Zorg ervoor dat Bluetooth is ingeschakeld op je <ph name="DEVICE_TYPE" />. <a>Meer informatie</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Voer de Powerwash-functie uit om je <ph name="IDS_SHORT_PRODUCT_NAME" />-apparaat opnieuw in te stellen.</translation> <translation id="2567257616420533738">Wachtwoord opgeslagen. Bekijk en beheer opgeslagen wachtwoorden via <ph name="SAVED_PASSWORDS_LINK" />.</translation> <translation id="2568774940984945469">Container voor infobalk</translation> +<translation id="2570454805927264159">Optimaal gebruikmaken van de Assistent</translation> <translation id="257088987046510401">Thema's</translation> <translation id="2572032849266859634">Alleen-lezen-toegang tot <ph name="VOLUME_NAME" /> is toegekend.</translation> <translation id="2573269395582837871">Kies een foto en een naam</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Verzenden</translation> <translation id="265390580714150011">Veldwaarde</translation> <translation id="2654166010170466751">Toestaan dat sites betalingshandlers installeren</translation> -<translation id="2655386581175833247">Gebruikerscertificaat:</translation> <translation id="2660779039299703961">Gebeurtenis</translation> <translation id="266079277508604648">Verbinding met printer niet mogelijk. Controleer of de printer is ingeschakeld en via wifi of USB is verbonden met je Chromebook.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Geen gebruiksgegevens</translation> <translation id="3007214526293698309">Beeldhouding corrigeren</translation> <translation id="3007771295016901659">Tabblad dupliceren</translation> +<translation id="3008272652534848354">Rechten resetten</translation> <translation id="3009300415590184725">Weet je zeker dat je het instellen van een mobiele dataservice wilt annuleren?</translation> <translation id="3009779501245596802">Geïndexeerde databases</translation> <translation id="3010279545267083280">Wachtwoord verwijderd</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Modules (<ph name="TOTAL_COUNT" />) - bekende conflicten: <ph name="BAD_COUNT" />, verdacht: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Datum en tijd</translation> <translation id="310671807099593501">Site gebruikt Bluetooth</translation> -<translation id="3108967419958202225">Kiezen...</translation> <translation id="3115128645424181617">Kan je telefoon niet vinden. Zorg ervoor dat je deze bij de hand hebt en dat Bluetooth is ingeschakeld.</translation> <translation id="3115147772012638511">Wachten op cache...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Help</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Sommige providers kunnen deze functie blokkeren.</translation> <translation id="316854673539778496">Log in en schakel synchronisatie in om al je extensies op al je apparaten beschikbaar te maken.</translation> <translation id="3170072451822350649">Je kunt het inloggen ook overslaan en <ph name="LINK_START" />browsen als gast<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Klik om het wachtwoord te verbergen</translation> <translation id="3177909033752230686">Brontaal:</translation> <translation id="3181110748548073003">Druk op |<ph name="SHORTCUT" />| om verder te gaan</translation> <translation id="3182749001423093222">Spellingcontrole</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Eigendom wordt overgedragen aan <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Extensie-opties openen</translation> <translation id="3241680850019875542">Selecteer de hoofddirectory van de extensie die je wilt inpakken. Als je een extensie wilt updaten, selecteer je ook het privésleutelbestand om dit opnieuw te gebruiken.</translation> -<translation id="3242765319725186192">Eerder gedeelde sleutel:</translation> <translation id="3244294424315804309">Geluid blijven dempen</translation> <translation id="3245321423178950146">Onbekende artiest</translation> <translation id="3246097286174000800">Smart Lock proberen</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Meer acties voor <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Goedkeuring vragen wanneer een site een plug-in wil gebruiken om toegang tot je computer te krijgen</translation> <translation id="3441653493275994384">Beeldscherm</translation> -<translation id="3445830502289589282">Phase 2-verificatie:</translation> <translation id="344630545793878684">Je gegevens voor een aantal websites lezen</translation> <translation id="3449839693241009168">Druk op <ph name="SEARCH_KEY" /> om opdrachten te verzenden naar <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Bezettingspercentage van inactieve status</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> fouten.</translation> <translation id="3495660573538963482">Instellingen van de Google Assistent</translation> <translation id="3496213124478423963">Kleiner</translation> -<translation id="3504135463003295723">Groepsnaam:</translation> <translation id="3505030558724226696">Apparaattoegang intrekken</translation> <translation id="3507421388498836150">Huidige rechten voor '<ph name="EXTENSION_NAME" />'</translation> <translation id="3507547268929739059">Linux-apps voor Chromebook verwijderen</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Inlogcertificering is niet geldig. Het venster wordt gesloten over <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Extensiepictogram</translation> <translation id="3665589677786828986">Chrome heeft gedetecteerd dat sommige van je instellingen zijn beschadigd door een ander programma en heeft de instellingen teruggezet naar de oorspronkelijke standaardwaarden.</translation> -<translation id="3665842570601375360">Beveiliging:</translation> <translation id="3668570675727296296">Taalinstellingen</translation> <translation id="3668823961463113931">Handlers</translation> <translation id="3670229581627177274">Bluetooth inschakelen</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Dit apparaat kan niet worden geopend omdat het bijbehorende bestandssysteem niet wordt ondersteund.</translation> <translation id="3727148787322499904">Het wijzigen van deze instelling is van invloed op alle gedeelde netwerken</translation> <translation id="3727187387656390258">Pop-up controleren</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Fout op regel <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-server met step-up</translation> <translation id="3737536731758327622">Je downloads worden hier weergegeven</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Druk op Enter als je klaar bent</translation> <translation id="3827774300009121996">&Volledig scherm</translation> <translation id="3828029223314399057">Zoeken in bladwijzers</translation> -<translation id="3829932584934971895">Type provider:</translation> <translation id="3830674330436234648">Afspelen is niet beschikbaar</translation> <translation id="3831486154586836914">Modus Vensteroverzicht ingeschakeld</translation> <translation id="383161972796689579">De eigenaar van dit apparaat heeft het toevoegen van nieuwe gebruikers uitgeschakeld</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Bijhouden van dataverbruik is beëindigd</translation> <translation id="3857228364945137633">Probeer Smart Lock om je <ph name="DEVICE_TYPE" /> te ontgrendelen zonder wachtwoord wanneer je telefoon zich in de buurt bevindt.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: synchronisatie gepauzeerd</translation> <translation id="3860381078714302691">Welkom bij Hangouts Meet</translation> <translation id="3862134173397075045">Welkom bij de Cast-functie in Chrome!</translation> <translation id="3862788408946266506">Een app met het manifestkenmerk 'kiosk_only' moet worden geïnstalleerd in de Chrome OS-kioskmodus</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Kan netwerk niet instellen</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Berekenen...</translation> -<translation id="3974195870082915331">Klik om het wachtwoord weer te geven</translation> <translation id="3975222297214566386">Ballon voor invoeropties</translation> <translation id="397703832102027365">Wordt voltooid...</translation> <translation id="3979395879372752341">Nieuwe extensie toegevoegd (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Geef je certificaatwachtwoord op</translation> <translation id="404493185430269859">Standaardzoekmachine</translation> <translation id="4047112090469382184">Waarom dit beveiligd is</translation> +<translation id="4051049974203704184">Informatie opvragen over wat er op het scherm wordt weergegeven</translation> <translation id="4052120076834320548">Heel klein</translation> <translation id="4055023634561256217">Opnieuw starten is vereist voordat je apparaat opnieuw kan worden ingesteld met Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Accepteren voor groep</translation> <translation id="4089235344645910861">Instellingen opgeslagen. Synchronisatie gestart.</translation> <translation id="4090103403438682346">Verified Access inschakelen</translation> +<translation id="4090947011087001172">Siterechten voor <ph name="SITE" /> resetten?</translation> <translation id="4091434297613116013">vellen papier</translation> <translation id="4093955363990068916">Lokaal bestand:</translation> <translation id="4095507791297118304">Primair scherm</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Synchronisatie, personalisatie en meer beheren</translation> <translation id="4421932782753506458">Pluisje</translation> <translation id="4422347585044846479">Bladwijzer voor deze pagina bewerken</translation> -<translation id="4423104065312875417">Aanvullende spraakengines installeren</translation> <translation id="4423376891418188461">Instellingen herstellen</translation> <translation id="4423482519432579560">&Spellingcontrole</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, de beheerder vereist dat je je wachtwoord wijzigt.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Op dit tabblad wordt audio afgespeeld.</translation> <translation id="4450974146388585462">Diagnose</translation> <translation id="4453946976636652378">Zoek met <ph name="SEARCH_ENGINE_NAME" /> of voer een URL in</translation> -<translation id="445923051607553918">Aanmelden bij wifi-netwerk</translation> <translation id="4462159676511157176">Aangepaste naamservers</translation> <translation id="4467100756425880649">Chrome Web Store-galerij</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> uitvouwen</translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Achtergronden worden weergegeven op het inlogscherm.</translation> <translation id="4684427112815847243">Alles synchroniseren</translation> <translation id="4689421377817139245">Deze bladwijzer synchroniseren met je iPhone</translation> +<translation id="4690091457710545971"><Vier bestanden gegenereerd door wifi-firmware van Intel: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. De eerste drie zijn binaire bestanden met registerdumps. Hiervan wordt door Intel verzekerd dat deze geen persoonlijke of apparaatidentificerende gegevens bevatten. Het laatste bestand is een bestand waarin uitvoering wordt bijgehouden. Alle persoonlijke of apparaatidentificerende gegevens zijn uit dit bestand verwijderd, maar het is te groot om hier weer te geven. Deze bestanden zijn gegenereerd als reactie op recente wifi-problemen met je apparaat en worden gedeeld met Intel om deze problemen op te lossen.></translation> <translation id="4692302215262324251">Je <ph name="DEVICE_TYPE" /> is aangemeld voor bedrijfsbeheer door <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Als dit onverwacht is, neem je contact op met de ondersteuning.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Deze pagina moet eventueel opnieuw worden geladen voordat de nieuwe instellingen van kracht zijn.</translation> <translation id="5075131525758602494">Pincode van de simkaart opgeven</translation> <translation id="5078638979202084724">Bladwijzer toevoegen aan alle tabbladen</translation> +<translation id="5079950360618752063">Voorgesteld wachtwoord gebruiken</translation> <translation id="5084230410268011727">Toestaan dat websites toegang krijgen tot bewegings- en lichtsensoren</translation> <translation id="5085162214018721575">Controleren op updates</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Dit item verwijderen</translation> <translation id="5139955368427980650">&Openen</translation> +<translation id="5142961317498132443">Verificatie</translation> <translation id="5143374789336132547">De extensie '<ph name="EXTENSION_NAME" />' heeft gewijzigd welke pagina wordt weergegeven wanneer je op de knop 'Homepage' klikt.</translation> <translation id="5143712164865402236">Volledig scherm openen</translation> <translation id="5145331109270917438">Bijgewerkt op</translation> @@ -2844,7 +2842,6 @@ <translation id="5380103295189760361">Houd Ctrl, Alt, Shift of Zoeken ingedrukt om sneltoetsen voor die functietoetsen te bekijken.</translation> <translation id="5382591305415226340">Ondersteunde links beheren</translation> <translation id="5384883051496921101">Deze site staat op het punt buiten de incognitomodus informatie met een app te delen.</translation> -<translation id="5388588172257446328">Gebruikersnaam:</translation> <translation id="5388885445722491159">Gekoppeld</translation> <translation id="5389237414310520250">De nieuwe gebruiker kan niet worden gemaakt. Controleer de ruimte op je harde schijf en je rechten, en probeer het opnieuw.</translation> <translation id="5390100381392048184">Toestaan dat sites geluid afspelen</translation> @@ -2969,7 +2966,6 @@ <translation id="5551573675707792127">Toetsenbord en tekstinvoer</translation> <translation id="5553089923092577885">Beleidstoewijzing voor certificaat</translation> <translation id="5554489410841842733">Dit pictogram wordt weergegeven wanneer de extensie een actie kan uitvoeren op de huidige pagina.</translation> -<translation id="5554573843028719904">Ander wifi-netwerk...</translation> <translation id="5554720593229208774">Certificeringsinstantie voor e-mail</translation> <translation id="5556206011531515970">Klik op 'Volgende' om je standaardbrowser te kiezen.</translation> <translation id="5556459405103347317">Opnieuw laden</translation> @@ -3010,7 +3006,6 @@ <translation id="5610038042047936818">Overschakelen naar cameramodus</translation> <translation id="5612720917913232150"><ph name="URL" /> wil de locatie van je computer gebruiken</translation> <translation id="5612734644261457353">Je wachtwoord kan nog steeds niet worden geverifieerd. Opmerking: als je je wachtwoord onlangs hebt gewijzigd, wordt je nieuwe wachtwoord doorgevoerd zodra je uitlogt. Gebruik hier het oude wachtwoord.</translation> -<translation id="5613695965848159202">Anonieme identiteit:</translation> <translation id="5614190747811328134">Gebruikerskennisgeving</translation> <translation id="561698261642843490">Firefox sluiten</translation> <translation id="5618075537869101857">De kiosk-app kan niet worden gestart.</translation> @@ -3228,7 +3223,6 @@ <translation id="5941343993301164315">Log in bij <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimaliseren</translation> <translation id="5946591249682680882">Rapport-ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Privénetwerk toevoegen</translation> <translation id="5949544233750246342">Kan bestand niet parseren</translation> <translation id="5955282598396714173">Je wachtwoord is verlopen. Log uit en weer in om het te wijzigen.</translation> <translation id="5956585768868398362">Is dit de zoekpagina die je had verwacht?</translation> @@ -3389,11 +3383,13 @@ <translation id="6198102561359457428">Log uit en log daarna weer in...</translation> <translation id="6198252989419008588">Pincode wijzigen</translation> <translation id="6199801702437275229">Wachten op ruimte-informatie...</translation> +<translation id="6204015976622790023">Bekijk relevante suggesties van de Assistent over wat je op je scherm ziet.</translation> <translation id="6205710420833115353">Sommige bewerkingen duren langer dan verwacht. Wil je deze afbreken?</translation> <translation id="6206311232642889873">A&fbeelding kopiëren</translation> <translation id="6207200176136643843">Standaardzoomniveau resetten</translation> <translation id="620722923698527029">Deze typen links altijd openen in de bijbehorende app</translation> <translation id="6207937957461833379">Land/regio</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: synchronisatie werkt niet</translation> <translation id="6212039847102026977">Geavanceerde netwerkeigenschappen weergeven</translation> <translation id="6212168817037875041">Scherm uitschakelen</translation> <translation id="6212752530110374741">Link e-mailen</translation> @@ -3431,7 +3427,6 @@ <translation id="6263541650532042179">synchronisatie opnieuw instellen</translation> <translation id="6264365405983206840">&Alles selecteren</translation> <translation id="6264422956566238156">Je hebt synchronisatie ingeschakeld</translation> -<translation id="6265930187414222160">Klaar! Schadelijke software is verwijderd.</translation> <translation id="6267166720438879315">Selecteer een certificaat om je identiteit te verifiëren voor <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Openen met <ph name="APP" /></translation> <translation id="6268747994388690914">Bladwijzers importeren uit HTML-bestand...</translation> @@ -3538,7 +3533,6 @@ Klik op Volgende om door te gaan met inloggen op je <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />-account.</translation> <translation id="6419546358665792306">Uitgepakte extensie laden</translation> <translation id="642282551015776456">Deze naam mag niet worden gebruikt als de naam van een bestand of map.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox-instellingen openen</translation> <translation id="6429384232893414837">Updatefout</translation> <translation id="6430814529589430811">Base64 Encoded ASCII, één certificaat</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">De webbrowser van Google, voor jou</translation> <translation id="6545665334409411530">Herhalingssnelheid</translation> <translation id="6545834809683560467">Een voorspellingsservice gebruiken om zoekopdrachten en URL's aan te vullen die in de adresbalk of het zoekvak van de App Launcher worden getypt</translation> -<translation id="6546686722964485737">Verbinden met WiMAX-netwerk</translation> <translation id="6547316139431024316">Geen waarschuwing meer weergeven voor deze extensie</translation> <translation id="6547354035488017500">Je moet minimaal 512 MB aan ruimte vrijmaken om ervoor te zorgen dat het apparaat blijft reageren. Verwijder bestanden uit de opslag van het apparaat om ruimte vrij te maken.</translation> <translation id="6549689063733911810">Recent</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Kan Linux-bestanden niet weergeven</translation> <translation id="720110658997053098">Dit apparaat permanent in kioskmodus houden</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' verwijderd</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> downloaden...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Pagina afsluiten}other{Pagina's afsluiten}}</translation> <translation id="7216409898977639127">Mobiele provider</translation> @@ -4515,7 +4507,6 @@ <translation id="7909969815743704077">Gedownload in incognitomodus</translation> <translation id="7910768399700579500">&Nieuwe map</translation> <translation id="7912080627461681647">Je wachtwoord is gewijzigd op de server. Log uit en weer in.</translation> -<translation id="7912883689016444961">Mobiel netwerk configureren</translation> <translation id="7915471803647590281">Vertel ons wat er aan de hand is voordat je de feedback verzendt.</translation> <translation id="7916556741383518510">Bij klik</translation> <translation id="792514962475806987">Gedockt zoomniveau:</translation> @@ -4569,7 +4560,6 @@ <translation id="7988355189918024273">Functies voor toegankelijkheid inschakelen</translation> <translation id="7994702968232966508">EAP-methode</translation> <translation id="799547531016638432">Snelle link verwijderen</translation> -<translation id="7997479212858899587">Identiteit:</translation> <translation id="7997826902155442747">Procesprioriteit</translation> <translation id="7999229196265990314">De volgende bestanden zijn gemaakt: @@ -4653,7 +4643,6 @@ <translation id="8105368624971345109">Uitschakelen</translation> <translation id="8106045200081704138">Gedeeld met mij</translation> <translation id="8107015733319732394">De Google Play Store wordt geïnstalleerd op je <ph name="DEVICE_TYPE" />. Dit kan enkele minuten duren.</translation> -<translation id="8109930990200908494">Inloggen vereist voor gebruikerscertificaat.</translation> <translation id="8111155949205007504">Dit wachtwoord delen met je iPhone</translation> <translation id="8113043281354018522">Licentietype kiezen</translation> <translation id="8116190140324504026">Meer informatie...</translation> @@ -4664,6 +4653,7 @@ <translation id="8118860139461251237">Je downloads beheren</translation> <translation id="81238879832906896">Geel-witte bloem</translation> <translation id="8124313775439841391">Beheerde ONC</translation> +<translation id="8125562866093998907">De site wil je beveiligingssleutel verifiëren voor extra beveiliging van je account.</translation> <translation id="813082847718468539">Sitegegevens bekijken</translation> <translation id="8131740175452115882">Bevestigen</translation> <translation id="8133676275609324831">&Weergeven in map</translation> @@ -4774,7 +4764,6 @@ <translation id="8308179586020895837">Vragen of <ph name="HOST" /> toegang wil tot je camera</translation> <translation id="830868413617744215">Bèta</translation> <translation id="8309458809024885768">Certificaat bestaat al</translation> -<translation id="8309505303672555187">Selecteer een netwerk:</translation> <translation id="8312871300878166382">Plakken in map</translation> <translation id="8317671367883557781">Netwerkverbinding toevoegen</translation> <translation id="8319414634934645341">Uitgebreid sleutelgebruik</translation> @@ -4849,7 +4838,6 @@ <translation id="8451512073679317615">assistent</translation> <translation id="8452135315243592079">Simkaart ontbreekt</translation> <translation id="8453482423012550001">$1 items kopiëren...</translation> -<translation id="8454288007744638700">Of selecteer een nieuw netwerk:</translation> <translation id="845627346958584683">Vervaltijd</translation> <translation id="8456681095658380701">Ongeldige naam</translation> <translation id="8457451314607652708">Bladwijzers importeren</translation> @@ -4913,6 +4901,7 @@ <translation id="855081842937141170">Tabblad vastzetten</translation> <translation id="8551388862522347954">Licenties</translation> <translation id="8553342806078037065">Andere mensen beheren</translation> +<translation id="8554899698005018844">Geen taal</translation> <translation id="855773602626431402">Er is voorkomen dat een plug-in zonder sandbox op deze pagina werd uitgevoerd.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Image Decoder</translation> @@ -4950,7 +4939,6 @@ <translation id="862727964348362408">Opgeschort</translation> <translation id="862750493060684461">CSS-cachegeheugen</translation> <translation id="8627795981664801467">Alleen beveiligde verbindingen</translation> -<translation id="8628085465172583869">Hostnaam van server:</translation> <translation id="8630903300770275248">Gebruiker met beperkte rechten importeren</translation> <translation id="8631032106121706562">Madeliefje</translation> <translation id="8637542770513281060">Je computer bevat een beveiligde module die wordt gebruikt om veel van de belangrijke beveiligingsfuncties in Chrome OS te implementeren. Ga voor meer informatie naar het Helpcentrum voor Chromebooks: https://support.google.com/chromebook/?p=sm</translation> @@ -5207,7 +5195,6 @@ <translation id="899403249577094719">Basis-URL voor Netscape-certificaat</translation> <translation id="8995603266996330174">Beheerd door <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Account toevoegen…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Er wordt een image van de schijf gemaakt.</translation> <translation id="9003647077635673607">Toestaan op alle websites</translation> <translation id="9003677638446136377">Nogmaals controleren</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb index 684de17..034ceb9 100644 --- a/chrome/app/resources/generated_resources_no.xtb +++ b/chrome/app/resources/generated_resources_no.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Snart tid for en pause</translation> <translation id="1062407476771304334">Erstatt</translation> -<translation id="1064835277883315402">Tilkobling til privat nettverk</translation> <translation id="1064912851688322329">Frakobling av Google-kontoen din</translation> <translation id="1067048845568873861">Opprettet</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Søker …</translation> <translation id="1316495628809031177">Synkroniseringen er satt på pause</translation> <translation id="1319979322914001937">En app som viser en filtrert liste over utvidelser fra Chrome Nettmarked. Utvidelser i listen kan installeres direkte fra appen.</translation> -<translation id="132090119144658135">Emnetreff:</translation> <translation id="1326317727527857210">For å få fanene dine fra de andre enhetene du bruker, logg på Chrome.</translation> <translation id="1327074568633507428">Skriver på Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -484,7 +482,6 @@ <translation id="1701062906490865540">Fjern denne personen</translation> <translation id="1706586824377653884">Lagt til av administratoren din</translation> <translation id="1706625117072057435">Zoomnivåer</translation> -<translation id="1707463636381878959">Del dette nettverket med andre brukere</translation> <translation id="1708338024780164500">(Inaktiv)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (innebygd)</translation> @@ -520,7 +517,6 @@ <translation id="175772926354468439">Aktiver temaet</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Se i Chrome Nettmarked</translation> -<translation id="1758831820837444715">Konfigurer Ethernet-nettverket</translation> <translation id="1763046204212875858">Opprett snarveier</translation> <translation id="1763108912552529023">Fortsett å utforske</translation> <translation id="1763808908432309942">Åpner en ny fane</translation> @@ -864,7 +860,6 @@ <translation id="2291643155573394834">Neste fane</translation> <translation id="2292848386125228270">Start <ph name="PRODUCT_NAME" /> som en vanlig bruker. Hvis du har behov for å kjøre som rot i forbindelse med utvikling, må du kjøre appen på nytt med flagget --no-sandbox.</translation> <translation id="2294358108254308676">Ønsker du å installere <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP-metode:</translation> <translation id="2297705863329999812">Søk i skrivere</translation> <translation id="2300383962156589922">Tilpass og kontrollér <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Utvidelsens rotkatalog er ugyldig.</translation> @@ -921,7 +916,6 @@ <translation id="2379281330731083556">Skriv ut med systemdialogen <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Spør før noe sendes (anbefales).</translation> <translation id="2384436799579181135">Det har oppstått en feil. Sjekk skriveren og prøv på nytt.</translation> -<translation id="2385700042425247848">Tjenestenavn:</translation> <translation id="2387458720915042159">Tilkoblingstype for proxy-tjener</translation> <translation id="2391419135980381625">Standardskrift</translation> <translation id="2391762656119864333">Opphev</translation> @@ -972,7 +966,6 @@ <translation id="247949520305900375">Del lyd</translation> <translation id="2480868415629598489">endre data du kopierer og limer inn</translation> <translation id="2482878487686419369">Varsler</translation> -<translation id="2485056306054380289">Tjenerens CA-sertifikat:</translation> <translation id="2485422356828889247">Avinstaller</translation> <translation id="2487067538648443797">Legg til nytt bokmerke</translation> <translation id="248861575772995840">Finner ikke telefonen. Sørg for at Bluetooth er aktivert på <ph name="DEVICE_TYPE" />-enheten. <a>Finn ut mer</a></translation> @@ -1095,7 +1088,6 @@ <translation id="2653659639078652383">Send</translation> <translation id="265390580714150011">Feltverdi</translation> <translation id="2654166010170466751">Tillat at nettsteder installerer betalingsbehandlere</translation> -<translation id="2655386581175833247">Brukersertifikat:</translation> <translation id="2660779039299703961">Aktivitet</translation> <translation id="266079277508604648">Kan ikke koble til skriveren. Kontrollér at skriveren er slått på og koblet til Chromebooken din via Wi-Fi eller USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1394,7 +1386,6 @@ <translation id="3100609564180505575">Moduler (<ph name="TOTAL_COUNT" />) – Kjente konflikter: <ph name="BAD_COUNT" />, mistenkte: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Dato og klokkeslett</translation> <translation id="310671807099593501">Nettstedet bruker Bluetooth</translation> -<translation id="3108967419958202225">Velg</translation> <translation id="3115128645424181617">Finner ikke telefonen. Sørg for at den er i nærheten, og at Bluetooth er slått på.</translation> <translation id="3115147772012638511">Venter på buffer...</translation> <translation id="3118319026408854581">Hjelp for <ph name="PRODUCT_NAME" /></translation> @@ -1439,7 +1430,6 @@ <translation id="3165390001037658081">Det kan hende at enkelte operatører blokkerer denne funksjonen.</translation> <translation id="316854673539778496">For å få alle utvidelsene dine på alle enhetene du bruker, logg på og slå på synkronisering.</translation> <translation id="3170072451822350649">Du kan også hoppe over påloggingen og <ph name="LINK_START" />surfe som gjest<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Klikk for å skjule passord</translation> <translation id="3177909033752230686">Språket siden er på:</translation> <translation id="3181110748548073003">Trykk på |<ph name="SHORTCUT" />| for å gå fremover</translation> <translation id="3182749001423093222">Stavekontroll</translation> @@ -1470,7 +1460,6 @@ <translation id="3236289833370040187">Eierskapet overføres til <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Åpne utvidelsesalternativer</translation> <translation id="3241680850019875542">Velg rotkatalogen til utvidelsen som skal pakkes. Hvis du vil oppdatere en utvidelse, velger du også den private nøkkelfilen.</translation> -<translation id="3242765319725186192">Forhåndsdelt nøkkel:</translation> <translation id="3244294424315804309">Fortsett med å kutte lyden</translation> <translation id="3245321423178950146">Ukjent artist</translation> <translation id="3246097286174000800">Prøv Smart Lock</translation> @@ -1602,7 +1591,6 @@ <translation id="3440663250074896476">Flere handlinger for <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Spør når et nettsted ønsker å bruke et programtillegg for å få tilgang til datamaskinen</translation> <translation id="3441653493275994384">Skjerm</translation> -<translation id="3445830502289589282">Fase 2-autentisering:</translation> <translation id="344630545793878684">Lesing av dataene dine på en rekke nettsteder</translation> <translation id="3449839693241009168">Trykk på <ph name="SEARCH_KEY" /> for å sende kommandoer til <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Utnyttelsesgrad for hviletilstand</translation> @@ -1643,7 +1631,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> feil.</translation> <translation id="3495660573538963482">Innstillinger for Google-assistenten</translation> <translation id="3496213124478423963">Zoom ut</translation> -<translation id="3504135463003295723">Gruppenavn:</translation> <translation id="3505030558724226696">Opphev enhetstilgangen</translation> <translation id="3507421388498836150">Nåværende tillatelser for «<ph name="EXTENSION_NAME" />»</translation> <translation id="3507547268929739059">Fjern Linux-apper for Chromebook</translation> @@ -1752,7 +1739,6 @@ <translation id="3661054927247347545">Påloggingssertifikatet er ugyldig. Vinduet lukkes om <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Utvidelsesikon</translation> <translation id="3665589677786828986">Chrome har oppdaget at noen av innstillingene ble ødelagt av et annet program og tilbakestille dem til originalinnstillingene.</translation> -<translation id="3665842570601375360">Sikkerhet:</translation> <translation id="3668570675727296296">Språkinnstillinger</translation> <translation id="3668823961463113931">Behandlere</translation> <translation id="3670229581627177274">Slå på Bluetooth</translation> @@ -1791,7 +1777,6 @@ <translation id="3726463242007121105">Denne enheten kan ikke åpnes fordi den har et filsystem som ikke støttes.</translation> <translation id="3727148787322499904">Endringer i denne innstillingen påvirker alle delte nettverk</translation> <translation id="3727187387656390258">Undersøk hurtigvindu</translation> -<translation id="3728067901555601989">Engangspassord:</translation> <translation id="3732078975418297900">Feil på linje <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-tjener med oppgradering </translation> <translation id="3737536731758327622">Nedlastingene dine vises her</translation> @@ -1866,7 +1851,6 @@ <translation id="38275787300541712">Trykk på Enter når du er ferdig</translation> <translation id="3827774300009121996">&Full skjerm</translation> <translation id="3828029223314399057">Søk i bokmerker</translation> -<translation id="3829932584934971895">Operatørtype:</translation> <translation id="3830674330436234648">Ingen avspillinger er tilgjengelige</translation> <translation id="3831486154586836914">Du er i modusen for vindusoversikt</translation> <translation id="383161972796689579">Eieren av denne enheten har deaktivert tillegging av nye brukere</translation> @@ -1962,7 +1946,6 @@ <translation id="3968261067169026421">Kunne ikke konfigurere nettverket</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Beregner …</translation> -<translation id="3974195870082915331">Klikk for å vise passord</translation> <translation id="3975222297214566386">Boble for valg av inndata</translation> <translation id="397703832102027365">Fullfører …</translation> <translation id="3979395879372752341">Ny utvidelse lagt til (<ph name="EXTENSION_NAME" />)</translation> @@ -2208,7 +2191,6 @@ <translation id="4419556793104466535">Kontrollér synkronisering, personlig tilpasning med mer</translation> <translation id="4421932782753506458">Pus</translation> <translation id="4422347585044846479">Rediger bokmerket for denne siden</translation> -<translation id="4423104065312875417">Installer flere talemotorer</translation> <translation id="4423376891418188461">Gjenopprett innstillingene</translation> <translation id="4423482519432579560">&Stavekontroll</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, administratoren din krever at du endrer passord.</translation> @@ -2233,7 +2215,6 @@ <translation id="4449996769074858870">Denne fanen spiller av lyd.</translation> <translation id="4450974146388585462">Diagnostiser</translation> <translation id="4453946976636652378">Søk i <ph name="SEARCH_ENGINE_NAME" /> eller skriv inn en nettadresse</translation> -<translation id="445923051607553918">Koble til Wi-Fi-nettverk</translation> <translation id="4462159676511157176">Egendefinerte navnetjenere</translation> <translation id="4467100756425880649">Chrome Nettmarked Galleri</translation> <translation id="4467101674048705704">Vis <ph name="FOLDER_NAME" /></translation> @@ -2835,7 +2816,6 @@ <translation id="5380103295189760361">Hold nede Control, Alt og Shift, eller søk for å se hurtigtaster for disse modifikatorene.</translation> <translation id="5382591305415226340">Administrer støttede linker</translation> <translation id="5384883051496921101">Dette nettstedet er i ferd med å dele informasjon med en app utenfor inkognitomodus.</translation> -<translation id="5388588172257446328">Brukernavn:</translation> <translation id="5388885445722491159">Sammenkoblet</translation> <translation id="5389237414310520250">Den nye brukeren kunne ikke opprettes. Sjekk hvor mye plass du har på harddisken og hvilke tillatelser som er aktive, og prøv på nytt.</translation> <translation id="5390100381392048184">Tillat nettsteder å spille av lyd</translation> @@ -2960,7 +2940,6 @@ <translation id="5551573675707792127">Tastatur og innskriving av tekst</translation> <translation id="5553089923092577885">Retningslinjetilordninger for sertifikat</translation> <translation id="5554489410841842733">Dette ikonet vises når utvidelsen kan brukes på gjeldende side.</translation> -<translation id="5554573843028719904">Annet Wi-Fi-nettverk</translation> <translation id="5554720593229208774">Sertifiseringsinstans for e-post</translation> <translation id="5556206011531515970">Klikk på Neste for å velge standardnettleser.</translation> <translation id="5556459405103347317">Last inn på nytt</translation> @@ -3001,7 +2980,6 @@ <translation id="5610038042047936818">Bytt til kameramodus</translation> <translation id="5612720917913232150"><ph name="URL" /> ber om å bruke posisjonen til enheten din</translation> <translation id="5612734644261457353">Passordet ditt kunne fortsatt ikke bekreftes. Merk: Hvis du endret passordet ditt nylig, blir det nye passordet ditt tatt i bruk når du logger deg av. Du må bruke det gamle passordet her.</translation> -<translation id="5613695965848159202">Anonym identitet:</translation> <translation id="5614190747811328134">Brukerinformasjon</translation> <translation id="561698261642843490">Lukk Firefox</translation> <translation id="5618075537869101857">Kiosk-appen kunne ikke kjøres.</translation> @@ -3219,7 +3197,6 @@ <translation id="5941343993301164315">Logg på <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimer</translation> <translation id="5946591249682680882">Rapport-ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Legg til privat nettverk</translation> <translation id="5949544233750246342">Kan ikke parse filen</translation> <translation id="5955282598396714173">Passordet ditt er utløpt. Logg av og på igjen for å endre det.</translation> <translation id="5956585768868398362">Er dette søkesiden du forventet?</translation> @@ -3422,7 +3399,6 @@ <translation id="6263541650532042179">tilbakestill synkronisering</translation> <translation id="6264365405983206840">Velg &alle</translation> <translation id="6264422956566238156">Du har slått på synkronisering</translation> -<translation id="6265930187414222160">Ferdig! Skadelig programvare er fjernet.</translation> <translation id="6267166720438879315">Velg sertifikat for å autentisere deg selv til <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Åpne med <ph name="APP" /></translation> <translation id="6268747994388690914">Importér bokmerker fra HTML-fil</translation> @@ -3529,7 +3505,6 @@ Klikk på «Neste» for å fortsette å logge på <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />-kontoen din.</translation> <translation id="6419546358665792306">Last inn upakket</translation> <translation id="642282551015776456">Dette navnet kan ikke brukes som fil- eller mappenavn</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Åpne innstillingene for ChromeVox</translation> <translation id="6429384232893414837">Oppdateringsfeil</translation> <translation id="6430814529589430811">Base64-kodede ASCII, enkelt sertifikat</translation> @@ -3609,7 +3584,6 @@ <translation id="6544215763872433504">Nettleseren fra Google – til deg</translation> <translation id="6545665334409411530">Gjentakelsesfrekvens</translation> <translation id="6545834809683560467">Bruk en forslagstjeneste for å fullføre søk og nettadresser som skrives inn i adressefeltet eller søkefeltet i appvelgeren</translation> -<translation id="6546686722964485737">Bli med i et WiMAX-nettverk</translation> <translation id="6547316139431024316">Ikke advar om denne utvidelsen igjen</translation> <translation id="6547354035488017500">Frigjør minst 512 MB lagringsplass for å unngå at enheten slutter å reagere. For å frigjøre plass, slett filer fra enhetslagringen.</translation> <translation id="6549689063733911810">Siste</translation> @@ -4028,7 +4002,6 @@ <translation id="7201014958346994077">Kan ikke vise Linux-filer</translation> <translation id="720110658997053098">Behold denne enheten permanent i kioskmodus</translation> <translation id="7201118060536064622">«<ph name="DELETED_ITEM_NAME" />» er slettet</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Laster ned <ph name="PLUGIN_NAME" /> …</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Lukk siden}other{Lukk sidene}}</translation> <translation id="7216409898977639127">Mobiloperatør</translation> @@ -4504,7 +4477,6 @@ <translation id="7909969815743704077">Lastet ned i inkognitomodus</translation> <translation id="7910768399700579500">&Ny mappe</translation> <translation id="7912080627461681647">Passordet ditt er endret på tjeneren. Logg av og på igjen.</translation> -<translation id="7912883689016444961">Konfigurer mobilnettverk</translation> <translation id="7915471803647590281">Fortell oss hva som skjer før du sender tilbakemeldingen.</translation> <translation id="7916556741383518510">Ved klikk</translation> <translation id="792514962475806987">Dokket zoomnivå:</translation> @@ -4558,7 +4530,6 @@ <translation id="7988355189918024273">Aktiver funksjoner for tilgjengelighet</translation> <translation id="7994702968232966508">EAP-metode</translation> <translation id="799547531016638432">Fjern snarveien</translation> -<translation id="7997479212858899587">Identitet:</translation> <translation id="7997826902155442747">Prosessprioritet</translation> <translation id="7999229196265990314">Opprettet følgende filer: @@ -4642,7 +4613,6 @@ <translation id="8105368624971345109">Slå av</translation> <translation id="8106045200081704138">Delt med meg</translation> <translation id="8107015733319732394">Installerer Google Play-butikken på <ph name="DEVICE_TYPE" />-enheten din. Dette kan ta noen minutter.</translation> -<translation id="8109930990200908494">Pålogging er påkrevd for brukersertifikatet.</translation> <translation id="8111155949205007504">Del dette passordet med iPhonen din</translation> <translation id="8113043281354018522">Velg lisenstype</translation> <translation id="8116190140324504026">Les mer</translation> @@ -4763,7 +4733,6 @@ <translation id="8308179586020895837">Spør om <ph name="HOST" /> vil bruke kameraet ditt</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Sertifikatet finnes allerede</translation> -<translation id="8309505303672555187">Velg nettverk:</translation> <translation id="8312871300878166382">Lim inn i mappen</translation> <translation id="8317671367883557781">Legg til nettverkstilkobling</translation> <translation id="8319414634934645341">Utvidet bruk av nøkkel</translation> @@ -4838,7 +4807,6 @@ <translation id="8451512073679317615">assistent</translation> <translation id="8452135315243592079">SIM-kort mangler</translation> <translation id="8453482423012550001">Kopierer $1 elementer ...</translation> -<translation id="8454288007744638700">Eller velg et nytt nettverk:</translation> <translation id="845627346958584683">Utløpstid</translation> <translation id="8456681095658380701">Ugyldig navn</translation> <translation id="8457451314607652708">Importér bokmerker</translation> @@ -4939,7 +4907,6 @@ <translation id="862727964348362408">Stanset</translation> <translation id="862750493060684461">CSS-buffer</translation> <translation id="8627795981664801467">Bare sikre tilkoblinger</translation> -<translation id="8628085465172583869">Vertsnavn for tjener:</translation> <translation id="8630903300770275248">Importér den administrerte brukeren</translation> <translation id="8631032106121706562">Tusenfryd</translation> <translation id="8637542770513281060">Datamaskinen din inneholder en sikker modul som brukes til å implementere mange viktige sikkerhetsfunksjoner i Chrome OS. Gå til Chromebook-brukerstøtten for å finne ut mer: https://support.google.com/chromebook/?p=sm</translation> @@ -5195,7 +5162,6 @@ <translation id="899403249577094719">Primære nettadresse for Netscape-sertifikat</translation> <translation id="8995603266996330174">Drevet av <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Legg til konto</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Oppretter diskavbildning.</translation> <translation id="9003647077635673607">Tillat på alle nettsteder</translation> <translation id="9003677638446136377">Sjekk på nytt</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb index 00afc5d..caefcb8 100644 --- a/chrome/app/resources/generated_resources_pl.xtb +++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Wielkimi krokami nadchodzi przerwa</translation> <translation id="1062407476771304334">Zastąp</translation> -<translation id="1064835277883315402">Połącz z siecią prywatną</translation> <translation id="1064912851688322329">Odłącz swoje konto Google</translation> <translation id="1067048845568873861">Utworzono</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Trwa wyszukiwanie...</translation> <translation id="1316495628809031177">Synchronizacja została wstrzymana</translation> <translation id="1319979322914001937">Aplikacja, która pokazuje przefiltrowaną listę rozszerzeń z Chrome Web Store. Rozszerzenia z takiej listy można instalować bezpośrednio z tej aplikacji.</translation> -<translation id="132090119144658135">Dopasowanie do tematu:</translation> <translation id="1326317727527857210">Aby korzystać z kart ze swoich innych urządzeń, zaloguj się w Chrome.</translation> <translation id="1327074568633507428">Drukarka w Google Cloud Print</translation> <translation id="1327977588028644528">Brama</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Okno aplikacji</translation> <translation id="1534389735079119190">BŁĄD: nie udało się uruchomić kontenera w maszynie wirtualnej.</translation> <translation id="15373452373711364">Duży kursor myszy</translation> +<translation id="1540605929960647700">Włącz tryb demonstracyjny</translation> <translation id="1543284117603151572">Zaimportowane z Edge</translation> <translation id="1545177026077493356">Automatyczny tryb kiosku</translation> <translation id="1545775234664667895">Zainstalowano motyw „<ph name="THEME_NAME" />”</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Pomóż ulepszyć <ph name="PRODUCT_NAME" />, przesyłając do Google statystyki użytkowania i raporty o awariach</translation> <translation id="1658424621194652532">Ta strona ma dostęp do mikrofonu.</translation> <translation id="1660204651932907780">Zezwalaj na odtwarzanie dźwięku na stronach internetowych (zalecane)</translation> +<translation id="1660938185063657230">Zweryfikuj swój klucz bezpieczeństwa</translation> <translation id="1661156625580498328">Wymuś szyfrowanie AES (zalecane).</translation> <translation id="1661245713600520330">Na tej stronie wyświetlane są wszystkie moduły załadowane do procesu głównego oraz moduły zarejestrowane do późniejszego załadowania.</translation> <translation id="166179487779922818">Hasło jest zbyt krótkie.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Nie zezwalaj stronom na dostęp do tekstu i obrazów skopiowanych do schowka</translation> <translation id="1682548588986054654">Nowe okno incognito</translation> <translation id="168715261339224929">Aby korzystać ze swoich zakładek na wszystkich urządzeniach, włącz synchronizację.</translation> +<translation id="1688867105868176567">Wyczyścić dane witryny?</translation> <translation id="1688935057616748272">Wpisz literę</translation> <translation id="168991973552362966">Dodaj drukarkę w pobliżu</translation> <translation id="1689945336726856614">Kopiuj &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Usuń tę osobę</translation> <translation id="1706586824377653884">Dodane przez administratora</translation> <translation id="1706625117072057435">Poziomy powiększenia</translation> -<translation id="1707463636381878959">Udostępnij tę sieć innym użytkownikom</translation> <translation id="1708338024780164500">(Nieaktywne)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (identyfikator: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (natywna)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Włącz motyw</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Wyświetl w Chrome Web Store</translation> -<translation id="1758831820837444715">Skonfiguruj sieć Ethernet</translation> <translation id="1763046204212875858">Utwórz skróty do aplikacji</translation> <translation id="1763108912552529023">Odkrywaj dalej</translation> <translation id="1763808908432309942">Otworzy się na nowej karcie</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Zmień sposób udostępniania tego pliku</translation> <translation id="1841545962859478868">Administrator urządzenia może monitorować te zdarzenia:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> – wyłączono</translation> +<translation id="1842766183094193446">Czy na pewno chcesz włączyć tryb demonstracyjny?</translation> <translation id="1844692022597038441">Ten plik nie jest dostępny offline.</translation> <translation id="1846308012215045257">Naciśnij klawisz Control i kliknij, by uruchomić wtyczkę <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Zapisano</translation> <translation id="1848219224579402567">Wyloguj, gdy pokrywa jest zamknięta</translation> <translation id="184823282865851239">Blokuj, jeśli na stronie wyświetlają się uciążliwe reklamy</translation> <translation id="1849186935225320012">Ta strona ma pełny dostęp do sterowania urządzeniami MIDI.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Możesz zmienić to później w Ustawieniach</translation> <translation id="2006638907958895361">Otwórz link w aplikacji <ph name="APP" /></translation> <translation id="2007404777272201486">Zgłaszanie problemu...</translation> +<translation id="2016237810978710652">Otwieram pliki Linuksa...</translation> <translation id="2016430552235416146">Tradycyjne</translation> <translation id="2017334798163366053">Wyłącz zbieranie danych o wydajności</translation> <translation id="2017836877785168846">Usuwa historię i wpisy autouzupełniania w pasku adresu.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Edytowanie karty</translation> <translation id="2154710561487035718">Kopiuj adres URL</translation> <translation id="2155772377859296191">Wygląda na <ph name="WIDTH" /> × <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Możesz pomóc w ulepszaniu Bezpiecznego przeglądania, wysyłając do Google pewne informacje o systemie i część zawartości stron.</translation> <translation id="215753907730220065">Zamknij pełny ekran</translation> <translation id="2157875535253991059">Ta strona jest wyświetlana w trybie pełnoekranowym.</translation> <translation id="216169395504480358">Dodaj Wi-Fi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Dodaj identyfikator przeznaczenia do tego urządzenia</translation> <translation id="2175042898143291048">Tłumacz zawsze</translation> <translation id="2175607476662778685">Pasek szybkiego uruchamiania</translation> +<translation id="2176087259161165020">Inne źródła</translation> <translation id="2177950615300672361">Karta incognito: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Wtyczka <ph name="PEPPER_PLUGIN_NAME" /> na <ph name="PEPPER_PLUGIN_DOMAIN" /> chce mieć dostęp do Twojego komputera</translation> <translation id="2178614541317717477">Naruszenie bezpieczeństwa urzędu certyfikacji</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Następna karta</translation> <translation id="2292848386125228270">Uruchom <ph name="PRODUCT_NAME" /> jako normalny użytkownik. Jeśli jesteś programistą i chcesz skorzystać z konta roota, uruchom program jeszcze raz z flagą --no-sandbox.</translation> <translation id="2294358108254308676">Czy chcesz zainstalować aplikację <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Metoda EAP:</translation> <translation id="2297705863329999812">Wyszukaj drukarki</translation> <translation id="2300383962156589922">Ustawienia aplikacji <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Główny katalog rozszerzenia jest nieprawidłowy.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">BŁĄD: nie udało się odinstalować aplikacji <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Dodaj udział plików</translation> <translation id="2367972762794486313">Pokaż aplikacje</translation> +<translation id="2369536625682139252">Zostaną usunięte wszystkie dane zapisane przez witrynę <ph name="SITE" /> (oprócz plików cookie).</translation> <translation id="2371076942591664043">Otwórz po &zakończeniu</translation> <translation id="2377319039870049694">Przełącz na widok listy</translation> <translation id="2377667304966270281">Poważne błędy</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Drukuj w oknie systemowym <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Pytaj przed wysłaniem (zalecane)</translation> <translation id="2384436799579181135">Wystąpił błąd. Sprawdź drukarkę i spróbuj ponownie.</translation> -<translation id="2385700042425247848">Nazwa usługi:</translation> <translation id="2387458720915042159">Typ połączenia z serwerem proxy</translation> <translation id="2391419135980381625">Czcionka standardowa</translation> <translation id="2391762656119864333">Unieważnij</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Udostępnij dźwięk</translation> <translation id="2480868415629598489">Modyfikowanie danych, które kopiujesz i wklejasz</translation> <translation id="2482878487686419369">Powiadomienia</translation> -<translation id="2485056306054380289">Certyfikat CA serwera:</translation> <translation id="2485422356828889247">Odinstaluj</translation> <translation id="2487067538648443797">Dodaj nową zakładkę</translation> <translation id="248861575772995840">Nie można znaleźć telefonu. Upewnij się, że <ph name="DEVICE_TYPE" /> ma włączony Bluetooth. <a>Więcej informacji</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Wykonaj Powerwash, by zresetować urządzenie z <ph name="IDS_SHORT_PRODUCT_NAME" /> do ustawień fabrycznych.</translation> <translation id="2567257616420533738">Hasło zostało zapisane. Możesz wyświetlać zapisane hasła i nimi zarządzać na <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Kontener paska informacji</translation> +<translation id="2570454805927264159">Wykorzystaj możliwości Asystenta</translation> <translation id="257088987046510401">Motywy</translation> <translation id="2572032849266859634">Uprawnienia tylko do odczytu dysku <ph name="VOLUME_NAME" /> zostały przyznane.</translation> <translation id="2573269395582837871">Wybierz obraz i nazwę</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Prześlij</translation> <translation id="265390580714150011">Wartość pola</translation> <translation id="2654166010170466751">Zezwalaj stronom na instalowanie modułów do obsługi płatności</translation> -<translation id="2655386581175833247">Certyfikat użytkownika:</translation> <translation id="2660779039299703961">Wydarzenie</translation> <translation id="266079277508604648">Nie można połączyć z drukarką. Upewnij się, że drukarka jest włączona i podłączona do Chromebooka przez Wi-Fi lub USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Brak danych o użytkowaniu</translation> <translation id="3007214526293698309">Stałe proporcje</translation> <translation id="3007771295016901659">Powiel kartę</translation> +<translation id="3008272652534848354">Zresetuj uprawnienia</translation> <translation id="3009300415590184725">Czy na pewno chcesz anulować konfigurowanie komórkowej usługi transmisji danych?</translation> <translation id="3009779501245596802">Zindeksowane bazy danych</translation> <translation id="3010279545267083280">Hasło usunięte</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Moduły (<ph name="TOTAL_COUNT" />) – znane konflikty: <ph name="BAD_COUNT" />, podejrzewane: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Data i godzina</translation> <translation id="310671807099593501">Strona używa Bluetootha</translation> -<translation id="3108967419958202225">Wybierz</translation> <translation id="3115128645424181617">Nie można znaleźć telefonu. Upewnij się, że masz go w zasięgu ręki i włączony jest na nim Bluetooth.</translation> <translation id="3115147772012638511">Czekam na pamięć podręczną...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> – pomoc</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Niektórzy operatorzy mogą blokować tę funkcję.</translation> <translation id="316854673539778496">Aby korzystać ze wszystkich swoich rozszerzeń na innych urządzeniach, zaloguj się i włącz synchronizację.</translation> <translation id="3170072451822350649">Możesz też pominąć logowanie i <ph name="LINK_START" />przeglądać internet jako gość<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Kliknij, aby ukryć hasło</translation> <translation id="3177909033752230686">Język strony:</translation> <translation id="3181110748548073003">Naciśnij |<ph name="SHORTCUT" />|, aby przejść dalej</translation> <translation id="3182749001423093222">Sprawdzanie pisowni</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Własność zostanie przeniesiona do domeny <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Otwórz opcje rozszerzenia</translation> <translation id="3241680850019875542">Wybierz główny katalog rozszerzenia, które chcesz umieścić w pakiecie. Aby zaktualizować rozszerzenie, wybierz również plik kluczy prywatnych do ponownego użycia.</translation> -<translation id="3242765319725186192">Klucz wstępny:</translation> <translation id="3244294424315804309">Nadal wyciszaj dźwięk</translation> <translation id="3245321423178950146">Nieznany wykonawca</translation> <translation id="3246097286174000800">Wypróbuj Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Więcej czynności dotyczących zakładki <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Pytaj, gdy strona chce uzyskać dostęp do komputera przez wtyczkę</translation> <translation id="3441653493275994384">Ekran</translation> -<translation id="3445830502289589282">Uwierzytelnianie Phase 2:</translation> <translation id="344630545793878684">Odczyt Twoich danych na kilku stronach internetowych</translation> <translation id="3449839693241009168">Naciśnij klawisz <ph name="SEARCH_KEY" />, aby wysłać polecenia do rozszerzenia <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Stan bezczynności – procentowo</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826">Błędy: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Ustawienia Asystenta Google</translation> <translation id="3496213124478423963">Pomniejsz</translation> -<translation id="3504135463003295723">Nazwa grupy:</translation> <translation id="3505030558724226696">Anuluj dostęp do urządzeń</translation> <translation id="3507421388498836150">Obecne uprawnienia rozszerzenia „<ph name="EXTENSION_NAME" />”</translation> <translation id="3507547268929739059">Usuń aplikacje na Linuksa z Chromebooka</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Certyfikat logowania jest nieprawidłowy, okno zamknie się za <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ikona rozszerzenia</translation> <translation id="3665589677786828986">Przeglądarka Chrome wykryła, że niektóre z jej ustawień zostały zmodyfikowane przez inny program, i przywróciła im pierwotne wartości domyślne.</translation> -<translation id="3665842570601375360">Zabezpieczenia:</translation> <translation id="3668570675727296296">Ustawienia języka</translation> <translation id="3668823961463113931">Moduły obsługi</translation> <translation id="3670229581627177274">Włącz Bluetooth</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Nie można otworzyć urządzenia, ponieważ jego system plików nie jest obsługiwany.</translation> <translation id="3727148787322499904">Zmiana tego ustawienia wpłynie na wszystkie sieci współdzielone</translation> <translation id="3727187387656390258">Sprawdź wyskakujące okienko</translation> -<translation id="3728067901555601989">Hasło jednorazowe:</translation> <translation id="3732078975418297900">Błąd w wierszu <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Serwer SSL z dostępem</translation> <translation id="3737536731758327622">Tutaj wyświetlają się pobrane pliki</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Naciśnij Enter po zakończeniu.</translation> <translation id="3827774300009121996">&Pełny ekran</translation> <translation id="3828029223314399057">Przeszukaj zakładki</translation> -<translation id="3829932584934971895">Typ dostawcy:</translation> <translation id="3830674330436234648">Odtwarzanie jest niedostępne</translation> <translation id="3831486154586836914">Jesteś w trybie przeglądu okien</translation> <translation id="383161972796689579">Właściciel tego urządzenia wyłączył możliwość dodawania nowych użytkowników</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Zakończono pomiar użycia danych</translation> <translation id="3857228364945137633">Użyj funkcji Smart Lock, by odblokować urządzenie <ph name="DEVICE_TYPE" /> bez podawania hasła, gdy masz telefon w pobliżu.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: synchronizacja wstrzymana</translation> <translation id="3860381078714302691">Witamy w Hangouts Meet</translation> <translation id="3862134173397075045">Witamy w Cast dla Chrome</translation> <translation id="3862788408946266506">Aplikację z atrybutem „kiosk_only” w pliku manifestu należy zainstalować w Chrome OS w trybie kiosku</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Nie udało się skonfigurować sieci</translation> <translation id="3970114302595058915">Identyfikator</translation> <translation id="397105322502079400">Obliczanie...</translation> -<translation id="3974195870082915331">Kliknij, aby pokazać hasło</translation> <translation id="3975222297214566386">Dymek opcji wejścia</translation> <translation id="397703832102027365">Kończę...</translation> <translation id="3979395879372752341">Dodano nowe rozszerzenie (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Podaj hasło certyfikatu</translation> <translation id="404493185430269859">Domyślna wyszukiwarka</translation> <translation id="4047112090469382184">Jak bezpieczna jest ta funkcja</translation> +<translation id="4051049974203704184">Uzyskaj informacje o tym, co wyświetla się na ekranie</translation> <translation id="4052120076834320548">Malutki</translation> <translation id="4055023634561256217">Przed zresetowaniem urządzenia przy użyciu Powerwash trzeba je zrestartować.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> – <ph name="RECEIVED_AMOUNT" /></translation> @@ -2035,10 +2031,11 @@ <translation id="4087089424473531098">Utworzono rozszerzenie: <ph name="EXTENSION_FILE" /></translation> -<translation id="4087470595660267445">Instaluj aplikacje i gry z Google Play na Chromebooku. <a target="_blank" href="<ph name="URL" />">Więcej informacji</a></translation> +<translation id="4087470595660267445">Instaluj gry i aplikacje z Google Play na Chromebooku. <a target="_blank" href="<ph name="URL" />">Więcej informacji</a></translation> <translation id="4088095054444612037">Zaakceptuj dla grupy</translation> <translation id="4089235344645910861">Ustawienia zapisane. Synchronizacja rozpoczęta.</translation> <translation id="4090103403438682346">Włącz weryfikację dostępu</translation> +<translation id="4090947011087001172">Zresetować uprawnienia witryny <ph name="SITE" />?</translation> <translation id="4091434297613116013">kartki</translation> <translation id="4093955363990068916">Plik lokalny:</translation> <translation id="4095507791297118304">Ekran główny</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Konfiguracja synchronizacji, personalizacji i innych opcji</translation> <translation id="4421932782753506458">Puszysty</translation> <translation id="4422347585044846479">Edytuj zakładkę tej strony</translation> -<translation id="4423104065312875417">Zainstaluj dodatkowe mechanizmy syntezy mowy</translation> <translation id="4423376891418188461">Przywróć ustawienia</translation> <translation id="4423482519432579560">&Sprawdzanie pisowni</translation> <translation id="442397852638519243">Twój administrator (<ph name="USER_NAME" />) prosi Cię o zmianę Twojego hasła.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Ta karta odtwarza dźwięk.</translation> <translation id="4450974146388585462">Diagnozuj</translation> <translation id="4453946976636652378">Wyszukaj w <ph name="SEARCH_ENGINE_NAME" /> lub wpisz URL</translation> -<translation id="445923051607553918">Połącz się z siecią Wi-Fi</translation> <translation id="4462159676511157176">Własne serwery nazw</translation> <translation id="4467100756425880649">Galeria Chrome Web Store</translation> <translation id="4467101674048705704">Rozwiń folder <ph name="FOLDER_NAME" /></translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Na ekranie logowania są wyświetlane tapety.</translation> <translation id="4684427112815847243">Synchronizuj wszystko</translation> <translation id="4689421377817139245">Zsynchronizuj tę zakładkę ze swoim iPhonem</translation> +<translation id="4690091457710545971"><Cztery pliki wygenerowane przez oprogramowanie układowe Wi-Fi Intel: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Pierwsze trzy to pliki binarne zawierające zrzuty rejestru. Intel twierdzi, że nie zawierają żadnych danych umożliwiających identyfikację osoby lub urządzenia. Ostatni plik zawiera ślad wykonywania oprogramowania układowego Intel. Wszelkie dane umożliwiające identyfikację osoby lub urządzenia zostały z niego usunięte, ale jest zbyt duży, by go tu wyświetlić. Te pliki zostały wygenerowane w reakcji na niedawne problemy z Wi-Fi na Twoim urządzeniu i zostaną przekazane firmie Intel, by pomóc w rozwiązaniu tych problemów.></translation> <translation id="4692302215262324251">Urządzenie <ph name="DEVICE_TYPE" /> zostało zarejestrowane na potrzeby zarządzania w firmie w domenie <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Jeśli nie spodziewałeś się tej wiadomości, skontaktuj się z pomocą.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Aby nowe ustawienia zaczęły działać, być może trzeba odświeżyć tę stronę.</translation> <translation id="5075131525758602494">Podaj kod PIN karty SIM</translation> <translation id="5078638979202084724">Dodaj wszystkie karty do zakładek</translation> +<translation id="5079950360618752063">Użyj sugerowanego hasła</translation> <translation id="5084230410268011727">Zezwalaj stronom internetowym na używanie czujników ruchu i światła</translation> <translation id="5085162214018721575">Sprawdzanie dostępności aktualizacji</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Usuń ten element</translation> <translation id="5139955368427980650">&Otwórz</translation> +<translation id="5142961317498132443">Uwierzytelnianie</translation> <translation id="5143374789336132547">Rozszerzenie „<ph name="EXTENSION_NAME" />” ustawiło inną stronę wyświetlaną po kliknięciu przycisku strony startowej.</translation> <translation id="5143712164865402236">Przejdź do pełnego ekranu</translation> <translation id="5145331109270917438">Data modyfikacji</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Przytrzymaj Control, Alt, Shift lub klawisz wyszukiwania, aby wyświetlić skróty klawiszowe dla tych modyfikatorów.</translation> <translation id="5382591305415226340">Zarządzaj obsługiwanymi linkami</translation> <translation id="5384883051496921101">Ta strona zamierza udostępnić informacje aplikacji poza trybem incognito.</translation> -<translation id="5388588172257446328">Nazwa użytkownika:</translation> <translation id="5388885445722491159">Sparowane</translation> <translation id="5389237414310520250">Nie można utworzyć nowego użytkownika. Sprawdź miejsce na dysku twardym i uprawnienia, a potem spróbuj ponownie.</translation> <translation id="5390100381392048184">Zezwalaj na odtwarzanie dźwięku na stronach internetowych</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Klawiatura i wprowadzanie tekstu</translation> <translation id="5553089923092577885">Odwzorowania zasad certyfikatu</translation> <translation id="5554489410841842733">Ta ikona jest widoczna wtedy, gdy rozszerzenie umożliwia wykonanie działania na bieżącej stronie.</translation> -<translation id="5554573843028719904">Inna sieć Wi-Fi</translation> <translation id="5554720593229208774">Urząd certyfikacji poczty e-mail</translation> <translation id="5556206011531515970">Kliknij Dalej, by wybrać domyślną przeglądarkę.</translation> <translation id="5556459405103347317">Odśwież</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Przełącz na tryb aparatu</translation> <translation id="5612720917913232150"><ph name="URL" /> chce używać lokalizacji Twojego komputera</translation> <translation id="5612734644261457353">Nadal nie można zweryfikować Twojego hasła. Uwaga: jeśli ostatnio hasło było zmieniane, nowe hasło zostanie zastosowane, gdy się wylogujesz. Tu podaj stare hasło.</translation> -<translation id="5613695965848159202">Tożsamość anonimowa:</translation> <translation id="5614190747811328134">Informacje dla użytkownika</translation> <translation id="561698261642843490">Zamykanie Firefoksa</translation> <translation id="5618075537869101857">Nie można uruchomić aplikacji kiosku.</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">Zaloguj się do urządzenia <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimalizuj</translation> <translation id="5946591249682680882">Identyfikator raportu: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Dodaj sieć prywatną</translation> <translation id="5949544233750246342">Nie można przeanalizować pliku</translation> <translation id="5955282598396714173">Twoje hasło utraciło ważność. Wyloguj się, a potem zaloguj się jeszcze raz, by je zmienić.</translation> <translation id="5956585768868398362">Czy to oczekiwana strona wyszukiwania?</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">Wyloguj się i ponownie zaloguj</translation> <translation id="6198252989419008588">Zmień kod PIN</translation> <translation id="6199801702437275229">Oczekuję na informacje o wolnym miejscu...</translation> +<translation id="6204015976622790023">Wyświetlaj sugestie Asystenta dotyczące tego, co wyświetla się na Twoim ekranie.</translation> <translation id="6205710420833115353">Niektóre operacje trwają dłużej niż powinny. Chcesz je przerwać?</translation> <translation id="6206311232642889873">Kop&iuj grafikę</translation> <translation id="6207200176136643843">Przywróć domyślny poziom powiększenia</translation> <translation id="620722923698527029">Zawsze otwieraj ten typ linków w powiązanej aplikacji</translation> <translation id="6207937957461833379">Kraj/region</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: synchronizacja nie działa</translation> <translation id="6212039847102026977">Pokaż zaawansowane właściwości sieci</translation> <translation id="6212168817037875041">Wyłącz ekran</translation> <translation id="6212752530110374741">Prześlij link e-mailem</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">zresetować synchronizację</translation> <translation id="6264365405983206840">Wybierz &wszystko</translation> <translation id="6264422956566238156">Synchronizacja została włączona</translation> -<translation id="6265930187414222160">Gotowe. Szkodliwe oprogramowanie zostało usunięte.</translation> <translation id="6267166720438879315">Wybierz certyfikat, aby uwierzytelnić się na serwerze <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Otwórz w <ph name="APP" /></translation> <translation id="6268747994388690914">Importuj zakładki z pliku HTML</translation> @@ -3537,7 +3532,6 @@ Kliknij „Dalej”, by kontynuować logowanie się na konto w domenie <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Załaduj rozpakowane</translation> <translation id="642282551015776456">Tej nazwy nie można używać jako nazwy pliku ani katalogu.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Otwórz ustawienia ChromeVoxa</translation> <translation id="6429384232893414837">Błąd aktualizacji</translation> <translation id="6430814529589430811">Plik ASCII z kodowaniem Base64, jeden certyfikat</translation> @@ -3618,7 +3612,6 @@ <translation id="6544215763872433504">Przeglądarka Google dla Ciebie</translation> <translation id="6545665334409411530">Szybkość powtarzania</translation> <translation id="6545834809683560467">Używaj podpowiedzi, by uzupełniać zapytania i adresy URL wpisywane na pasku adresu lub w polu wyszukiwania menu z aplikacjami</translation> -<translation id="6546686722964485737">Połącz z siecią WiMAX</translation> <translation id="6547316139431024316">Nie pokazuj już ostrzeżeń dla tego rozszerzenia</translation> <translation id="6547354035488017500">Zwolnij co najmniej 512 MB miejsca. W przeciwnym razie urządzenie przestanie odpowiadać. Aby zwolnić miejsce, usuń pliki z pamięci urządzenia.</translation> <translation id="6549689063733911810">Ostatnie</translation> @@ -4037,7 +4030,6 @@ <translation id="7201014958346994077">Nie można wyświetlić plików Linuksa</translation> <translation id="720110658997053098">Trwale utrzymuj to urządzenie w trybie kiosku</translation> <translation id="7201118060536064622">Element „<ph name="DELETED_ITEM_NAME" />” został usunięty</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Pobieram <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Zamknij stronę}few{Zamknij strony}many{Zamknij strony}other{Zamknij strony}}</translation> <translation id="7216409898977639127">Operator komórkowy</translation> @@ -4514,7 +4506,6 @@ <translation id="7909969815743704077">Pobrano w trybie incognito</translation> <translation id="7910768399700579500">&Nowy folder</translation> <translation id="7912080627461681647">Twoje hasło zostało zmienione na serwerze. Wyloguj się i zaloguj się ponownie.</translation> -<translation id="7912883689016444961">Skonfiguruj sieć komórkową</translation> <translation id="7915471803647590281">Zanim wyślesz opinię, powiedz nam, co się dzieje.</translation> <translation id="7916556741383518510">Po kliknięciu</translation> <translation id="792514962475806987">Poziom powiększenia lupy zadokowanej:</translation> @@ -4568,7 +4559,6 @@ <translation id="7988355189918024273">Włącz ułatwienia dostępu</translation> <translation id="7994702968232966508">Metoda EAP</translation> <translation id="799547531016638432">Usuń skrót</translation> -<translation id="7997479212858899587">Tożsamość:</translation> <translation id="7997826902155442747">Priorytet procesu</translation> <translation id="7999229196265990314">Utworzono następujące pliki: @@ -4652,7 +4642,6 @@ <translation id="8105368624971345109">Wyłącz</translation> <translation id="8106045200081704138">Udostępnione dla mnie</translation> <translation id="8107015733319732394">Instaluję Sklep Google Play na urządzeniu <ph name="DEVICE_TYPE" />. Może to potrwać kilka minut.</translation> -<translation id="8109930990200908494">Logowanie wymagane dla certyfikatu użytkownika.</translation> <translation id="8111155949205007504">Udostępnij to hasło za pomocą iPhone'a</translation> <translation id="8113043281354018522">Wybierz typ licencji</translation> <translation id="8116190140324504026">Więcej informacji...</translation> @@ -4663,6 +4652,7 @@ <translation id="8118860139461251237">Zarządzanie pobranymi plikami</translation> <translation id="81238879832906896">Żółto-biały kwiat</translation> <translation id="8124313775439841391">Zarządzana konfiguracja ONC</translation> +<translation id="8125562866093998907">Witryna chce zweryfikować Twój klucz bezpieczeństwa, by zwiększyć bezpieczeństwo konta.</translation> <translation id="813082847718468539">Wyświetl informacje o witrynie</translation> <translation id="8131740175452115882">Potwierdź</translation> <translation id="8133676275609324831">&Pokaż w folderze</translation> @@ -4773,7 +4763,6 @@ <translation id="8308179586020895837">Pytaj, gdy witryna <ph name="HOST" /> chce mieć dostęp do kamery</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certyfikat już istnieje</translation> -<translation id="8309505303672555187">Wybierz sieć:</translation> <translation id="8312871300878166382">Wklej do folderu</translation> <translation id="8317671367883557781">Dodaj połączenie sieciowe</translation> <translation id="8319414634934645341">Rozszerzone użycie klucza</translation> @@ -4849,7 +4838,6 @@ <translation id="8451512073679317615">Asystent</translation> <translation id="8452135315243592079">Brak karty SIM</translation> <translation id="8453482423012550001">Kopiuję $1 elementy(ów)...</translation> -<translation id="8454288007744638700">Lub wybierz nową sieć:</translation> <translation id="845627346958584683">Data ważności</translation> <translation id="8456681095658380701">Nieprawidłowa nazwa</translation> <translation id="8457451314607652708">Importuj zakładki</translation> @@ -4913,6 +4901,7 @@ <translation id="855081842937141170">Przypnij kartę</translation> <translation id="8551388862522347954">Licencje</translation> <translation id="8553342806078037065">Zarządzaj innymi osobami</translation> +<translation id="8554899698005018844">Brak języka</translation> <translation id="855773602626431402">Uruchomienie wtyczki spoza piaskownicy zostało zablokowane na tej stronie.</translation> <translation id="8557930019681227453">Plik manifestu</translation> <translation id="8559694214572302298">Dekoder obrazów</translation> @@ -4950,7 +4939,6 @@ <translation id="862727964348362408">Zawieszona</translation> <translation id="862750493060684461">Pamięć podręczna CSS</translation> <translation id="8627795981664801467">Tylko bezpieczne połączenia</translation> -<translation id="8628085465172583869">Nazwa hosta serwera:</translation> <translation id="8630903300770275248">Zaimportuj użytkownika nadzorowanego</translation> <translation id="8631032106121706562">Płatki</translation> <translation id="8637542770513281060">Twój komputer ma moduł zabezpieczeń, który umożliwia zastosowanie wielu krytycznych funkcji zabezpieczeń w systemie operacyjnym Chrome. Więcej informacji znajdziesz w Centrum pomocy Chromebooka na stronie: https://support.google.com/chromebook/?p=sm</translation> @@ -5206,7 +5194,6 @@ <translation id="899403249577094719">Podstawowy adres URL certyfikatu firmy Netscape</translation> <translation id="8995603266996330174">Zarządzane przez <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Dodaj konto...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Tworzę obrazu dysku.</translation> <translation id="9003647077635673607">Zezwól we wszystkich witrynach</translation> <translation id="9003677638446136377">Sprawdź ponownie</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb index 1eaa814d..8e43753 100644 --- a/chrome/app/resources/generated_resources_pt-BR.xtb +++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Está quase na hora de fazer uma pausa</translation> <translation id="1062407476771304334">Substituir</translation> -<translation id="1064835277883315402">Conectar a uma rede particular</translation> <translation id="1064912851688322329">Desconecta sua Conta do Google</translation> <translation id="1067048845568873861">Criado em</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Pesquisando...</translation> <translation id="1316495628809031177">A sincronização está pausada</translation> <translation id="1319979322914001937">Um aplicativo que mostra uma lista filtrada de extensões da Chrome Web Store. As extensões que estão na lista podem ser instaladas diretamente a partir do app.</translation> -<translation id="132090119144658135">Correspondência de assunto:</translation> <translation id="1326317727527857210">Para ver as guias dos seus outros dispositivos, faça login no Chrome.</translation> <translation id="1327074568633507428">Impressora no Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Remover esta pessoa</translation> <translation id="1706586824377653884">Adicionado pelo seu administrador</translation> <translation id="1706625117072057435">Níveis de zoom</translation> -<translation id="1707463636381878959">Compartilhar esta rede</translation> <translation id="1708338024780164500">(Inativa)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (código: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativo)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Ativar tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Ver na Chrome Web Store</translation> -<translation id="1758831820837444715">Configurar rede Ethernet</translation> <translation id="1763046204212875858">Criar atalhos para aplicativos</translation> <translation id="1763108912552529023">Continuar explorando</translation> <translation id="1763808908432309942">Abre em uma nova guia</translation> @@ -875,7 +871,6 @@ <translation id="2291643155573394834">Próxima guia</translation> <translation id="2292848386125228270">Inicie o <ph name="PRODUCT_NAME" /> como um usuário normal. Se precisar executar como raiz para desenvolvimento, execute novamente com a sinalização --no-sandbox.</translation> <translation id="2294358108254308676">Quer instalar o <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Método EAP:</translation> <translation id="2297705863329999812">Pesquisar impressoras</translation> <translation id="2300383962156589922">Personalizar e controlar o app <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">O diretório raiz da extensão é inválido.</translation> @@ -933,7 +928,6 @@ <translation id="2379281330731083556">Imprimir utilizando caixa de diálogo de sistema... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Perguntar antes de enviar (recomendado)</translation> <translation id="2384436799579181135">Ocorreu um erro. Verifique sua impressora e tente novamente.</translation> -<translation id="2385700042425247848">Nome do serviço:</translation> <translation id="2387458720915042159">Tipo de conexão proxy</translation> <translation id="2391419135980381625">Fonte padrão</translation> <translation id="2391762656119864333">Revogar</translation> @@ -984,7 +978,6 @@ <translation id="247949520305900375">Compartilhar áudio</translation> <translation id="2480868415629598489">Modificar os dados que você copia e cola</translation> <translation id="2482878487686419369">Notificações</translation> -<translation id="2485056306054380289">Cert. AC do servidor:</translation> <translation id="2485422356828889247">Desinstalar</translation> <translation id="2487067538648443797">Adicionar novo favorito</translation> <translation id="248861575772995840">Não foi possível localizar seu smartphone. Certifique-se de que o Bluetooth do <ph name="DEVICE_TYPE" /> esteja ativado. <a>Saiba mais</a></translation> @@ -1109,7 +1102,6 @@ <translation id="2653659639078652383">Enviar</translation> <translation id="265390580714150011">Valor do campo</translation> <translation id="2654166010170466751">Permitir que sites instalem gerenciadores de pagamento</translation> -<translation id="2655386581175833247">Certificado do usuário:</translation> <translation id="2660779039299703961">Evento</translation> <translation id="266079277508604648">Não é possível conectar a impressora. Verifique se ela está ligada e conectada ao seu Chromebook por Wi-Fi ou USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1409,7 +1401,6 @@ <translation id="3100609564180505575">Módulos (<ph name="TOTAL_COUNT" />) - Conflitos conhecidos: <ph name="BAD_COUNT" />, suspeitos: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Data e hora</translation> <translation id="310671807099593501">O site está usando o Bluetooth</translation> -<translation id="3108967419958202225">Escolher...</translation> <translation id="3115128645424181617">Não foi possível encontrar seu smartphone. Certifique-se de que ele esteja acessível e com o Bluetooth ativado.</translation> <translation id="3115147772012638511">Aguardando o cache...</translation> <translation id="3118319026408854581">Ajuda do <ph name="PRODUCT_NAME" /></translation> @@ -1454,7 +1445,6 @@ <translation id="3165390001037658081">Algumas operadoras podem bloquear esse recurso.</translation> <translation id="316854673539778496">Para ter todas as suas extensões em todos os seus dispositivos, faça login e ative a sincronização.</translation> <translation id="3170072451822350649">Também é possível ignorar o login e <ph name="LINK_START" />navegar como visitante<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Clique para ocultar senha</translation> <translation id="3177909033752230686">Idioma da página:</translation> <translation id="3181110748548073003">Pressione |<ph name="SHORTCUT" />| para avançar</translation> <translation id="3182749001423093222">Verificação ortográfica</translation> @@ -1485,7 +1475,6 @@ <translation id="3236289833370040187">A propriedade será transferida para <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Abrir opções de extensão</translation> <translation id="3241680850019875542">Selecione o diretório raiz da extensão a ser empacotada. Para atualizar uma extensão, selecione também a chave privada a ser reutilizada.</translation> -<translation id="3242765319725186192">Chave pré-compartilhada:</translation> <translation id="3244294424315804309">Continuar com o som desativado</translation> <translation id="3245321423178950146">Artista desconhecido</translation> <translation id="3246097286174000800">Fazer um teste com o Smart Lock</translation> @@ -1618,7 +1607,6 @@ <translation id="3440663250074896476">Mais ações para <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Perguntar quando um site quiser usar um plug-in para acessar seu computador</translation> <translation id="3441653493275994384">Tela</translation> -<translation id="3445830502289589282">Aut. da fase 2:</translation> <translation id="344630545793878684">Leia seus dados em uma série de websites</translation> <translation id="3449839693241009168">Pressione <ph name="SEARCH_KEY" /> para enviar comandos para <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Porcentagem de ocupação em estado de inatividade</translation> @@ -1659,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> erros.</translation> <translation id="3495660573538963482">Configurações do Google Assistente</translation> <translation id="3496213124478423963">Afastar</translation> -<translation id="3504135463003295723">Nome do grupo:</translation> <translation id="3505030558724226696">Revogar acesso ao dispositivo</translation> <translation id="3507421388498836150">Permissões atuais para "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Remover apps do Linux para Chromebook</translation> @@ -1768,7 +1755,6 @@ <translation id="3661054927247347545">A certificação de login não é válida. Janela fechando em <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ícone de extensão</translation> <translation id="3665589677786828986">O Google Chrome detectou que algumas das suas configurações foram corrompidas por outro programa e as redefiniu para os padrões originais.</translation> -<translation id="3665842570601375360">Segurança:</translation> <translation id="3668570675727296296">Configurações de idioma</translation> <translation id="3668823961463113931">Manipuladores</translation> <translation id="3670229581627177274">Ativar Bluetooth</translation> @@ -1807,7 +1793,6 @@ <translation id="3726463242007121105">Não foi possível abrir este dispositivo porque seu sistema de arquivos não é suportado.</translation> <translation id="3727148787322499904">A alteração dessa configuração afetará todas as redes compartilhadas</translation> <translation id="3727187387656390258">Inspecionar pop-up</translation> -<translation id="3728067901555601989">Senha descartável (OTP):</translation> <translation id="3732078975418297900">Erro na linha <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Servidor SSL com Step-up</translation> <translation id="3737536731758327622">Seus downloads são exibidos aqui</translation> @@ -1882,7 +1867,6 @@ <translation id="38275787300541712">Pressione "Enter" ao terminar</translation> <translation id="3827774300009121996">&Tela cheia</translation> <translation id="3828029223314399057">Pesquisar favoritos</translation> -<translation id="3829932584934971895">Tipo de provedor:</translation> <translation id="3830674330436234648">Nenhuma reprodução disponível</translation> <translation id="3831486154586836914">Iniciado modo de visão geral da janela</translation> <translation id="383161972796689579">O proprietário deste dispositivo desativou a adição de novos usuários</translation> @@ -1981,7 +1965,6 @@ <translation id="3968261067169026421">Não foi possível configurar a rede</translation> <translation id="3970114302595058915">Código</translation> <translation id="397105322502079400">Calculando...</translation> -<translation id="3974195870082915331">Clique para exibir senha</translation> <translation id="3975222297214566386">Balão de opções de entrada</translation> <translation id="397703832102027365">Finalizando...</translation> <translation id="3979395879372752341">Nova extensão adicionada (<ph name="EXTENSION_NAME" />)</translation> @@ -2229,7 +2212,6 @@ <translation id="4419556793104466535">Controlar sincronização, personalização e muito mais</translation> <translation id="4421932782753506458">Pelúcia</translation> <translation id="4422347585044846479">Editar favorito para esta página</translation> -<translation id="4423104065312875417">Instalar mecanismos de fala adicionais</translation> <translation id="4423376891418188461">Restaurar configurações</translation> <translation id="4423482519432579560">&Correção ortográfica</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, seu administrador solicita que você altere sua senha.</translation> @@ -2254,7 +2236,6 @@ <translation id="4449996769074858870">Esta guia está reproduzindo áudio.</translation> <translation id="4450974146388585462">Diagnosticar</translation> <translation id="4453946976636652378">Pesquisar no <ph name="SEARCH_ENGINE_NAME" /> ou digitar URL</translation> -<translation id="445923051607553918">Entrar na rede Wi-Fi</translation> <translation id="4462159676511157176">Servidores de nome personalizados</translation> <translation id="4467100756425880649">Galeria da Chrome Web Store</translation> <translation id="4467101674048705704">Expandir <ph name="FOLDER_NAME" /></translation> @@ -2860,7 +2841,6 @@ <translation id="5380103295189760361">Pressione Control, Alt, Shift ou "Pesquisar" para visualizar os atalhos do teclado para estes modificadores.</translation> <translation id="5382591305415226340">Gerenciar links compatíveis</translation> <translation id="5384883051496921101">Este site está prestes a compartilhar informações com um app fora do modo de navegação anônima.</translation> -<translation id="5388588172257446328">Nome de usuário:</translation> <translation id="5388885445722491159">Emparelhado</translation> <translation id="5389237414310520250">Não foi possível criar o novo usuário. Verifique o espaço no seu disco rígido e suas permissões e tente novamente.</translation> <translation id="5390100381392048184">Permitir que os sites reproduzam sons</translation> @@ -2985,7 +2965,6 @@ <translation id="5551573675707792127">Teclado e entrada de texto</translation> <translation id="5553089923092577885">Mapeamentos da diretiva de certificação</translation> <translation id="5554489410841842733">Este ícone ficará visível quando a extensão puder agir na página atual.</translation> -<translation id="5554573843028719904">Outra rede Wi-Fi...</translation> <translation id="5554720593229208774">Autoridade de certificação de e-mail</translation> <translation id="5556206011531515970">Clique ao lado para escolher o navegador padrão.</translation> <translation id="5556459405103347317">Recarregar</translation> @@ -3026,7 +3005,6 @@ <translation id="5610038042047936818">Alternar para o modo de câmera</translation> <translation id="5612720917913232150">O URL <ph name="URL" /> quer usar o local do seu computador</translation> <translation id="5612734644261457353">Não foi possível confirmar sua senha. Nota: se você alterou sua senha recentemente, a nova senha será aplicada depois que você sair. Use a senha antiga aqui.</translation> -<translation id="5613695965848159202">Identidade anônima:</translation> <translation id="5614190747811328134">Aviso para o usuário</translation> <translation id="561698261642843490">Fechar o Firefox</translation> <translation id="5618075537869101857">Puxa, não foi possível iniciar o aplicativo de quiosque.</translation> @@ -3245,7 +3223,6 @@ <translation id="5941343993301164315">Faça login em <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimizar</translation> <translation id="5946591249682680882">Código de relatório <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Adicionar rede privada</translation> <translation id="5949544233750246342">Não foi possível analisar o arquivo</translation> <translation id="5955282598396714173">Sua senha expirou. Saia e faça login novamente para alterá-la.</translation> <translation id="5956585768868398362">Esta é a página de pesquisa que você esperava?</translation> @@ -3451,7 +3428,6 @@ <translation id="6263541650532042179">redefinir sincronização</translation> <translation id="6264365405983206840">Selecionar &tudo</translation> <translation id="6264422956566238156">Você ativou a sincronização</translation> -<translation id="6265930187414222160">Pronto! Software perigoso removido.</translation> <translation id="6267166720438879315">Selecione um certificado para se autenticar no <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Abrir com <ph name="APP" /></translation> <translation id="6268747994388690914">Importar favoritos de arquivo HTML...</translation> @@ -3558,7 +3534,6 @@ Clique em "Próxima" para continuar e fazer login na sua conta <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Carregar sem compactação</translation> <translation id="642282551015776456">Este não é um nome válido para arquivos ou pastas.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Abrir as configurações do ChromeVox</translation> <translation id="6429384232893414837">Erro de atualização</translation> <translation id="6430814529589430811">ASCII codificado na Base64, certificado único</translation> @@ -3639,7 +3614,6 @@ <translation id="6544215763872433504">O navegador da Web do Google para você</translation> <translation id="6545665334409411530">Taxa de repetição</translation> <translation id="6545834809683560467">Utilizar o serviço de previsão para ajudar a completar pesquisas e URLs digitados na barra de endereço ou na caixa de pesquisa do Acesso rápido aos apps</translation> -<translation id="6546686722964485737">Entrar para a rede WiMAX</translation> <translation id="6547316139431024316">Não avisar novamente para esta extensão</translation> <translation id="6547354035488017500">Libere pelo menos 512 MB de espaço. Caso contrário, seu dispositivo deixará de responder. Para liberar espaço, exclua arquivos do armazenamento do dispositivo.</translation> <translation id="6549689063733911810">Recentes</translation> @@ -4058,7 +4032,6 @@ <translation id="7201014958346994077">Não é possível ver os arquivos do Linux</translation> <translation id="720110658997053098">Manter este dispositivo permanentemente no modo quiosque</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' excluído</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Fazendo download do <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Sair da página}one{Sair da página}other{Sair das páginas}}</translation> <translation id="7216409898977639127">Operadora de celular</translation> @@ -4536,7 +4509,6 @@ <translation id="7909969815743704077">Download feito no modo anônimo</translation> <translation id="7910768399700579500">&Nova pasta</translation> <translation id="7912080627461681647">Sua senha foi alterada no servidor. Saia e faça login novamente.</translation> -<translation id="7912883689016444961">Configurar rede móvel</translation> <translation id="7915471803647590281">Conte-nos o que está acontecendo antes de enviar comentários.</translation> <translation id="7916556741383518510">Ao Clicar</translation> <translation id="792514962475806987">Nível de zoom da lupa ancorada:</translation> @@ -4590,7 +4562,6 @@ <translation id="7988355189918024273">Permitir recursos de acessibilidade</translation> <translation id="7994702968232966508">Método EAP</translation> <translation id="799547531016638432">Remover atalho</translation> -<translation id="7997479212858899587">Identidade:</translation> <translation id="7997826902155442747">Prioridade de processo</translation> <translation id="7999229196265990314">Os seguintes arquivos foram criados: @@ -4674,7 +4645,6 @@ <translation id="8105368624971345109">Desativar</translation> <translation id="8106045200081704138">Compartilhado comigo</translation> <translation id="8107015733319732394">Instalando a Google Play Store no seu <ph name="DEVICE_TYPE" />. Isso pode demorar alguns minutos.</translation> -<translation id="8109930990200908494">É obrigatório fazer login para receber o certificado de usuário.</translation> <translation id="8111155949205007504">Compartilhar essa senha com seu iPhone</translation> <translation id="8113043281354018522">Escolha o tipo de licença</translation> <translation id="8116190140324504026">Mais informações...</translation> @@ -4796,7 +4766,6 @@ <translation id="8308179586020895837">Perguntar se <ph name="HOST" /> deseja acessar sua câmera</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">O certificado já existe</translation> -<translation id="8309505303672555187">Selecione uma rede:</translation> <translation id="8312871300878166382">Colar na pasta</translation> <translation id="8317671367883557781">Adicionar conexão de rede</translation> <translation id="8319414634934645341">Uso estendido de chave</translation> @@ -4872,7 +4841,6 @@ <translation id="8451512073679317615">assistente</translation> <translation id="8452135315243592079">Cartão SIM ausente</translation> <translation id="8453482423012550001">Copiando $1 itens...</translation> -<translation id="8454288007744638700">Ou selecione uma nova rede:</translation> <translation id="845627346958584683">Tempo de vencimento</translation> <translation id="8456681095658380701">Nome inválido</translation> <translation id="8457451314607652708">Importar favoritos</translation> @@ -4974,7 +4942,6 @@ <translation id="862727964348362408">Em suspensão</translation> <translation id="862750493060684461">Cache CSS</translation> <translation id="8627795981664801467">Somente conexões seguras</translation> -<translation id="8628085465172583869">Nome do host do servidor:</translation> <translation id="8630903300770275248">Importar usuário supervisionado</translation> <translation id="8631032106121706562">Bem-me-quer</translation> <translation id="8637542770513281060">Seu computador possui um módulo de segurança, que é utilizado para implementar muitos recursos de segurança importantes no Chrome OS. Visite a Central de Ajuda do Chromebook para saber mais: https://support.google.com/chromebook/?p=sm</translation> @@ -5230,7 +5197,6 @@ <translation id="899403249577094719">URL base do certificado do Netscape</translation> <translation id="8995603266996330174">Gerenciado por <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Adicionar conta...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Criando imagem de disco.</translation> <translation id="9003647077635673607">Permitir em todos os websites</translation> <translation id="9003677638446136377">Verificar novamente</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb index f637798..95940be 100644 --- a/chrome/app/resources/generated_resources_pt-PT.xtb +++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Está quase na altura de fazer uma pausa</translation> <translation id="1062407476771304334">Substituir</translation> -<translation id="1064835277883315402">Aderir a rede privada</translation> <translation id="1064912851688322329">Desligar a sua Conta Google</translation> <translation id="1067048845568873861">Data da criação</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">A pesquisar...</translation> <translation id="1316495628809031177">A sincronização está em pausa.</translation> <translation id="1319979322914001937">Uma aplicação que mostra uma lista filtrada de extensões da Web Store do Chrome. As extensões da lista podem ser instaladas diretamente a partir da aplicação.</translation> -<translation id="132090119144658135">Correspondência de assunto:</translation> <translation id="1326317727527857210">Para obter os separadores dos seus outros dispositivos, inicie sessão no Chrome.</translation> <translation id="1327074568633507428">Impressora no Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -377,6 +375,7 @@ <translation id="1531004739673299060">Janela da aplicação</translation> <translation id="1534389735079119190">ERRO: falha ao iniciar o contentor na VM.</translation> <translation id="15373452373711364">Cursor do rato grande</translation> +<translation id="1540605929960647700">Ativar o modo de demonstração</translation> <translation id="1543284117603151572">Importado do Edge</translation> <translation id="1545177026077493356">Modo quiosque automático</translation> <translation id="1545775234664667895">Tema instalado "<ph name="THEME_NAME" />"</translation> @@ -460,6 +459,7 @@ <translation id="1657406563541664238">Ajude a melhorar o <ph name="PRODUCT_NAME" /> enviando automaticamente estatísticas de utilização e relatórios de falhas para a Google</translation> <translation id="1658424621194652532">Esta página está a aceder ao seu microfone.</translation> <translation id="1660204651932907780">Permitir que os sites reproduzam som (recomendado)</translation> +<translation id="1660938185063657230">Validar a Chave de segurança</translation> <translation id="1661156625580498328">Aplicar Encriptação AES (recomendado).</translation> <translation id="1661245713600520330">Esta página lista todos os módulos carregados no processo principal e os módulos registados para serem carregados mais tarde.</translation> <translation id="166179487779922818">A palavra-passe é demasiado curta.</translation> @@ -477,6 +477,7 @@ <translation id="16815041330799488">Não permitir que os sites vejam o texto e as imagens copiados para a área de transferência</translation> <translation id="1682548588986054654">Nova janela de navegação anónima</translation> <translation id="168715261339224929">Para obter os seus marcadores em todos os dispositivos, ative a sincronização.</translation> +<translation id="1688867105868176567">Pretende limpar os dados do site?</translation> <translation id="1688935057616748272">Introduza uma letra.</translation> <translation id="168991973552362966">Adicionar uma impressora próxima</translation> <translation id="1689945336726856614">Copiar &URL</translation> @@ -488,7 +489,6 @@ <translation id="1701062906490865540">Remover esta pessoa</translation> <translation id="1706586824377653884">Adicionado pelo gestor</translation> <translation id="1706625117072057435">Níveis de zoom</translation> -<translation id="1707463636381878959">Partilhar esta rede com outros utilizadores</translation> <translation id="1708338024780164500">(Inativa)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativa)</translation> @@ -524,7 +524,6 @@ <translation id="175772926354468439">Ativar tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Ver na Web Store do Chrome</translation> -<translation id="1758831820837444715">Configurar rede Ethernet</translation> <translation id="1763046204212875858">Criar atalhos da aplicação</translation> <translation id="1763108912552529023">Continuar a explorar</translation> <translation id="1763808908432309942">Abre-se num novo separador.</translation> @@ -583,8 +582,10 @@ <translation id="1839704667838141620">Alterar a forma como este ficheiro é partilhado</translation> <translation id="1841545962859478868">O gestor do dispositivo pode monitorizar o seguinte:</translation> <translation id="1841705068325380214">A extensão <ph name="EXTENSION_NAME" /> está desativada</translation> +<translation id="1842766183094193446">Tem a certeza de que pretende ativar o modo de demonstração?</translation> <translation id="1844692022597038441">Este ficheiro não está disponível offline.</translation> <translation id="1846308012215045257">Clique e prima a tecla Ctrl em simultâneo para executar o <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Guardado</translation> <translation id="1848219224579402567">Terminar sessão quando a tampa for fechada</translation> <translation id="184823282865851239">Bloquear se o site tiver tendência para mostrar anúncios intrusivos</translation> <translation id="1849186935225320012">Esta página tem controlo total sobre dispositivos MIDI.</translation> @@ -682,6 +683,7 @@ <translation id="200544492091181894">Pode alterar esta opção mais tarde nas definições.</translation> <translation id="2006638907958895361">Abrir link na aplicação <ph name="APP" /></translation> <translation id="2007404777272201486">Comunicar um problema...</translation> +<translation id="2016237810978710652">A abrir ficheiros Linux…</translation> <translation id="2016430552235416146">Tradicional</translation> <translation id="2017334798163366053">Desativar a recolha de dados de desempenho</translation> <translation id="2017836877785168846">Limpa o histórico e os preenchimentos automáticos da barra de endereço.</translation> @@ -776,6 +778,7 @@ <translation id="2154484045852737596">Editar cartão</translation> <translation id="2154710561487035718">Copiar URL</translation> <translation id="2155772377859296191">Parece ter <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Pode ajudar a melhorar a Navegação segura ao enviar algumas informações do sistema e conteúdo da página para a Google.</translation> <translation id="215753907730220065">Sair do modo de ecrã inteiro</translation> <translation id="2157875535253991059">Esta página está agora em ecrã inteiro.</translation> <translation id="216169395504480358">Adicionar Wi-Fi...</translation> @@ -785,6 +788,7 @@ <translation id="2173801458090845390">Adicionar ID de requisição a este dispositivo</translation> <translation id="2175042898143291048">Fazer sempre isto</translation> <translation id="2175607476662778685">Barra de início rápido</translation> +<translation id="2176087259161165020">Outras fontes</translation> <translation id="2177950615300672361">Separador de navegação anónima: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">O <ph name="PEPPER_PLUGIN_NAME" /> em <ph name="PEPPER_PLUGIN_DOMAIN" /> pretende aceder ao seu computador.</translation> <translation id="2178614541317717477">AC comprometida</translation> @@ -868,7 +872,6 @@ <translation id="2291643155573394834">Separador seguinte</translation> <translation id="2292848386125228270">Inicie o <ph name="PRODUCT_NAME" /> como um utilizador normal. Se precisar de executar com acesso máximo para programação, volte a executar com a sinalização --no-sandbox.</translation> <translation id="2294358108254308676">Pretende instalar o <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Método EAP:</translation> <translation id="2297705863329999812">Pesquisar impressoras</translation> <translation id="2300383962156589922">Personalizar e controlar a aplicação <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">O directório de raiz da extensão é inválido.</translation> @@ -916,6 +919,7 @@ <translation id="2366463953911599217">ERRO: falha ao desinstalar a aplicação <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Adicionar partilha de ficheiros</translation> <translation id="2367972762794486313">Mostrar aplicações</translation> +<translation id="2369536625682139252">Todos os dados armazenados pelo site <ph name="SITE" /> serão eliminados, exceto os cookies.</translation> <translation id="2371076942591664043">Abrir quando estiver concluí&do</translation> <translation id="2377319039870049694">Mudar para a vista de lista</translation> <translation id="2377667304966270281">Falhas de hardware</translation> @@ -925,7 +929,6 @@ <translation id="2379281330731083556">Imprimir utilizando a caixa de diálogo do sistema... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Perguntar antes de enviar (recomendado)</translation> <translation id="2384436799579181135">Ocorreu um erro. Verifique a impressora e tente novamente.</translation> -<translation id="2385700042425247848">Nome do serviço:</translation> <translation id="2387458720915042159">Tipo de ligação proxy</translation> <translation id="2391419135980381625">Tipo de letra padrão</translation> <translation id="2391762656119864333">Revogar</translation> @@ -976,7 +979,6 @@ <translation id="247949520305900375">Partilhar áudio</translation> <translation id="2480868415629598489">Modificar os dados que copia e cola</translation> <translation id="2482878487686419369">Notificações</translation> -<translation id="2485056306054380289">Certificado AC do servidor:</translation> <translation id="2485422356828889247">Desinstalar</translation> <translation id="2487067538648443797">Adicionar novo marcador</translation> <translation id="248861575772995840">Não é possível localizar o telemóvel. Certifique-se de que o Bluetooth de <ph name="DEVICE_TYPE" /> está ativado. <a>Saiba mais</a></translation> @@ -1037,6 +1039,7 @@ <translation id="2566124945717127842">Efetue um Powerwash para repor o dispositivo <ph name="IDS_SHORT_PRODUCT_NAME" /> e deixá-lo como novo.</translation> <translation id="2567257616420533738">Palavra-passe guardada. Veja e faça a gestão das palavras-passe guardadas em <ph name="SAVED_PASSWORDS_LINK" />.</translation> <translation id="2568774940984945469">Contentor da Barra de informações</translation> +<translation id="2570454805927264159">Tirar o máximo proveito do seu Assistente</translation> <translation id="257088987046510401">Temas</translation> <translation id="2572032849266859634">Autorizações só de leitura concedidas a <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Escolha uma foto e um nome</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">Submeter</translation> <translation id="265390580714150011">Campo Valor</translation> <translation id="2654166010170466751">Permitir que os sites instalem controladores de pagamentos</translation> -<translation id="2655386581175833247">Certificado de utilizador:</translation> <translation id="2660779039299703961">Evento</translation> <translation id="266079277508604648">Não é possível ligar à impressora. Verifique se a impressora está ligada e associada ao Chromebook por Wi-Fi ou USB.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1334,6 +1336,7 @@ <translation id="3006881078666935414">Sem dados de utilização</translation> <translation id="3007214526293698309">Corrigir proporção</translation> <translation id="3007771295016901659">Duplicar o separador</translation> +<translation id="3008272652534848354">Repor autorizações</translation> <translation id="3009300415590184725">Tem a certeza de que pretende cancelar o processo de configuração do serviço de dados móveis?</translation> <translation id="3009779501245596802">Bases de dados indexadas</translation> <translation id="3010279545267083280">Palavra-passe eliminada</translation> @@ -1400,7 +1403,6 @@ <translation id="3100609564180505575">Módulos (<ph name="TOTAL_COUNT" />) – Conflitos conhecidos: <ph name="BAD_COUNT" />, suspeitos: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Data e hora</translation> <translation id="310671807099593501">O site está a utilizar o Bluetooth.</translation> -<translation id="3108967419958202225">Escolher...</translation> <translation id="3115128645424181617">Não é possível localizar o telemóvel. Certifique-se de que o mesmo está próximo e que o Bluetooth está ativado.</translation> <translation id="3115147772012638511">A aguardar pela cache...</translation> <translation id="3118319026408854581">Ajuda do <ph name="PRODUCT_NAME" /></translation> @@ -1445,7 +1447,6 @@ <translation id="3165390001037658081">Alguns operadores podem bloquear esta funcionalidade.</translation> <translation id="316854673539778496">Para obter todas as suas extensões em todos os dispositivos, inicie sessão e ative a sincronização.</translation> <translation id="3170072451822350649">Também pode ignorar o início de sessão e <ph name="LINK_START" />navegar como Convidado<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Clicar para ocultar a palavra-passe</translation> <translation id="3177909033752230686">Idioma da página:</translation> <translation id="3181110748548073003">Prima |<ph name="SHORTCUT" />| para avançar</translation> <translation id="3182749001423093222">Verificação ortográfica</translation> @@ -1476,7 +1477,6 @@ <translation id="3236289833370040187">A propriedade será transferida para <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Abrir opções de extensão</translation> <translation id="3241680850019875542">Selecione o directório raiz da extensão a comprimir. Para atualizar uma extensão, selecione também o ficheiro de chave privada a reutilizar.</translation> -<translation id="3242765319725186192">Chave pré-partilhada:</translation> <translation id="3244294424315804309">Manter o som desativado</translation> <translation id="3245321423178950146">Artista Desconhecido</translation> <translation id="3246097286174000800">Experimentar o Smart Lock</translation> @@ -1609,7 +1609,6 @@ <translation id="3440663250074896476">Mais ações para <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Perguntar quando um site pretender utilizar um plug-in para aceder ao seu computador</translation> <translation id="3441653493275994384">Ecrã</translation> -<translation id="3445830502289589282">Autenticação da fase 2:</translation> <translation id="344630545793878684">Ler os seus dados em vários Sites</translation> <translation id="3449839693241009168">Prima <ph name="SEARCH_KEY" /> para enviar comandos para <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Percentagem de ocupação no estado inativo</translation> @@ -1650,7 +1649,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> erros.</translation> <translation id="3495660573538963482">Definições do Assistente Google</translation> <translation id="3496213124478423963">Reduzir</translation> -<translation id="3504135463003295723">Nome do grupo:</translation> <translation id="3505030558724226696">Revogar acesso aos dispositivos</translation> <translation id="3507421388498836150">Autorizações atuais para "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Remover aplicações do Linux do Chromebook</translation> @@ -1759,7 +1757,6 @@ <translation id="3661054927247347545">A certificação do início de sessão não é válida. A janela será fechada dentro de <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ícone da extensão</translation> <translation id="3665589677786828986">O Chrome detetou que algumas das suas definições foram danificadas por outro programa e repôs as respetivas predefinições originais.</translation> -<translation id="3665842570601375360">Segurança:</translation> <translation id="3668570675727296296">Definições de idioma</translation> <translation id="3668823961463113931">Processadores</translation> <translation id="3670229581627177274">Ativar o Bluetooth</translation> @@ -1798,7 +1795,6 @@ <translation id="3726463242007121105">Não é possível abrir este aparelho porque o sistema de ficheiros não é suportado.</translation> <translation id="3727148787322499904">Alterar esta definição afetará todas as redes partilhadas</translation> <translation id="3727187387656390258">Inspeccionar pop-up</translation> -<translation id="3728067901555601989">Palavra-passe de Utilização Única:</translation> <translation id="3732078975418297900">Erro na linha <ph name="ERROR_LINE" />.</translation> <translation id="3733127536501031542">Servidor SSL com "Step-up"</translation> <translation id="3737536731758327622">As suas transferências aparecem aqui</translation> @@ -1873,7 +1869,6 @@ <translation id="38275787300541712">Prima Enter quando terminar</translation> <translation id="3827774300009121996">&Ecrã inteiro</translation> <translation id="3828029223314399057">Pesquisar marcadores</translation> -<translation id="3829932584934971895">Tipo de fornecedor:</translation> <translation id="3830674330436234648">Reprodução não disponível</translation> <translation id="3831486154586836914">Modo de vista geral de janelas introduzido</translation> <translation id="383161972796689579">O proprietário deste dispositivo desativou a adição de novos utilizadores</translation> @@ -1894,6 +1889,7 @@ <translation id="3856921555429624101">A medição da utilização de dados terminou</translation> <translation id="3857228364945137633">Experimente o Smart Lock para desbloquear o <ph name="DEVICE_TYPE" /> sem palavra-passe quando o seu telemóvel estiver próximo.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: sincronização em pausa</translation> <translation id="3860381078714302691">Bem-vindo ao Hangouts Meet</translation> <translation id="3862134173397075045">Bem-vindo à experiência do Google Cast no Chrome!</translation> <translation id="3862788408946266506">É necessário instalar a aplicação com o atributo de manifesto "kiosk_only" no modo quiosque do Chrome OS.</translation> @@ -1971,7 +1967,6 @@ <translation id="3968261067169026421">Não foi possível configurar a rede</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">A calcular...</translation> -<translation id="3974195870082915331">Clicar para mostrar a palavra-passe</translation> <translation id="3975222297214566386">Balão de opções de introdução</translation> <translation id="397703832102027365">A finalizar...</translation> <translation id="3979395879372752341">Nova extensão adicionada (<ph name="EXTENSION_NAME" />)</translation> @@ -2013,6 +2008,7 @@ <translation id="4044612648082411741">Introduzir a palavra-passe do certificado</translation> <translation id="404493185430269859">Motor de pesquisa predefinido</translation> <translation id="4047112090469382184">Por que é que é seguro</translation> +<translation id="4051049974203704184">Obter informações sobre o que está no ecrã</translation> <translation id="4052120076834320548">Minúsculo</translation> <translation id="4055023634561256217">É necessário reiniciar antes de ser possível repor o dispositivo com o Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2041,6 +2037,7 @@ <translation id="4088095054444612037">Aceitar para o grupo</translation> <translation id="4089235344645910861">Definições guardadas. A sincronização foi iniciada.</translation> <translation id="4090103403438682346">Ativar acesso confirmado</translation> +<translation id="4090947011087001172">Pretende repor as autorizações de sites para <ph name="SITE" />?</translation> <translation id="4091434297613116013">folhas de papel</translation> <translation id="4093955363990068916">Ficheiro local:</translation> <translation id="4095507791297118304">Ecrã principal</translation> @@ -2217,7 +2214,6 @@ <translation id="4419556793104466535">Controlar a sincronização, a personalização e muito mais</translation> <translation id="4421932782753506458">Fofo</translation> <translation id="4422347585044846479">Editar marcador para esta página</translation> -<translation id="4423104065312875417">Instalar motores de voz adicionais</translation> <translation id="4423376891418188461">Restaurar definições</translation> <translation id="4423482519432579560">&Verificação ortográfica</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, o seu gestor requer que altere a sua palavra-passe.</translation> @@ -2242,7 +2238,6 @@ <translation id="4449996769074858870">Este separador está a reproduzir áudio.</translation> <translation id="4450974146388585462">Diagnosticar</translation> <translation id="4453946976636652378">Procurar no <ph name="SEARCH_ENGINE_NAME" /> ou introduzir um URL</translation> -<translation id="445923051607553918">Ligar a uma rede Wi-Fi</translation> <translation id="4462159676511157176">Servidores de nome personalizado</translation> <translation id="4467100756425880649">Galeria da Web Store do Chrome</translation> <translation id="4467101674048705704">Expandir a pasta <ph name="FOLDER_NAME" /></translation> @@ -2378,6 +2373,7 @@ <translation id="4682551433947286597">As imagens de fundo aparecem no Ecrã de início de sessão.</translation> <translation id="4684427112815847243">Sincronizar tudo</translation> <translation id="4689421377817139245">Sincronizar este marcador com o seu iPhone</translation> +<translation id="4690091457710545971"><Quatro ficheiros gerados pelo firmware de Wi-Fi da Intel: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Os três primeiros são ficheiros binários que contêm cópias do registo e são confirmados pela Intel como não contendo informações identificativas do dispositivo ou pessoais. O último ficheiro é um rastreio de execução do firmware da Intel; foram dele removidas quaisquer informações identificativas do dispositivo ou pessoais, mas é demasiado grande para apresentar aqui. Estes ficheiros foram gerados como resposta aos recentes problemas de Wi-Fi do seu dispositivo e serão partilhados com a Intel para ajudar a resolver estes problemas.></translation> <translation id="4692302215262324251">O seu <ph name="DEVICE_TYPE" /> foi inscrito com êxito para gestão empresarial por <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Se isto não for o esperado, contacte o apoio técnico.</translation> @@ -2637,6 +2633,7 @@ <translation id="5074318175948309511">Poderá ser necessário voltar a atualizar esta página antes de aplicar as novas definições.</translation> <translation id="5075131525758602494">Introduzir PIN do cartão SIM</translation> <translation id="5078638979202084724">Adicionar todos os separadores aos marcadores</translation> +<translation id="5079950360618752063">Utilizar palavra-passe sugerida</translation> <translation id="5084230410268011727">Autorizar que os sites utilizem sensores de movimento e de luz</translation> <translation id="5085162214018721575">A verificar existência de atualizações</translation> <translation id="5086082738160935172">HID</translation> @@ -2675,6 +2672,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Eliminar este item</translation> <translation id="5139955368427980650">&Abrir</translation> +<translation id="5142961317498132443">Autenticação</translation> <translation id="5143374789336132547">A extensão "<ph name="EXTENSION_NAME" />" alterou a página apresentada quando clica no botão Página inicial.</translation> <translation id="5143712164865402236">Entrar no modo de ecrã inteiro</translation> <translation id="5145331109270917438">Data de modificação</translation> @@ -2845,7 +2843,6 @@ <translation id="5380103295189760361">Mantenha premido Control, Alt, Shift ou a Tecla de Pesquisa para ver atalhos de teclado para esses modificadores.</translation> <translation id="5382591305415226340">Gerir links suportados</translation> <translation id="5384883051496921101">Este site está prestes a partilhar informações com uma aplicação fora do modo de navegação anónima.</translation> -<translation id="5388588172257446328">Nome de utilizador:</translation> <translation id="5388885445722491159">Emparelhado</translation> <translation id="5389237414310520250">Não foi possível criar o novo utilizador. Verifique o espaço no disco rígido e as autorizações e tente novamente.</translation> <translation id="5390100381392048184">Permitir que os sites reproduzam som</translation> @@ -2970,7 +2967,6 @@ <translation id="5551573675707792127">Teclado e introdução de texto</translation> <translation id="5553089923092577885">Mapeamentos de políticas de certificados</translation> <translation id="5554489410841842733">Este ícone estará visível se for possível utilizar a extensão na página actual.</translation> -<translation id="5554573843028719904">Outra rede Wi-Fi...</translation> <translation id="5554720593229208774">Autoridade de certificação de e-mails</translation> <translation id="5556206011531515970">Clique em seguinte para escolher o seu navegador predefinido.</translation> <translation id="5556459405103347317">Recarregar</translation> @@ -3011,7 +3007,6 @@ <translation id="5610038042047936818">Mudar para modo de câmara</translation> <translation id="5612720917913232150"><ph name="URL" /> pretende utilizar a localização do seu computador.</translation> <translation id="5612734644261457353">Lamentamos, mas não foi possível confirmar a sua palavra-passe. Nota: se alterou a palavra-passe recentemente, a nova palavra-passe será aplicada quando terminar sessão. Utilize a palavra-passe antiga aqui.</translation> -<translation id="5613695965848159202">Identidade anónima:</translation> <translation id="5614190747811328134">Aviso ao utilizador</translation> <translation id="561698261642843490">Fechar Firefox</translation> <translation id="5618075537869101857">Raios, não foi possível iniciar a aplicação de quiosque.</translation> @@ -3230,7 +3225,6 @@ <translation id="5941343993301164315">Inicie sessão em <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimizar</translation> <translation id="5946591249682680882">ID do relatório <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Adicionar rede privada</translation> <translation id="5949544233750246342">Não é possível analisar o ficheiro</translation> <translation id="5955282598396714173">A sua palavra-passe expirou. Termine e inicie sessão novamente para a alterar.</translation> <translation id="5956585768868398362">É esta a página de pesquisa de que estava à espera?</translation> @@ -3391,11 +3385,13 @@ <translation id="6198102561359457428">Terminar sessão e, em seguida, iniciar sessão novamente...</translation> <translation id="6198252989419008588">Alterar PIN</translation> <translation id="6199801702437275229">A aguardar informações de espaço...</translation> +<translation id="6204015976622790023">Veja sugestões relevantes do seu Assistente relacionadas com o que está no ecrã.</translation> <translation id="6205710420833115353">Algumas operações estão a demorar mais tempo do que o previsto. Pretende interrompê-las?</translation> <translation id="6206311232642889873">Cop&iar Imagem</translation> <translation id="6207200176136643843">Repor o nível de zoom predefinido</translation> <translation id="620722923698527029">Abrir sempre estes tipos de link na aplicação associada</translation> <translation id="6207937957461833379">País/Região</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: a sincronização não está a funcionar</translation> <translation id="6212039847102026977">Mostrar propriedades de rede avançadas</translation> <translation id="6212168817037875041">Desligar o ecrã</translation> <translation id="6212752530110374741">Enviar link por email</translation> @@ -3433,7 +3429,6 @@ <translation id="6263541650532042179">Redefinir sincronização</translation> <translation id="6264365405983206840">Seleccion&ar Tudo</translation> <translation id="6264422956566238156">Ativou a sincronização</translation> -<translation id="6265930187414222160">Concluído. Software prejudicial removido.</translation> <translation id="6267166720438879315">Seleccione um certificado para se autenticar perante <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Abrir com <ph name="APP" /></translation> <translation id="6268747994388690914">Importar Marcadores de Ficheiro HTML...</translation> @@ -3540,7 +3535,6 @@ Clique em "Seguinte" para continuar a iniciar sessão na sua conta de <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Carregar expandida</translation> <translation id="642282551015776456">Este nome não pode ser utilizado como um nome de ficheiro ou de pasta</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Abrir as definições do ChromeVox</translation> <translation id="6429384232893414837">Atualizar erro</translation> <translation id="6430814529589430811">Certificado único, ASCII codificado em Base64</translation> @@ -3621,7 +3615,6 @@ <translation id="6544215763872433504">O navegador de Internet da Google, para si</translation> <translation id="6545665334409411530">Taxa de repetição</translation> <translation id="6545834809683560467">Utilize um serviço de previsão para ajudar a concluir as pesquisas e os URLs introduzidos na barra de endereço ou na caixa de pesquisa do iniciador de aplicações</translation> -<translation id="6546686722964485737">Aderir à rede WiMAX</translation> <translation id="6547316139431024316">Não avisar novamente para esta extensão</translation> <translation id="6547354035488017500">Liberte, pelo menos, 512 MB de espaço ou o seu dispositivo deixa de responder. Para libertar espaço, elimine ficheiros do armazenamento do dispositivo.</translation> <translation id="6549689063733911810">Recente</translation> @@ -4040,7 +4033,6 @@ <translation id="7201014958346994077">Não é possível ver os Ficheiros Linux.</translation> <translation id="720110658997053098">Manter este dispositivo permanentemente no modo quiosque</translation> <translation id="7201118060536064622">"<ph name="DELETED_ITEM_NAME" />" eliminado</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">A transferir <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Sair da página}other{Sair das páginas}}</translation> <translation id="7216409898977639127">Operador de telemóvel</translation> @@ -4518,7 +4510,6 @@ <translation id="7909969815743704077">Transferido em modo de navegação anónima</translation> <translation id="7910768399700579500">&Nova pasta</translation> <translation id="7912080627461681647">A sua palavra-passe foi alterada no servidor. Termine e inicie sessão novamente.</translation> -<translation id="7912883689016444961">Configurar rede móvel</translation> <translation id="7915471803647590281">Indique-nos o que está a acontecer antes de enviar os comentários.</translation> <translation id="7916556741383518510">Ao clicar</translation> <translation id="792514962475806987">Nível de zoom da lupa ancorada:</translation> @@ -4572,7 +4563,6 @@ <translation id="7988355189918024273">Activar funcionalidades de acessibilidade</translation> <translation id="7994702968232966508">Método EAP</translation> <translation id="799547531016638432">Remover atalho</translation> -<translation id="7997479212858899587">Identidade:</translation> <translation id="7997826902155442747">Prioridade do processo</translation> <translation id="7999229196265990314">Criou os seguintes ficheiros: @@ -4656,7 +4646,6 @@ <translation id="8105368624971345109">Desativar</translation> <translation id="8106045200081704138">Partilhado comigo</translation> <translation id="8107015733319732394">A instalar a Google Play Store no <ph name="DEVICE_TYPE" />… Esta ação pode demorar alguns minutos.</translation> -<translation id="8109930990200908494">Início de sessão necessário para o certificado do utilizador.</translation> <translation id="8111155949205007504">Partilhar esta palavra-passe com o seu iPhone</translation> <translation id="8113043281354018522">Selecionar o tipo de licença</translation> <translation id="8116190140324504026">Mais informações...</translation> @@ -4667,6 +4656,7 @@ <translation id="8118860139461251237">Gerir as transferências</translation> <translation id="81238879832906896">Flor amarela e branca</translation> <translation id="8124313775439841391">ONC gerido</translation> +<translation id="8125562866093998907">O site pretende validar a sua Chave de segurança para aumentar a segurança da sua conta.</translation> <translation id="813082847718468539">Ver informações do Web site</translation> <translation id="8131740175452115882">Confirmar</translation> <translation id="8133676275609324831">&Mostrar numa pasta</translation> @@ -4777,7 +4767,6 @@ <translation id="8308179586020895837">Perguntar se <ph name="HOST" /> pretende aceder à sua câmara</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">O certificado já existe</translation> -<translation id="8309505303672555187">Selecionar uma rede:</translation> <translation id="8312871300878166382">Colar numa pasta</translation> <translation id="8317671367883557781">Adicionar ligação de rede</translation> <translation id="8319414634934645341">Utilização alargada da chave</translation> @@ -4852,7 +4841,6 @@ <translation id="8451512073679317615">assistente</translation> <translation id="8452135315243592079">Cartão SIM em falta</translation> <translation id="8453482423012550001">A copiar $1 itens...</translation> -<translation id="8454288007744638700">Em alternativa, selecione uma nova rede:</translation> <translation id="845627346958584683">Prazo de validade</translation> <translation id="8456681095658380701">Nome inválido</translation> <translation id="8457451314607652708">Importar marcadores</translation> @@ -4916,6 +4904,7 @@ <translation id="855081842937141170">Fixar separador</translation> <translation id="8551388862522347954">Licenças</translation> <translation id="8553342806078037065">Gerir outras pessoas</translation> +<translation id="8554899698005018844">Nenhum idioma</translation> <translation id="855773602626431402">A execução de um plug-in sem isolamento de processos foi impedida nesta página.</translation> <translation id="8557930019681227453">Manifesto</translation> <translation id="8559694214572302298">Descodificador de imagem</translation> @@ -4953,7 +4942,6 @@ <translation id="862727964348362408">Suspenso</translation> <translation id="862750493060684461">Cache CSS</translation> <translation id="8627795981664801467">Apenas ligações seguras</translation> -<translation id="8628085465172583869">Nome de anfitrião do servidor:</translation> <translation id="8630903300770275248">Importar utilizador supervisionado</translation> <translation id="8631032106121706562">Pétalas</translation> <translation id="8637542770513281060">O seu computador contém um módulo seguro, que é utilizado para implementar várias funcionalidades de segurança essenciais no Chrome OS. Aceda ao Centro de Ajuda do Chromebook em https://support.google.com/chromebook/?p=sm para saber mais.</translation> @@ -5209,7 +5197,6 @@ <translation id="899403249577094719">URL base do certificado Netscape</translation> <translation id="8995603266996330174">Gerido por <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Adicionar conta...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [ <ph name="ISSUED_TO" /> ] ( <ph name="DEVICE" /> )</translation> <translation id="8998788483361403036">A criar a imagem do disco...</translation> <translation id="9003647077635673607">Permitir em todos os Sites</translation> <translation id="9003677638446136377">Verificar novamente</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb index 2056bb9..b6b0f18 100644 --- a/chrome/app/resources/generated_resources_ro.xtb +++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">Codul PUK</translation> <translation id="1061904396131502319">Se apropie timpul pentru o pauză</translation> <translation id="1062407476771304334">Înlocuiți</translation> -<translation id="1064835277883315402">Alăturați-vă rețelei private</translation> <translation id="1064912851688322329">Deconectați Contul dvs. Google</translation> <translation id="1067048845568873861">Creat</translation> <translation id="1067291318998134776">Linux (beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Se caută...</translation> <translation id="1316495628809031177">Sincronizarea este întreruptă</translation> <translation id="1319979322914001937">O aplicație care afișează o listă filtrată de extensii din Magazinul web Chrome. Extensiile din listă pot fi instalate direct din aplicație.</translation> -<translation id="132090119144658135">Potrivirea subiectului:</translation> <translation id="1326317727527857210">Pentru a accesa filele de pe alte dispozitive, conectează-te la Chrome.</translation> <translation id="1327074568633507428">Imprimantă în Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Fereastra aplicației</translation> <translation id="1534389735079119190">EROARE: Nu s-a putut porni containerul în VM.</translation> <translation id="15373452373711364">Cursor de mouse mare</translation> +<translation id="1540605929960647700">Activează modul demonstrativ</translation> <translation id="1543284117603151572">Importate din Edge</translation> <translation id="1545177026077493356">Mod chioșc automat</translation> <translation id="1545775234664667895">S-a instalat tema „<ph name="THEME_NAME" />”</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Trimite automat statistici de utilizare și rapoarte de blocare la Google pentru a contribui la îmbunătățirea <ph name="PRODUCT_NAME" />.</translation> <translation id="1658424621194652532">Această pagină vă accesează microfonul.</translation> <translation id="1660204651932907780">Permite site-urilor să redea sunet (recomandat)</translation> +<translation id="1660938185063657230">Verifică Cheia de securitate</translation> <translation id="1661156625580498328">Aplică criptarea AES (recomandat).</translation> <translation id="1661245713600520330">Această pagină afișează toate modulele încărcate în procesul principal și modulele înregistrate pentru a se încărca ulterior.</translation> <translation id="166179487779922818">Parola este prea scurtă.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Nu permite site-urilor să vadă textul și imaginile copiate în clipboard</translation> <translation id="1682548588986054654">Fereastră &incognito nouă</translation> <translation id="168715261339224929">Pentru a accesa marcajele pe toate dispozitivele, activează sincronizarea.</translation> +<translation id="1688867105868176567">Ștergi datele site-ului?</translation> <translation id="1688935057616748272">Tastează o literă</translation> <translation id="168991973552362966">Adaugă o imprimantă din apropiere</translation> <translation id="1689945336726856614">Copiază adresa &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Elimină această persoană</translation> <translation id="1706586824377653884">Adăugat de administrator</translation> <translation id="1706625117072057435">Niveluri de zoom</translation> -<translation id="1707463636381878959">Permite accesul la această rețea altor utilizatori</translation> <translation id="1708338024780164500">(Inactivă)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativă)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Activați tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Vezi în Magazinul web Chrome</translation> -<translation id="1758831820837444715">Configurați rețeaua Ethernet</translation> <translation id="1763046204212875858">Creează comenzi rapide pentru aplicație</translation> <translation id="1763108912552529023">Explorați în continuare</translation> <translation id="1763808908432309942">Se deschide într-o filă nouă</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Modifică modul în care se permite accesul la acest fișier</translation> <translation id="1841545962859478868">Este posibil ca administratorul dispozitivului să monitorizeze următoarele:</translation> <translation id="1841705068325380214">Extensia <ph name="EXTENSION_NAME" /> este dezactivată</translation> +<translation id="1842766183094193446">Sigur vrei să activezi modul demonstrativ?</translation> <translation id="1844692022597038441">Acest fișier nu este disponibil offline.</translation> <translation id="1846308012215045257">Dă control-clic pentru a rula <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">S-a salvat</translation> <translation id="1848219224579402567">Când capacul este închis: deconectare</translation> <translation id="184823282865851239">Blochează dacă site-ul tinde să afișeze anunțuri deranjante</translation> <translation id="1849186935225320012">Această pagină are control complet asupra dispozitivelor MIDI.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Poți modifica ulterior această opțiune în Setări</translation> <translation id="2006638907958895361">Deschide linkul în <ph name="APP" /></translation> <translation id="2007404777272201486">Raportează o problemă...</translation> +<translation id="2016237810978710652">Se deschid fișierele Linux...</translation> <translation id="2016430552235416146">Tradițională</translation> <translation id="2017334798163366053">Dezactivați culegerea datelor privind performanța</translation> <translation id="2017836877785168846">Șterge istoricul și completările automate din bara de adrese.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Editează cardul</translation> <translation id="2154710561487035718">Copiați adresa URL</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Ne poți ajuta să îmbunătățim Navigarea sigură dacă trimiți la Google anumite informații despre sistem și conținutul paginii.</translation> <translation id="215753907730220065">Ieși din ecranul complet</translation> <translation id="2157875535253991059">Acum această pagină este în modul ecran complet.</translation> <translation id="216169395504480358">Adăugați o rețea Wi-Fi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Adaugă ID-ul de solicitare la acest dispozitiv</translation> <translation id="2175042898143291048">Tradu întotdeauna</translation> <translation id="2175607476662778685">Bara Lansare rapidă</translation> +<translation id="2176087259161165020">Alte surse</translation> <translation id="2177950615300672361">Fila Incognito: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Pluginul <ph name="PEPPER_PLUGIN_NAME" /> de pe <ph name="PEPPER_PLUGIN_DOMAIN" /> dorește să acceseze computerul</translation> <translation id="2178614541317717477">Compromitere CA</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Fila următoare</translation> <translation id="2292848386125228270">Pornește <ph name="PRODUCT_NAME" /> ca utilizator normal. Pentru a rula cu privilegii de utilizator root pentru dezvoltare, rulează-l din nou cu marcajul --no-sandbox.</translation> <translation id="2294358108254308676">Doriți să instalezi <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Metodă EAP:</translation> <translation id="2297705863329999812">Caută imprimante</translation> <translation id="2300383962156589922">Personalizează și controlează <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Directorul rădăcină pentru extensie este nevalid.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">EROARE: nu s-a putut dezinstala <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Adaugă un dispozitiv de stocare în rețea</translation> <translation id="2367972762794486313">Afișați aplicații</translation> +<translation id="2369536625682139252">Toate datele stocate de <ph name="SITE" /> vor fi șterse, cu excepția cookie-urilor.</translation> <translation id="2371076942591664043">Deschide când s-a &descărcat</translation> <translation id="2377319039870049694">Comută la afișarea listă</translation> <translation id="2377667304966270281">Erori de hardware</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Printați utilizând caseta de dialog a sistemului... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Solicită permisiunea înainte de trimitere (recomandat)</translation> <translation id="2384436799579181135">A apărut o eroare. Verifică imprimanta și încearcă din nou.</translation> -<translation id="2385700042425247848">Nume serviciu:</translation> <translation id="2387458720915042159">Tip de conexiune prin proxy</translation> <translation id="2391419135980381625">Font standard</translation> <translation id="2391762656119864333">Revocați</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Trimite conținutul audio</translation> <translation id="2480868415629598489">Modifică datele pe care le copiezi și le inserezi</translation> <translation id="2482878487686419369">Notificări</translation> -<translation id="2485056306054380289">Certificat CA server:</translation> <translation id="2485422356828889247">Dezinstalează</translation> <translation id="2487067538648443797">Adaugă un marcaj nou</translation> <translation id="248861575772995840">Telefonul nu poate fi găsit. Asigură-te că dispozitivul <ph name="DEVICE_TYPE" /> are conexiunea Bluetooth activată. <a>Află mai multe</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Folosiți Powerwash pentru a reseta dispozitivul <ph name="IDS_SHORT_PRODUCT_NAME" /> la configurația din fabrică.</translation> <translation id="2567257616420533738">Parola a fost salvată. Vezi și gestionează parolele salvate la <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Container bară de informații</translation> +<translation id="2570454805927264159">Profită la maximum de Asistent</translation> <translation id="257088987046510401">Teme</translation> <translation id="2572032849266859634">A fost acordat accesul numai în citire la <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Alegeți o imagine și un nume</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Trimite</translation> <translation id="265390580714150011">Valoarea câmpului</translation> <translation id="2654166010170466751">Permite site-urilor să instaleze handlere pentru plăți</translation> -<translation id="2655386581175833247">Certificat de utilizator:</translation> <translation id="2660779039299703961">Eveniment</translation> <translation id="266079277508604648">Nu se poate conecta imprimanta. Asigură-te că este pornită și conectată la Chromebook prin Wi-Fi sau USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Nu există date de utilizare</translation> <translation id="3007214526293698309">Remediază raportul de dimensiuni</translation> <translation id="3007771295016901659">Duplică fila</translation> +<translation id="3008272652534848354">Resetează permisiunile</translation> <translation id="3009300415590184725">Sigur doriți să anulați procesul de configurare al serviciului de date mobile?</translation> <translation id="3009779501245596802">Baze de date indexate</translation> <translation id="3010279545267083280">Parolă ștearsă</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Module (<ph name="TOTAL_COUNT" />) – Conflicte cunoscute: <ph name="BAD_COUNT" />, suspectate: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Data și ora</translation> <translation id="310671807099593501">Site-ul folosește Bluetooth</translation> -<translation id="3108967419958202225">Alege...</translation> <translation id="3115128645424181617">Telefonul nu poate fi găsit. Asigură-te că este la îndemână și că ai activat Bluetooth.</translation> <translation id="3115147772012638511">Se așteaptă cache-ul...</translation> <translation id="3118319026408854581">Ajutor <ph name="PRODUCT_NAME" /></translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Este posibil ca unii operatori să blocheze funcția.</translation> <translation id="316854673539778496">Pentru a accesa toate extensiile pe toate dispozitivele, conectează-te și activează sincronizarea.</translation> <translation id="3170072451822350649">De asemenea, puteți să omiteți conectarea și să <ph name="LINK_START" />navigați ca invitat<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Faceți clic pentru a ascunde parola</translation> <translation id="3177909033752230686">Limba paginii:</translation> <translation id="3181110748548073003">Apasă pe |<ph name="SHORTCUT" />| pentru a naviga înainte</translation> <translation id="3182749001423093222">Verificarea ortografiei</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Calitatea de proprietar va fi transferată către <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Deschide opțiunile pentru extensii</translation> <translation id="3241680850019875542">Selectează directorul rădăcină al extensiei ce trebuie împachetată. Pentru a actualiza o extensie, selectează și fișierul cu cheia privată pentru reutilizare.</translation> -<translation id="3242765319725186192">Cheie distribuită anterior:</translation> <translation id="3244294424315804309">Continuă să dezactivezi sunetul</translation> <translation id="3245321423178950146">Artist necunoscut</translation> <translation id="3246097286174000800">Încearcă Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Mai multe acțiuni pentru <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Întreabă-mă atunci când un site vrea să folosească un plugin să-mi acceseze computerul</translation> <translation id="3441653493275994384">Ecran</translation> -<translation id="3445830502289589282">Autentificarea din a doua fază:</translation> <translation id="344630545793878684">Citește datele de pe un număr de site-uri</translation> <translation id="3449839693241009168">Apasă pe <ph name="SEARCH_KEY" /> pentru a trimite comenzi la <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Procentaj de ocupare în starea inactivă</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> erori.</translation> <translation id="3495660573538963482">Setări Asistent Google</translation> <translation id="3496213124478423963">Micșorează</translation> -<translation id="3504135463003295723">Numele grupului:</translation> <translation id="3505030558724226696">Revocă accesul la dispozitiv</translation> <translation id="3507421388498836150">Permisiuni actuale pentru „<ph name="EXTENSION_NAME" />”</translation> <translation id="3507547268929739059">Elimină aplicațiile Linux pentru Chromebook</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Certificatul de conectare nu este valid; fereastra se închide în <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Pictograma extensiei</translation> <translation id="3665589677786828986">Chrome a detectat că unele dintre setări au fost deteriorate de alt program și le-a resetat la valorile inițiale.</translation> -<translation id="3665842570601375360">Securitate:</translation> <translation id="3668570675727296296">Setări de limbă</translation> <translation id="3668823961463113931">Handlere</translation> <translation id="3670229581627177274">Activează Bluetooth</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Acest dispozitiv nu poate fi deschis, deoarece sistemul său de fișiere nu este acceptat.</translation> <translation id="3727148787322499904">Modificarea acestei setări se va aplica tuturor rețelelor folosite în comun</translation> <translation id="3727187387656390258">Fereastră pop-up de inspectare</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Eroare pe linia <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Server SSL cu Step-Up</translation> <translation id="3737536731758327622">Descărcările sunt afișate aici</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Apăsați pe Enter când ați terminat</translation> <translation id="3827774300009121996">&Ecran complet</translation> <translation id="3828029223314399057">Căutați în marcaje</translation> -<translation id="3829932584934971895">Tipul furnizorului:</translation> <translation id="3830674330436234648">Nicio redare disponibilă</translation> <translation id="3831486154586836914">S-a trecut în modul de prezentare a ferestrei</translation> <translation id="383161972796689579">Proprietarul acestui dispozitiv a dezactivat adăugarea de utilizatori noi</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Măsurarea utilizării datelor s-a încheiat</translation> <translation id="3857228364945137633">Încearcă Smart Lock pentru a debloca dispozitivul <ph name="DEVICE_TYPE" /> fără o parolă când telefonul tău este în apropiere.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: sincronizarea a fost întreruptă</translation> <translation id="3860381078714302691">Bun venit la Hangouts Meet</translation> <translation id="3862134173397075045">Bun venit la experiența Cast în Chrome!</translation> <translation id="3862788408946266506">Aplicația cu atributul „kiosk_only” din manifest trebuie să fie instalată în modul chioșc pentru sistemul de operare Chrome</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Această rețea nu a putut fi configurată</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Se calculează...</translation> -<translation id="3974195870082915331">Faceți clic pentru a afișa parola</translation> <translation id="3975222297214566386">Balonul cu opțiunile de introducere a textului</translation> <translation id="397703832102027365">Se finalizează...</translation> <translation id="3979395879372752341">A fost adăugată o extensie (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Introdu parola pentru certificat</translation> <translation id="404493185430269859">Motor de căutare prestabilit</translation> <translation id="4047112090469382184">Ce siguranță oferă</translation> +<translation id="4051049974203704184">Obține informații despre conținutul de pe ecran</translation> <translation id="4052120076834320548">Mic</translation> <translation id="4055023634561256217">Trebuie să reporniți dispozitivul înainte de a fi resetat folosind Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> – <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Acceptă pentru grup</translation> <translation id="4089235344645910861">Setările au fost salvate. Sincronizarea a început.</translation> <translation id="4090103403438682346">Activați Acces verificat</translation> +<translation id="4090947011087001172">Resetezi permisiunile la nivel de site pentru <ph name="SITE" />?</translation> <translation id="4091434297613116013">foi de hârtie</translation> <translation id="4093955363990068916">Fișier local:</translation> <translation id="4095507791297118304">Afișare principală</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Gestionează sincronizarea, personalizarea și altele</translation> <translation id="4421932782753506458">Pufoșel</translation> <translation id="4422347585044846479">Editați marcajul pentru această pagină</translation> -<translation id="4423104065312875417">Instalează motoare de vorbire suplimentare</translation> <translation id="4423376891418188461">Restabilește setările</translation> <translation id="4423482519432579560">&Verificare ortografică</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, administratorul solicită să îți schimbi parola.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Această filă redă fișiere audio.</translation> <translation id="4450974146388585462">Diagnosticați</translation> <translation id="4453946976636652378">Caută <ph name="SEARCH_ENGINE_NAME" /> sau introdu o adresă URL</translation> -<translation id="445923051607553918">Conectează-te la rețeaua Wi-Fi</translation> <translation id="4462159676511157176">Servere de nume personalizate</translation> <translation id="4467100756425880649">Galeria Magazinului web Chrome</translation> <translation id="4467101674048705704">Extinde <ph name="FOLDER_NAME" /></translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Imaginile de fundal apar pe ecranul de conectare.</translation> <translation id="4684427112815847243">Sincronizare totală</translation> <translation id="4689421377817139245">Sincronizează marcajul pe iPhone</translation> +<translation id="4690091457710545971"><Patru fișiere generate de firmware-ul Wi-Fi Intel: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Primele trei sunt fișiere binare care conțin dumpuri de registru, despre care Intel afirmă că nu conțin informații cu caracter personal sau de identificare a dispozitivelor. Ultimul fișier este o urmărire a executării firmware-ului Intel; din acesta au fost eliminate informațiile cu caracter personal sau de identificare a dispozitivelor, dar este prea mare pentru a fi afișat aici. Aceste fișiere au fost generate ca răspuns la problemele recente privind conexiunea Wi-Fi ale dispozitivului și vor fi trimise la Intel în vederea remedierii.></translation> <translation id="4692302215262324251">Dispozitivul <ph name="DEVICE_TYPE" /> a fost înscris pentru gestionarea de întreprindere de <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Dacă acest lucru este neașteptat, contactează asistența.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Este posibil să fie necesară reîncărcarea acestei pagini înainte ca noile setări să se aplice.</translation> <translation id="5075131525758602494">Introdu codul PIN al cardului SIM</translation> <translation id="5078638979202084724">Marchează toate filele</translation> +<translation id="5079950360618752063">Folosește parola sugerată</translation> <translation id="5084230410268011727">Permite folosirea senzorilor de mișcare și de lumină de către site-uri</translation> <translation id="5085162214018721575">Se caută actualizări</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Ștergeți acest articol</translation> <translation id="5139955368427980650">&Deschide</translation> +<translation id="5142961317498132443">Autentificare</translation> <translation id="5143374789336132547">Extensia „<ph name="EXTENSION_NAME" />” a modificat ce pagină se afișează când dai clic pe butonul Pagina principală.</translation> <translation id="5143712164865402236">Deschide în ecran complet</translation> <translation id="5145331109270917438">Data modificării</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Mențineți apăsate tastele Control, Alt, Shift sau Căutare pentru a vedea comenzi rapide de la tastatură pentru respectivele taste de modificare.</translation> <translation id="5382591305415226340">Gestionează linkurile acceptate</translation> <translation id="5384883051496921101">Site-ul este pe cale să permită accesul la informații unei aplicații în afara modului incognito.</translation> -<translation id="5388588172257446328">Nume de utilizator:</translation> <translation id="5388885445722491159">Împerecheat</translation> <translation id="5389237414310520250">Noul utilizator nu a putut fi creat. Verifică spațiul de pe hard disk și permisiunile, apoi încearcă din nou.</translation> <translation id="5390100381392048184">Permite site-urilor să redea sunet</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Tastatură și introducerea textului</translation> <translation id="5553089923092577885">Mapări de certificate de politică</translation> <translation id="5554489410841842733">Această pictogramă va deveni vizibilă când extensia va putea acționa pe pagina curentă.</translation> -<translation id="5554573843028719904">Altă rețea Wi-Fi...</translation> <translation id="5554720593229208774">Autoritate de certificare e-mail</translation> <translation id="5556206011531515970">Faceți clic pe Înainte pentru a alege browserul dvs. prestabilit.</translation> <translation id="5556459405103347317">Reîncarcă</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Comută la modul Cameră foto</translation> <translation id="5612720917913232150"><ph name="URL" /> dorește să utilizeze locația computerului</translation> <translation id="5612734644261457353">Ne pare rău, parola dvs. tot nu a putut fi confirmată. Notă: dacă v-ați schimbat recent parola, aceasta se va aplica după ce vă deconectați. Vă rugăm să utilizați aici parola veche.</translation> -<translation id="5613695965848159202">Identitate anonimă:</translation> <translation id="5614190747811328134">Notificare pentru utilizator</translation> <translation id="561698261642843490">Închide Firefox</translation> <translation id="5618075537869101857">Hopa, aplicația de tip chioșc nu a putut fi lansată.</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">Conectează-te la <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimizează</translation> <translation id="5946591249682680882">ID raport <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Adaugă o rețea privată</translation> <translation id="5949544233750246342">Fișierul nu poate fi analizat</translation> <translation id="5955282598396714173">Parola a expirat. Pentru a o schimba, deconectează-te, apoi conectează-te din nou.</translation> <translation id="5956585768868398362">Aceasta este pagina de căutare la care vă așteptați?</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">Deconectați-vă, apoi conectați-vă din nou...</translation> <translation id="6198252989419008588">Schimbă codul PIN</translation> <translation id="6199801702437275229">Se așteaptă informațiile despre spațiu...</translation> +<translation id="6204015976622790023">Vezi sugestiile relevante de la Asistent în legătură cu conținutul de pe ecran.</translation> <translation id="6205710420833115353">Unele operațiuni durează mai mult decât ar trebui. Dorești să le anulezi?</translation> <translation id="6206311232642889873">Cop&iază imaginea</translation> <translation id="6207200176136643843">Resetează la nivelul de zoom prestabilit</translation> <translation id="620722923698527029">Deschide întotdeauna aceste tipuri de linkuri în aplicația asociată</translation> <translation id="6207937957461833379">Țară/Regiune</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: sincronizarea nu funcționează</translation> <translation id="6212039847102026977">Afișează proprietățile avansate pentru rețea</translation> <translation id="6212168817037875041">Dezactivează ecranul</translation> <translation id="6212752530110374741">Trimite linkul prin e-mail</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">resetează sincronizarea</translation> <translation id="6264365405983206840">Select&ează tot</translation> <translation id="6264422956566238156">Ai activat Sincronizarea</translation> -<translation id="6265930187414222160">Gata! Software-ul dăunător a fost eliminat.</translation> <translation id="6267166720438879315">Selectează un certificat pentru a te autentifica pe <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Deschide cu <ph name="APP" /></translation> <translation id="6268747994388690914">Importați marcaje dintr-un fișier HTML...</translation> @@ -3537,7 +3532,6 @@ Dă clic pe „Înainte” pentru a continua conectarea la contul <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Încarcă extensia neîmpachetată</translation> <translation id="642282551015776456">Acest nume nu poate fi folosit ca nume de fișier sau de dosar</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Deschide setările ChromeVox</translation> <translation id="6429384232893414837">Eroare de actualizare</translation> <translation id="6430814529589430811">ASCII codificat Base64, certificat unic</translation> @@ -3618,7 +3612,6 @@ <translation id="6544215763872433504">Browserul web de la Google, pentru tine</translation> <translation id="6545665334409411530">Frecvența de repetare</translation> <translation id="6545834809683560467">Folosește un serviciu de predicții pentru a completa căutările și adresele URL introduse în bara de adrese sau în caseta de căutare a lansatorului de aplicații</translation> -<translation id="6546686722964485737">Conectați-vă la rețeaua WiMAX</translation> <translation id="6547316139431024316">Nu mai notifica pentru această extensie</translation> <translation id="6547354035488017500">Eliberează un spațiu de cel puțin 512 MB sau dispozitivul nu va mai răspunde la comenzi. Pentru a elibera spațiu, șterge fișiere din stocarea dispozitivului.</translation> <translation id="6549689063733911810">Recente</translation> @@ -4037,7 +4030,6 @@ <translation id="7201014958346994077">Fișierele Linux nu pot fi afișate</translation> <translation id="720110658997053098">Menține permanent acest dispozitiv în modul chioșc</translation> <translation id="7201118060536064622">„<ph name="DELETED_ITEM_NAME" />” a fost șters</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Se descarcă pluginul <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Închide pagina}few{Închide paginile}other{Închide paginile}}</translation> <translation id="7216409898977639127">Furnizor de date mobile</translation> @@ -4515,7 +4507,6 @@ <translation id="7909969815743704077">Descărcat în modul incognito</translation> <translation id="7910768399700579500">Dosar &nou</translation> <translation id="7912080627461681647">Parola a fost modificată pe server. Deconectează-te, apoi conectează-te din nou.</translation> -<translation id="7912883689016444961">Configurează rețeaua mobilă</translation> <translation id="7915471803647590281">Spune-ne ce se întâmplă înainte de a trimite feedback.</translation> <translation id="7916556741383518510">Când se dă clic</translation> <translation id="792514962475806987">Nivelul de zoom al lupei andocate:</translation> @@ -4569,7 +4560,6 @@ <translation id="7988355189918024273">Activați funcțiile de accesibilitate</translation> <translation id="7994702968232966508">Metodă EAP</translation> <translation id="799547531016638432">Eliminați comanda rapidă</translation> -<translation id="7997479212858899587">Identitate:</translation> <translation id="7997826902155442747">Prioritatea procesului</translation> <translation id="7999229196265990314">Au fost create următoarele fișiere: @@ -4653,7 +4643,6 @@ <translation id="8105368624971345109">Dezactivează</translation> <translation id="8106045200081704138">Cu acces permis pentru mine</translation> <translation id="8107015733319732394">Se instalează Magazinul Google Play pe dispozitivul <ph name="DEVICE_TYPE" />. Ar putea dura câteva minute.</translation> -<translation id="8109930990200908494">Conectarea este obligatorie pentru certificatul de utilizator.</translation> <translation id="8111155949205007504">Trimite această parolă pe iPhone</translation> <translation id="8113043281354018522">Alege tipul de licență</translation> <translation id="8116190140324504026">Mai multe informații...</translation> @@ -4664,6 +4653,7 @@ <translation id="8118860139461251237">Gestionează descărcările</translation> <translation id="81238879832906896">Floare galbenă și albă</translation> <translation id="8124313775439841391">Proprietăți ONC gestionate</translation> +<translation id="8125562866093998907">Site-ul dorește să verifice Cheia de securitate pentru o siguranță sporită a contului.</translation> <translation id="813082847718468539">Afișează informațiile privind site-ul</translation> <translation id="8131740175452115882">Confirmați</translation> <translation id="8133676275609324831">&Afișează în dosar</translation> @@ -4774,7 +4764,6 @@ <translation id="8308179586020895837">Întreabă dacă <ph name="HOST" /> solicită acces la cameră</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certificatul există deja</translation> -<translation id="8309505303672555187">Selectați o rețea:</translation> <translation id="8312871300878166382">Inserați în dosar</translation> <translation id="8317671367883557781">Adaugă o conexiune la rețea</translation> <translation id="8319414634934645341">Utilizare de cheie extinsă</translation> @@ -4849,7 +4838,6 @@ <translation id="8451512073679317615">asistent</translation> <translation id="8452135315243592079">Lipsește cardul SIM</translation> <translation id="8453482423012550001">Se copiază $1 elemente...</translation> -<translation id="8454288007744638700">Sau selectează o rețea nouă:</translation> <translation id="845627346958584683">Ora expirării</translation> <translation id="8456681095658380701">Nume nevalid</translation> <translation id="8457451314607652708">Importă marcajele</translation> @@ -4913,6 +4901,7 @@ <translation id="855081842937141170">Fixează fila</translation> <translation id="8551388862522347954">Licențe</translation> <translation id="8553342806078037065">Gestionează alte persoane</translation> +<translation id="8554899698005018844">Nicio limbă</translation> <translation id="855773602626431402">Pe această pagină a fost împiedicată rularea unui plugin scos din mediul de testare.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Decodor de imagini</translation> @@ -4950,7 +4939,6 @@ <translation id="862727964348362408">Suspendat</translation> <translation id="862750493060684461">Memorie cache CSS</translation> <translation id="8627795981664801467">Numai conexiuni sigure</translation> -<translation id="8628085465172583869">Nume de gazdă server:</translation> <translation id="8630903300770275248">Importați un utilizator monitorizat</translation> <translation id="8631032106121706562">Petale</translation> <translation id="8637542770513281060">Computerul conține un modul securizat, care este folosit pentru a implementa numeroase funcții esențiale de securitate în sistemul de operare Chrome. Accesează Centrul de ajutor Chromebook pentru a afla mai multe: https://support.google.com/chromebook/?p=sm</translation> @@ -5206,7 +5194,6 @@ <translation id="899403249577094719">Adresă URL de bază pentru certificat Netscape</translation> <translation id="8995603266996330174">Gestionat de <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Adăugați un cont...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Se creează imaginea de pe disc.</translation> <translation id="9003647077635673607">Permiteți pe toate site-urile</translation> <translation id="9003677638446136377">Verifică din nou</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb index 5a55f5a..3912d00e 100644 --- a/chrome/app/resources/generated_resources_ru.xtb +++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Скоро перерыв</translation> <translation id="1062407476771304334">Заменить</translation> -<translation id="1064835277883315402">Подключение к частной сети</translation> <translation id="1064912851688322329">Отключение аккаунта Google</translation> <translation id="1067048845568873861">Создано</translation> <translation id="1067291318998134776">Linux (бета)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Поиск...</translation> <translation id="1316495628809031177">Синхронизация приостановлена.</translation> <translation id="1319979322914001937">В "Галерее" показан список избранных расширений из Интернет-магазина Chrome, которые можно установить прямо из приложения.</translation> -<translation id="132090119144658135">Совпадение тем:</translation> <translation id="1326317727527857210">Чтобы получить доступ к вкладкам на всех ваших устройствах, войдите в Chrome.</translation> <translation id="1327074568633507428">Принтер, подключенный к Виртуальному принтеру Google</translation> <translation id="1327977588028644528">Шлюз</translation> @@ -489,7 +487,6 @@ <translation id="1701062906490865540">Удалить пользователя</translation> <translation id="1706586824377653884">Добавлено администратором</translation> <translation id="1706625117072057435">Масштабирование</translation> -<translation id="1707463636381878959">Разрешить другим пользователям доступ к этой сети</translation> <translation id="1708338024780164500">(неактивно)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (идентификатор: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (оригинальное)</translation> @@ -525,7 +522,6 @@ <translation id="175772926354468439">Включить тему</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Перейти в Интернет-магазин Chrome</translation> -<translation id="1758831820837444715">Настройка сети Ethernet</translation> <translation id="1763046204212875858">Создание ярлыков приложений</translation> <translation id="1763108912552529023">Дополнительные сведения</translation> <translation id="1763808908432309942">Страница откроется в новой вкладке</translation> @@ -874,7 +870,6 @@ <translation id="2291643155573394834">Следующая вкладка</translation> <translation id="2292848386125228270">Запустите <ph name="PRODUCT_NAME" /> от имени обычного пользователя. Если вам нужно выполнить запуск от имени суперпользователя, перезапустите браузер, установив параметр "--no-sandbox".</translation> <translation id="2294358108254308676">Установить <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Метод EAP:</translation> <translation id="2297705863329999812">Найти принтеры</translation> <translation id="2300383962156589922">Настройка приложения "<ph name="APP_NAME" />" и управление им</translation> <translation id="2301382460326681002">Недействительный корневой каталог расширения.</translation> @@ -932,7 +927,6 @@ <translation id="2379281330731083556">Печатать с помощью системного диалогового окна <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Спрашивать разрешение перед отправкой (рекомендуется)</translation> <translation id="2384436799579181135">Произошла ошибка. Проверьте принтер и повторите попытку.</translation> -<translation id="2385700042425247848">Название службы:</translation> <translation id="2387458720915042159">Тип подключения через прокси-сервер</translation> <translation id="2391419135980381625">Стандартный шрифт</translation> <translation id="2391762656119864333">Отменить</translation> @@ -983,7 +977,6 @@ <translation id="247949520305900375">Общий доступ к аудио</translation> <translation id="2480868415629598489">Изменение копируемых и вставляемых данных</translation> <translation id="2482878487686419369">Уведомления</translation> -<translation id="2485056306054380289">Сертификат сервера ЦС:</translation> <translation id="2485422356828889247">Удалить</translation> <translation id="2487067538648443797">Новая закладка</translation> <translation id="248861575772995840">Телефон не обнаружен. Убедитесь, что на устройстве <ph name="DEVICE_TYPE" /> включен Bluetooth. <a>Подробнее…</a></translation> @@ -1110,7 +1103,6 @@ <translation id="2653659639078652383">Отправить</translation> <translation id="265390580714150011">Значение поля</translation> <translation id="2654166010170466751">Разрешить сайтам устанавливать обработчики платежей.</translation> -<translation id="2655386581175833247">Сертификат пользователя:</translation> <translation id="2660779039299703961">Событие</translation> <translation id="266079277508604648">Не удается установить соединение с принтером. Убедитесь, что он включен и подключен к устройству Chromebook через Wi-Fi или USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1410,7 +1402,6 @@ <translation id="3100609564180505575">Модули (<ph name="TOTAL_COUNT" />) – Известных конфликтов: <ph name="BAD_COUNT" />; подозрительных: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Дата и время</translation> <translation id="310671807099593501">Сайт использует Bluetooth</translation> -<translation id="3108967419958202225">Выберите...</translation> <translation id="3115128645424181617">Не удалось найти телефон. Убедитесь, что он поблизости и на нем включен Bluetooth.</translation> <translation id="3115147772012638511">Ожидание кеша…</translation> <translation id="3118319026408854581">Справка <ph name="PRODUCT_NAME" /></translation> @@ -1455,7 +1446,6 @@ <translation id="3165390001037658081">Некоторые операторы могут блокировать эту функцию.</translation> <translation id="316854673539778496">Чтобы получить доступ к расширениям на всех своих устройствах, войдите в аккаунт и включите синхронизацию.</translation> <translation id="3170072451822350649">Можно пропустить это действие и начать <ph name="LINK_START" />гостевой сеанс<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Нажмите, чтобы скрыть пароль</translation> <translation id="3177909033752230686">Язык страницы:</translation> <translation id="3181110748548073003">Чтобы перейти на следующую страницу, нажмите |<ph name="SHORTCUT" />|</translation> <translation id="3182749001423093222">Проверка правописания</translation> @@ -1486,7 +1476,6 @@ <translation id="3236289833370040187">Право собственности будет передано домену <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Открыть параметры расширения</translation> <translation id="3241680850019875542">Выберите корневой каталог упаковываемого расширения. Для обновления расширения также укажите закрытый ключ.</translation> -<translation id="3242765319725186192">Общий ключ:</translation> <translation id="3244294424315804309">Не включать звук</translation> <translation id="3245321423178950146">Неизвестный исполнитель</translation> <translation id="3246097286174000800">Настроить Smart Lock</translation> @@ -1619,7 +1608,6 @@ <translation id="3440663250074896476">Другие действия с закладкой <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Предупреждать, что сайт пытается использовать плагин для доступа к компьютеру</translation> <translation id="3441653493275994384">Экран</translation> -<translation id="3445830502289589282">Двухэтапная аутентификация:</translation> <translation id="344630545793878684">Просмотр данных на нескольких сайтах</translation> <translation id="3449839693241009168">Нажмите <ph name="SEARCH_KEY" /> для отправки команд в <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Продолжительность состояния бездействия в процентах</translation> @@ -1660,7 +1648,6 @@ <translation id="3495304270784461826">Ошибок: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Настройки Google Ассистента</translation> <translation id="3496213124478423963">Уменьшить</translation> -<translation id="3504135463003295723">Название группы:</translation> <translation id="3505030558724226696">Запретить доступ к устройствам</translation> <translation id="3507421388498836150">Текущие разрешения расширения "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Удалить приложения Linux с устройства Chromebook</translation> @@ -1769,7 +1756,6 @@ <translation id="3661054927247347545">Сертификация входа недействительна. Окно закроется через <ph name="MINUTES" />:<ph name="SECONDS" />.</translation> <translation id="3664511988987167893">Значок расширения</translation> <translation id="3665589677786828986">Некоторые настройки Chrome недавно были изменены посторонней программой. Браузер восстановил их значения по умолчанию.</translation> -<translation id="3665842570601375360">Безопасность:</translation> <translation id="3668570675727296296">Настройки языка</translation> <translation id="3668823961463113931">Обработчики</translation> <translation id="3670229581627177274">Включить Bluetooth</translation> @@ -1808,7 +1794,6 @@ <translation id="3726463242007121105">Невозможно получить доступ к устройству, так как его файловая система не поддерживается.</translation> <translation id="3727148787322499904">Изменение этого параметра повлияет на все общие сети</translation> <translation id="3727187387656390258">Просмотреть всплывающее окно</translation> -<translation id="3728067901555601989">Одноразовый пароль:</translation> <translation id="3732078975418297900">Ошибка в строке <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-сервер с повышением</translation> <translation id="3737536731758327622">Здесь появятся скачанные файлы.</translation> @@ -1883,7 +1868,6 @@ <translation id="38275787300541712">После завершения нажмите клавишу Enter</translation> <translation id="3827774300009121996">Полноэкранный режим</translation> <translation id="3828029223314399057">Искать в закладках</translation> -<translation id="3829932584934971895">Тип поставщика услуг:</translation> <translation id="3830674330436234648">Воспроизведение невозможно</translation> <translation id="3831486154586836914">Активирован режим обзора.</translation> <translation id="383161972796689579">Владелец этого устройства отключил возможность добавлять новых пользователей</translation> @@ -1982,7 +1966,6 @@ <translation id="3968261067169026421">Не удалось настроить сеть</translation> <translation id="3970114302595058915">Идентификатор</translation> <translation id="397105322502079400">Вычисление…</translation> -<translation id="3974195870082915331">Нажмите, чтобы показать пароль</translation> <translation id="3975222297214566386">Всплывающая подсказка с параметрами ввода</translation> <translation id="397703832102027365">Завершение…</translation> <translation id="3979395879372752341">Добавлено новое расширение (<ph name="EXTENSION_NAME" />)</translation> @@ -2230,7 +2213,6 @@ <translation id="4419556793104466535">Настройки синхронизации, персонализации и других сервисов</translation> <translation id="4421932782753506458">Пушистик</translation> <translation id="4422347585044846479">Изменить эту закладку</translation> -<translation id="4423104065312875417">Установить дополнительные синтезаторы речи.</translation> <translation id="4423376891418188461">Восстановить настройки</translation> <translation id="4423482519432579560">&Проверка правописания</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, администратор просит вас сменить пароль.</translation> @@ -2255,7 +2237,6 @@ <translation id="4449996769074858870">На этой вкладке воспроизводится аудио</translation> <translation id="4450974146388585462">Проверить подключение</translation> <translation id="4453946976636652378">Введите поисковый запрос в <ph name="SEARCH_ENGINE_NAME" /> или укажите URL</translation> -<translation id="445923051607553918">Подключение к сети Wi-Fi</translation> <translation id="4462159676511157176">Другие серверы имен</translation> <translation id="4467100756425880649">Галерея Интернет-магазина Chrome</translation> <translation id="4467101674048705704">Развернуть папку <ph name="FOLDER_NAME" /></translation> @@ -2861,7 +2842,6 @@ <translation id="5380103295189760361">Нажмите Control, Alt, Shift или Search, чтобы увидеть соответствующие быстрые клавиши.</translation> <translation id="5382591305415226340">Управление поддерживаемыми ссылками</translation> <translation id="5384883051496921101">Этот сайт передает информацию стороннему приложению, пока вы в режиме инкогнито.</translation> -<translation id="5388588172257446328">Имя пользователя:</translation> <translation id="5388885445722491159">Пара создана</translation> <translation id="5389237414310520250">Не удалось создать контролируемый профиль. Убедитесь, что у вас есть необходимые разрешения и свободное место на жестком диске, а затем повторите попытку.</translation> <translation id="5390100381392048184">Разрешить сайтам воспроизводить звуки</translation> @@ -2986,7 +2966,6 @@ <translation id="5551573675707792127">Клавиатура и ввод текста</translation> <translation id="5553089923092577885">Сопоставления политики сертификатов</translation> <translation id="5554489410841842733">Значок будет видимым, если расширение может работать на текущей странице.</translation> -<translation id="5554573843028719904">Другие сети Wi-Fi...</translation> <translation id="5554720593229208774">Центр сертификации электронной почты</translation> <translation id="5556206011531515970">Чтобы выбрать браузер по умолчанию, нажмите "Далее".</translation> <translation id="5556459405103347317">Перезагрузить</translation> @@ -3027,7 +3006,6 @@ <translation id="5610038042047936818">Включить режим фото</translation> <translation id="5612720917913232150">Сайт <ph name="URL" /> запрашивает данные о местоположении вашего компьютера.</translation> <translation id="5612734644261457353">Неверный пароль. Обратите внимание: если вы недавно изменили пароль, но не выходили из системы, значит новый пароль ещё не вступил в силу и необходимо указать старый.</translation> -<translation id="5613695965848159202">Анонимные идентификационные данные:</translation> <translation id="5614190747811328134">Уведомление пользователя</translation> <translation id="561698261642843490">Закройте Firefox</translation> <translation id="5618075537869101857">К сожалению, не удалось запустить киоск-приложение.</translation> @@ -3245,7 +3223,6 @@ <translation id="5941343993301164315"><ph name="TOKEN_NAME" />: необходимо войти.</translation> <translation id="5941711191222866238">Свернуть</translation> <translation id="5946591249682680882">Идентификатор отчета: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Добавить частную сеть</translation> <translation id="5949544233750246342">Не удалось проанализировать файл</translation> <translation id="5955282598396714173">Срок действия пароля истек. Чтобы изменить пароль, выйдите из аккаунта и войдите снова.</translation> <translation id="5956585768868398362">Другая поисковая система?</translation> @@ -3450,7 +3427,6 @@ <translation id="6263541650532042179">сбросить синхронизацию</translation> <translation id="6264365405983206840">Выделить все</translation> <translation id="6264422956566238156">Синхронизация включена</translation> -<translation id="6265930187414222160">Вредоносные программы удалены.</translation> <translation id="6267166720438879315">Выберите сертификат для аутентификации на <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Открыть в приложении <ph name="APP" /></translation> <translation id="6268747994388690914">Импорт закладок из файла HTML</translation> @@ -3557,7 +3533,6 @@ Нажмите кнопку "Далее" и войдите в аккаунт <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Загрузить распакованное расширение</translation> <translation id="642282551015776456">Недопустимое название для файла или папки</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Открыть настройки ChromeVox</translation> <translation id="6429384232893414837">Ошибка обновления</translation> <translation id="6430814529589430811">Единый сертификат ASCII с кодировкой Base64</translation> @@ -3638,7 +3613,6 @@ <translation id="6544215763872433504">Ваш браузер от Google</translation> <translation id="6545665334409411530">Скорость повтора</translation> <translation id="6545834809683560467">Показывать подсказки при вводе поисковых запросов и URL</translation> -<translation id="6546686722964485737">Подключение к сети Wimax</translation> <translation id="6547316139431024316">Больше не показывать для этого расширения</translation> <translation id="6547354035488017500">Чтобы устройство работало, требуется как минимум 512 МБ свободного пространства. Рекомендуем удалить файлы, хранящиеся на устройстве.</translation> <translation id="6549689063733911810">Недавние</translation> @@ -4057,7 +4031,6 @@ <translation id="7201014958346994077">Нет доступа к файлам Linux.</translation> <translation id="720110658997053098">Всегда запускать устройство в режиме киоска</translation> <translation id="7201118060536064622">Объект "<ph name="DELETED_ITEM_NAME" />" удален</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Скачивание плагина <ph name="PLUGIN_NAME" />…</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Закрыть страницу}one{Закрыть страницы}few{Закрыть страницы}many{Закрыть страницы}other{Закрыть страницы}}</translation> <translation id="7216409898977639127">Оператор сотовой связи</translation> @@ -4535,7 +4508,6 @@ <translation id="7909969815743704077">Скачано в режиме инкогнито</translation> <translation id="7910768399700579500">&Новая папка</translation> <translation id="7912080627461681647">Пароль был изменен на сервере. Выйдите из аккаунта и войдите снова.</translation> -<translation id="7912883689016444961">Настроить мобильную сеть</translation> <translation id="7915471803647590281">Введите текст отзыва.</translation> <translation id="7916556741383518510">При нажатии</translation> <translation id="792514962475806987">Масштаб закрепленной лупы:</translation> @@ -4589,7 +4561,6 @@ <translation id="7988355189918024273">Включить функции для людей с ограниченными возможностями</translation> <translation id="7994702968232966508">Метод EAP</translation> <translation id="799547531016638432">Удалить ярлык</translation> -<translation id="7997479212858899587">Идентификационные данные:</translation> <translation id="7997826902155442747">Приоритет процессов</translation> <translation id="7999229196265990314">Созданы следующие файлы: @@ -4673,7 +4644,6 @@ <translation id="8105368624971345109">Отключить</translation> <translation id="8106045200081704138">Доступные мне</translation> <translation id="8107015733319732394">Установка Google Play Маркета на устройство <ph name="DEVICE_TYPE" /> (может занять несколько минут)…</translation> -<translation id="8109930990200908494">Чтобы получить сертификат пользователя, необходимо войти в систему.</translation> <translation id="8111155949205007504">Поделитесь паролем с iPhone</translation> <translation id="8113043281354018522">Выберите тип лицензии</translation> <translation id="8116190140324504026">Дополнительная информация...</translation> @@ -4795,7 +4765,6 @@ <translation id="8308179586020895837">Запрашивать разрешение на доступ к камере для сайта <ph name="HOST" /></translation> <translation id="830868413617744215">Бета</translation> <translation id="8309458809024885768">Такой сертификат уже существует</translation> -<translation id="8309505303672555187">Выберите сеть:</translation> <translation id="8312871300878166382">Вставить в папку</translation> <translation id="8317671367883557781">Добавить сетевое подключение</translation> <translation id="8319414634934645341">Расширенное использование ключа</translation> @@ -4870,7 +4839,6 @@ <translation id="8451512073679317615">Ассистент</translation> <translation id="8452135315243592079">SIM-карта не обнаружена</translation> <translation id="8453482423012550001">Копирование элементов ($1)…</translation> -<translation id="8454288007744638700">Выберите другую сеть:</translation> <translation id="845627346958584683">Время окончания срока действия</translation> <translation id="8456681095658380701">Недопустимое название</translation> <translation id="8457451314607652708">Импортировать закладки</translation> @@ -4972,7 +4940,6 @@ <translation id="862727964348362408">Приостановлено</translation> <translation id="862750493060684461">Кеш CSS</translation> <translation id="8627795981664801467">только при защищенном подключении</translation> -<translation id="8628085465172583869">Имя хоста сервера:</translation> <translation id="8630903300770275248">Импортировать контролируемый профиль</translation> <translation id="8631032106121706562">Цветок</translation> <translation id="8637542770513281060">Компьютер оснащен безопасным модулем, который используется для выполнения многих важных функций защиты в Chrome OS. Более подробную информацию можно получить в Справочном центре Chromebook: https://support.google.com/chromebook/?p=sm</translation> @@ -5228,7 +5195,6 @@ <translation id="899403249577094719">URL базы сертификатов Netscape</translation> <translation id="8995603266996330174">В домене <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Добавить аккаунт</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Создание образа диска…</translation> <translation id="9003647077635673607">Разрешить на всех сайтах</translation> <translation id="9003677638446136377">Проверить снова</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb index 6b90e97..4ad5488 100644 --- a/chrome/app/resources/generated_resources_sk.xtb +++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Už je takmer čas na prestávku</translation> <translation id="1062407476771304334">Nahradiť</translation> -<translation id="1064835277883315402">Pripojiť sa k súkromnej sieti</translation> <translation id="1064912851688322329">Odpojenie účtu Google</translation> <translation id="1067048845568873861">Vytvorené</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Prebieha vyhľadávanie...</translation> <translation id="1316495628809031177">Synchronizácia je pozastavená</translation> <translation id="1319979322914001937">Aplikácia, ktorá zobrazuje filtrovaný zoznam rozšírení z Internetového obchodu Chrome. Rozšírenia z tohto zoznamu sa dajú nainštalovať priamo z aplikácie.</translation> -<translation id="132090119144658135">Zhoda predmetu:</translation> <translation id="1326317727527857210">Ak chcete získať karty z ďalších svojich zariadení, prihláste sa do Chromu.</translation> <translation id="1327074568633507428">Tlačiareň v službe Google Cloud Print</translation> <translation id="1327977588028644528">Brána</translation> @@ -490,7 +488,6 @@ <translation id="1701062906490865540">Odstrániť túto osobu</translation> <translation id="1706586824377653884">Pridané správcom</translation> <translation id="1706625117072057435">Úrovne priblíženia</translation> -<translation id="1707463636381878959">Zdieľať túto sieť s ďalšími používateľmi</translation> <translation id="1708338024780164500">(Neaktívne)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (natívne)</translation> @@ -526,7 +523,6 @@ <translation id="175772926354468439">Povoliť motív</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Zobraziť v Internetovom obchode Chrome</translation> -<translation id="1758831820837444715">Konfigurácia siete Ethernet</translation> <translation id="1763046204212875858">Vytvoriť odkazy na aplikáciu</translation> <translation id="1763108912552529023">Skúmať</translation> <translation id="1763808908432309942">Otvorí sa na novej karte</translation> @@ -876,7 +872,6 @@ <translation id="2291643155573394834">Nasledujúca karta</translation> <translation id="2292848386125228270">Spustite <ph name="PRODUCT_NAME" /> ako normálny používateľ. Ak to potrebujete urobiť ako používateľ root na účely vývoja, spustite ho znova pomocou príznaku --no-sandbox.</translation> <translation id="2294358108254308676">Chcete nainštalovať aplikáciu <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Metóda EAP:</translation> <translation id="2297705863329999812">Hľadať tlačiarne</translation> <translation id="2300383962156589922">Prispôsobiť a spravovať aplikáciu <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Koreňový adresár rozšírenia je neplatný.</translation> @@ -934,7 +929,6 @@ <translation id="2379281330731083556">Tlačiť pomocou dialógového okna systému... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Spýtať sa pred odoslaním (odporúčané)</translation> <translation id="2384436799579181135">Vyskytla sa chyba. Skontrolujte tlačiareň a skúste to znova.</translation> -<translation id="2385700042425247848">Názov služby:</translation> <translation id="2387458720915042159">Typ pripojenia proxy</translation> <translation id="2391419135980381625">Štandardné písmo</translation> <translation id="2391762656119864333">Odvolať</translation> @@ -985,7 +979,6 @@ <translation id="247949520305900375">Zdieľať zvuk</translation> <translation id="2480868415629598489">Upravovať dáta, ktoré kopírujete a prilepujete</translation> <translation id="2482878487686419369">Upozornenia</translation> -<translation id="2485056306054380289">Certifikát CA servera:</translation> <translation id="2485422356828889247">Odinštalovať</translation> <translation id="2487067538648443797">Pridať novú záložku</translation> <translation id="248861575772995840">Telefón sa nedarí nájsť. Skontrolujte, či je v zariadení <ph name="DEVICE_TYPE" /> zapnuté rozhranie Bluetooth. <a>Ďalšie informácie</a></translation> @@ -1109,7 +1102,6 @@ <translation id="2653659639078652383">Odoslať</translation> <translation id="265390580714150011">Hodnota poľa</translation> <translation id="2654166010170466751">Povoliť webom inštalovať obslužné nástroje platieb</translation> -<translation id="2655386581175833247">Certifikát používateľa:</translation> <translation id="2660779039299703961">Udalosť</translation> <translation id="266079277508604648">K tlačiarni sa nepodarilo pripojiť. Skontrolujte, či je zapnutá a pripojená k Chromebooku prostredníctvom Wi-Fi alebo USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1409,7 +1401,6 @@ <translation id="3100609564180505575">Moduly (<ph name="TOTAL_COUNT" />) – Známe konflikty: <ph name="BAD_COUNT" />, podozrivé: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Dátum a čas</translation> <translation id="310671807099593501">Web používa Bluetooth</translation> -<translation id="3108967419958202225">Vybrať...</translation> <translation id="3115128645424181617">Telefón sa nedarí nájsť. Skontrolujte, či je v dosahu a či má zapnuté rozhranie Bluetooth.</translation> <translation id="3115147772012638511">Čakanie na vyrovnávaciu pamäť...</translation> <translation id="3118319026408854581">Pomocník aplikácie <ph name="PRODUCT_NAME" /></translation> @@ -1454,7 +1445,6 @@ <translation id="3165390001037658081">Niektorí operátori môžu túto funkciu blokovať.</translation> <translation id="316854673539778496">Ak chcete získať svoje rozšírenia vo všetkých zariadeniach, prihláste sa a zapnite synchronizáciu.</translation> <translation id="3170072451822350649">Môžete tiež preskočiť prihlásenie a <ph name="LINK_START" />prehliadať ako hosť<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Kliknutím skryjete heslo</translation> <translation id="3177909033752230686">Jazyk stránky:</translation> <translation id="3181110748548073003">Ak chcete prejsť dopredu, stlačte |<ph name="SHORTCUT" />|</translation> <translation id="3182749001423093222">Kontrola pravopisu</translation> @@ -1485,7 +1475,6 @@ <translation id="3236289833370040187">Vlastníctvo bude prenesené do domény <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Otvoriť možnosti rozšírenia</translation> <translation id="3241680850019875542">Vyberte koreňový adresár rozšírenia, ktoré chcete zbaliť. Ak chcete rozšírenie aktualizovať, vyberte tiež súbor súkromného kľúča, ktorý sa má znova použiť.</translation> -<translation id="3242765319725186192">Predzdieľaný kľúč:</translation> <translation id="3244294424315804309">Ponechať zvuk vypnutý</translation> <translation id="3245321423178950146">Neznámy interpret</translation> <translation id="3246097286174000800">Vyskúšať Smart Lock</translation> @@ -1618,7 +1607,6 @@ <translation id="3440663250074896476">Ďalšie akcie so záložkou <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Opýtať sa, keď bude web chcieť použiť doplnok na prístup do počítača</translation> <translation id="3441653493275994384">Obrazovka</translation> -<translation id="3445830502289589282">Overenie – 2. fáza:</translation> <translation id="344630545793878684">Čítať vaše údaje na viacerých webových stránkach</translation> <translation id="3449839693241009168">Stlačením tlačidla <ph name="SEARCH_KEY" /> odošlete príkazy rozšíreniu <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Percento obsadenia priestoru údajmi stavu nečinnosti</translation> @@ -1659,7 +1647,6 @@ <translation id="3495304270784461826">Počet chýb: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Nastavenia Asistenta Google</translation> <translation id="3496213124478423963">Oddialiť</translation> -<translation id="3504135463003295723">Názov skupiny:</translation> <translation id="3505030558724226696">Odvolať prístup k zariadeniam</translation> <translation id="3507421388498836150">Aktuálne povolenia pre rozšírenie <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Odstrániť aplikácie Linux pre Chromebook</translation> @@ -1768,7 +1755,6 @@ <translation id="3661054927247347545">Certifikácia prihlásenia nie je platná. Okno sa zavrie o <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ikona rozšírenia</translation> <translation id="3665589677786828986">Chrome zistil, že niektoré nastavenia boli poškodené iným programom, a preto obnovil pôvodné predvolené nastavenia.</translation> -<translation id="3665842570601375360">Zabezpečenie:</translation> <translation id="3668570675727296296">Nastavenia jazyka</translation> <translation id="3668823961463113931">Obslužné nástroje</translation> <translation id="3670229581627177274">Zapnúť Bluetooth</translation> @@ -1807,7 +1793,6 @@ <translation id="3726463242007121105">Toto zariadenie nie je možné otvoriť, pretože jeho systém súborov nie je podporovaný.</translation> <translation id="3727148787322499904">Zmena tohto nastavenia ovplyvní všetky zdieľané siete</translation> <translation id="3727187387656390258">Kontrola kontextovej ponuky</translation> -<translation id="3728067901555601989">Jednorazové heslo:</translation> <translation id="3732078975418297900">Chyba v riadku <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Server SSL s prestupom na vyššiu edíciu</translation> <translation id="3737536731758327622">Tu sa zobrazia stiahnuté súbory</translation> @@ -1882,7 +1867,6 @@ <translation id="38275787300541712">Po dokončení stlačte kláves Enter</translation> <translation id="3827774300009121996">&Celá obrazovka</translation> <translation id="3828029223314399057">Prehľadať záložky</translation> -<translation id="3829932584934971895">Typ poskytovateľa:</translation> <translation id="3830674330436234648">Prehrávanie nie je k dispozícii</translation> <translation id="3831486154586836914">Vstúpili ste do režimu prehľadu okien</translation> <translation id="383161972796689579">Vlastník tohto zariadenia zakázal pridávanie nových používateľov</translation> @@ -1981,7 +1965,6 @@ <translation id="3968261067169026421">Sieť sa nepodarilo nastaviť</translation> <translation id="3970114302595058915">Identifikátor</translation> <translation id="397105322502079400">Prebieha výpočet...</translation> -<translation id="3974195870082915331">Kliknutím zobrazíte heslo</translation> <translation id="3975222297214566386">Bublina s možnosťami vstupu</translation> <translation id="397703832102027365">Prebieha dokončovanie...</translation> <translation id="3979395879372752341">Bolo pridané nové rozšírenie (<ph name="EXTENSION_NAME" />)</translation> @@ -2229,7 +2212,6 @@ <translation id="4419556793104466535">Ovládanie synchronizácie, prispôsobenia a ďalších funkcií</translation> <translation id="4421932782753506458">Páperový</translation> <translation id="4422347585044846479">Upraviť záložku pre túto stránku</translation> -<translation id="4423104065312875417">Inštalovať ďalšie nástroje hlasovej odozvy</translation> <translation id="4423376891418188461">Obnoviť nastavenia</translation> <translation id="4423482519432579560">&Kontrola pravopisu</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, váš správca vyžaduje zmenu hesla.</translation> @@ -2254,7 +2236,6 @@ <translation id="4449996769074858870">Táto karta prehráva zvuk.</translation> <translation id="4450974146388585462">Diagnostikovať</translation> <translation id="4453946976636652378">Vyhľadajte v službe <ph name="SEARCH_ENGINE_NAME" /> alebo zadajte webovú adresu</translation> -<translation id="445923051607553918">Pripojiť sa k sieti Wi‑Fi</translation> <translation id="4462159676511157176">Vlastné menné servery</translation> <translation id="4467100756425880649">Galéria Internetového obchodu Chrome</translation> <translation id="4467101674048705704">Rozbaliť <ph name="FOLDER_NAME" /></translation> @@ -2860,7 +2841,6 @@ <translation id="5380103295189760361">Stlačením klávesov Ctrl, Alt, Shift alebo Hľadať zobrazíte klávesové skratky pre tieto modifikátory.</translation> <translation id="5382591305415226340">Spravovať podporované odkazy</translation> <translation id="5384883051496921101">Tento web chce zdieľať informácie s aplikáciou mimo režimu inkognito.</translation> -<translation id="5388588172257446328">Používateľské meno:</translation> <translation id="5388885445722491159">Spárované</translation> <translation id="5389237414310520250">Nového používateľa sa nepodarilo vytvoriť. Skontrolujte priestor na pevnom disku a povolenia a skúste to znova.</translation> <translation id="5390100381392048184">Povoliť webom prehrávať zvuk</translation> @@ -2985,7 +2965,6 @@ <translation id="5551573675707792127">Klávesnica a textový vstup</translation> <translation id="5553089923092577885">Priraďovanie politiky certifikátu</translation> <translation id="5554489410841842733">Táto ikona sa zobrazí, keď bude môcť dané rozšírenie na aktuálnej stránke realizovať akcie.</translation> -<translation id="5554573843028719904">Iná sieť Wi‑Fi...</translation> <translation id="5554720593229208774">E-mailová certifikačná autorita</translation> <translation id="5556206011531515970">Kliknutím na tlačidlo Ďalej zvolíte predvolený prehliadač.</translation> <translation id="5556459405103347317">Obnoviť</translation> @@ -3026,7 +3005,6 @@ <translation id="5610038042047936818">Prepnúť na režimu fotoaparátu</translation> <translation id="5612720917913232150"><ph name="URL" /> chce použiť polohu vášho počítača</translation> <translation id="5612734644261457353">Je nám ľúto, stále sa nedarí overiť vaše heslo. Poznámka: Ak ste nedávno zmenili heslo, vaše nové heslo bude použité až po odhlásení. Použite svoje staré heslo.</translation> -<translation id="5613695965848159202">Anonymná identita:</translation> <translation id="5614190747811328134">Oznámenie pre používateľa</translation> <translation id="561698261642843490">Zatvorenie prehliadača Firefox</translation> <translation id="5618075537869101857">Hops, aplikáciu pre režim kiosku sa nepodarilo spustiť.</translation> @@ -3244,7 +3222,6 @@ <translation id="5941343993301164315">Prihláste sa do <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimalizovať</translation> <translation id="5946591249682680882">ID prehľadu <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Pridať súkromnú sieť</translation> <translation id="5949544233750246342">Súbor nie je možné analyzovať</translation> <translation id="5955282598396714173">Platnosť hesla vypršala. Odhláste sa, potom sa znova prihláste a zmeňte ho.</translation> <translation id="5956585768868398362">Je toto stránka vyhľadávania, ktorú ste čakali?</translation> @@ -3449,7 +3426,6 @@ <translation id="6263541650532042179">resetovať synchronizáciu</translation> <translation id="6264365405983206840">Vybrať &všetko</translation> <translation id="6264422956566238156">Zapli ste synchronizáciu</translation> -<translation id="6265930187414222160">Hotovo! Škodlivý softvér bol odstránený.</translation> <translation id="6267166720438879315">Vyberte certifikát, ktorý overí vašu osobu pre <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Otvoriť pomocou aplikácie <ph name="APP" /></translation> <translation id="6268747994388690914">Importovať záložky zo súboru HTML...</translation> @@ -3556,7 +3532,6 @@ Ak sa chcete prihlásiť do účtu <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, kliknite na tlačidlo Ďalej.</translation> <translation id="6419546358665792306">Načítať rozbalené</translation> <translation id="642282551015776456">Tento názov nie je možné použiť na pomenovanie súboru ani priečinka.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Otvoriť nastavenia ChromeVox</translation> <translation id="6429384232893414837">Chyba aktualizácie</translation> <translation id="6430814529589430811">ASCII s kódovaním Base64, jeden certifikát</translation> @@ -3637,7 +3612,6 @@ <translation id="6544215763872433504">Webový prehliadač od Googlu – pre vás</translation> <translation id="6545665334409411530">Rýchlosť opakovania</translation> <translation id="6545834809683560467">Predpovedať vyhľadávané výrazy a webové adresy zadávané na paneli s adresou alebo vo vyhľadávacom poli spúšťača</translation> -<translation id="6546686722964485737">Pripojiť k sieti WiMax</translation> <translation id="6547316139431024316">Nezobrazovať znova upozornenia pre toto rozšírenie</translation> <translation id="6547354035488017500">Uvoľnite aspoň 512 MB miesta, inak vaše zariadenie prestane reagovať. Miesto uvoľníte odstránením súborov z úložiska zariadenia.</translation> <translation id="6549689063733911810">Nedávne</translation> @@ -4054,7 +4028,6 @@ <translation id="7201014958346994077">Nepodarilo sa zobraziť súbory systému Linux</translation> <translation id="720110658997053098">Udržiavať toto zariadenie trvale v režime kiosku</translation> <translation id="7201118060536064622">Položka <ph name="DELETED_ITEM_NAME" /> bola odstránená</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Sťahovanie doplnku <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Opustiť stránku}few{Opustiť stránky}many{Opustiť stránky}other{Opustiť stránky}}</translation> <translation id="7216409898977639127">Poskytovateľ mobilného pripojenia</translation> @@ -4532,7 +4505,6 @@ <translation id="7909969815743704077">Stiahnuté v režime inkognito</translation> <translation id="7910768399700579500">&Nový priečinok</translation> <translation id="7912080627461681647">Vaše heslo bolo zmenené na serveri. Odhláste sa a potom sa znova prihláste.</translation> -<translation id="7912883689016444961">Konfigurovať mobilnú sieť</translation> <translation id="7915471803647590281">Pred odoslaním spätnej väzby nám popíšte situáciu.</translation> <translation id="7916556741383518510">Po kliknutí</translation> <translation id="792514962475806987">Úroveň priblíženia ukotvenej lupy:</translation> @@ -4586,7 +4558,6 @@ <translation id="7988355189918024273">Povoliť funkcie zjednodušeného ovládania</translation> <translation id="7994702968232966508">Metóda EAP</translation> <translation id="799547531016638432">Odstrániť skratku</translation> -<translation id="7997479212858899587">Identita:</translation> <translation id="7997826902155442747">Priorita procesov</translation> <translation id="7999229196265990314">Boli vytvorené nasledujúce súbory: @@ -4670,7 +4641,6 @@ <translation id="8105368624971345109">Vypnúť</translation> <translation id="8106045200081704138">Zdieľané so mnou</translation> <translation id="8107015733319732394">Inštaluje sa Obchod Google Play na zariadení <ph name="DEVICE_TYPE" />. Môžete to chvíľu trvať.</translation> -<translation id="8109930990200908494">Certifikát používateľa vyžaduje prihlásenie.</translation> <translation id="8111155949205007504">Zdieľajte toto heslo so svojím zariadením iPhone</translation> <translation id="8113043281354018522">Vyberte typ licencie</translation> <translation id="8116190140324504026">Ďalšie informácie...</translation> @@ -4792,7 +4762,6 @@ <translation id="8308179586020895837">Opýtať sa, ak chcú stránky <ph name="HOST" /> pristupovať ku kamere</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certifikát už existuje</translation> -<translation id="8309505303672555187">Vyberte sieť:</translation> <translation id="8312871300878166382">Prilepiť do priečinka</translation> <translation id="8317671367883557781">Pridať sieťové pripojenie</translation> <translation id="8319414634934645341">Rozšírené použitie kľúča</translation> @@ -4867,7 +4836,6 @@ <translation id="8451512073679317615">asistent</translation> <translation id="8452135315243592079">Chýba SIM karta</translation> <translation id="8453482423012550001">Prebieha kopírovanie $1 položiek...</translation> -<translation id="8454288007744638700">Prípadne vyberte novú sieť:</translation> <translation id="845627346958584683">Čas vypršania platnosti</translation> <translation id="8456681095658380701">Neplatný názov</translation> <translation id="8457451314607652708">Import záložiek</translation> @@ -4969,7 +4937,6 @@ <translation id="862727964348362408">Pozastavené</translation> <translation id="862750493060684461">Vyrovnávacia pamäť CSS</translation> <translation id="8627795981664801467">Len bezpečné pripojenia</translation> -<translation id="8628085465172583869">Názov hostiteľského servera:</translation> <translation id="8630903300770275248">Importovať kontrolovaného používateľa</translation> <translation id="8631032106121706562">Lupienky</translation> <translation id="8637542770513281060">Váš počítač obsahuje bezpečnostný modul, ktorý sa v systéme Chrome OS používa na implementáciu mnohých dôležitých bezpečnostných funkcií. Ďalšie informácie nájdete v centre pomoci pre Chromebooky na adrese https://support.google.com/chromebook/?p=sm</translation> @@ -5225,7 +5192,6 @@ <translation id="899403249577094719">Netscape – základná webová adresa certifikátu</translation> <translation id="8995603266996330174">Spravované doménou <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Pridať účet...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Vytvára sa obraz disku.</translation> <translation id="9003647077635673607">Povoliť na všetkých webových stránkach</translation> <translation id="9003677638446136377">Skontrolovať znova</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb index a9d4fde..c7dcdf8 100644 --- a/chrome/app/resources/generated_resources_sl.xtb +++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Skoraj je že čas za odmor</translation> <translation id="1062407476771304334">Zamenjaj</translation> -<translation id="1064835277883315402">Pridružite se zasebnemu omrežju</translation> <translation id="1064912851688322329">Prekinitev povezave z Google Računom</translation> <translation id="1067048845568873861">Ustvarjeno</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Iskanje ...</translation> <translation id="1316495628809031177">Sinhronizacija je zaustavljena</translation> <translation id="1319979322914001937">Aplikacija, ki prikaže filtriran seznam razširitev v Spletni trgovini Chrome. Razširitve na seznamu je mogoče namestiti neposredno iz aplikacije.</translation> -<translation id="132090119144658135">Ujemanje zadeve:</translation> <translation id="1326317727527857210">Če želite dostopati do zavihkov v drugih napravah, se prijavite v Chrome.</translation> <translation id="1327074568633507428">Tiskalnik v Google Tiskanju v oblaku</translation> <translation id="1327977588028644528">Prehod</translation> @@ -377,6 +375,7 @@ <translation id="1531004739673299060">Okno aplikacije</translation> <translation id="1534389735079119190">NAPAKA: vsebnika ni bilo mogoče zagnati znotraj navideznega računalnika.</translation> <translation id="15373452373711364">Velik miškin kazalec</translation> +<translation id="1540605929960647700">Omogočanje predstavitvenega načina</translation> <translation id="1543284117603151572">Uvoženo iz brskalnika Edge</translation> <translation id="1545177026077493356">Samodejni način kiosk</translation> <translation id="1545775234664667895">Nameščena tema »<ph name="THEME_NAME" />«</translation> @@ -460,6 +459,7 @@ <translation id="1657406563541664238">Pomagajte izboljšati <ph name="PRODUCT_NAME" /> s samodejnim pošiljanjem statističnih podatkov o uporabi in poročil o zrušitvah Googlu</translation> <translation id="1658424621194652532">Ta stran dostopa do vašega mikrofona.</translation> <translation id="1660204651932907780">Dovoli spletnim mestom predvajanje zvoka (priporočljivo)</translation> +<translation id="1660938185063657230">Preverjanje varnostnega ključa</translation> <translation id="1661156625580498328">Vsili šifriranje AES (priporočeno).</translation> <translation id="1661245713600520330">Stran navaja vse module, naložene v glavni proces in module, registrirane za poznejšo naložitev.</translation> <translation id="166179487779922818">Geslo je prekratko.</translation> @@ -477,6 +477,7 @@ <translation id="16815041330799488">Spletnim mestom ne dovoli ogleda besedila in slik, kopiranih v odložišče</translation> <translation id="1682548588986054654">Novo &okno brez beleženja zgodovine</translation> <translation id="168715261339224929">Če želite dostopati do zaznamkov v vseh napravah, vklopite sinhronizacijo.</translation> +<translation id="1688867105868176567">Ali želite izbrisati podatke spletnega mesta?</translation> <translation id="1688935057616748272">Vnesite črko</translation> <translation id="168991973552362966">Dodajanje tiskalnika v bližini</translation> <translation id="1689945336726856614">Kopiranje &URL-ja</translation> @@ -488,7 +489,6 @@ <translation id="1701062906490865540">Odstrani to osebo</translation> <translation id="1706586824377653884">Dodal skrbnik</translation> <translation id="1706625117072057435">Ravni povečave/pomanjšave</translation> -<translation id="1707463636381878959">Skupna raba tega omrežja z drugimi uporabniki</translation> <translation id="1708338024780164500">(Neaktivno)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (izvorna)</translation> @@ -524,7 +524,6 @@ <translation id="175772926354468439">Omogoči temo</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Prikaži v Spletni trgovini Chrome</translation> -<translation id="1758831820837444715">Konfiguriranje etherneta</translation> <translation id="1763046204212875858">Ustvari bližnjice do &programov ...</translation> <translation id="1763108912552529023">Nadaljujte raziskovanje</translation> <translation id="1763808908432309942">Odpre se na novem zavihku</translation> @@ -583,8 +582,10 @@ <translation id="1839704667838141620">Spremeni način skupne rabe te datoteke</translation> <translation id="1841545962859478868">Skrbnik naprave morda nadzira naslednje:</translation> <translation id="1841705068325380214">Razširitev <ph name="EXTENSION_NAME" /> je onemogočena</translation> +<translation id="1842766183094193446">Ali ste prepričani, da želite omogočiti predstavitveni način?</translation> <translation id="1844692022597038441">Ta datoteka ni na voljo brez povezave.</translation> <translation id="1846308012215045257">Pridržite tipko »control« in kliknite za zagon vtičnika <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Shranjeno</translation> <translation id="1848219224579402567">Odjava, ko je pokrov zaprt</translation> <translation id="184823282865851239">Blokiraj, če spletno mesto prikazuje vsiljive oglase</translation> <translation id="1849186935225320012">To spletno mesto ima popolni nadzor nad napravami MIDI.</translation> @@ -682,6 +683,7 @@ <translation id="200544492091181894">To lahko pozneje spremenite v nastavitvah</translation> <translation id="2006638907958895361">Odpiranje povezave v aplikaciji <ph name="APP" /></translation> <translation id="2007404777272201486">Prijavi težavo ...</translation> +<translation id="2016237810978710652">Odpiranje datotek za Linux ...</translation> <translation id="2016430552235416146">Tradicionalno</translation> <translation id="2017334798163366053">Onemogoči zbiranje podatkov o učinkovitosti delovanja</translation> <translation id="2017836877785168846">Izbriše zgodovino in samodokončanja v naslovni vrstici.</translation> @@ -776,6 +778,7 @@ <translation id="2154484045852737596">Urejanje kartice</translation> <translation id="2154710561487035718">Kopiraj URL</translation> <translation id="2155772377859296191">Videti je <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">S pošiljanjem nekaterih informacij o sistemu in vsebine strani Googlu lahko pomagate izboljšati Varno brskanje.</translation> <translation id="215753907730220065">Izhod iz celozaslonskega načina</translation> <translation id="2157875535253991059">Ta stran je zdaj prikazana na celotnem zaslonu.</translation> <translation id="216169395504480358">Dodaj Wi-Fi ...</translation> @@ -785,6 +788,7 @@ <translation id="2173801458090845390">Dodajanje ID-ja zahteve tej napravi</translation> <translation id="2175042898143291048">Vedno izvedi to</translation> <translation id="2175607476662778685">Vrstica za hitri zagon</translation> +<translation id="2176087259161165020">Drugi viri</translation> <translation id="2177950615300672361">Zavihek za način brez beleženja zgodovine: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Vtičnik <ph name="PEPPER_PLUGIN_NAME" /> v domeni <ph name="PEPPER_PLUGIN_DOMAIN" /> želi dostopati do vašega računalnika</translation> <translation id="2178614541317717477">Overitelj potrdil ni več varen</translation> @@ -868,7 +872,6 @@ <translation id="2291643155573394834">Naslednji zavihek</translation> <translation id="2292848386125228270">Zaženite <ph name="PRODUCT_NAME" /> kot običajni uporabnik. Če ga morate zaradi razvoja izvajati kot korenski uporabnik, ga znova zaženite z zastavico »--no-sandbox«.</translation> <translation id="2294358108254308676">Ali želite namestiti <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Metoda EAP:</translation> <translation id="2297705863329999812">Iskanje tiskalnikov</translation> <translation id="2300383962156589922">Prilagajanje in nadziranje aplikacije <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Korenski imenik razširitve je neveljaven.</translation> @@ -916,6 +919,7 @@ <translation id="2366463953911599217">NAPAKA: odstranjevanje aplikacije <ph name="APP_NAME" /> ni uspelo.</translation> <translation id="2367199180085172140">Dodajanje naprave za skupno rabo datotek</translation> <translation id="2367972762794486313">Pokaži aplikacije</translation> +<translation id="2369536625682139252">Izbrisani bodo vsi podatki, ki jih je shranilo spletno mesto <ph name="SITE" />, razen piškotkov.</translation> <translation id="2371076942591664043">Odpri, ko je &dokončano</translation> <translation id="2377319039870049694">Preklop na pogled seznama</translation> <translation id="2377667304966270281">Težke napake</translation> @@ -925,7 +929,6 @@ <translation id="2379281330731083556">Tiskanje v pogovornem oknu sistema ... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Vprašaj pred pošiljanjem (priporočljivo)</translation> <translation id="2384436799579181135">Prišlo je do napake. Preverite tiskalnik in poskusite znova.</translation> -<translation id="2385700042425247848">Ime storitve:</translation> <translation id="2387458720915042159">Vrsta povezave strežnika proxy</translation> <translation id="2391419135980381625">Standardna pisava</translation> <translation id="2391762656119864333">Prekliči</translation> @@ -976,7 +979,6 @@ <translation id="247949520305900375">Skupna raba zvoka</translation> <translation id="2480868415629598489">Spreminjanje podatkov, ki jih kopirate in prilepite</translation> <translation id="2482878487686419369">Obvestila</translation> -<translation id="2485056306054380289">Overjeno strežniško potrdilo</translation> <translation id="2485422356828889247">Odstranjevanje</translation> <translation id="2487067538648443797">Dodaj nov zaznamek</translation> <translation id="248861575772995840">Telefona ni mogoče najti. Bluetooth v napravi <ph name="DEVICE_TYPE" /> mora biti vklopljen. <a>Več o tem</a></translation> @@ -1037,6 +1039,7 @@ <translation id="2566124945717127842">Uporabite Powerwash za ponastavitev naprave <ph name="IDS_SHORT_PRODUCT_NAME" />, da bo kot nova.</translation> <translation id="2567257616420533738">Geslo je shranjeno. Shranjena gesla si je mogoče ogledati na <ph name="SAVED_PASSWORDS_LINK" /> in tam jih je mogoče tudi upravljati.</translation> <translation id="2568774940984945469">Vsebnik informacijske vrstice</translation> +<translation id="2570454805927264159">Kar najbolje izkoristite Pomočnika</translation> <translation id="257088987046510401">Teme</translation> <translation id="2572032849266859634">Odobren je dostop samo za branje za <ph name="VOLUME_NAME" />.</translation> <translation id="2573269395582837871">Izberite sliko in ime</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">Pošlji</translation> <translation id="265390580714150011">Vrednost polja</translation> <translation id="2654166010170466751">Spletnim mestom dovoli namestitev rutin za obravnavo plačil</translation> -<translation id="2655386581175833247">Uporabniško potrdilo:</translation> <translation id="2660779039299703961">Dogodek</translation> <translation id="266079277508604648">Ni se mogoče povezati s tiskalnikom. Preverite, ali je tiskalnik vklopljen in povezan s Chromebookom prek omrežja Wi-Fi ali z USB-jem.</translation> <translation id="2661146741306740526">16 x 9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">Ni podatkov o uporabi</translation> <translation id="3007214526293698309">Popravi razmerje</translation> <translation id="3007771295016901659">Duplicate Tab</translation> +<translation id="3008272652534848354">Ponastavi dovoljenja</translation> <translation id="3009300415590184725">Ali ste prepričani, da želite preklicati postopek nastavitve mobilne podatkovne storitve?</translation> <translation id="3009779501245596802">Indeksirane zbirke podatkov</translation> <translation id="3010279545267083280">Geslo je izbrisano</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">Moduli (<ph name="TOTAL_COUNT" />) – Znani spori: <ph name="BAD_COUNT" />, domnevno: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Datum in ura</translation> <translation id="310671807099593501">Spletno mesto uporablja Bluetooth</translation> -<translation id="3108967419958202225">Izberite ...</translation> <translation id="3115128645424181617">Telefona ni mogoče najti. Imeti ga morate pri roki in vklopiti morate Bluetooth.</translation> <translation id="3115147772012638511">Čakam predpomnilnik ...</translation> <translation id="3118319026408854581">Pomoč za <ph name="PRODUCT_NAME" /> </translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">Nekateri operaterji morda blokirajo to funkcijo.</translation> <translation id="316854673539778496">Če želite dostopati do razširitev v vseh napravah, se prijavite in vklopite sinhronizacijo.</translation> <translation id="3170072451822350649">Prijavo lahko tudi preskočite in <ph name="LINK_START" />brskate kot gost<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Kliknite, če želite skriti geslo</translation> <translation id="3177909033752230686">Jezik strani:</translation> <translation id="3181110748548073003">Pritisnite |<ph name="SHORTCUT" />|, če želite nadaljevati</translation> <translation id="3182749001423093222">Preverjanje črkovanja</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187">Lastništvo bo preneseno v domeno <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Odpiranje možnosti razširitev</translation> <translation id="3241680850019875542">Izberite korenski imenik razširitve, ki jo želite zapakirati. Če želite posodobiti razširitev, izberite tudi datoteko z zasebnim ključem, ki jo želite znova uporabiti.</translation> -<translation id="3242765319725186192">Ključ v predhodni skupni rabi:</translation> <translation id="3244294424315804309">Zvok naj bo še naprej izklopljen</translation> <translation id="3245321423178950146">Neznan izvajalec</translation> <translation id="3246097286174000800">Preskusite Smart Lock</translation> @@ -1608,7 +1608,6 @@ <translation id="3440663250074896476">Več dejanj za <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Vprašaj, ko želi spletno mesto z vtičnikom dostopati do računalnika</translation> <translation id="3441653493275994384">Zaslon</translation> -<translation id="3445830502289589282">2. del preverjanja pristnosti:</translation> <translation id="344630545793878684">Branje vaših podatkov na več spletnih mestih</translation> <translation id="3449839693241009168">Pritisnite <ph name="SEARCH_KEY" />, če želite poslati ukaze v <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Odstotek zasedenosti stanja nedejavnosti</translation> @@ -1649,7 +1648,6 @@ <translation id="3495304270784461826">Št. napak: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Nastavitve Pomočnika Google</translation> <translation id="3496213124478423963">Pomanjšaj</translation> -<translation id="3504135463003295723">Ime skupine:</translation> <translation id="3505030558724226696">Umakni dostop do naprav</translation> <translation id="3507421388498836150">Trenutna dovoljenja za »<ph name="EXTENSION_NAME" />«</translation> <translation id="3507547268929739059">Odstranjevanje aplikacij za Linux za Chromebook</translation> @@ -1758,7 +1756,6 @@ <translation id="3661054927247347545">Potrdilo za prijavo ni veljavno; okno se bo zaprlo čez <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Ikona razširitve</translation> <translation id="3665589677786828986">Chrome je zaznal, da je drug program spremenil nastavitve, in jih ponastavil na prvotne privzete nastavitve.</translation> -<translation id="3665842570601375360">Varnost:</translation> <translation id="3668570675727296296">Jezikovne nastavitve</translation> <translation id="3668823961463113931">Kontrolniki</translation> <translation id="3670229581627177274">Vklop vmesnika Bluetooth</translation> @@ -1797,7 +1794,6 @@ <translation id="3726463242007121105">Naprave ni mogoče odpreti, ker njen datotečni sistem ni podprt.</translation> <translation id="3727148787322499904">Sprememba te nastavitve vpliva na vsa omrežja v skupni rabi</translation> <translation id="3727187387656390258">Preglej pojavno okno</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Napaka v vrstici <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Strežnik SSL z nadgradnjo</translation> <translation id="3737536731758327622">Tu so prikazani prenosi</translation> @@ -1872,7 +1868,6 @@ <translation id="38275787300541712">Ko končate, pritisnite Enter</translation> <translation id="3827774300009121996">&Celozaslonsko</translation> <translation id="3828029223314399057">Išči po zaznamkih</translation> -<translation id="3829932584934971895">Vrsta ponudnika:</translation> <translation id="3830674330436234648">Predvajanje ni na voljo</translation> <translation id="3831486154586836914">Izbran je način pregleda okna</translation> <translation id="383161972796689579">Lastnik te naprave je onemogočil dodajanje novih uporabnikov</translation> @@ -1893,6 +1888,7 @@ <translation id="3856921555429624101">Merjenje porabe podatkov je končano</translation> <translation id="3857228364945137633">Preskusite Smart Lock za odklepanje naprave <ph name="DEVICE_TYPE" /> brez gesla, ko je telefon v bližini.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: sinhronizacija zaustavljena</translation> <translation id="3860381078714302691">Pozdravljeni v storitvi Hangouts Meet</translation> <translation id="3862134173397075045">Pozdravljeni v doživetju predvajanja v Chromu.</translation> <translation id="3862788408946266506">Aplikacijo z atributom manifesta »kiosk_only« je treba namestiti v načinu kioska sistema OS Chrome</translation> @@ -1970,7 +1966,6 @@ <translation id="3968261067169026421">Omrežja ni bilo mogoče nastaviti</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Izračunavanje …</translation> -<translation id="3974195870082915331">Kliknite, če želite prikazati geslo</translation> <translation id="3975222297214566386">Oblaček z možnostmi vnosa</translation> <translation id="397703832102027365">Dokončanje ...</translation> <translation id="3979395879372752341">Nova razširitev je dodana (<ph name="EXTENSION_NAME" />)</translation> @@ -2012,6 +2007,7 @@ <translation id="4044612648082411741">Vnesite geslo za potrdilo</translation> <translation id="404493185430269859">Privzeti iskalnik</translation> <translation id="4047112090469382184">Kako je to varno</translation> +<translation id="4051049974203704184">Ogled informacij o tem, kaj je na zaslonu</translation> <translation id="4052120076834320548">Drobna</translation> <translation id="4055023634561256217">Pred ponastavitvijo naprave s funkcijo Powerwash je potreben vnovičen zagon.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> – <ph name="RECEIVED_AMOUNT" /></translation> @@ -2040,6 +2036,7 @@ <translation id="4088095054444612037">Sprejmi za skupino</translation> <translation id="4089235344645910861">Nastavitve so bile shranjene. Sinhronizacija se je začela.</translation> <translation id="4090103403438682346">Omogočanje preverjenega dostopa</translation> +<translation id="4090947011087001172">Ali želite ponastaviti dovoljenja za spletno mesto <ph name="SITE" />?</translation> <translation id="4091434297613116013">listi papirja</translation> <translation id="4093955363990068916">Lokalna datoteka:</translation> <translation id="4095507791297118304">Glavni zaslon</translation> @@ -2216,7 +2213,6 @@ <translation id="4419556793104466535">Nadziranje sinhronizacije, prilagajanja in drugega</translation> <translation id="4421932782753506458">Puhek</translation> <translation id="4422347585044846479">Uredite zaznamek za to stran</translation> -<translation id="4423104065312875417">Namestitev dodatnih mehanizmov govora</translation> <translation id="4423376891418188461">Obnovi nastavitve</translation> <translation id="4423482519432579560">&Črkovalnik</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, skrbnik zahteva, da spremenite geslo.</translation> @@ -2241,7 +2237,6 @@ <translation id="4449996769074858870">Na tem zavihku se predvaja zvok.</translation> <translation id="4450974146388585462">Diagnosticiraj</translation> <translation id="4453946976636652378">Uporabite <ph name="SEARCH_ENGINE_NAME" /> za iskanje ali vnesite URL</translation> -<translation id="445923051607553918">Pridružite se omrežju Wi-Fi</translation> <translation id="4462159676511157176">Imenski strežniki po meri</translation> <translation id="4467100756425880649">Galerija za Spletno trgovino Chrome</translation> <translation id="4467101674048705704">Razširi <ph name="FOLDER_NAME" /></translation> @@ -2377,6 +2372,7 @@ <translation id="4682551433947286597">Ozadja so prikazana na zaslonu za prijavo.</translation> <translation id="4684427112815847243">Sinhroniziraj vse</translation> <translation id="4689421377817139245">Sinhronizacija tega zaznamka z iPhonom</translation> +<translation id="4690091457710545971"><Štiri datoteke, ki jih generira Intelova vdelana programska oprema za Wi-Fi: csr.lst, fh_regs.lst, radio_reg.lst in monitor.lst.sysmon. Prve tri so dvojiške datoteke, ki vsebujejo izvoze registra in Intel zanje zagotavlja, da ne vsebujejo osebnih podatkov ali podatkov, ki bi omogočali prepoznavo naprave. Zadnja datoteka je sled izvajanja iz Intelove vdelane programske opreme; očiščena je vseh osebnih podatkov ali podatkov, ki bi omogočali prepoznavo naprave, vendar je prevelika, da bi jo bilo mogoče prikazati tukaj. Te datoteke so bile generirane kot odziv na nedavne težave z Wi-Fi-jem v vaši napravi in bodo posredovane Intelu za pomoč pri odpravljanju teh težav.></translation> <translation id="4692302215262324251">Napravo <ph name="DEVICE_TYPE" /> je za upravljanje v poslovnem okolju uspešno včlanila domena <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Če je to nepričakovano, se obrnite na podporo.</translation> @@ -2636,6 +2632,7 @@ <translation id="5074318175948309511">Nove nastavitve bodo morda začele veljati, šele ko znova naložite to stran.</translation> <translation id="5075131525758602494">Vnos kode PIN za kartico SIM</translation> <translation id="5078638979202084724">Dodaj vse zavihke med zaznamke</translation> +<translation id="5079950360618752063">Uporabi predlagano geslo</translation> <translation id="5084230410268011727">Spletnim mestom dovoli uporabo tipal za gibanje in svetlobo</translation> <translation id="5085162214018721575">Preverjanje, ali so na voljo posodobitve</translation> <translation id="5086082738160935172">HID</translation> @@ -2674,6 +2671,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Izbriši ta element</translation> <translation id="5139955368427980650">&Odpri</translation> +<translation id="5142961317498132443">Preverjanje pristnosti</translation> <translation id="5143374789336132547">Zaradi razširitve <ph name="EXTENSION_NAME" /> se je spremenila stran, ki je prikazana, ko kliknete gumb za začetno stran.</translation> <translation id="5143712164865402236">Prehod v celozaslonski način</translation> <translation id="5145331109270917438">Datum spremembe</translation> @@ -2844,7 +2842,6 @@ <translation id="5380103295189760361">Držite tipko Ctrl, Alt, Shift ali tipko za iskanje, če želite videti bližnjične tipke za te modifikatorje.</translation> <translation id="5382591305415226340">Upravljanje podprtih povezav</translation> <translation id="5384883051496921101">To spletno mesto bo delilo podatke z aplikacijo zunaj načina brez beleženja zgodovine.</translation> -<translation id="5388588172257446328">Uporabniško ime:</translation> <translation id="5388885445722491159">Povezano</translation> <translation id="5389237414310520250">Novega uporabnika ni bilo mogoče ustvariti. Preverite, koliko je prostora na trdem disku in dovoljenja, ter poskusite znova.</translation> <translation id="5390100381392048184">Dovoli spletnim mestom predvajanje zvoka</translation> @@ -2969,7 +2966,6 @@ <translation id="5551573675707792127">Tipkovnica in vnos besedila</translation> <translation id="5553089923092577885">Preslikave pravilnika potrdila</translation> <translation id="5554489410841842733">Ta ikona bo vidna, ko lahko razširitev deluje na trenutni strani.</translation> -<translation id="5554573843028719904">Drugo omrežje Wi-Fi ...</translation> <translation id="5554720593229208774">Overitelj potrdil za e-pošto</translation> <translation id="5556206011531515970">Kliknite »Naprej«, da izberete privzeti brskalnik.</translation> <translation id="5556459405103347317">Ponovno naloži</translation> @@ -3010,7 +3006,6 @@ <translation id="5610038042047936818">Preklopi v osnovni način fotoaparata</translation> <translation id="5612720917913232150"><ph name="URL" /> želi uporabljati lokacijo vašega računalnika</translation> <translation id="5612734644261457353">Vašega gesla še ni bilo mogoče preveriti. Opomba: Če ste v zadnjem času spremenili geslo, bo novo geslo začelo veljati, ko se odjavite. Tu uporabite starega.</translation> -<translation id="5613695965848159202">Anonimna identiteta:</translation> <translation id="5614190747811328134">Uporabniško obvestilo</translation> <translation id="561698261642843490">Zapiranje Firefoxa</translation> <translation id="5618075537869101857">Presneto, aplikacije Kiosk ni bilo mogoče zagnati.</translation> @@ -3229,7 +3224,6 @@ <translation id="5941343993301164315">Prijavite se v <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Pomanjšaj</translation> <translation id="5946591249682680882">ID poročila: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Dodaj zasebno omrežje</translation> <translation id="5949544233750246342">Datoteke ni mogoče razčleniti</translation> <translation id="5955282598396714173">Geslo je poteklo. Odjavite se in se nato znova prijavite, da ga spremenite.</translation> <translation id="5956585768868398362">Ali je to iskalna stran, ki ste jo pričakovali?</translation> @@ -3390,11 +3384,13 @@ <translation id="6198102561359457428">Odjavite se in znova prijavite ...</translation> <translation id="6198252989419008588">Spremeni PIN</translation> <translation id="6199801702437275229">Čakanje na podatke o prostoru ...</translation> +<translation id="6204015976622790023">Ogled ustreznih predlogov Pomočnika glede na vsebino zaslona.</translation> <translation id="6205710420833115353">Nekateri postopki trajajo dlje, kot je pričakovano. Ali jih želite opustiti?</translation> <translation id="6206311232642889873">Kop&iraj sliko</translation> <translation id="6207200176136643843">Ponastavitev na privzeto stopnjo povečave/pomanjšave</translation> <translation id="620722923698527029">Vedno odpri povezave te vrste v povezani aplikaciji</translation> <translation id="6207937957461833379">Država/regija</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: sinhronizacija ne deluje</translation> <translation id="6212039847102026977">Prikaži dodatne lastnosti omrežja</translation> <translation id="6212168817037875041">Izklop zaslona</translation> <translation id="6212752530110374741">Pošlji povezavo po e-pošti</translation> @@ -3432,7 +3428,6 @@ <translation id="6263541650532042179">ponastavi sinhronizacijo</translation> <translation id="6264365405983206840">Izberi &vse</translation> <translation id="6264422956566238156">Vklopili ste sinhroniziranje</translation> -<translation id="6265930187414222160">Končano. Škodljiva programska oprema je odstranjena.</translation> <translation id="6267166720438879315">Izberite potrdilo za preverjanje pristnosti za <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Odpri z aplikacijo <ph name="APP" /></translation> <translation id="6268747994388690914">Uvoz zaznamkov iz datoteke HTML ...</translation> @@ -3539,7 +3534,6 @@ Kliknite »Naprej«, če želite nadaljevati prijavo v račun za <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Naloži razpakirano</translation> <translation id="642282551015776456">Tega imena ne morete uporabiti kot ime za datoteko ali mapo</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Odpri nastavitve ChromeVoxa</translation> <translation id="6429384232893414837">Napaka glede posodobitve</translation> <translation id="6430814529589430811">Base64 kodiran ASCII, enojno potrdilo</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">Googlov brskalnik za vas</translation> <translation id="6545665334409411530">Hitrost ponavljanja</translation> <translation id="6545834809683560467">Za pomoč pri dokončanju iskalnih poizvedb in URL-jev, vnesenih v naslovno vrstico ali iskalno polje zaganjalnika aplikacij, uporabite storitev za predvidevanje</translation> -<translation id="6546686722964485737">Pridružite se omrežju WiMAX</translation> <translation id="6547316139431024316">Ne opozori več za to razširitev</translation> <translation id="6547354035488017500">Sprostite najmanj 512 MB prostora, sicer bo postala naprava neodzivna. Če želite sprostiti prostor, izbrišite datoteke iz shrambe v napravi.</translation> <translation id="6549689063733911810">Nedavno</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Ni si mogoče ogledati datotek za Linux</translation> <translation id="720110658997053098">Ta naprava naj bo trajno v načinu kioska</translation> <translation id="7201118060536064622">Element »<ph name="DELETED_ITEM_NAME" />« je izbrisan</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Prenos vtičnika <ph name="PLUGIN_NAME" /> ...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Izhodna stran}one{Izhodne strani}two{Izhodne strani}few{Izhodne strani}other{Izhodne strani}}</translation> <translation id="7216409898977639127">Ponudnik mobilnih storitev</translation> @@ -4516,7 +4508,6 @@ <translation id="7909969815743704077">Preneseno v načinu brez beleženja zgodovine</translation> <translation id="7910768399700579500">&Nova mapa</translation> <translation id="7912080627461681647">Geslo je bilo spremenjeno v strežniku. Odjavite se in se nato znova prijavite.</translation> -<translation id="7912883689016444961">Konfiguriraj mobilno omrežje</translation> <translation id="7915471803647590281">Povejte nam, kaj se dogaja, preden nam pošljete povratne informacije.</translation> <translation id="7916556741383518510">Ob kliku</translation> <translation id="792514962475806987">Stopnja povečave zasidrane lupe:</translation> @@ -4570,7 +4561,6 @@ <translation id="7988355189918024273">Omogoči funkcije za ljudi s posebnimi potrebami</translation> <translation id="7994702968232966508">Način EAP</translation> <translation id="799547531016638432">Odstrani bližnjico</translation> -<translation id="7997479212858899587">Identiteta:</translation> <translation id="7997826902155442747">Prednost postopkov</translation> <translation id="7999229196265990314">Ustvarjene so bile te datoteke: @@ -4654,7 +4644,6 @@ <translation id="8105368624971345109">Izklop</translation> <translation id="8106045200081704138">V skupni rabi z menoj</translation> <translation id="8107015733319732394">Nameščanje Trgovine Google Play v napravi <ph name="DEVICE_TYPE" />. To lahko traja nekaj minut.</translation> -<translation id="8109930990200908494">Za uporabniško potrdilo je potrebna prijava.</translation> <translation id="8111155949205007504">Deljenje tega gesla z iPhonom</translation> <translation id="8113043281354018522">Izberite vrsto licence</translation> <translation id="8116190140324504026">Več informacij ...</translation> @@ -4665,6 +4654,7 @@ <translation id="8118860139461251237">Upravljanje prenosov</translation> <translation id="81238879832906896">Rumena in bela roža</translation> <translation id="8124313775439841391">Upravljan ONC</translation> +<translation id="8125562866093998907">Spletno mesto želi zaradi dodatne varnosti v vašem računu preveriti vaš varnostni ključ.</translation> <translation id="813082847718468539">Ogled podatkov o mestu</translation> <translation id="8131740175452115882">Potrdi</translation> <translation id="8133676275609324831">&Pokaži v mapi</translation> @@ -4775,7 +4765,6 @@ <translation id="8308179586020895837">Vprašaj, ali <ph name="HOST" /> zahteva dostop do kamere</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Potrdilo že obstaja</translation> -<translation id="8309505303672555187">Izberite omrežje:</translation> <translation id="8312871300878166382">Prilepi v mapo</translation> <translation id="8317671367883557781">Dodaj omrežno povezavo</translation> <translation id="8319414634934645341">Razširjena raba ključa</translation> @@ -4850,7 +4839,6 @@ <translation id="8451512073679317615">pomočnik</translation> <translation id="8452135315243592079">Ni kartice SIM</translation> <translation id="8453482423012550001">Kopiranje toliko elementov: $1 ...</translation> -<translation id="8454288007744638700">Izberete lahko tudi novo omrežje:</translation> <translation id="845627346958584683">Ura poteka</translation> <translation id="8456681095658380701">Neveljavno ime</translation> <translation id="8457451314607652708">Uvozi zaznamke</translation> @@ -4914,6 +4902,7 @@ <translation id="855081842937141170">Pripni zavihek</translation> <translation id="8551388862522347954">Licence</translation> <translation id="8553342806078037065">Upravljanje drugih oseb</translation> +<translation id="8554899698005018844">Brez jezika</translation> <translation id="855773602626431402">Vtičniku brez varnostnih omejitev je bilo preprečeno izvajanje na tej strani.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Slikovni dekodirnik</translation> @@ -4951,7 +4940,6 @@ <translation id="862727964348362408">Onemogočeno</translation> <translation id="862750493060684461">Predpomnilnik CSS</translation> <translation id="8627795981664801467">Samo varne povezave</translation> -<translation id="8628085465172583869">Ime gostitelja strežnika</translation> <translation id="8630903300770275248">Uvoz zaščitenega uporabnika</translation> <translation id="8631032106121706562">Rožica</translation> <translation id="8637542770513281060">V računalnik je vgrajen varni modul, potreben za številne nujne varnostne funkcije v sistemu OS Chrome. Več o njem lahko preberete v centru za pomoč za Chromebook: https://support.google.com/chromebook/?p=tpm</translation> @@ -5207,7 +5195,6 @@ <translation id="899403249577094719">Osnovni spletni naslov Netscapeovega potrdila</translation> <translation id="8995603266996330174">Upravljavec: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Dodajanje računa ...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Ustvarjanje posnetka diska.</translation> <translation id="9003647077635673607">Dovoli na vseh spletnih mestih</translation> <translation id="9003677638446136377">Vnovično preverjanje</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb index 717a344..0e8fc60a 100644 --- a/chrome/app/resources/generated_resources_sr.xtb +++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Скоро је време за паузу</translation> <translation id="1062407476771304334">Замени</translation> -<translation id="1064835277883315402">Придруживање приватној мрежи</translation> <translation id="1064912851688322329">Прекид везе са Google налогом...</translation> <translation id="1067048845568873861">Направљено</translation> <translation id="1067291318998134776">Linux (бета)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Претраживање...</translation> <translation id="1316495628809031177">Синхронизација је паузирана</translation> <translation id="1319979322914001937">Апликација која приказује филтрирану листу додатака из Chrome веб-продавнице. Додатке са листе можете да инсталирате директно из апликације.</translation> -<translation id="132090119144658135">Подударање наслова:</translation> <translation id="1326317727527857210">Да би вам картице биле доступне на другим уређајима, пријавите се у Chrome.</translation> <translation id="1327074568633507428">Штампач у Google Cloud штампању</translation> <translation id="1327977588028644528">Мрежни пролаз</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">Прозор за апликацију</translation> <translation id="1534389735079119190">ГРЕШКА: Покретање контејнера у VM-у није успело.</translation> <translation id="15373452373711364">Велики курсор</translation> +<translation id="1540605929960647700">Омогућите режим демонстрације</translation> <translation id="1543284117603151572">Увезени из Edge-а</translation> <translation id="1545177026077493356">Аутоматски режим киоска</translation> <translation id="1545775234664667895">Инсталирана је тема „<ph name="THEME_NAME" />“</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">Помозите унапређивање <ph name="PRODUCT_NAME" /> прегледача тако што ћете аутоматски слати Google-у статистику коришћења и извештаје о отказивању</translation> <translation id="1658424621194652532">Ова страница приступа микрофону.</translation> <translation id="1660204651932907780">Дозволи сајтовима да пуштају звук (препоручено)</translation> +<translation id="1660938185063657230">Потврдите безбедносни кључ</translation> <translation id="1661156625580498328">Примени AES шифровање (препоручено).</translation> <translation id="1661245713600520330">Ова страница наводи све модуле учитане у главни процес и модуле регистроване за накнадно учитавање.</translation> <translation id="166179487779922818">Лозинка је прекратка.</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">Не дозвољавај сајтовима да виде текст и слике који су копирани у привремену меморију</translation> <translation id="1682548588986054654">Нови прозор без архивирања</translation> <translation id="168715261339224929">Да би вам обележивачи били доступни на свим уређајима, укључите синхронизацију.</translation> +<translation id="1688867105868176567">Желите ли да обришете податке сајта?</translation> <translation id="1688935057616748272">Унесите неко слово</translation> <translation id="168991973552362966">Додајте штампач у близини</translation> <translation id="1689945336726856614">Копирај &URL</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">Уклони ову особу</translation> <translation id="1706586824377653884">Додао администратор</translation> <translation id="1706625117072057435">Нивои зумирања</translation> -<translation id="1707463636381878959">Дели ову мрежу са другим корисницима</translation> <translation id="1708338024780164500">(Неактивно)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ИД: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Основна)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">Омогући тему</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Прикажи у Chrome веб-продавници</translation> -<translation id="1758831820837444715">Конфигурисање етернет мреже</translation> <translation id="1763046204212875858">Направите пречице за апликације</translation> <translation id="1763108912552529023">Настави са истраживањем</translation> <translation id="1763808908432309942">Отвара се на новој картици</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">Промените начин дељења ове датотеке</translation> <translation id="1841545962859478868">Администратор уређаја може да прати следеће:</translation> <translation id="1841705068325380214">Додатак <ph name="EXTENSION_NAME" /> је онемогућен</translation> +<translation id="1842766183094193446">Желите ли стварно да омогућите режим демонстрације?</translation> <translation id="1844692022597038441">Ова датотека није доступна ван мреже.</translation> <translation id="1846308012215045257">Кликните и задржите тастер Control да бисте покренули <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Сачувано</translation> <translation id="1848219224579402567">Одјави ме кад се поклопац затвори</translation> <translation id="184823282865851239">Блокирај ако сајт приказује огласе који ометају</translation> <translation id="1849186935225320012">Ова страница у потпуности контролише MIDI уређаје.</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">То можете да промените касније у подешавањима.</translation> <translation id="2006638907958895361">Отвори линк у <ph name="APP" /></translation> <translation id="2007404777272201486">Пријави проблем...</translation> +<translation id="2016237810978710652">Отварају се Linux датотеке...</translation> <translation id="2016430552235416146">Традиционално</translation> <translation id="2017334798163366053">Онемогући прикупљање података о учинку</translation> <translation id="2017836877785168846">Брише историју и аутоматска довршавања у траци за адресу.</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">Измените картицу</translation> <translation id="2154710561487035718">Копирање URL адресе</translation> <translation id="2155772377859296191">Изгледа да је у питању <ph name="WIDTH" />×<ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Можете да побољшате Безбедно прегледање ако пошаљете неке системске информације и садржај страница Google-у.</translation> <translation id="215753907730220065">Изађи из режима целог екрана</translation> <translation id="2157875535253991059">Ова страница је сада у режиму целог екрана.</translation> <translation id="216169395504480358">Додај Wi-Fi...</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">Додајте ИД захтева на овај уређај</translation> <translation id="2175042898143291048">Увек ради ово</translation> <translation id="2175607476662778685">Трака „Брзо покретање“</translation> +<translation id="2176087259161165020">Други извори</translation> <translation id="2177950615300672361">Картица Без архивирања: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Додатна компонента <ph name="PEPPER_PLUGIN_NAME" /> на домену <ph name="PEPPER_PLUGIN_DOMAIN" /> жели да приступи рачунару</translation> <translation id="2178614541317717477">CA је компромитован</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">Следећа картица</translation> <translation id="2292848386125228270">Покрените <ph name="PRODUCT_NAME" /> као обичан корисник. Ако треба да га покренете као основни производ ради програмирања, покрените га поново помоћу ознаке --no-sandbox.</translation> <translation id="2294358108254308676">Желите ли да инсталирате <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP метод:</translation> <translation id="2297705863329999812">Претражите штампаче</translation> <translation id="2300383962156589922">Прилагодите и контролишите апликацију <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Основни директоријум додатка је неважећи.</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">ГРЕШКА: Инсталирање апликације <ph name="APP_NAME" /> није успело.</translation> <translation id="2367199180085172140">Додајте дељење датотека</translation> <translation id="2367972762794486313">Прикажите апликације</translation> +<translation id="2369536625682139252">Сви подаци које <ph name="SITE" /> сачува биће избрисани осим колачића.</translation> <translation id="2371076942591664043">Отвори кад буде &довршено</translation> <translation id="2377319039870049694">Пређи на приказ листе</translation> <translation id="2377667304966270281">Грешке у вези са хард-диском</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">Штампај помоћу системског дијалога... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Питај пре слања (препоручује се)</translation> <translation id="2384436799579181135">Дошло је до грешке. Проверите штампач и пробајте поново.</translation> -<translation id="2385700042425247848">Назив услуге:</translation> <translation id="2387458720915042159">Тип везе са проксијем</translation> <translation id="2391419135980381625">Стандардни фонт</translation> <translation id="2391762656119864333">Опозови</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">Дели звук</translation> <translation id="2480868415629598489">Мењање података које прекопирате</translation> <translation id="2482878487686419369">Обавештења</translation> -<translation id="2485056306054380289">CA сертификат сервера:</translation> <translation id="2485422356828889247">Деинсталирај</translation> <translation id="2487067538648443797">Додај нови обележивач</translation> <translation id="248861575772995840">Не можемо да пронађемо телефон. Проверите да ли је на <ph name="DEVICE_TYPE" />-у укључен Bluetooth. <a>Сазнајте више</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">Powerwash ресетује <ph name="IDS_SHORT_PRODUCT_NAME" /> уређај да би био као нов.</translation> <translation id="2567257616420533738">Лозинка је сачувана. Прегледајте сачуване лозинке и управљајте њима на <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Контејнер траке са информацијама</translation> +<translation id="2570454805927264159">Максимално искористите Помоћник</translation> <translation id="257088987046510401">Теме</translation> <translation id="2572032849266859634">Одобрен је приступ за <ph name="VOLUME_NAME" /> само за читање.</translation> <translation id="2573269395582837871">Изаберите слику и име</translation> @@ -1095,7 +1098,6 @@ <translation id="2653659639078652383">Пошаљи</translation> <translation id="265390580714150011">Вредност поља</translation> <translation id="2654166010170466751">Дозволи сајтовима да инсталирају обрађиваче плаћања</translation> -<translation id="2655386581175833247">Сертификат корисника:</translation> <translation id="2660779039299703961">Догађај</translation> <translation id="266079277508604648">Повезивање са штампачем није успело. Проверите да ли је штампач укључен и повезан са Chromebook-ом помоћу Wi-Fi-ја или USB-а.</translation> <translation id="2661146741306740526">16×9</translation> @@ -1328,6 +1330,7 @@ <translation id="3006881078666935414">Нема података о коришћењу</translation> <translation id="3007214526293698309">Поправи сразмеру</translation> <translation id="3007771295016901659">Направи дупликат картице</translation> +<translation id="3008272652534848354">Ресетуј дозволе</translation> <translation id="3009300415590184725">Да ли сте сигурни да желите да откажете процес подешавања услуге мобилног преноса података?</translation> <translation id="3009779501245596802">Индексиране базе података</translation> <translation id="3010279545267083280">Лозинка је избрисана</translation> @@ -1394,7 +1397,6 @@ <translation id="3100609564180505575">Модули (<ph name="TOTAL_COUNT" />) – Позната сукобљавања: <ph name="BAD_COUNT" />, сумњиво: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Датум и време</translation> <translation id="310671807099593501">Сајт користи Bluetooth</translation> -<translation id="3108967419958202225">Изаберите...</translation> <translation id="3115128645424181617">Не можемо да пронађемо телефон. Проверите да ли је у близини и да ли је Bluetooth укључен.</translation> <translation id="3115147772012638511">Чека се кеш меморија...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> – помоћ</translation> @@ -1439,7 +1441,6 @@ <translation id="3165390001037658081">Неки мобилни оператери могу да блокирају ову функцију.</translation> <translation id="316854673539778496">Да би вам додаци били доступни на свим уређајима, пријавите се и укључите синхронизацију.</translation> <translation id="3170072451822350649">Можете и да прескочите пријављивање и да <ph name="LINK_START" />прегледате као гост<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Кликните да бисте сакрили лозинку</translation> <translation id="3177909033752230686">Језик странице:</translation> <translation id="3181110748548073003">Притисните |<ph name="SHORTCUT" />| да бисте ишли напред</translation> <translation id="3182749001423093222">Провера правописа</translation> @@ -1470,7 +1471,6 @@ <translation id="3236289833370040187">Власништво ће бити пренесено на <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Отвори опције додатака</translation> <translation id="3241680850019875542">Изаберите основни директоријум додатка за паковање. Да бисте ажурирали додатак, изаберите и датотеку приватног кључа која ће се поново користити.</translation> -<translation id="3242765319725186192">Тајни кључ:</translation> <translation id="3244294424315804309">Не укључуј звук</translation> <translation id="3245321423178950146">Непознати извођач</translation> <translation id="3246097286174000800">Испробајте Smart Lock</translation> @@ -1603,7 +1603,6 @@ <translation id="3440663250074896476">Још радњи за обележивач <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Питај када сајт жели да приступи мом рачунару помоћу додатне компоненте</translation> <translation id="3441653493275994384">Екран</translation> -<translation id="3445830502289589282">Потврда идентитета 2. фазе:</translation> <translation id="344630545793878684">Читање ваших података на више веб-сајтова</translation> <translation id="3449839693241009168">Притисните <ph name="SEARCH_KEY" /> да бисте послали команде у <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Проценат заузетости стања мировања</translation> @@ -1644,7 +1643,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> грешака.</translation> <translation id="3495660573538963482">Подешавања Google помоћника</translation> <translation id="3496213124478423963">Умањи</translation> -<translation id="3504135463003295723">Назив групе:</translation> <translation id="3505030558724226696">Опозови приступ уређају</translation> <translation id="3507421388498836150">Тренутне дозволе за „<ph name="EXTENSION_NAME" />“</translation> <translation id="3507547268929739059">Уклоните Linux апликације за Chromebook</translation> @@ -1753,7 +1751,6 @@ <translation id="3661054927247347545">Сертификат за пријављивање није важећи, прозор се затвара за <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Икона додатка</translation> <translation id="3665589677786828986">Chrome је открио да је други програм оштетио нека од подешавања и ресетовао их је на првобитне подразумеване вредности.</translation> -<translation id="3665842570601375360">Безбедност:</translation> <translation id="3668570675727296296">Подешавања језика</translation> <translation id="3668823961463113931">Обрађивачи</translation> <translation id="3670229581627177274">Укључи Bluetooth</translation> @@ -1792,7 +1789,6 @@ <translation id="3726463242007121105">Овај уређај не може да се отвори јер његов систем датотека није подржан.</translation> <translation id="3727148787322499904">Ако промените ово подешавање, то ће утицати на све дељене мреже</translation> <translation id="3727187387656390258">Испитај искачући прозор</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Грешка у <ph name="ERROR_LINE" />. реду</translation> <translation id="3733127536501031542">SSL сервер са могућношћу преласка на новију верзију</translation> <translation id="3737536731758327622">Преузимања ће се приказивати овде</translation> @@ -1867,7 +1863,6 @@ <translation id="38275787300541712">Притисните Enter када завршите</translation> <translation id="3827774300009121996">&Цео екран</translation> <translation id="3828029223314399057">Претражи обележиваче</translation> -<translation id="3829932584934971895">Тип добављача:</translation> <translation id="3830674330436234648">Репродукција није доступна</translation> <translation id="3831486154586836914">Ушли сте у режим прегледа прозора</translation> <translation id="383161972796689579">Власник овог уређаја је онемогућио додавање нових корисника</translation> @@ -1888,6 +1883,7 @@ <translation id="3856921555429624101">Мерење коришћења података је завршено</translation> <translation id="3857228364945137633">Испробајте Smart Lock да бисте откључавали <ph name="DEVICE_TYPE" /> без лозинке кад вам је телефон у близини.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: синхронизација је паузирана</translation> <translation id="3860381078714302691">Добро дошли у Hangouts Meet</translation> <translation id="3862134173397075045">Добро дошли у Cast доживљај у Chrome-у!</translation> <translation id="3862788408946266506">Апликација са атрибутом манифеста „kiosk_only“ мора да се инсталира у режиму киоска у Chrome ОС-у</translation> @@ -1965,7 +1961,6 @@ <translation id="3968261067169026421">Подешавање мреже није успело</translation> <translation id="3970114302595058915">ИД</translation> <translation id="397105322502079400">Израчунавање...</translation> -<translation id="3974195870082915331">Кликните да бисте приказали лозинку</translation> <translation id="3975222297214566386">Облачић за опције уноса</translation> <translation id="397703832102027365">Довршавање...</translation> <translation id="3979395879372752341">Додат је нови додатак (<ph name="EXTENSION_NAME" />)</translation> @@ -2007,6 +2002,7 @@ <translation id="4044612648082411741">Унесите лозинку за сертификат</translation> <translation id="404493185430269859">Подразумевани претраживач</translation> <translation id="4047112090469382184">Како је ово безбедно</translation> +<translation id="4051049974203704184">Преузмите информације о садржају екрана</translation> <translation id="4052120076834320548">Сићушна</translation> <translation id="4055023634561256217">Морате поново да покренете уређај да бисте могли да га вратите на почетне вредности помоћу Powerwash-а.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2035,6 +2031,7 @@ <translation id="4088095054444612037">Прихвати за групу</translation> <translation id="4089235344645910861">Подешавања су сачувана. Синхронизација је почела.</translation> <translation id="4090103403438682346">Омогућите верификовани приступ</translation> +<translation id="4090947011087001172">Желите ли да ресетујете дозволе за сајт <ph name="SITE" />?</translation> <translation id="4091434297613116013">листови папира</translation> <translation id="4093955363990068916">Локална датотека:</translation> <translation id="4095507791297118304">Главни приказ</translation> @@ -2211,7 +2208,6 @@ <translation id="4419556793104466535">Контролишите синхронизацију, персонализацију и још много тога</translation> <translation id="4421932782753506458">Пуфница</translation> <translation id="4422347585044846479">Измените обележивач за ову страницу</translation> -<translation id="4423104065312875417">Инсталирајте додатне механизме говора</translation> <translation id="4423376891418188461">Врати подешавања</translation> <translation id="4423482519432579560">&Провера правописа</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, администратор захтева да промените лозинку.</translation> @@ -2236,7 +2232,6 @@ <translation id="4449996769074858870">Ова картица репродукује звук.</translation> <translation id="4450974146388585462">Дијагностикуј</translation> <translation id="4453946976636652378">Претражите <ph name="SEARCH_ENGINE_NAME" /> или унесите URL</translation> -<translation id="445923051607553918">Придружите се Wi-Fi мрежи</translation> <translation id="4462159676511157176">Прилагођени сервери назива</translation> <translation id="4467100756425880649">Галерија Chrome веб-продавнице</translation> <translation id="4467101674048705704">Прошири директоријум <ph name="FOLDER_NAME" /></translation> @@ -2372,6 +2367,7 @@ <translation id="4682551433947286597">Позадине се приказују на екрану за пријављивање.</translation> <translation id="4684427112815847243">Синхронизуј све</translation> <translation id="4689421377817139245">Синхронизујте овај обележивач са iPhone-ом</translation> +<translation id="4690091457710545971"><Четири датотеке које је генерисао Intel фирмвер за Wi-Fi: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Прве три датотеке су бинарне датотеке које садрже исписе регистара и Intel потврђује да не садрже личне податке нити податке који могу да идентификују уређај. Последња датотека је траг извршења Intel фирмвера; из ње су уклоњени било какви лични подаци или подаци који могу да идентификују уређај, али је превелика да бисмо је овде приказали. Ове датотеке су генерисане као одговор на недавне проблеме са Wi-Fi-јем на уређају и делићемо их са Intel-ом да бисмо решили те проблеме.></translation> <translation id="4692302215262324251"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> је пријавио <ph name="DEVICE_TYPE" /> за управљање предузећем. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Ако то нисте очекивали, контактирајте подршку.</translation> @@ -2631,6 +2627,7 @@ <translation id="5074318175948309511">Можда треба поново да учитате ову страницу да би нова подешавања ступила на снагу.</translation> <translation id="5075131525758602494">Унесите PIN SIM картице</translation> <translation id="5078638979202084724">Обележавање свих картица</translation> +<translation id="5079950360618752063">Користите предложену лозинку</translation> <translation id="5084230410268011727">Дозволи сајтовима да користе сензоре за покрет и светло</translation> <translation id="5085162214018721575">Тражење ажурирања</translation> <translation id="5086082738160935172">Уређај са интерфејсом за људе</translation> @@ -2669,6 +2666,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Избриши ову ставку</translation> <translation id="5139955368427980650">&Отвори</translation> +<translation id="5142961317498132443">Потврда идентитета</translation> <translation id="5143374789336132547">Додатак „<ph name="EXTENSION_NAME" />“ је променио страницу која се приказује када кликнете на дугме Почетна.</translation> <translation id="5143712164865402236">Пређи на режим целог екрана</translation> <translation id="5145331109270917438">Датум измене</translation> @@ -2839,7 +2837,6 @@ <translation id="5380103295189760361">Држите Control, Alt, Shift или Search да бисте видели тастерске пречице за те модификаторе.</translation> <translation id="5382591305415226340">Управљај подржаним линковима</translation> <translation id="5384883051496921101">Овај сајт ће делити информације са апликацијом изван режима без архивирања.</translation> -<translation id="5388588172257446328">Корисничко име:</translation> <translation id="5388885445722491159">Упарено</translation> <translation id="5389237414310520250">Прављење новог корисника није успело. Проверите да ли имате довољно простора на хард-диску и одговарајуће дозволе и покушајте поново.</translation> <translation id="5390100381392048184">Дозволи сајтовима да пуштају звук</translation> @@ -2964,7 +2961,6 @@ <translation id="5551573675707792127">Тастатура и унос текста</translation> <translation id="5553089923092577885">Мапирања смерница сертификата</translation> <translation id="5554489410841842733">Ова икона ће бити видљива када додатак може да делује на тренутној страници.</translation> -<translation id="5554573843028719904">Друга Wi-Fi мрежа...</translation> <translation id="5554720593229208774">Ауторитет за издавање сертификата е-поште</translation> <translation id="5556206011531515970">Кликните на Даље да бисте изабрали подразумевани прегледач.</translation> <translation id="5556459405103347317">Учитај поново</translation> @@ -3005,7 +3001,6 @@ <translation id="5610038042047936818">Пребаци на режим камере</translation> <translation id="5612720917913232150"><ph name="URL" /> жели да користи локацију рачунара</translation> <translation id="5612734644261457353">Жао нам је, још увек није могуће верификовати лозинку. Напомена: Ако сте недавно променили лозинку, нова лозинка биће примењена када се одјавите. Овде користите стару лозинку.</translation> -<translation id="5613695965848159202">Непознати идентитет:</translation> <translation id="5614190747811328134">Обавештење о кориснику</translation> <translation id="561698261642843490">Затворите Firefox</translation> <translation id="5618075537869101857">До ђавола! Није могуће покренути киоск апликацију.</translation> @@ -3225,7 +3220,6 @@ <translation id="5941343993301164315">Пријавите се на <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Смањи</translation> <translation id="5946591249682680882">ИД извештаја <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Додај приватну мрежу</translation> <translation id="5949544233750246342">Рашчлањивање датотеке није успело</translation> <translation id="5955282598396714173">Лозинка је истекла. Одјавите се, па се поново пријавите да бисте је променили.</translation> <translation id="5956585768868398362">Је ли ово страница претраге коју сте очекивали?</translation> @@ -3386,11 +3380,13 @@ <translation id="6198102561359457428">Одјави ме, па ме поново пријави...</translation> <translation id="6198252989419008588">Промени PIN</translation> <translation id="6199801702437275229">Чекају се информације о простору...</translation> +<translation id="6204015976622790023">Погледајте релевантне предлоге Помоћника у вези са оним што је на екрану.</translation> <translation id="6205710420833115353">Неке радње трају дуже од очекиваног. Желите ли да их прекинете?</translation> <translation id="6206311232642889873">Коп&ирај слику</translation> <translation id="6207200176136643843">Ресетуј на подразумевани ниво зумирања</translation> <translation id="620722923698527029">Увек отварај ове типове линкова у повезаној апликацији</translation> <translation id="6207937957461833379">Земља/регија</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: синхронизација не ради</translation> <translation id="6212039847102026977">Прикажи напредна својства мреже</translation> <translation id="6212168817037875041">Искључи екран</translation> <translation id="6212752530110374741">Пошаљи линк имејлом</translation> @@ -3428,7 +3424,6 @@ <translation id="6263541650532042179">враћање синхронизације на почетне вредности</translation> <translation id="6264365405983206840">Изабери &све</translation> <translation id="6264422956566238156">Искључили сте синхронизацију</translation> -<translation id="6265930187414222160">Готово! Штетан софтвер је уклоњен.</translation> <translation id="6267166720438879315">Изаберите сертификат да бисте потврдили идентитет хосту <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Отвори помоћу апликације <ph name="APP" /></translation> <translation id="6268747994388690914">Увези обележиваче из HTML датотеке...</translation> @@ -3535,7 +3530,6 @@ Кликните на „Даље“ да бисте наставили пријављивање на налог за <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Учитајте отпакованo</translation> <translation id="642282551015776456">Овај назив не може да се користи као назив датотеке или директоријума</translation> -<translation id="6423239382391657905">Отворена VPN</translation> <translation id="6426200009596957090">Отвори подешавања ChromeVox-а</translation> <translation id="6429384232893414837">Грешка при ажурирању</translation> <translation id="6430814529589430811">ASCII датотека шифрована методом „Base64“, један сертификат</translation> @@ -3615,7 +3609,6 @@ <translation id="6544215763872433504">Google-ов веб-прегледач за вас</translation> <translation id="6545665334409411530">Брзина понављања</translation> <translation id="6545834809683560467">Користите услугу предвиђања за довршавање упита за претрагу и URL-ова које куцате у траци за адресу или оквиру за претрагу у покретачу апликација</translation> -<translation id="6546686722964485737">Придруживање WiMAX мрежи</translation> <translation id="6547316139431024316">Не упозоравај поново за овај додатак</translation> <translation id="6547354035488017500">Ослободите бар 512 MB простора или ће уређај престати да се одазива. Да бисте ослободили простор, избришите датотеке из меморијског простора уређаја.</translation> <translation id="6549689063733911810">Недавно</translation> @@ -4034,7 +4027,6 @@ <translation id="7201014958346994077">Приказ Linux датотека није успео</translation> <translation id="720110658997053098">Трајно задржи овај уређај у режиму киоска</translation> <translation id="7201118060536064622">Ставка „<ph name="DELETED_ITEM_NAME" />“ је избрисана</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Преузимање додатне компоненте <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Затвори страницу}one{Затвори странице}few{Затвори странице}other{Затвори странице}}</translation> <translation id="7216409898977639127">Мобилни оператер</translation> @@ -4512,7 +4504,6 @@ <translation id="7909969815743704077">Преузето је у режиму без архивирања</translation> <translation id="7910768399700579500">&Нови директоријум</translation> <translation id="7912080627461681647">Лозинка је промењена на серверу. Одјавите се, па се поново пријавите.</translation> -<translation id="7912883689016444961">Кофигуриши мобилну мрежу</translation> <translation id="7915471803647590281">Реците нам шта се дешава пре него што пошаљете повратне информације.</translation> <translation id="7916556741383518510">При клику</translation> <translation id="792514962475806987">Ниво зумирања монтиране лупе екрана:</translation> @@ -4566,7 +4557,6 @@ <translation id="7988355189918024273">Омогући функције приступачности</translation> <translation id="7994702968232966508">EAP метод</translation> <translation id="799547531016638432">Уклони пречицу</translation> -<translation id="7997479212858899587">Идентитет:</translation> <translation id="7997826902155442747">Приоритет процеса</translation> <translation id="7999229196265990314">Направљене су следеће датотеке: @@ -4650,7 +4640,6 @@ <translation id="8105368624971345109">Искључи</translation> <translation id="8106045200081704138">Дељено са мном</translation> <translation id="8107015733319732394">Google Play продавница се инсталира на уређају <ph name="DEVICE_TYPE" />. То може да потраје неколико минута.</translation> -<translation id="8109930990200908494">Пријављивање је обавезно за кориснички сертификат.</translation> <translation id="8111155949205007504">Делите ову лозинку са iPhone-ом</translation> <translation id="8113043281354018522">Одаберите тип лиценце</translation> <translation id="8116190140324504026">Више информација...</translation> @@ -4661,6 +4650,7 @@ <translation id="8118860139461251237">Управљање преузимањима</translation> <translation id="81238879832906896">Жути и бели цвет</translation> <translation id="8124313775439841391">Управљани ONC</translation> +<translation id="8125562866093998907">Сајт жели да верификује безбедносни кључ ради боље безбедности налога.</translation> <translation id="813082847718468539">Погледајте информације о сајту</translation> <translation id="8131740175452115882">Потврди</translation> <translation id="8133676275609324831">&Прикажи у директоријуму</translation> @@ -4771,7 +4761,6 @@ <translation id="8308179586020895837">Питај ме ако <ph name="HOST" /> жели да приступи камери</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Сертификат већ постоји</translation> -<translation id="8309505303672555187">Изаберите мрежу:</translation> <translation id="8312871300878166382">Налепи у директоријум</translation> <translation id="8317671367883557781">Додај мрежну везу</translation> <translation id="8319414634934645341">Употреба проширеног кључа</translation> @@ -4846,7 +4835,6 @@ <translation id="8451512073679317615">Помоћник</translation> <translation id="8452135315243592079">SIM картица недостаје</translation> <translation id="8453482423012550001">Копирање $1 ставке(и)...</translation> -<translation id="8454288007744638700">Или изаберите нову мрежу:</translation> <translation id="845627346958584683">Време истека</translation> <translation id="8456681095658380701">Неважеће име</translation> <translation id="8457451314607652708">Увези обележиваче</translation> @@ -4910,6 +4898,7 @@ <translation id="855081842937141170">Закачи картицу</translation> <translation id="8551388862522347954">Лиценце</translation> <translation id="8553342806078037065">Управљање другим људима</translation> +<translation id="8554899698005018844">Без језика</translation> <translation id="855773602626431402">Спречено је покретање додатне компоненте која је изван заштићеног окружења на овој страници.</translation> <translation id="8557930019681227453">Манифест</translation> <translation id="8559694214572302298">Декодирање слика</translation> @@ -4947,7 +4936,6 @@ <translation id="862727964348362408">Обустављено</translation> <translation id="862750493060684461">CSS кеш</translation> <translation id="8627795981664801467">Само безбедне везе</translation> -<translation id="8628085465172583869">Име хоста сервера:</translation> <translation id="8630903300770275248">Увези корисника под надзором</translation> <translation id="8631032106121706562">Латице</translation> <translation id="8637542770513281060">Рачунар садржи безбедносни модул, који се користи за примену многих изузетно важних безбедносних функција у Chrome ОС-у. Посетите центар за помоћ за Chromebook да бисте сазнали више: https://support.google.com/chromebook/?p=sm</translation> @@ -5203,7 +5191,6 @@ <translation id="899403249577094719">Основна URL адреса за Netscape сертификат</translation> <translation id="8995603266996330174">Управља <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Додај налог...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Прави се слика диска.</translation> <translation id="9003647077635673607">Дозволи на свим веб-сајтовима</translation> <translation id="9003677638446136377">Проверите поново</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb index 775a2eb0..ec89c2b 100644 --- a/chrome/app/resources/generated_resources_sv.xtb +++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK-kod</translation> <translation id="1061904396131502319">Snart dags för en paus</translation> <translation id="1062407476771304334">Ersätt</translation> -<translation id="1064835277883315402">Anslut till privat nätverk</translation> <translation id="1064912851688322329">Koppla bort Google-kontot</translation> <translation id="1067048845568873861">Skapad</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Söker ...</translation> <translation id="1316495628809031177">Synkroniseringen har pausats</translation> <translation id="1319979322914001937">En app som visar en filtrerad lista över tillägg från Chrome Web Store. Tillägg på listan kan installeras direkt från appen.</translation> -<translation id="132090119144658135">Ämnesmatchning:</translation> <translation id="1326317727527857210">Logga in i Chrome om du vill ha samma flikar tillgängliga på alla enheter.</translation> <translation id="1327074568633507428">Skrivare på Google Cloud Print</translation> <translation id="1327977588028644528">Gateway</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Appfönster</translation> <translation id="1534389735079119190">FEL: Det gick inte att starta behållaren i den virtuella maskinen.</translation> <translation id="15373452373711364">Stor muspekare</translation> +<translation id="1540605929960647700">Aktivera demoläge</translation> <translation id="1543284117603151572">Importerade från Edge</translation> <translation id="1545177026077493356">Automatiskt kioskläge</translation> <translation id="1545775234664667895">Installerat tema "<ph name="THEME_NAME" />"</translation> @@ -458,6 +457,7 @@ <translation id="1657406563541664238">Hjälp till att göra <ph name="PRODUCT_NAME" /> bättre genom att automatiskt skicka användningsstatistik och felrapporter till Google</translation> <translation id="1658424621194652532">Den här sidan använder din mikrofon.</translation> <translation id="1660204651932907780">Tillåt att ljud spelas upp på webbplatser (rekommenderas)</translation> +<translation id="1660938185063657230">Verifiera säkerhetsnyckeln</translation> <translation id="1661156625580498328">Tillämpa AES-kryptering (rekommenderas).</translation> <translation id="1661245713600520330">På den här sidan listas alla moduler som har lästs in i huvudprocessen och moduler som har registrerats för att läsas in senare.</translation> <translation id="166179487779922818">Lösenordet är för kort.</translation> @@ -475,6 +475,7 @@ <translation id="16815041330799488">Ge inte webbplatser tillgång till text och bilder som kopierats till Urklipp</translation> <translation id="1682548588986054654">Nytt inkognitofönster</translation> <translation id="168715261339224929">Aktivera synkronisering om du vill få tillgång till dina bokmärken på alla enheter</translation> +<translation id="1688867105868176567">Vill du ta bort webbplatsdata?</translation> <translation id="1688935057616748272">Skriv en bokstav</translation> <translation id="168991973552362966">Lägg till en skrivare i närheten</translation> <translation id="1689945336726856614">Kopiera webbadress</translation> @@ -486,7 +487,6 @@ <translation id="1701062906490865540">Ta bort personen</translation> <translation id="1706586824377653884">Lades till av administratören</translation> <translation id="1706625117072057435">Zoomnivåer</translation> -<translation id="1707463636381878959">Dela nätverket med andra användare</translation> <translation id="1708338024780164500">(Inaktiv)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (id: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (standard)</translation> @@ -522,7 +522,6 @@ <translation id="175772926354468439">Aktivera tema</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Visa i Chrome Web Store</translation> -<translation id="1758831820837444715">Konfigurera Ethernet-nätverk</translation> <translation id="1763046204212875858">Skapa programgenvägar</translation> <translation id="1763108912552529023">Fortsätt att utforska</translation> <translation id="1763808908432309942">Öppnas på en ny flik</translation> @@ -581,8 +580,10 @@ <translation id="1839704667838141620">Ändra hur filen delas</translation> <translation id="1841545962859478868">Enhetsadministratören kan övervaka följande:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> har inaktiverats</translation> +<translation id="1842766183094193446">Vill du aktivera demoläget?</translation> <translation id="1844692022597038441">Den här filen är inte tillgänglig offline.</translation> <translation id="1846308012215045257">Kontroll-klicka för att köra <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Sparat</translation> <translation id="1848219224579402567">Logga ut när locket stängs</translation> <translation id="184823282865851239">Blockera om webbplatsen brukar visa påträngande annonser</translation> <translation id="1849186935225320012">Den här sidan har fullständig kontroll över MIDI-enheter.</translation> @@ -680,6 +681,7 @@ <translation id="200544492091181894">Du kan alltid ändra detta senare i inställningarna</translation> <translation id="2006638907958895361">Öppna länken i <ph name="APP" /></translation> <translation id="2007404777272201486">Rapportera ett problem...</translation> +<translation id="2016237810978710652">Öppnar Linux-filer …</translation> <translation id="2016430552235416146">Traditionell</translation> <translation id="2017334798163366053">Inaktivera insamling av resultatdata</translation> <translation id="2017836877785168846">Rensar historik och autoslutföranden i adressfältet.</translation> @@ -774,6 +776,7 @@ <translation id="2154484045852737596">Redigera kortet</translation> <translation id="2154710561487035718">Kopiera webbadress</translation> <translation id="2155772377859296191">Ser ut som <ph name="WIDTH" /> × <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Du kan hjälpa oss att förbättra Säker webbsökning genom att låta viss systeminformation och visst sidinnehåll skickas automatiskt till Google.</translation> <translation id="215753907730220065">Avsluta helskärmsläge</translation> <translation id="2157875535253991059">Denna sida visas nu i helskärm.</translation> <translation id="216169395504480358">Lägg till Wi-Fi ...</translation> @@ -783,6 +786,7 @@ <translation id="2173801458090845390">Lägg till rekvirerings-id på enheten</translation> <translation id="2175042898143291048">Gör alltid det</translation> <translation id="2175607476662778685">Fältet Snabbstart</translation> +<translation id="2176087259161165020">Andra källor</translation> <translation id="2177950615300672361">Fliken Inkognito: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> på <ph name="PEPPER_PLUGIN_DOMAIN" /> vill ha åtkomst till datorn</translation> <translation id="2178614541317717477">CA-kompromiss</translation> @@ -866,7 +870,6 @@ <translation id="2291643155573394834">Nästa flik</translation> <translation id="2292848386125228270">Starta <ph name="PRODUCT_NAME" /> som vanlig användare. Om du behöver köra som systemadministratör startar du om med flaggan --no-sandbox.</translation> <translation id="2294358108254308676">Vill du installera <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">EAP-metod:</translation> <translation id="2297705863329999812">Sök skrivare</translation> <translation id="2300383962156589922">Anpassa och kontrollera <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Tilläggets rotkatalog är ogiltig.</translation> @@ -914,6 +917,7 @@ <translation id="2366463953911599217">FEL: Det gick inte att avinstallera <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Lägg till File Share</translation> <translation id="2367972762794486313">Visa appar</translation> +<translation id="2369536625682139252">All data som sparats av <ph name="SITE" /> tas bort utom cookies.</translation> <translation id="2371076942591664043">Öppna när nedladdning är &klar</translation> <translation id="2377319039870049694">Byt till listvy</translation> <translation id="2377667304966270281">Sidfel</translation> @@ -923,7 +927,6 @@ <translation id="2379281330731083556">Skriv ut via systemets dialogruta ... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Fråga innan något skickas (rekommenderas)</translation> <translation id="2384436799579181135">Ett fel uppstod. Kontrollera skrivaren och försök igen.</translation> -<translation id="2385700042425247848">Namn på tjänsten</translation> <translation id="2387458720915042159">Proxyanslutningstyp</translation> <translation id="2391419135980381625">Standardteckensnitt</translation> <translation id="2391762656119864333">Återkalla</translation> @@ -974,7 +977,6 @@ <translation id="247949520305900375">Dela ljud</translation> <translation id="2480868415629598489">Ändra data som du kopierar och klistrar in</translation> <translation id="2482878487686419369">Aviseringar</translation> -<translation id="2485056306054380289">Server CA-certifikat:</translation> <translation id="2485422356828889247">Avinstallera</translation> <translation id="2487067538648443797">Lägg till ett nytt bokmärke</translation> <translation id="248861575772995840">Mobilen hittades inte. Kontrollera att Bluetooth är aktiverat på <ph name="DEVICE_TYPE" />. <a>Läs mer</a></translation> @@ -1035,6 +1037,7 @@ <translation id="2566124945717127842">Gör en Powerwash för att återställa <ph name="IDS_SHORT_PRODUCT_NAME" />-enheten så att den blir som ny.</translation> <translation id="2567257616420533738">Lösenordet sparades. Visa och hantera sparade lösenord på <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Infobar-behållare</translation> +<translation id="2570454805927264159">Få ut mesta möjliga av assistenten</translation> <translation id="257088987046510401">Teman</translation> <translation id="2572032849266859634">Skrivskyddad åtkomst till <ph name="VOLUME_NAME" /> har beviljats.</translation> <translation id="2573269395582837871">Välj bild och namn</translation> @@ -1098,7 +1101,6 @@ <translation id="2653659639078652383">Skicka</translation> <translation id="265390580714150011">Fältvärde</translation> <translation id="2654166010170466751">Tillåt att nya betalningshanterare installeras av webbplatser</translation> -<translation id="2655386581175833247">Användarcertifikat:</translation> <translation id="2660779039299703961">Event</translation> <translation id="266079277508604648">Det gick inte att ansluta till skrivaren. Kontrollera att skrivaren är påslagen och ansluten till Chromebook via Wi-Fi eller USB.</translation> <translation id="2661146741306740526">16:9</translation> @@ -1331,6 +1333,7 @@ <translation id="3006881078666935414">Ingen användningsdata tillgänglig</translation> <translation id="3007214526293698309">Fixera förhållande</translation> <translation id="3007771295016901659">Duplicera flik</translation> +<translation id="3008272652534848354">Återställ behörigheter</translation> <translation id="3009300415590184725">Är du säker på att du vill avbryta konfigurationen av den mobila datatjänsten?</translation> <translation id="3009779501245596802">Indexerade databaser</translation> <translation id="3010279545267083280">Lösenordet har tagits bort</translation> @@ -1397,7 +1400,6 @@ <translation id="3100609564180505575">Moduler (<ph name="TOTAL_COUNT" />) – kända konflikter: <ph name="BAD_COUNT" />, misstänkta: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Datum och tid</translation> <translation id="310671807099593501">Webbplatsen använder Bluetooth</translation> -<translation id="3108967419958202225">Välj...</translation> <translation id="3115128645424181617">Mobilen hittades inte. Den måste finnas i närheten och Bluetooth måste vara på.</translation> <translation id="3115147772012638511">Väntar på cache-minnet...</translation> <translation id="3118319026408854581">Hjälp för <ph name="PRODUCT_NAME" /></translation> @@ -1442,7 +1444,6 @@ <translation id="3165390001037658081">Vissa operatörer kanske blockerar den här funktionen.</translation> <translation id="316854673539778496">Logga in och aktivera synkronisering om du vill ha samma tillägg tillgängliga oavsett vilken enhet du använder.</translation> <translation id="3170072451822350649">Du kan även hoppa över inloggningen och <ph name="LINK_START" />surfa som gäst<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Klicka om du vill dölja lösenordet</translation> <translation id="3177909033752230686">Sidans språk:</translation> <translation id="3181110748548073003">Fortsätt med |<ph name="SHORTCUT" />|</translation> <translation id="3182749001423093222">Stavningskontroll</translation> @@ -1473,7 +1474,6 @@ <translation id="3236289833370040187"><ph name="DESTINATION_DOMAIN" /> blir den nya ägaren efter överföringen.</translation> <translation id="323803881985677942">Öppna tilläggsalternativ</translation> <translation id="3241680850019875542">Välj rotkatalogen för tillägget som ska paketeras. Om du vill uppdatera ett tillägg väljer du också den privata nyckel som ska återanvändas.</translation> -<translation id="3242765319725186192">I förväg delad nyckel:</translation> <translation id="3244294424315804309">Ljud fortsatt av</translation> <translation id="3245321423178950146">Okänd artist</translation> <translation id="3246097286174000800">Testa Smart Lock</translation> @@ -1606,7 +1606,6 @@ <translation id="3440663250074896476">Fler åtgärder för <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Fråga om en webbplats försöker använda en plugin för att få åtkomst till datorn</translation> <translation id="3441653493275994384">Skärm</translation> -<translation id="3445830502289589282">Autentisering av fas 2:</translation> <translation id="344630545793878684">Läsa din data på ett antal webbplatser</translation> <translation id="3449839693241009168">Tryck på <ph name="SEARCH_KEY" /> om du vill skicka kommandon till <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Kapacitetsprocentsats för inaktivitet</translation> @@ -1647,7 +1646,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> fel.</translation> <translation id="3495660573538963482">Inställningar för Google Assistent</translation> <translation id="3496213124478423963">Zooma ut</translation> -<translation id="3504135463003295723">Gruppnamn:</translation> <translation id="3505030558724226696">Återkalla enhetsåtkomst</translation> <translation id="3507421388498836150">Aktuella behörigheter för <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Ta bort Linux-appar för Chromebook</translation> @@ -1756,7 +1754,6 @@ <translation id="3661054927247347545">Inloggningscertifieringen är ogiltig. Fönstret stängs om <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Tilläggsikon</translation> <translation id="3665589677786828986">Chrome har upptäckt att visa av inställningarna har skadats av ett annat program och återställer dem till standardinställningarna.</translation> -<translation id="3665842570601375360">Säkerhet:</translation> <translation id="3668570675727296296">Språkinställningar</translation> <translation id="3668823961463113931">Hanterare</translation> <translation id="3670229581627177274">Aktivera Bluetooth</translation> @@ -1795,7 +1792,6 @@ <translation id="3726463242007121105">Enheten kan inte öppnas eftersom dess filsystem inte stöds.</translation> <translation id="3727148787322499904">Om du ändrar denna inställning påverkas alla delade nätverk</translation> <translation id="3727187387656390258">Kontrollera popup</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Fel på rad <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-server med uppgradering</translation> <translation id="3737536731758327622">Det du laddar ned visas här</translation> @@ -1870,7 +1866,6 @@ <translation id="38275787300541712">Tryck på Retur när du är klar</translation> <translation id="3827774300009121996">&Helskärm</translation> <translation id="3828029223314399057">Sök efter bokmärken</translation> -<translation id="3829932584934971895">Leverantörstyp:</translation> <translation id="3830674330436234648">Ingen uppspelning är tillgänglig</translation> <translation id="3831486154586836914">Fönsteröversiktsläget har startats</translation> <translation id="383161972796689579">Ägaren av den här enheten har inaktiverat nya användare från att läggas till</translation> @@ -1891,6 +1886,7 @@ <translation id="3856921555429624101">Mätningen av dataanvändningen har avslutats</translation> <translation id="3857228364945137633">Testa att låsa upp din <ph name="DEVICE_TYPE" /> utan lösenord när mobilen finns i närheten med Smart Lock.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Synkroniseringen har pausats</translation> <translation id="3860381078714302691">Välkommen till Hangouts Meet</translation> <translation id="3862134173397075045">Välkommen till Cast-upplevelsen i Chrome!</translation> <translation id="3862788408946266506">En app med manifestattributet kiosk_only måste installeras i kioskläget i Chrome OS</translation> @@ -1968,7 +1964,6 @@ <translation id="3968261067169026421">Det gick inte att konfigurera nätverket</translation> <translation id="3970114302595058915">Id</translation> <translation id="397105322502079400">Beräknar ...</translation> -<translation id="3974195870082915331">Klicka om du vill visa lösenordet</translation> <translation id="3975222297214566386">Bubbla för inmatningsalternativ</translation> <translation id="397703832102027365">Slutför ...</translation> <translation id="3979395879372752341">Ett nytt tillägg har lagts till (<ph name="EXTENSION_NAME" />)</translation> @@ -2010,6 +2005,7 @@ <translation id="4044612648082411741">Ange certifikatlösenordet</translation> <translation id="404493185430269859">Standardsökmotor</translation> <translation id="4047112090469382184">Därför är detta säkert</translation> +<translation id="4051049974203704184">Få information om det som visas på skärmen</translation> <translation id="4052120076834320548">Mycket liten</translation> <translation id="4055023634561256217">En omstart krävs innan enheten kan återställas med Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2038,6 +2034,7 @@ <translation id="4088095054444612037">Acceptera för grupp</translation> <translation id="4089235344645910861">Inställningarna har sparats och synkroniseringen startats.</translation> <translation id="4090103403438682346">Aktivera verifierad åtkomst</translation> +<translation id="4090947011087001172">Vill du återställa behörigheterna för webbplatsen <ph name="SITE" />?</translation> <translation id="4091434297613116013">pappersark</translation> <translation id="4093955363990068916">Lokal fil:</translation> <translation id="4095507791297118304">Primär skärm</translation> @@ -2214,7 +2211,6 @@ <translation id="4419556793104466535">Styr synkronisering, anpassning med mera</translation> <translation id="4421932782753506458">Misse</translation> <translation id="4422347585044846479">Redigera bokmärke för den här sidan</translation> -<translation id="4423104065312875417">Installera ytterligare talmotorer</translation> <translation id="4423376891418188461">Återställ inställningar</translation> <translation id="4423482519432579560">&Stavningskontroll</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, administratören kräver att du ändrar ditt lösenord.</translation> @@ -2239,7 +2235,6 @@ <translation id="4449996769074858870">Ljud spelas upp på den här fliken.</translation> <translation id="4450974146388585462">Diagnostisera</translation> <translation id="4453946976636652378">Sök på <ph name="SEARCH_ENGINE_NAME" /> eller skriv en webbadress</translation> -<translation id="445923051607553918">Anslut till Wi-Fi-nätverk</translation> <translation id="4462159676511157176">Anpassade namnservrar</translation> <translation id="4467100756425880649">Chrome Web Store Gallery</translation> <translation id="4467101674048705704">Utöka <ph name="FOLDER_NAME" /></translation> @@ -2375,6 +2370,7 @@ <translation id="4682551433947286597">Bakgrunder visas på inloggningsskärmen.</translation> <translation id="4684427112815847243">Synkronisera allt</translation> <translation id="4689421377817139245">Synkronisera det här bokmärket med din iPhone</translation> +<translation id="4690091457710545971"><Fyra filer som genererats av Intels Wi-Fi-firmware: csr.lst, fh_regs.lst, radio_reg.lst och monitor.lst.sysmon. De tre första är binärfiler med registerdumpar, och Intel intygar att de inte innehåller några personliga uppgifter eller uppgifter som kan identifiera en enhet. Den sista filen är en körningsspårning från Intels firmware. Alla personliga uppgifter eller uppgifter som kan identifiera en enhet har tagits bort från den, men filen är för stor att visa här. Filerna genererades på grund av problem med Wi-Fi på enheten nyligen och delas med Intel så att de kan hjälpa till med felsökningen.></translation> <translation id="4692302215262324251"><ph name="DEVICE_TYPE" /> har registrerats för företagshantering av <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Om du inte väntade dig detta kontaktar du support.</translation> @@ -2634,6 +2630,7 @@ <translation id="5074318175948309511">Den här sidan kan behöva läsas in igen innan den nya inställningen börjar gälla.</translation> <translation id="5075131525758602494">Ange SIM-kortets pinkod</translation> <translation id="5078638979202084724">Skapa bokmärken för alla flikar</translation> +<translation id="5079950360618752063">Använd det föreslagna lösenordet</translation> <translation id="5084230410268011727">Tillåt att webbplatser använder rörelse- och ljussensorer</translation> <translation id="5085162214018721575">Söker efter uppdateringar</translation> <translation id="5086082738160935172">HID</translation> @@ -2672,6 +2669,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Ta bort det här objektet</translation> <translation id="5139955368427980650">&Öppna</translation> +<translation id="5142961317498132443">Autentisering</translation> <translation id="5143374789336132547">Tillägget <ph name="EXTENSION_NAME" /> har ändrat vilken sida som visas när du klickar på hemknappen.</translation> <translation id="5143712164865402236">Visa i helskärm</translation> <translation id="5145331109270917438">Ändrad den</translation> @@ -2842,7 +2840,6 @@ <translation id="5380103295189760361">Håll ned Ctrl, Alt, Skift eller Sök om du vill visa kortkommandon för dessa modifierare.</translation> <translation id="5382591305415226340">Hantera länkar som stöds</translation> <translation id="5384883051496921101">Data på den här webbplatsen delas med en app utanför inkognitoläget.</translation> -<translation id="5388588172257446328">Användarnamn:</translation> <translation id="5388885445722491159">Kopplad</translation> <translation id="5389237414310520250">Det gick inte att skapa den nya användaren. Kontrollera hårddiskutrymmet och dina behörigheter och försök igen.</translation> <translation id="5390100381392048184">Tillåt att ljud spelas upp på webbplatser</translation> @@ -2967,7 +2964,6 @@ <translation id="5551573675707792127">Tangentbord och textinmatning</translation> <translation id="5553089923092577885">Mappningar för certifikatpolicy </translation> <translation id="5554489410841842733">Ikonen visas när tillägget kan agera på den aktuella sidan.</translation> -<translation id="5554573843028719904">Andra Wi-Fi-nätverk ...</translation> <translation id="5554720593229208774">Utfärdare av e-postcertifikat</translation> <translation id="5556206011531515970">Klicka på Nästa om du vill välja en standardwebbläsare.</translation> <translation id="5556459405103347317">Hämta igen</translation> @@ -3008,7 +3004,6 @@ <translation id="5610038042047936818">Byt till kameraläget</translation> <translation id="5612720917913232150"><ph name="URL" /> vill använda datorns plats</translation> <translation id="5612734644261457353">Det gick inte att verifiera lösenordet nu heller. Obs! Om du nyligen har bytt lösenord börjar det nya lösenordet gälla när du loggar ut. Använd det gamla lösenordet här.</translation> -<translation id="5613695965848159202">Anonym identitet:</translation> <translation id="5614190747811328134">Meddelande till användaren</translation> <translation id="561698261642843490">Stäng Firefox</translation> <translation id="5618075537869101857">Det gick inte att starta kioskappen.</translation> @@ -3226,7 +3221,6 @@ <translation id="5941343993301164315">Logga in på <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Minimera</translation> <translation id="5946591249682680882">Rapport-id <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Lägg till privat nätverk</translation> <translation id="5949544233750246342">Det gick inte att analysera filen</translation> <translation id="5955282598396714173">Lösenordet har upphört att gälla. Logga ut och logga sedan in igen innan du ändrar det.</translation> <translation id="5956585768868398362">Är det här den söksida du väntade dig?</translation> @@ -3387,11 +3381,13 @@ <translation id="6198102561359457428">Logga ut och sedan in igen ...</translation> <translation id="6198252989419008588">Byt PIN</translation> <translation id="6199801702437275229">Väntar på information om lagringsutrymme ...</translation> +<translation id="6204015976622790023">Få relevanta förslag av assistenten utifrån det som visas på skärmen.</translation> <translation id="6205710420833115353">Vissa åtgärder tar längre tid än väntat. Vill du avbryta dem?</translation> <translation id="6206311232642889873">Kopiera &bild</translation> <translation id="6207200176136643843">Återställ standardzoomnivån</translation> <translation id="620722923698527029">Öppna alltid dessa typer av länkar i den kopplade appen</translation> <translation id="6207937957461833379">Land/region</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Synkroniseringen fungerar inte</translation> <translation id="6212039847102026977">Visa avancerade nätverksinställningar</translation> <translation id="6212168817037875041">Stäng av skärmen</translation> <translation id="6212752530110374741">Skicka länk via e-post</translation> @@ -3429,7 +3425,6 @@ <translation id="6263541650532042179">återställ synkronisering</translation> <translation id="6264365405983206840">Markera &alla</translation> <translation id="6264422956566238156">Du har aktiverat Sync</translation> -<translation id="6265930187414222160">Klart! Skadlig programvara borttagen.</translation> <translation id="6267166720438879315">Välj ett certifikat för att styrka din identitet för <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Öppna med <ph name="APP" /></translation> <translation id="6268747994388690914">Importera bokmärken från HTML-filen ...</translation> @@ -3536,7 +3531,6 @@ Fortsätt med inloggningen på kontot på <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> genom att klicka på Nästa.</translation> <translation id="6419546358665792306">Läser in okomprimerat tillägg</translation> <translation id="642282551015776456">Det här namnet får inte användas som namn på en fil eller mapp</translation> -<translation id="6423239382391657905">Öppen VPN</translation> <translation id="6426200009596957090">Öppna ChromeVox-inställningarna</translation> <translation id="6429384232893414837">Uppdateringsfel</translation> <translation id="6430814529589430811">Base64-kodad ASCII, enstaka certifikat</translation> @@ -3617,7 +3611,6 @@ <translation id="6544215763872433504">En webbläsare till dig från Google</translation> <translation id="6545665334409411530">Upprepningsintervall</translation> <translation id="6545834809683560467">Använd en förslagstjänst om du vill ha hjälp att slutföra sökningar och fylla i webbadresser i adressfältet eller i sökrutan i startprogrammet för appar</translation> -<translation id="6546686722964485737">Anslut till WiMAX-nätverk</translation> <translation id="6547316139431024316">Varna inte för det här tillägget fler gånger</translation> <translation id="6547354035488017500">Frigör åtminstone 512 MB utrymme för att enheten ska fortsätta att svara. Frigör utrymme genom att radera filer från lagringsutrymmet på enheten.</translation> <translation id="6549689063733911810">Senaste</translation> @@ -4036,7 +4029,6 @@ <translation id="7201014958346994077">Det gick inte att visa Linux-filer</translation> <translation id="720110658997053098">Behåll enheten permanent i kioskläge</translation> <translation id="7201118060536064622"><ph name="DELETED_ITEM_NAME" /> har raderats</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Laddar ned <ph name="PLUGIN_NAME" /> ...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Lämna sidan}other{Lämna sidorna}}</translation> <translation id="7216409898977639127">Mobiloperatör</translation> @@ -4514,7 +4506,6 @@ <translation id="7909969815743704077">Laddades ned i inkognitoläge</translation> <translation id="7910768399700579500">&Ny mapp</translation> <translation id="7912080627461681647">Lösenordet har ändrats på servern. Logga ut och logga sedan in igen.</translation> -<translation id="7912883689016444961">Konfigurera mobilnätverk</translation> <translation id="7915471803647590281">Berätta för oss vad som händer innan du skickar feedback.</translation> <translation id="7916556741383518510">Vid klick</translation> <translation id="792514962475806987">Zoomnivå för dockad skärmförstorare</translation> @@ -4568,7 +4559,6 @@ <translation id="7988355189918024273">Aktivera tillgänglighetsfunktioner</translation> <translation id="7994702968232966508">EAP-metod</translation> <translation id="799547531016638432">Ta bort genväg</translation> -<translation id="7997479212858899587">Identitet:</translation> <translation id="7997826902155442747">Prioriteringsprocess</translation> <translation id="7999229196265990314">Följande filer har skapats: @@ -4652,7 +4642,6 @@ <translation id="8105368624971345109">Inaktivera</translation> <translation id="8106045200081704138">Delade med mig</translation> <translation id="8107015733319732394">Google Play Butik installeras på din <ph name="DEVICE_TYPE" />. Det kan ta några minuter.</translation> -<translation id="8109930990200908494">Inloggning krävs för användarcertifikat.</translation> <translation id="8111155949205007504">Dela det här lösenordet med din iPhone</translation> <translation id="8113043281354018522">Välj licenstyp</translation> <translation id="8116190140324504026">Mer information...</translation> @@ -4663,6 +4652,7 @@ <translation id="8118860139461251237">Hantera dina nedladdningar</translation> <translation id="81238879832906896">Gul och vit blomma</translation> <translation id="8124313775439841391">Hanterad ONC</translation> +<translation id="8125562866093998907">Webbplatsen vill verifiera din säkerhetsnyckel som ett ytterligare skydd för ditt konto.</translation> <translation id="813082847718468539">Visa information om webbplatsen</translation> <translation id="8131740175452115882">Bekräfta</translation> <translation id="8133676275609324831">&Visa i mapp</translation> @@ -4773,7 +4763,6 @@ <translation id="8308179586020895837">Fråga om <ph name="HOST" /> vill använda din kamera</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Certifikatet finns redan</translation> -<translation id="8309505303672555187">Välj ett nätverk:</translation> <translation id="8312871300878166382">Klistra in i mapp</translation> <translation id="8317671367883557781">Lägg till nätverksanslutning</translation> <translation id="8319414634934645341">Utökad nyckelanvändning</translation> @@ -4848,7 +4837,6 @@ <translation id="8451512073679317615">assistent</translation> <translation id="8452135315243592079">SIM-kort saknas</translation> <translation id="8453482423012550001">$1 objekt kopieras ...</translation> -<translation id="8454288007744638700">Du kan även välja ett nytt nätverk:</translation> <translation id="845627346958584683">Giltig till</translation> <translation id="8456681095658380701">Ogiltigt namn</translation> <translation id="8457451314607652708">Importera bokmärken</translation> @@ -4912,6 +4900,7 @@ <translation id="855081842937141170">Fäst flik</translation> <translation id="8551388862522347954">Licenser</translation> <translation id="8553342806078037065">Hantera andra personer</translation> +<translation id="8554899698005018844">Inget språk</translation> <translation id="855773602626431402">Ett pluginprogram utanför sandlådan hindrades från att köras på den här sidan.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Bildavkodare</translation> @@ -4949,7 +4938,6 @@ <translation id="862727964348362408">Tillfälligt avstängd</translation> <translation id="862750493060684461">CSS-cacheminne</translation> <translation id="8627795981664801467">Endast säkra anslutningar</translation> -<translation id="8628085465172583869">Serverns värdnamn:</translation> <translation id="8630903300770275248">Importera hanterad användare</translation> <translation id="8631032106121706562">Blomster</translation> <translation id="8637542770513281060">Datorn innehåller en säker modul som används för att implementera flera viktiga säkerhetsfunktioner i Chrome OS. Besök hjälpcentret för Chromebook om du vill läsa mer: https://support.google.com/chromebook/?p=sm</translation> @@ -5205,7 +5193,6 @@ <translation id="899403249577094719">Basadress för Netscape-certifikat</translation> <translation id="8995603266996330174">Hanteras av <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Lägg till konto …</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Diskavbildningen skapas.</translation> <translation id="9003647077635673607">Tillåt på alla webbplatser</translation> <translation id="9003677638446136377">Kontrollera igen</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb index ddd8979..6ec5508 100644 --- a/chrome/app/resources/generated_resources_sw.xtb +++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Muda wa kupumzika umekaribia</translation> <translation id="1062407476771304334">Badilisha</translation> -<translation id="1064835277883315402">Jiunge na mtandao binafsi</translation> <translation id="1064912851688322329">Tenganisha Akaunti yako ya Google</translation> <translation id="1067048845568873861">Kiliundwa</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Inatafuta...</translation> <translation id="1316495628809031177">Imesitisha Usawazishaji</translation> <translation id="1319979322914001937">Programu inaonyesha orodha iliyochujwa ya viendelezi kutoka kwenye Duka la Chrome kwenye Wavuti. Viendelezi katika orodha vinaweza kusakinishwa moja kwa moja kutoka kwenye programu.</translation> -<translation id="132090119144658135">Kichwa Kinacholingana:</translation> <translation id="1326317727527857210">Ili upate vichupo kutoka kwenye vifaa vyako vingine, ingia katika Chrome.</translation> <translation id="1327074568633507428">Printa kwenye Google Cloud Print</translation> <translation id="1327977588028644528">Lango</translation> @@ -374,6 +372,7 @@ <translation id="1531004739673299060">Dirisha la Programu</translation> <translation id="1534389735079119190">HITILAFU: Imeshindwa kuanzisha metadata ndani ya VM.</translation> <translation id="15373452373711364">Kishale kikubwa cha kipanya</translation> +<translation id="1540605929960647700">Washa hali ya onyesho</translation> <translation id="1543284117603151572">Zilizoletwa Kutoka Kivinjari cha Edge</translation> <translation id="1545177026077493356">Skrini Nzima Kiotomatiki</translation> <translation id="1545775234664667895">Mandhari "<ph name="THEME_NAME" />" imesanidiwa</translation> @@ -457,6 +456,7 @@ <translation id="1657406563541664238">Saidia kuboresha <ph name="PRODUCT_NAME" /> kwa kutumia Google takwimu za matumizi na ripoti wakati wowote huduma hii inapoacha kufanya kazi.</translation> <translation id="1658424621194652532">Ukarasa huu unafikia maikrofoni yako.</translation> <translation id="1660204651932907780">Ruhusu tovuti kucheza sauti (inapendekezwa)</translation> +<translation id="1660938185063657230">Thibitisha Ufunguo wako wa Usalama</translation> <translation id="1661156625580498328">Imarisha usimbaji wa AES (inapendekezwa).</translation> <translation id="1661245713600520330">Ukurasa huu unaorodhesha vipengee vyote vilivyopakiwa katika mchakato halisi na vilivyosajiliwa kupakiwa baadaye.</translation> <translation id="166179487779922818">Nenosiri ni fupi mno.</translation> @@ -474,6 +474,7 @@ <translation id="16815041330799488">Usiruhusu tovuti zione maandishi na picha zilizonakiliwa kwenye ubao wa kunakili</translation> <translation id="1682548588986054654">Dirisha Fiche Jipya</translation> <translation id="168715261339224929">Ili upate alamisho kwenye vifaa vyako vyote, washa usawazishaji.</translation> +<translation id="1688867105868176567">Ungependa kufuta data ya tovuti?</translation> <translation id="1688935057616748272">Andika herufi</translation> <translation id="168991973552362966">Ongeza printa iliyo karibu</translation> <translation id="1689945336726856614">Nakili URL</translation> @@ -485,7 +486,6 @@ <translation id="1701062906490865540">Ondoa mtumiaji huyu</translation> <translation id="1706586824377653884">Imeongezwa na msimamizi wako</translation> <translation id="1706625117072057435">Viwango vya kukuza</translation> -<translation id="1707463636381878959">Shiriki mtandao huu na watumiaji wengine</translation> <translation id="1708338024780164500">(Sio amilifu)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (Kitambulisho: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Asili)</translation> @@ -521,7 +521,6 @@ <translation id="175772926354468439">Washa mandhari</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Angalia katika Duka la Chrome kwenye Wavuti</translation> -<translation id="1758831820837444715">Sanidi mtandao wa Ethernet</translation> <translation id="1763046204212875858">Unda mikato ya programu</translation> <translation id="1763108912552529023">Endelea kugundua</translation> <translation id="1763808908432309942">Itafungua katika kichupo kipya</translation> @@ -580,8 +579,10 @@ <translation id="1839704667838141620">Badilisha jinsi faili hii inavyoshirikiwa</translation> <translation id="1841545962859478868">Msimamizi wa kifaa anaweza kufuatilia mambo yafuatayo:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> imezimwa</translation> +<translation id="1842766183094193446">Una hakika kuwa ungependa kuwasha hali ya onyesho?</translation> <translation id="1844692022597038441">Faili hii haipatikani nje ya mtandao.</translation> <translation id="1846308012215045257">Shikilia kitufe cha 'Control' ukibofya programu-jalizi ya <ph name="PLUGIN_NAME" /> ili kuitimia</translation> +<translation id="1847880352285315359">Imehifadhi</translation> <translation id="1848219224579402567">Ondoka kwenye akaunti kifuniko kikiwa kimefungwa</translation> <translation id="184823282865851239">Zuia ikiwa tovuti inaonyesha matangazo yanayokatiza matumizi</translation> <translation id="1849186935225320012">Ukurasa huu una udhibiti kamili wa vifaa vya MIDI.</translation> @@ -679,6 +680,7 @@ <translation id="200544492091181894">Unaweza kubadilisha hali hii baadaye katika mipangilio</translation> <translation id="2006638907958895361">Fungua Kiungo katika <ph name="APP" /></translation> <translation id="2007404777272201486">Ripoti Tatizo...</translation> +<translation id="2016237810978710652">Inafungua Faili za Linux...</translation> <translation id="2016430552235416146">Vya Asili</translation> <translation id="2017334798163366053">Zima ukusanyaji wa data ya utendaji</translation> <translation id="2017836877785168846">Hufuta historia na ujazaji kiotomatiki katika sehemu ya anwani.</translation> @@ -773,6 +775,7 @@ <translation id="2154484045852737596">Badilisha kadi</translation> <translation id="2154710561487035718">Nakili UR:</translation> <translation id="2155772377859296191">Inaonekana kama <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Unaweza kuboresha huduma ya Kuvinjari Salama kwa kutuma baadhi ya maelezo ya mfumo na maudhui ya ukurasa kwa Google.</translation> <translation id="215753907730220065">Ondoka kwenye Skrini Kamili</translation> <translation id="2157875535253991059">Ukurasa huu sasa umejaa.</translation> <translation id="216169395504480358">Ongeza Wi-Fi...</translation> @@ -782,6 +785,7 @@ <translation id="2173801458090845390">Ongeza ombi la Kitambulisho kwenye kifaa hiki</translation> <translation id="2175042898143291048">Fanya hivi kila mara</translation> <translation id="2175607476662778685">Upau-Zindua-Kasi</translation> +<translation id="2176087259161165020">Vyanzo vingine</translation> <translation id="2177950615300672361">Kichupo Fiche: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> iliyo kwenye <ph name="PEPPER_PLUGIN_DOMAIN" /> inataka kufikia kompyuta yako</translation> <translation id="2178614541317717477">Kuvurugwa kwa Mamlaka ya Cheti</translation> @@ -865,7 +869,6 @@ <translation id="2291643155573394834">Kichupo kinachofuata</translation> <translation id="2292848386125228270">Tafadhali anzisha <ph name="PRODUCT_NAME" /> ukiwa mtumiaji wa kawaida. Ikiwa unahitaji kutumia kama chanzo cha uimarishaji, tumia tena kwa alama ya --no-sandbox.</translation> <translation id="2294358108254308676">Je, untataka kusakinisha <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Mbinu ya EAP:</translation> <translation id="2297705863329999812">Tafuta printa</translation> <translation id="2300383962156589922">Dhibiti na uweke mapendeleo kwenye <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Saraka la shina la kiendelezi ni batili.</translation> @@ -913,6 +916,7 @@ <translation id="2366463953911599217">HITILAFU: Imeshindwa kuondoa <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Ongeza Faili Utakayoshiriki</translation> <translation id="2367972762794486313">Onyesha programu</translation> +<translation id="2369536625682139252">Data yote iliyohifadhiwa na <ph name="SITE" /> itafutwa, isipokuwa vidakuzi.</translation> <translation id="2371076942591664043">Fungua baada ya &kumaliza</translation> <translation id="2377319039870049694">Tumia mwonekano wa orodha</translation> <translation id="2377667304966270281">Mabadilko ya Hifadhi</translation> @@ -922,7 +926,6 @@ <translation id="2379281330731083556">Chapisha kwa kutumia kidadisi cha mfumo... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Uliza kabla ya kutuma (imependekezwa)</translation> <translation id="2384436799579181135">Hitilafu imetokea. Tafadhali angalia printa yako kisha ujaribu tena.</translation> -<translation id="2385700042425247848">Jina la huduma:</translation> <translation id="2387458720915042159">Aina ya muunganisho wa seva mbadala</translation> <translation id="2391419135980381625">Fonti wastani</translation> <translation id="2391762656119864333">Kufuta</translation> @@ -973,7 +976,6 @@ <translation id="247949520305900375">Shiriki sauti</translation> <translation id="2480868415629598489">Badilisha data unayonakili na kubandika</translation> <translation id="2482878487686419369">Arifa</translation> -<translation id="2485056306054380289">Cheti cha Seva ya CA:</translation> <translation id="2485422356828889247">Ondoa</translation> <translation id="2487067538648443797">Ongeza alamisho mpya</translation> <translation id="248861575772995840">Imeshindwa kupata simu. Hakikisha kuwa Bluetooth ya kifaa chako cha <ph name="DEVICE_TYPE" /> imewashwa. <a>Pata maelezo zaidi</a></translation> @@ -1034,6 +1036,7 @@ <translation id="2566124945717127842">Tumia Powerwash ili uweke upya kifaa chako cha <ph name="IDS_SHORT_PRODUCT_NAME" /> kiwe kama kipya.</translation> <translation id="2567257616420533738">Imehifadhi nenosiri. Angalia na udhibiti manenosiri yaliyohifadhiwa kwenye <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Hifadhi ya Upau wa Maelezo</translation> +<translation id="2570454805927264159">Pata manufaa zaidi kutoka programu ya Mratibu</translation> <translation id="257088987046510401">Mandhari</translation> <translation id="2572032849266859634">Idhini ya kufikia kusoma tu kwenye <ph name="VOLUME_NAME" /> imeruhusiwa.</translation> <translation id="2573269395582837871">Chagua picha na jina</translation> @@ -1096,7 +1099,6 @@ <translation id="2653659639078652383">Wasilisha</translation> <translation id="265390580714150011">Thamani ya Uga</translation> <translation id="2654166010170466751">Ruhusu tovuti zisakinishe vidhibiti vya malipo</translation> -<translation id="2655386581175833247">Cheti cha mtumiaji:</translation> <translation id="2660779039299703961">Tukio</translation> <translation id="266079277508604648">Imeshindwa kuunganisha kwenye printa. Hakikisha kuwa printa imewashwa na imeunganishwa kwenye Chromebook yako kwa kutumia Wi-Fi au USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1329,6 +1331,7 @@ <translation id="3006881078666935414">Hakuna data ya matumizi</translation> <translation id="3007214526293698309">Uwiano usiobadilika</translation> <translation id="3007771295016901659">Toa nakala rudufu ya Kichupo</translation> +<translation id="3008272652534848354">Badilisha ruhusa</translation> <translation id="3009300415590184725">Je una uhakika unataka kughairi mchakato wa usanidi wa huduma ya data ya simu ya mkononi?</translation> <translation id="3009779501245596802">Hifadhidata zilizofahirisiwa</translation> <translation id="3010279545267083280">Nenosiri limefutwa</translation> @@ -1395,7 +1398,6 @@ <translation id="3100609564180505575">Vipengee (<ph name="TOTAL_COUNT" />) - Migogoro inayojulikana: <ph name="BAD_COUNT" />, inayoshukiwa: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Tarehe na wakati</translation> <translation id="310671807099593501">Tovuti inatumia bluetooth</translation> -<translation id="3108967419958202225">Chagua...</translation> <translation id="3115128645424181617">Imeshindwa kupata simu yako. Hakikisha kuwa unayo na umewasha Bluetooth.</translation> <translation id="3115147772012638511">Inasubiri akiba...</translation> <translation id="3118319026408854581">Usaidizi wa <ph name="PRODUCT_NAME" /></translation> @@ -1440,7 +1442,6 @@ <translation id="3165390001037658081">Huenda watoa huduma wengine wakazuia kipengele hiki.</translation> <translation id="316854673539778496">Ingia katika akaunti na uwashe kipengele cha usawazishaji ili upate viendelezi vyako vyote kwenye vifaa vyako vyote.</translation> <translation id="3170072451822350649">Pia unaweza kuruka kuingia na <ph name="LINK_START" />uvinjari kama Mgeni<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Bofya ili kuficha nenosiri</translation> <translation id="3177909033752230686">Lugha ya Ukurasa:</translation> <translation id="3181110748548073003">Bonyeza |<ph name="SHORTCUT" />| ili uende mbele</translation> <translation id="3182749001423093222">Kikagua maendelezo</translation> @@ -1471,7 +1472,6 @@ <translation id="3236289833370040187">Umiliki utahamishiwa kwenye <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Fungua chaguo za viendelezi</translation> <translation id="3241680850019875542">Chagua saraka msingi ya kiendelezi ya kuweka kwenye furushi. Kusasisha kiendelezi, chagua pia ufunguo wa kibinafsi wa kutumia tena.</translation> -<translation id="3242765319725186192">Kitufe kilichoshirikiwa awali:</translation> <translation id="3244294424315804309">Endelea kuzima sauti</translation> <translation id="3245321423178950146">Msanii Asiyejulikana</translation> <translation id="3246097286174000800">Jaribu Smart Lock</translation> @@ -1601,7 +1601,6 @@ <translation id="3440663250074896476">Vitendo zaidi katika <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Uliza tovuti inapotaka kutumia programu-jalizi kufikia kompyuta yako</translation> <translation id="3441653493275994384">Skrini</translation> -<translation id="3445830502289589282">Uthibitishaji wa awamu ya pili:</translation> <translation id="344630545793878684">Soma data yako kwenye tovuti kadhaa</translation> <translation id="3449839693241009168">Bonyeza <ph name="SEARCH_KEY" /> ili kutuma amri kwenye <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Asilimia ya Ukaaji wa Hali ya Kutofanya Kitu</translation> @@ -1642,7 +1641,6 @@ <translation id="3495304270784461826">Hitilafu <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Mipangilio ya Mratibu wa Google</translation> <translation id="3496213124478423963">Kuza</translation> -<translation id="3504135463003295723">Jina la kikundi:</translation> <translation id="3505030558724226696">Batilisha uwezo wa kufikia kifaa</translation> <translation id="3507421388498836150">Ruhusa za Sasa za "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Ondoa Programu za Linux za Chromebook</translation> @@ -1751,7 +1749,6 @@ <translation id="3661054927247347545">Cheti cha kuingia katika akaunti si sahihi, dirisha litafungwa baada ya <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Aikoni ya Kiendelezi</translation> <translation id="3665589677786828986">Chrome imegundua kuwa baadhi ya mipangilio yako ilivurugwa na programu nyingine na ikairejesha kwenye mipangilio yake iliyotoka nayo kiwandani.</translation> -<translation id="3665842570601375360">Usalama:</translation> <translation id="3668570675727296296">Mipangilio ya lugha</translation> <translation id="3668823961463113931">Vishikilizi</translation> <translation id="3670229581627177274">Washa Bluetooth</translation> @@ -1790,7 +1787,6 @@ <translation id="3726463242007121105">Kifaa hakiwezi kufunguliwa kwa sababu mfumo wake wa faili hauhimiliwi.</translation> <translation id="3727148787322499904">Kubadilisha mipangilio hii kutaathiri mitandao yote inayoshirikiwa</translation> <translation id="3727187387656390258">Kagua dirisha ibukizi</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Hililafu kwenye mstari wa <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Seva ya SSL iliyo na Upandishaji</translation> <translation id="3737536731758327622">Vipakuliwa vyako vitaonekana hapa</translation> @@ -1865,7 +1861,6 @@ <translation id="38275787300541712">Bonyeza Enter unapokamilisha</translation> <translation id="3827774300009121996">&Skrini Kamili</translation> <translation id="3828029223314399057">Tafuta katika alamisho</translation> -<translation id="3829932584934971895">Aina ya mtoaji:</translation> <translation id="3830674330436234648">Kipengele cha kucheza hakipatikani.</translation> <translation id="3831486154586836914">Hali ya muhtasari wa dirisha imeingizwa</translation> <translation id="383161972796689579">Mmiliki wa kifaa hiki amelemaza kuongezwa kwa watumiaji wapya</translation> @@ -1886,6 +1881,7 @@ <translation id="3856921555429624101">Upimaji wa matumizi ya data umekamilika</translation> <translation id="3857228364945137633">Jaribu kutumia Smart Lock kukifungua kifa chako cha <ph name="DEVICE_TYPE" /> bila kutumia nenosiri, simu yako ikiwa karibu.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Umesitisha usawazishaji</translation> <translation id="3860381078714302691">Karibu kwenye Hangouts Meet</translation> <translation id="3862134173397075045">Karibu kwenye huduma ya Kutuma katika Chrome!</translation> <translation id="3862788408946266506">Ni lazima programu iliyo na sifa ya faili ya maelezo ya 'kiosk_only' isakinishwe katika skrini nzima ya Mfumo wa Uendeshaji wa Chrome</translation> @@ -1963,7 +1959,6 @@ <translation id="3968261067169026421">Haikuweka mipangilio ya mtandao</translation> <translation id="3970114302595058915">Kitambulisho</translation> <translation id="397105322502079400">Inakokotoa...</translation> -<translation id="3974195870082915331">Bofya ili kuonyesha nenosiri</translation> <translation id="3975222297214566386">Kiputo cha chaguo za kuingiza data</translation> <translation id="397703832102027365">Inahitimisha</translation> <translation id="3979395879372752341">Kiendelezi kipya kimeongezwa (<ph name="EXTENSION_NAME" />)</translation> @@ -2005,6 +2000,7 @@ <translation id="4044612648082411741">Weka nenosiri la cheti chako</translation> <translation id="404493185430269859">Injini tafuti chaguo msingi</translation> <translation id="4047112090469382184">Namna hiki kilivyo salama</translation> +<translation id="4051049974203704184">Pata maelezo ya maudhui yaliyo kwenye skrini</translation> <translation id="4052120076834320548">Ndogo sana</translation> <translation id="4055023634561256217">Uwashaji upya unahitajika kabla ya kifaa chako kuwekwa upya na Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2031,6 +2027,7 @@ <translation id="4088095054444612037">Kubali ombi la kundi</translation> <translation id="4089235344645910861">Mipangilio imehifadhiwa. Imeanza kusawazisha.</translation> <translation id="4090103403438682346">Washa Ufikiaji Uliothibitishwa</translation> +<translation id="4090947011087001172">Ungependa kubadilisha ruhusa za tovuti ya <ph name="SITE" />?</translation> <translation id="4091434297613116013">karatasi</translation> <translation id="4093955363990068916">Faili ya ndani:</translation> <translation id="4095507791297118304">Onyesho msingi</translation> @@ -2207,7 +2204,6 @@ <translation id="4419556793104466535">Dhibiti usawazishaji, mapendeleo na nyinginezo</translation> <translation id="4421932782753506458">Kibonge</translation> <translation id="4422347585044846479">Badilisha alamisho ya ukurasa huu</translation> -<translation id="4423104065312875417">Sakinisha mitambo mingine ya sauti</translation> <translation id="4423376891418188461">Rejesha Mipangilio</translation> <translation id="4423482519432579560">Kukagua maendelezo</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, msimamizi wako anakuhitaji ubadilishe nenosiri lako.</translation> @@ -2232,7 +2228,6 @@ <translation id="4449996769074858870">Kichupo hiki kinacheza sauti.</translation> <translation id="4450974146388585462">Tambua hitilafu</translation> <translation id="4453946976636652378">Tafuta kwenye <ph name="SEARCH_ENGINE_NAME" /> au uandike URL</translation> -<translation id="445923051607553918">Jiunge kwenye mtandao wa Wi-Fi</translation> <translation id="4462159676511157176">Seva za jina maalum</translation> <translation id="4467100756425880649">Ghala la Duka la Chrome kwenye Wavuti</translation> <translation id="4467101674048705704">Panua <ph name="FOLDER_NAME" /></translation> @@ -2368,6 +2363,7 @@ <translation id="4682551433947286597">Mandhari hutokea kwenye Skrini ya Kuingia.</translation> <translation id="4684427112815847243">Sawazisha kila kitu</translation> <translation id="4689421377817139245">Sawazisha alamisho hii kwenye iPhone yako</translation> +<translation id="4690091457710545971"><Faili nne zinazozalishwa na programu dhibiti ya Intel Wi-Fi: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Faili za kwanza tatu ni faili za mfumo wa jozi zilizo na data ya faili za sajili, na zimethibitishwa na Intel kuwa hazina maelezo yanayoweza kutambulisha mtu au kifaa. Faili ya mwisho ni faili ya utekelezaji kutoka programu dhibiti ya Intel; imeondolewa maelezo yoyote yanayoweza kutambulisha mtu au kifaa, lakini haiwezi kuonekana hapa kwa kuwa ni kubwa mno. Faili hizi zilizalishwa ili kusuluhisha matatizo ya hivi karibuni ya Wi-Fi ambayo yalikumba kifaa chako, na tutazishiriki na Intel ili kukusaidia utatue matatizo haya.></translation> <translation id="4692302215262324251">Kifaa chako cha <ph name="DEVICE_TYPE" /> kimesajiliwa kwa ajili ya usimamizi wa biashara na <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Ikiwa hili halitarajiwi, tafadhali wasiliana na kituo cha usaidizi.</translation> @@ -2627,6 +2623,7 @@ <translation id="5074318175948309511">Huenda ukurasa huu ukahitaji kupakiwa tena kabla mipangilio mipya ianze kutumika.</translation> <translation id="5075131525758602494">Weka PIN ya SIM</translation> <translation id="5078638979202084724">Alamisha vichupo vyote</translation> +<translation id="5079950360618752063">Tumia nenosiri lililopendekezwa</translation> <translation id="5084230410268011727">Ruhusu tovuti kutumia vitambuzi vya mwendo na mwangaza</translation> <translation id="5085162214018721575">Inatafuta visasishi</translation> <translation id="5086082738160935172">HID</translation> @@ -2665,6 +2662,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Futa kipengee hiki</translation> <translation id="5139955368427980650">&Fungua</translation> +<translation id="5142961317498132443">Uthibitishaji</translation> <translation id="5143374789336132547">Kiendelezi "<ph name="EXTENSION_NAME" />" kimebadilisha ukurasa unaoonyeshwa unapobofya kitufe cha Mwanzo.</translation> <translation id="5143712164865402236">Ingia Skrini Kamili</translation> <translation id="5145331109270917438">Tarehe ilipobadilishwa</translation> @@ -2835,7 +2833,6 @@ <translation id="5380103295189760361">Shikilia "Control", "Alt", "Shift", au "Search" ili kuona mikato ya kibodi ya virekebishi hivyo.</translation> <translation id="5382591305415226340">Dhibiti viungo vinavyotumika</translation> <translation id="5384883051496921101">Tovuti hii inakaribia kushiriki maelezo na programu nyingine isiyo katika hali fiche.</translation> -<translation id="5388588172257446328">Jina la mtumiaji:</translation> <translation id="5388885445722491159">Imeoanishwa</translation> <translation id="5389237414310520250">Imeshindwa kuunda mtumiaji mpya. Tafadhali angalia ruhusa na nafasi ya hifadhi ya diski kuu kisha ujaribu tena.</translation> <translation id="5390100381392048184">Ruhusu tovuti kucheza sauti</translation> @@ -2960,7 +2957,6 @@ <translation id="5551573675707792127">Kibodi na uwekaji wa maandishi</translation> <translation id="5553089923092577885">Ramani ya Sera za Vyeti</translation> <translation id="5554489410841842733">Aikoni hii itaonekana kiendelezi kitakapoanza kufanya kazi kwenye ukurasa huu.</translation> -<translation id="5554573843028719904">Mtandao mwingine wa Wi-Fi...</translation> <translation id="5554720593229208774">Mamlaka ya Uthibitishaji wa Barua pepe</translation> <translation id="5556206011531515970">Bofya ifuatayo ili kuchagua kivinjari chako chaguo msingi.</translation> <translation id="5556459405103347317">Pakia upya</translation> @@ -3001,7 +2997,6 @@ <translation id="5610038042047936818">Badili utumie hali ya kamera</translation> <translation id="5612720917913232150"><ph name="URL" /> inataka kutumia maelezo ya mahali kompyuta yako ilipo</translation> <translation id="5612734644261457353">Samahani, bado nenosiri lako halikuweza kuthibitishwa. Kumbuka: ikiwa ulibadilisha nenosiri lako hivi karibuni, nenosiri lako jipya litaanza kutumika pindi tu utakapoondoka, tafadhali tumia nenosiri jipya hapa.</translation> -<translation id="5613695965848159202">Kitambulisho kisichojulikana:</translation> <translation id="5614190747811328134">Arifa ya Mtumiaji</translation> <translation id="561698261642843490">Funga Firefox</translation> <translation id="5618075537869101857">Lo! programu ya kioski haikuweza kuzinduliwa.</translation> @@ -3219,7 +3214,6 @@ <translation id="5941343993301164315">Tafadhali ingia kwenye <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Punguza</translation> <translation id="5946591249682680882">Kitambulisho cha ripoti <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Ongeza mtandao wa faragha</translation> <translation id="5949544233750246342">Imeshindwa kuchanganua faili</translation> <translation id="5955282598396714173">Nenosiri lako limekwisha muda. Tafadhali ondoka kisha uingie katika akaunti tena ili ulibadilishe.</translation> <translation id="5956585768868398362">Je, huu ndio ukurasa wa utafutaji uliokuwa ukitarajia?</translation> @@ -3380,11 +3374,13 @@ <translation id="6198102561359457428">Ondoka na kisha uingie tena...</translation> <translation id="6198252989419008588">Badilisha PIN</translation> <translation id="6199801702437275229">Inasubiri maelezo ya nafasi...</translation> +<translation id="6204015976622790023">Angalia mapendekezo muhimu kutoka kwa programu ya Mratibu, yanayohusiana na maudhui yaliyo kwenye skrini yako.</translation> <translation id="6205710420833115353">Vitendo vingine vinachukua muda zaidi ya ilivyotarajiwa. Unataka kuvighairi?</translation> <translation id="6206311232642889873">&Nakili Picha</translation> <translation id="6207200176136643843">Rejesha kiwango cha kukuza kuwa chaguo msingi</translation> <translation id="620722923698527029">Fungua aina hizi za viungo katika programu husika wakati wowote</translation> <translation id="6207937957461833379">Nchi/Eneo</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Kipengele cha kusawazisha hakifanyi kazi</translation> <translation id="6212039847102026977">Onyesha sifa za kina za mtandao</translation> <translation id="6212168817037875041">Izime skrini</translation> <translation id="6212752530110374741">Kiungo cha Barua pepe</translation> @@ -3422,7 +3418,6 @@ <translation id="6263541650532042179">weka upya usawazishaji</translation> <translation id="6264365405983206840">Chagua &Zote</translation> <translation id="6264422956566238156">Umewasha Usawazishaji</translation> -<translation id="6265930187414222160">Safi! Programu hasidi imeondolewa.</translation> <translation id="6267166720438879315">Chagua cheti cha kujithibitisha kwa <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Fungua kwa kutumia <ph name="APP" /></translation> <translation id="6268747994388690914">Ingiza alamisho kutoka faili ya HTML...</translation> @@ -3529,7 +3524,6 @@ Tafadhali bofya "Inayofuata" ili uendelee kuingia katika akaunti yako ya <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Pakia kiendelezi kilichopakuliwa</translation> <translation id="642282551015776456">Jina hili halifai kutumiwe kama faili ya jina la folda</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Fungua mipangilio ya ChromeVox</translation> <translation id="6429384232893414837">Hitilafu ya kusasisha</translation> <translation id="6430814529589430811">ASCII iliyosimbwa kwa Base64, cheti kimoja</translation> @@ -3610,7 +3604,6 @@ <translation id="6544215763872433504">Kivinjari cha Google, kwa ajili yako</translation> <translation id="6545665334409411530">Ukadiriaji wa kurudia</translation> <translation id="6545834809683560467">Tumia huduma ya kutabiri ili isaidie kukamilisha utafutaji na URL zilizoingizwa katika upau wa anwani au katika kisanduku cha kutafutia kizindua programu</translation> -<translation id="6546686722964485737">Jiunge kwenye mtandao wa WiMAX</translation> <translation id="6547316139431024316">Usitume onyo kuhusu kiendelezi hiki tena</translation> <translation id="6547354035488017500">Futa angalau MB 512 za hifadhi, la sivyo kifaa chako kitakwama. Ili kupata nafasi, futa faili kwenye hifadhi ya kifaa.</translation> <translation id="6549689063733911810">Za hivi karibuni</translation> @@ -4029,7 +4022,6 @@ <translation id="7201014958346994077">Imeshindwa kuona Faili za Linux</translation> <translation id="720110658997053098">Weka kifaa hiki katika hali ya skrini nzima kila wakati</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' imefutwa</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Inapakua <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Funga ukurasa}other{Funga kurasa}}</translation> <translation id="7216409898977639127">Mtoa huduma za vifaa vya mkononi</translation> @@ -4508,7 +4500,6 @@ <translation id="7909969815743704077">Ilipakuliwa katika Hali Fiche</translation> <translation id="7910768399700579500">&Folda jipya</translation> <translation id="7912080627461681647">Nenosiri lako limebadilishwa kwenye seva. Tafadhali ondoka na uingie katika akaunti tena.</translation> -<translation id="7912883689016444961">Weka mipangilio ya mtandao wa simu</translation> <translation id="7915471803647590281">Tafadhali tuelezee kinachofanyika kabla ya kutuma mwitiko.</translation> <translation id="7916556741383518510">Unapobofya</translation> <translation id="792514962475806987">Kiwango cha ukuzaji uliofungwa:</translation> @@ -4562,7 +4553,6 @@ <translation id="7988355189918024273">Washa vipengele vya zana za walio na matatizo ya kuona au kusikia</translation> <translation id="7994702968232966508">Mbinu ya EAP</translation> <translation id="799547531016638432">Ondoa njia ya mkato</translation> -<translation id="7997479212858899587">Kitambulisho:</translation> <translation id="7997826902155442747">Kipaumbele cha Mchakato</translation> <translation id="7999229196265990314">Imeunda faili zifuatazo: @@ -4646,7 +4636,6 @@ <translation id="8105368624971345109">Zima</translation> <translation id="8106045200081704138">Zilizoshirikiwa na mimi</translation> <translation id="8107015733319732394">Inasakinisha duka la Google Play kwenye <ph name="DEVICE_TYPE" />. Huenda hatua hii ikachukua dakika chache.</translation> -<translation id="8109930990200908494">Unahitaji kuingia katika akaunti ili kupata cheti cha mtumiaji.</translation> <translation id="8111155949205007504">Shiriki nenosiri hili ukitumia iPhone yako</translation> <translation id="8113043281354018522">Chagua aina ya leseni</translation> <translation id="8116190140324504026">Maelezo zaidi…</translation> @@ -4657,6 +4646,7 @@ <translation id="8118860139461251237">Kudhibiti maudhui unayopakua</translation> <translation id="81238879832906896">Ua la rangi ya manjano na nyeupe</translation> <translation id="8124313775439841391">ONC Inayodhibitiwa</translation> +<translation id="8125562866093998907">Tovuti ingependa kuthibitisha Ufunguo wako wa Usalama ili kuboresha usalama wa akaunti yako.</translation> <translation id="813082847718468539">Angalia maelezo ya tovuti</translation> <translation id="8131740175452115882">Thibitisha</translation> <translation id="8133676275609324831">&Onyesha katika folda</translation> @@ -4767,7 +4757,6 @@ <translation id="8308179586020895837">Uliza kama <ph name="HOST" /> anataka kufikia kamera yako</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Cheti tayari kipo</translation> -<translation id="8309505303672555187">Chagua mtandao:</translation> <translation id="8312871300878166382">Bandika ndani ya folda</translation> <translation id="8317671367883557781">Ongeza muunganisho wa mtandao</translation> <translation id="8319414634934645341">Matumizi ya Ziada ya Ufunguo</translation> @@ -4843,7 +4832,6 @@ <translation id="8451512073679317615">mratibu</translation> <translation id="8452135315243592079">Hakuna SIM kadi</translation> <translation id="8453482423012550001">Inanakili vipengee $1...</translation> -<translation id="8454288007744638700">Au, chagua mtandao mpya:</translation> <translation id="845627346958584683">Wakati wa Muda Kuisha</translation> <translation id="8456681095658380701">Jina batili</translation> <translation id="8457451314607652708">Leta alamisho</translation> @@ -4907,6 +4895,7 @@ <translation id="855081842937141170">Bandikiza kichupo</translation> <translation id="8551388862522347954">Leseni</translation> <translation id="8553342806078037065">Dhibiti watumiaji wengine</translation> +<translation id="8554899698005018844">Hakuna lugha</translation> <translation id="855773602626431402">Programu-jalizi isiyo ya majaribio ilizuiwa kutekeleza kwenye ukurasa huu.</translation> <translation id="8557930019681227453">Faili ya maelezo</translation> <translation id="8559694214572302298">Kisimbuaji cha Picha</translation> @@ -4944,7 +4933,6 @@ <translation id="862727964348362408">Imesitishwa</translation> <translation id="862750493060684461">Akiba ya CSS</translation> <translation id="8627795981664801467">Miunganisho salama pekee</translation> -<translation id="8628085465172583869">Jina la mpangishaji seva:</translation> <translation id="8630903300770275248">Ingiza mtumiaji anayesimamiwa</translation> <translation id="8631032106121706562">Petali</translation> <translation id="8637542770513281060">Kompyuta yako ina sehemu salama ambayo inatumiwa kutekeleza vipengele vingi muhimu vya usalama kwenye Mfumo wa Uendeshaji wa Chrome. Tembelea Kituo cha Usaidizi cha Chromebook ili upate malezo zaidi: https://support.google.com/chromebook/?p=sm</translation> @@ -5200,7 +5188,6 @@ <translation id="899403249577094719">URL ya Msingi wa Vyeti wa Netscape</translation> <translation id="8995603266996330174">Inadhibitiwa na <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Ongeza akaunti...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Inaunda picha ya diski.</translation> <translation id="9003647077635673607">Ruhusu kwenye tovuti zote</translation> <translation id="9003677638446136377">Angalia tena</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index 8f695a5..ef9bc08 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">சாதனம் பூட்டப்பட உள்ளது</translation> <translation id="1062407476771304334">மாற்றியமை</translation> -<translation id="1064835277883315402">தனிப்பட்ட பிணையத்துடன் சேர்</translation> <translation id="1064912851688322329">உங்கள் Google கணக்கைத் துண்டிக்கவும்</translation> <translation id="1067048845568873861">உருவாக்கப்பட்டது</translation> <translation id="1067291318998134776">Linux (பீட்டா)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">தேடுகிறது...</translation> <translation id="1316495628809031177">ஒத்திசைவு இடைநிறுத்தப்பட்டது</translation> <translation id="1319979322914001937">Chrome இணைய அங்காடியிலிருந்து வடிகட்டப்பட்ட நீட்டிப்புகளின் பட்டியலைக் காட்டும் பயன்பாடு. பட்டியலிலுள்ள நீட்டிப்புகளை, பயன்பாட்டிலிருந்து நேரடியாக நிறுவலாம்.</translation> -<translation id="132090119144658135">பொருந்தும் பொருள்:</translation> <translation id="1326317727527857210">உங்கள் பிற சாதனங்களிலிருந்து தாவல்களைப் பெற, Chrome இல் உள்நுழையவும்.</translation> <translation id="1327074568633507428">Google கிளவுடு அச்சில் உள்ள பிரிண்டர்</translation> <translation id="1327977588028644528">கேட்வே</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">பயன்பாட்டுச் சாளரம்</translation> <translation id="1534389735079119190">பிழை: VMமில் கன்டெய்னரைத் தொடங்க முடியவில்லை.</translation> <translation id="15373452373711364">பெரிய மவுஸ் இடஞ்சுட்டி</translation> +<translation id="1540605929960647700">டெமோ பயன்முறையை இயக்கவும்</translation> <translation id="1543284117603151572">Edge இலிருந்து இறக்கப்பட்டது</translation> <translation id="1545177026077493356">தானியங்கு கியோஸ்க் பயன்முறை</translation> <translation id="1545775234664667895">"<ph name="THEME_NAME" />? என்ற தீம் நிறுவப்பட்டது</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">தானாகவே பயன்பாட்டு புள்ளிவிவரங்களையும் சிதைவு புகார்களையும் Google க்கு அனுப்புவதன் மூலம், <ph name="PRODUCT_NAME" /> ஐ மேலும் சிறப்பானதாக்க உதவுங்கள்</translation> <translation id="1658424621194652532">இந்தப் பக்கமானது உங்கள் மைக்ரோஃபோனை அணுகுகிறது.</translation> <translation id="1660204651932907780">ஒலியை இயக்க, தளங்களை அனுமதிக்கும் (பரிந்துரைக்கப்படுவது)</translation> +<translation id="1660938185063657230">பாதுகாப்புச் சாவியைச் சரிபார்க்கவும்</translation> <translation id="1661156625580498328">AES என்க்ரிப்ஷனைச் (பரிந்துரைக்கப்பட்டது) செயல்படுத்தும்.</translation> <translation id="1661245713600520330">முதன்மை செயல்முறையில் ஏற்றப்பட்ட எல்லா தொகுதிகூறுகளையும், பின்னர் ஏற்றுவதற்கு பதிவுசெய்யப்பட்டுள்ள தொகுதிக்கூறுகளையும் இந்தப் பக்கம் பட்டியலிடுகிறது.</translation> <translation id="166179487779922818">கடவுச்சொல் மிகச் சிறியதாக உள்ளது.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">கிளிப்போர்டுக்கு நகலெடுத்த உரையையும் படங்களையும் பார்க்க, தளங்களை அனுமதிக்காதே</translation> <translation id="1682548588986054654">புதிய மறைநிலை சாளரம்</translation> <translation id="168715261339224929">உங்கள் எல்லா சாதனங்களிலும் புத்தகக்குறிகளைப் பெற, ஒத்திசைவை இயக்கவும்.</translation> +<translation id="1688867105868176567">தளத் தரவை அழிக்கவா?</translation> <translation id="1688935057616748272">ஓர் எழுத்தை உள்ளிடவும்</translation> <translation id="168991973552362966">அருகிலுள்ள பிரிண்டரைச் சேர்</translation> <translation id="1689945336726856614">&URLஐ நகலெடு</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">இவரை அகற்று</translation> <translation id="1706586824377653884">உங்கள் நிர்வாகி சேர்த்துள்ளார்</translation> <translation id="1706625117072057435">அளவுமாற்ற நிலைகள்</translation> -<translation id="1707463636381878959">பிற பயனர்களுடன் இந்தப் பிணையத்தைப் பகிர்</translation> <translation id="1708338024780164500">(செயல்படா நிலையில்)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ஐடி: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (நிலையானது)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">தீம் ஐ இயக்கு</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome இணைய அங்காடியில் காட்டு</translation> -<translation id="1758831820837444715">ஈத்தர்நெட் நெட்வொர்க்கை உள்ளமைக்கவும்</translation> <translation id="1763046204212875858">பயன்பாட்டு குறுக்குவழிகளை உருவாக்குக</translation> <translation id="1763108912552529023">தொடர்ந்து அறிக</translation> <translation id="1763808908432309942">புதிய தாவலில் திறக்கும்</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">இந்தக் கோப்புப் பகிரப்படும் விதத்தை மாற்றவும்</translation> <translation id="1841545962859478868">பின்வருவனவற்றைச் சாதன நிர்வாகி கண்காணிக்கக்கூடும்:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> முடக்கப்பட்டுள்ளது</translation> +<translation id="1842766183094193446">டெமோ பயன்முறையை இயக்க விரும்புகிறீர்களா?</translation> <translation id="1844692022597038441">இந்தக் கோப்பு ஆஃப்லைனில் கிடைக்காது.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" />ஐ இயக்க, கண்ட்ரோலைப் பிடித்து, கிளிக் செய்யவும்</translation> +<translation id="1847880352285315359">சேமிக்கப்பட்டது</translation> <translation id="1848219224579402567">மூடியிருக்கும் போது, வெளியேறு</translation> <translation id="184823282865851239">தளத்தில் குறுக்கிடும் விளம்பரங்கள் அடிக்கடிக் காட்டப்படும் எனில், அதைத் தடு</translation> <translation id="1849186935225320012">இந்தப் பக்கத்திற்கு MIDI சாதனங்களுக்கான முழுக் கட்டுப்பாடு உள்ளது.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">இதை எப்போது வேண்டுமானாலும் பின்னர் அமைப்புகளில் மாற்றிக்கொள்ளலாம்</translation> <translation id="2006638907958895361"><ph name="APP" /> இல் இணைப்பைத் திற</translation> <translation id="2007404777272201486">சிக்கலைப் புகார் செய்க...</translation> +<translation id="2016237810978710652">Linux கோப்புகளைத் திறக்கிறது...</translation> <translation id="2016430552235416146">பழைய முறை</translation> <translation id="2017334798163366053">செயல்திறன் தரவுச் சேகரிப்பை முடக்கு</translation> <translation id="2017836877785168846">முகவரிப் பட்டியில் வரலாற்றையும் தானே நிரப்புதல்களையும் அழிக்கும்.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">கார்டைத் திருத்தவும்</translation> <translation id="2154710561487035718">URL ஐ நகலெடு</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> போல் தெரிகிறது</translation> +<translation id="2156283799932971644">Googleக்கு சில சாதனத் தகவல்களையும் பக்க உள்ளடக்கத்தையும் அனுப்புவதன் மூலம் பாதுகாப்பான உலாவலை மேம்படுத்த உதவலாம்.</translation> <translation id="215753907730220065">முழுத்திரையிலிருந்து வெளியேறு</translation> <translation id="2157875535253991059">இந்தப் பக்கம் இப்போது முழுத் திரையில்.</translation> <translation id="216169395504480358">வைஃபை ஐச் சேர்...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">இந்தச் சாதனத்தில் கோரிக்கை ஐடியைச் சேர்</translation> <translation id="2175042898143291048">எப்போதும் இதைச் செய்</translation> <translation id="2175607476662778685">விரைவு தொடக்கப் பட்டி</translation> +<translation id="2176087259161165020">பிற ஆதாரங்கள்</translation> <translation id="2177950615300672361">மறைநிலைத் தாவல்: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> இல் உள்ள <ph name="PEPPER_PLUGIN_NAME" /> உங்கள் கணினியை அணுக விரும்புகிறது</translation> <translation id="2178614541317717477">CA இணக்கம்</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">அடுத்த தாவல்</translation> <translation id="2292848386125228270"><ph name="PRODUCT_NAME" />ஐ வழக்கமான பயனராகத் தொடங்குங்கள். டெவெலப்மென்ட்டுக்காக அதை ரூட் பயனராக இயக்க வேண்டும் எனில், --no-sandbox விருப்பத்தைப் பயன்படுத்தி மீண்டும் இயக்கவும்.</translation> <translation id="2294358108254308676"><ph name="PRODUCT_NAME" /> ஐ நிறுவ விரும்புகிறீர்களா?</translation> -<translation id="2296019197782308739">EAP முறை:</translation> <translation id="2297705863329999812">பிரிண்டர்களைத் தேடவும்</translation> <translation id="2300383962156589922"><ph name="APP_NAME" />ஐத் தனிப்பயனாக்கி, கட்டுப்படுத்தும்</translation> <translation id="2301382460326681002">நீட்டிப்பு மூல கோப்பகம் செல்லாதது.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">பிழை: <ph name="APP_NAME" />ஐ நிறுவல்நீக்க முடியவில்லை.</translation> <translation id="2367199180085172140">கோப்புப் பகிர்வைச் சேர்</translation> <translation id="2367972762794486313">பயன்பாடுகளைக் காட்டு</translation> +<translation id="2369536625682139252">குக்கீகள் தவிர, <ph name="SITE" /> சேமித்த எல்லாத் தரவும் நீக்கப்படும்.</translation> <translation id="2371076942591664043">&முடிந்ததும் திற</translation> <translation id="2377319039870049694">பட்டியல் காட்சிக்கு மாறு</translation> <translation id="2377667304966270281">ஹார்டு ஃபால்ட்கள்</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">கணினி உரையாடலைப் பயன்படுத்தி அச்சிடுக…<ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">அனுப்பும் முன் கேள் (பரிந்துரைக்கப்படுகிறது)</translation> <translation id="2384436799579181135">பிழை ஏற்பட்டது. உங்கள் பிரிண்டரைச் சரிபார்த்து, மீண்டும் முயலவும்.</translation> -<translation id="2385700042425247848">சேவையின் பெயர்:</translation> <translation id="2387458720915042159">ப்ராக்ஸி இணைப்பு வகை</translation> <translation id="2391419135980381625">நிலையான எழுத்துரு</translation> <translation id="2391762656119864333">திரும்பப்பெறு</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">ஆடியோவைப் பகிர்</translation> <translation id="2480868415629598489">நீங்கள் நகலெடுத்து ஒட்டும் தரவைத் திருத்தலாம்</translation> <translation id="2482878487686419369">அறிவிப்புகள்</translation> -<translation id="2485056306054380289">சேவையக CA சான்றிதழ்:</translation> <translation id="2485422356828889247">நிறுவல் நீக்கு</translation> <translation id="2487067538648443797">புதிய புத்தகக்குறியைச் சேர்</translation> <translation id="248861575772995840">மொபைலைக் கண்டறிய முடியவில்லை. <ph name="DEVICE_TYPE" /> இன் புளூடூத் இயக்கப்பட்டிருப்பதை உறுதிப்படுத்திக்கொள்ளவும். <a>மேலும் அறிக</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">பவர்வாஷ், உங்கள் <ph name="IDS_SHORT_PRODUCT_NAME" /> சாதனத்தைப் புதியதைப் போன்று மீட்டமைக்கும்.</translation> <translation id="2567257616420533738">கடவுச்சொல் சேமிக்கப்பட்டது. <ph name="SAVED_PASSWORDS_LINK" /> என்ற இணைப்பில் கடவுச்சொற்களைப் பார்க்கலாம் நிர்வகிக்கலாம்</translation> <translation id="2568774940984945469">தகவல்பட்டி கொள்கலன்</translation> +<translation id="2570454805927264159">அசிஸ்டண்ட்டிலிருந்து அதிகப் பலன்களைப் பெறுக</translation> <translation id="257088987046510401">தீம்கள்</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> இல் படிப்பதற்கான அணுகல் வழங்கப்பட்டது.</translation> <translation id="2573269395582837871">படத்தையும் பெயரையும் தேர்ந்தெடு</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">சமர்ப்பி</translation> <translation id="265390580714150011">புல மதிப்பு</translation> <translation id="2654166010170466751">பேமண்ட் ஹேண்ட்லர்களை நிறுவுவதற்குத் தளங்களை அனுமதிக்கும்</translation> -<translation id="2655386581175833247">பயனர் சான்றிதழ்:</translation> <translation id="2660779039299703961">நிகழ்வு</translation> <translation id="266079277508604648">பிரிண்டருடன் இணைக்க முடியவில்லை. பிரிண்டர் இயக்கப்பட்டு, வைஃபை அல்லது USB மூலம் அது உங்கள் Chromebook உடன் இணைக்கப்பட்டுள்ளதா எனச் சரிபார்க்கவும்.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">பயன்பாட்டுத் தரவு இல்லை</translation> <translation id="3007214526293698309">விகிதத்தைச் சரிசெய்</translation> <translation id="3007771295016901659">தாவலை நகலெடு</translation> +<translation id="3008272652534848354">அனுமதிகளை மீட்டமை</translation> <translation id="3009300415590184725">மொபைல் டேட்டா சேவை அமைப்பு செயலாக்கத்தை நிச்சயம் ரத்துசெய்ய வேண்டுமா?</translation> <translation id="3009779501245596802">அட்டவணைப்படுத்திய தரவுத்தளங்கள்</translation> <translation id="3010279545267083280">கடவுச்சொல் நீக்கப்பட்டது</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">தொகுதிக்கூறுகள் (<ph name="TOTAL_COUNT" />) - அறியப்பட்ட சிக்கல்கள்: <ph name="BAD_COUNT" />, சந்தேகத்திற்கிடமுள்ளவை: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">தேதி மற்றும் நேரம்</translation> <translation id="310671807099593501">தளமானது புளூடூத்தைப் பயன்படுத்துகிறது</translation> -<translation id="3108967419958202225">தேர்வுசெய்க...</translation> <translation id="3115128645424181617">மொபைலைக் கண்டறிய முடியவில்லை. மொபைல் அருகில் இருப்பதையும் புளூடூத் இயக்கப்பட்டிருப்பதையும் உறுதிப்படுத்திக்கொள்ளவும்.</translation> <translation id="3115147772012638511">தேக்ககத்திற்காக காத்திருக்கிறது...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> உதவி</translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">சில தொலைத்தொடர்பு நிறுவனங்கள் இந்த அம்சத்தைத் தடுக்கலாம்.</translation> <translation id="316854673539778496">உங்கள் எல்லாச் சாதனங்களிலும் நீட்டிப்புகளைப் பெற, உள்நுழைந்து, ஒத்திசைவை இயக்கவும்.</translation> <translation id="3170072451822350649">உள்நுழைவதைத் தவிர்த்துவிட்டு <ph name="LINK_START" />விருந்தினராக உலாவலாம்<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">கடவுச்சொல்லை மறைக்க கிளிக் செய்க</translation> <translation id="3177909033752230686">பக்கத்தின் மொழி:</translation> <translation id="3181110748548073003">அடுத்த பக்கத்திற்குச் செல்ல, |<ph name="SHORTCUT" />| என்பதை அழுத்தவும்</translation> <translation id="3182749001423093222">எழுத்துப் பிழை சரிபார்ப்பான்</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187"><ph name="DESTINATION_DOMAIN" />க்கு உரிமை மாற்றப்படும்.</translation> <translation id="323803881985677942">நீட்டிப்பு விருப்பங்களைத் திற</translation> <translation id="3241680850019875542">தொகுக்க வேண்டிய நீட்டிப்பின் மூல இருப்பிடத்தைத் தேர்ந்தெடு. ஒரு நீட்டிப்பைப் புதுப்பிக்க, மீண்டும் பயன்படுத்துவதற்கு தனிப்பட்ட விசைக் கோப்பையும் தேர்ந்தெடு.</translation> -<translation id="3242765319725186192">முன்பே-பகிர்ந்து கொள்ளப்பட்ட விசை:</translation> <translation id="3244294424315804309">தொடர்ந்து ஒலியடக்கு</translation> <translation id="3245321423178950146">அறியாத கலைஞர்</translation> <translation id="3246097286174000800">Smart Lockஐப் பயன்படுத்திப் பார்க்கவும்</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" />க்கான மேலும் செயல்கள்</translation> <translation id="3440761377721825626">எனது கணினியை அணுகுவதற்குச் செருகுநிரலைத் தளம் பயன்படுத்த விரும்பும் போது கேள்</translation> <translation id="3441653493275994384">பார்</translation> -<translation id="3445830502289589282">2 ஆம் நிலை அங்கீகரிப்பு:</translation> <translation id="344630545793878684">பல இணையதளங்களில் உங்கள் தரவைப் படித்தல்</translation> <translation id="3449839693241009168"><ph name="EXTENSION_NAME" /> க்கு கட்டளைகளை அனுப்ப <ph name="SEARCH_KEY" /> ஐ அழுத்துக</translation> <translation id="3450157232394774192">செயல்படா நிலையின் பணிசெயல் சதவீதம்</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> பிழைகள்.</translation> <translation id="3495660573538963482">Google அசிஸ்டண்ட் அமைப்புகள்</translation> <translation id="3496213124478423963">சிறிதாக்கு</translation> -<translation id="3504135463003295723">குழுப் பெயர்:</translation> <translation id="3505030558724226696">சாதன அணுகலை ரத்துசெய்</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" இன் தற்போதைய அனுமதிகள்</translation> <translation id="3507547268929739059">Chromebook இல் Linux பயன்பாடுகளை அகற்று</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">உள்நுழைவுச் சான்றிதழ் தவறானது. <ph name="MINUTES" /> : <ph name="SECONDS" /> இல் சாளரம் மூடப்படும்</translation> <translation id="3664511988987167893">நீட்டிப்பு ஐகான்</translation> <translation id="3665589677786828986">மற்றொரு நிரலால் உங்கள் அமைப்புகளில் சில சிதைந்துள்ளதை Chrome கண்டறிந்ததுடன், அவற்றை அசல் இயல்புநிலைகளுக்கு மீட்டமைக்கிறது.</translation> -<translation id="3665842570601375360">பாதுகாப்பு:</translation> <translation id="3668570675727296296">மொழி அமைப்புகள்</translation> <translation id="3668823961463113931">ஹேண்ட்லர்கள்</translation> <translation id="3670229581627177274">புளூடூத்தை இயக்கு</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">இந்த சாதனத்தின் கோப்புமுறைமை ஆதரிக்கப்படாததால், இந்த சாதனத்தை திறக்க முடியவில்லை.</translation> <translation id="3727148787322499904">இந்த அமைப்பை மாற்றினால், பகிர்ந்த எல்லா நெட்வொர்க்குகளும் பாதிக்கப்படும்</translation> <translation id="3727187387656390258">பாப்அப் கண்காணிப்பு</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900"><ph name="ERROR_LINE" />வது வரியில் பிழை</translation> <translation id="3733127536501031542">அதிகமாக்குதலுடனான SSL சேவையகம்</translation> <translation id="3737536731758327622">உங்கள் பதிவிறக்கங்கள் இங்கே தோன்றும்</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">முடிந்ததும், Enter அழுத்துக</translation> <translation id="3827774300009121996">&முழுத்திரை</translation> <translation id="3828029223314399057">புக்மார்க்ஸை தேடுதல்</translation> -<translation id="3829932584934971895">வழங்குநர் வகை:</translation> <translation id="3830674330436234648">பிளேபேக் இல்லை</translation> <translation id="3831486154586836914">சாளர மேலோட்ட பயன்முறைக்குள் நுழைந்துவிட்டீர்கள்</translation> <translation id="383161972796689579">இந்தச் சாதனத்தில் புதியவர்கள் சேர்க்கப்படுவதை இதன் உரிமையாளர் முடக்கியுள்ளார்</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">தரவுப் பயன்பாட்டை அளவிடுதல் முடிந்தது</translation> <translation id="3857228364945137633">உங்கள் மொபைல் அருகில் இருக்கும் போது, கடவுச்சொல்லை உள்ளிடாமல் <ph name="DEVICE_TYPE" /> சாதனத்தைத் திறக்க, Smart Lockஐப் பயன்படுத்திப் பார்க்கவும்.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: ஒத்திசைவு இடைநிறுத்தப்பட்டுள்ளது</translation> <translation id="3860381078714302691">Hangouts Meetக்கு வரவேற்கிறோம்</translation> <translation id="3862134173397075045">Chrome இன் அனுப்புதல் அனுபவத்திற்கு வரவேற்கிறோம்!</translation> <translation id="3862788408946266506">'kiosk_only' மெனிஃபெஸ்ட் பண்புக்கூறைக் கொண்ட பயன்பாட்டை, Chrome OS கியோஸ்க் பயன்முறையிலேயே நிறுவ வேண்டும்</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">நெட்வொர்க்கை அமைக்க முடியவில்லை</translation> <translation id="3970114302595058915">ஐடி</translation> <translation id="397105322502079400">கணக்கிடுகிறது...</translation> -<translation id="3974195870082915331">கடவுச்சொல்லை காண்பிக்க கிளிக் செய்க</translation> <translation id="3975222297214566386">உள்ளீட்டு விருப்பங்கள் குமிழி</translation> <translation id="397703832102027365">இறுதிபடுத்துகிறது...</translation> <translation id="3979395879372752341">புதிய நீட்டிப்பு சேர்க்கப்பட்டது (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">சான்றிதழ் கடவுச்சொல்லை உள்ளிடவும்</translation> <translation id="404493185430269859">இயல்பு தேடல் இன்ஜின்</translation> <translation id="4047112090469382184">இது எப்படிப் பாதுகாக்கிறது</translation> +<translation id="4051049974203704184">திரையில் உள்ளவற்றைப் பற்றிய தகவலைப் பெறுக</translation> <translation id="4052120076834320548">சிறிய</translation> <translation id="4055023634561256217">பவர்வாஷால் உங்கள் சாதனம் மீட்டமைக்கும் முன்பு மறுதொடக்கம் அவசியம்.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">குழுவிற்கு ஏற்றுக்கொள்</translation> <translation id="4089235344645910861">அமைப்புகள் சேமிக்கப்பட்டன. ஒத்திசைவு தொடங்கியது.</translation> <translation id="4090103403438682346">சரிபார்க்கப்பட்ட அணுகலை இயக்கு</translation> +<translation id="4090947011087001172"><ph name="SITE" />க்கான தள அனுமதிகளை மீட்டமைக்கவா?</translation> <translation id="4091434297613116013">தாள்கள்</translation> <translation id="4093955363990068916">அகக் கோப்பு:</translation> <translation id="4095507791297118304">முதன்மைத் திரை</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">ஒத்திசைவு, தனிப்பயனாக்கம் மற்றும் பலவற்றைக் கட்டுப்படுத்துக</translation> <translation id="4421932782753506458">ஃபளஃபி</translation> <translation id="4422347585044846479">இந்தப் பக்கத்திற்கான புக்மார்க்ஸைத் திருத்து</translation> -<translation id="4423104065312875417">கூடுதல் பேச்சு என்ஜின்களை நிறுவு</translation> <translation id="4423376891418188461">அமைப்புகளை மீட்டெடு</translation> <translation id="4423482519432579560">&பிழைதிருத்தம்</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, உங்கள் கடவுச்சொல்லை மாற்றும்படி நிர்வாகி கோருகிறார்.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">இந்தத் தாவல் ஆடியோவை இயக்குகிறது.</translation> <translation id="4450974146388585462">கண்டறி</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" />ஐத் தேடுக அல்லது URLஐ உள்ளிடுக</translation> -<translation id="445923051607553918">வைஃபை நெட்வொர்க்கில் சேர்</translation> <translation id="4462159676511157176">தனிப்பயன் பெயர் சேவையகங்கள்</translation> <translation id="4467100756425880649">Chrome இணைய அங்காடி கேலரி</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" />ஐ விரிக்கும் பொத்தான்</translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">உள்நுழைவு திரையில் தோன்றும் வால்பேப்பர்கள்.</translation> <translation id="4684427112815847243">அனைத்தையும் ஒத்திசை</translation> <translation id="4689421377817139245">இந்தப் புத்தகக்குறியை iPhone உடன் ஒத்திசையுங்கள்</translation> +<translation id="4690091457710545971"><Intel வைஃபை நிலைபொருள் உருவாக்கிய நான்கு கோப்புகள்: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. முதல் மூன்று கோப்புகளும் பதிவு டம்ப்களைக் கொண்டுள்ள பைனரிக் கோப்புகளாகும், அவற்றில் தனிப்பட்ட அல்லது சாதனத்தை அடையாளப்படுத்தும் தகவல்கள் எதுவும் இல்லை என்று Intel உறுதிப்படுத்தியுள்ளது. கடைசிக் கோப்பு, Intel நிலைபொருளைச் சேர்ந்த ஓர் இயக்கக் கண்காணிப்புக் கோப்பாகும்; அதிலிருந்து தனிப்பட்ட அல்லது சாதனத்தை அடையாளப்படுத்தும் தகவல்கள் அகற்றப்பட்டுள்ளன, ஆனால் கோப்பு மிகப் பெரிதாக இருப்பதால் அதை இங்கு காட்ட முடியாது. இந்தக் கோப்புகள் உங்கள் சாதனத்தில் சமீபத்தில் ஏற்பட்ட வைஃபை குறித்த சிக்கல்களுக்குப் பதிலளிக்கையில் உருவாக்கப்பட்டன, அவை இந்தச் சிக்கல்களைப் பிழையறிந்து திருத்துவதற்கு உதவ, Intelலுடன் பகிரப்படும்.></translation> <translation id="4692302215262324251">உங்கள் <ph name="DEVICE_TYPE" /> சாதனம் <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> இன் நிறுவன மேலாண்மைக்குப் பதிவுசெய்யப்பட்டது. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> இது எதிர்பாராதது எனில், ஆதரவைத் தொடர்புகொள்ளவும்.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">புதிய அமைப்புகளைச் செயல்படுத்துவதற்கு முன், இந்தப் பக்கம் மீண்டும் ஏற்றப்பட வேண்டியிருக்கும்.</translation> <translation id="5075131525758602494">சிம்மின் பின்னை உள்ளிடுக</translation> <translation id="5078638979202084724">அனைத்து தாவல்களையும் புக்மார்க்கிடுக</translation> +<translation id="5079950360618752063">பரிந்துரைக்கப்படும் கடவுச்சொல்லைப் பயன்படுத்து</translation> <translation id="5084230410268011727">தளங்கள் நகர்வு மற்றும் ஒளி உணர்விகளைப் பயன்படுத்த அனுமதி</translation> <translation id="5085162214018721575">புதுப்பிப்புகளைத் தேடுகிறது</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">இந்த உருப்படியை நீக்கு</translation> <translation id="5139955368427980650">&திற</translation> +<translation id="5142961317498132443">அங்கீகாரம்</translation> <translation id="5143374789336132547">முகப்புப் பொத்தானைக் கிளிக் செய்யும் போது காண்பிக்கப்படும் பக்கத்தை, "<ph name="EXTENSION_NAME" />" நீட்டிப்பு மாற்றியுள்ளது.</translation> <translation id="5143712164865402236">முழுத்திரைக்குச் செல்</translation> <translation id="5145331109270917438">மாற்றிய தேதி</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">அந்த மாடிஃபையர்களுக்கான விசைப்பலகைக் குறுக்குவழிகளைப் பார்க்க Control, Alt, Shift ஆகியவற்றை அல்லது Search ஐ அழுத்திப் பிடிக்கவும்.</translation> <translation id="5382591305415226340">ஆதரிக்கப்படும் இணைப்புகளை நிர்வகி</translation> <translation id="5384883051496921101">இந்தத் தளமானது மறைநிலைக்கு வெளியே உள்ள பயன்பாட்டுடன் தகவலைப் பகிரவிருக்கிறது.</translation> -<translation id="5388588172257446328">பயனர்பெயர்:</translation> <translation id="5388885445722491159">சேர்க்கப்பட்டவை</translation> <translation id="5389237414310520250">புதிய பயனரை உருவாக்க முடியவில்லை. உங்கள் வட்டு இயக்ககத்தின் இடம் மற்றும் அனுமதிகளைச் சரிபார்த்து மீண்டும் முயலவும்.</translation> <translation id="5390100381392048184">ஒலியை இயக்க, தளங்களை அனுமதி</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">கீபோர்டு மற்றும் உரை உள்ளீடு</translation> <translation id="5553089923092577885">சான்றிதழ் கொள்கை மேப்பிங்ஸ்</translation> <translation id="5554489410841842733">நீட்டிப்பானது நடப்பு பக்கத்தில் செயல்படும்போது இந்த ஐகான் தெரியும்.</translation> -<translation id="5554573843028719904">பிற வைஃபை நெட்வொர்க்...</translation> <translation id="5554720593229208774">மின்னஞ்சல் சான்றளிக்கும் மையம்</translation> <translation id="5556206011531515970">உங்களின் இயல்புநிலை உலாவியைத் தேர்வுசெய்ய, அடுத்தது என்பதைக் கிளிக் செய்யவும்.</translation> <translation id="5556459405103347317">மீண்டும் ஏற்று</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">கேமரா பயன்முறைக்கு மாறு</translation> <translation id="5612720917913232150"><ph name="URL" /> உங்கள் கணினியின் இருப்பிடத்தைப் பயன்படுத்த விரும்புகிறது</translation> <translation id="5612734644261457353">மன்னிக்கவும், உங்கள் கடவுச்சொல் இன்னும் சரிபார்க்கப்படவில்லை. குறிப்பு: உங்கள் கடவுச்சொல்லை சமீபத்தில் மாற்றியிருந்தால், நீங்கள் வெளியேறியவுடன் புதிய கடவுச்சொல் செயல்படுத்தப்படும், இங்கு பழைய கடவுச்சொல்லைப் பயன்படுத்தவும்.</translation> -<translation id="5613695965848159202">அநாமதேய அடையாளம்:</translation> <translation id="5614190747811328134">பயனர் அறிவிப்பு</translation> <translation id="561698261642843490">Firefoxஐ மூடு</translation> <translation id="5618075537869101857">அச்சோ, Kiosk பயன்பாட்டை தொடங்க முடியவில்லை.</translation> @@ -3228,7 +3223,6 @@ <translation id="5941343993301164315">தயவுசெய்து <ph name="TOKEN_NAME" /> இல் உள்நுழைக.</translation> <translation id="5941711191222866238">சிறிதாக்கு</translation> <translation id="5946591249682680882"><ph name="WEBRTC_LOG_REPORT_ID" /> ஐடியைப் புகாரளி</translation> -<translation id="5948544841277865110">தனிப்பட்ட பிணையத்தைச் சேர்</translation> <translation id="5949544233750246342">கோப்பைப் பாகுபடுத்த முடியவில்லை</translation> <translation id="5955282598396714173">உங்கள் கடவுச்சொல் காலாவதியாகிவிட்டது. அதை மாற்ற, வெளியேறி, மீண்டும் உள்நுழையவும்.</translation> <translation id="5956585768868398362">இந்தத் தேடல் பக்கம் நீங்கள் எதிர்பார்த்தது போன்று உள்ளதா?</translation> @@ -3389,11 +3383,13 @@ <translation id="6198102561359457428">வெளியேறி பிறகு மீண்டும் உள்நுழைக...</translation> <translation id="6198252989419008588">PIN ஐ மாற்றவும்</translation> <translation id="6199801702437275229">இடத் தகவலுக்காக காத்திருக்கிறது...</translation> +<translation id="6204015976622790023">அசிஸ்டண்ட் வழங்கும் உங்கள் திரையில் உள்ள உள்ளடக்கத்துடன் தொடர்புடைய பரிந்துரைகளைப் பார்க்கலாம்.</translation> <translation id="6205710420833115353">சில செயல்பாடுகள் எதிர்பார்த்ததை விட அதிக நேரம் எடுக்கிறது. அவற்றை நிறுத்த விரும்புகிறீர்களா?</translation> <translation id="6206311232642889873">படத்தை நகலெ&டு</translation> <translation id="6207200176136643843">இயல்பான அளவிற்கு மீட்டமைக்கும்</translation> <translation id="620722923698527029">இந்த வகையான இணைப்புகளை எப்போதும் தொடர்புடைய பயன்பாட்டில் திற</translation> <translation id="6207937957461833379">நாடு/பிராந்தியம்</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: ஒத்திசைவு வேலை செய்யவில்லை</translation> <translation id="6212039847102026977">மேம்பட்ட நெட்வொர்க் பண்புகளைக் காட்டு</translation> <translation id="6212168817037875041">திரையை அணை</translation> <translation id="6212752530110374741">இணைப்பை மின்னஞ்சல் செய்</translation> @@ -3431,7 +3427,6 @@ <translation id="6263541650532042179">ஒத்திசைவை மீட்டமை</translation> <translation id="6264365405983206840">அ&னைத்தையும் தேர்ந்தெடு</translation> <translation id="6264422956566238156">ஒத்திசைவை இயக்கியுள்ளீர்கள்</translation> -<translation id="6265930187414222160">முடிந்தது! தீங்கிழைக்கும் மென்பொருள் அகற்றப்பட்டது.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" /> க்கு உங்களை அங்கீகரிக்க ஒரு சான்றிதழைத் தேர்ந்தெடுங்கள்</translation> <translation id="6268252012308737255"><ph name="APP" /> இல் திற</translation> <translation id="6268747994388690914">HTML கோப்பிலிருந்து புக்மார்க்குகளை இறக்குமதி செய்...</translation> @@ -3538,7 +3533,6 @@ உங்கள் <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> கணக்கில் உள்நுழைவதைத் தொடர, 'அடுத்து' என்பதைக் கிளிக் செய்யவும்.</translation> <translation id="6419546358665792306">தொகுக்கப்படாத நீட்டிப்பை ஏற்று</translation> <translation id="642282551015776456">கோப்புறைப் பெயரின் கோப்பாக இந்தப் பெயரைப் பயன்பட முடியாமல் போகக்கூடும்</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox அமைப்புகளைத் திற</translation> <translation id="6429384232893414837">புதுப்பிப்பதில் பிழை</translation> <translation id="6430814529589430811">Base64-குறியேற்றப்பட்ட ASCII, ஒற்றைச் சான்றிதழ்</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">Google உங்களுக்காக வழங்கும் இணைய உலாவி</translation> <translation id="6545665334409411530">மீண்டும் இயக்குவதன் வீதம்</translation> <translation id="6545834809683560467">தேடல்களையும், முகவரிப் பட்டி அல்லது பயன்பாட்டுத் துவக்கியின் தேடல் பெட்டியில் தட்டச்சு செய்யப்பட்ட URLகளையும் நிறைவு செய்ய யூகச் சேவையைப் பயன்படுத்தவும்</translation> -<translation id="6546686722964485737">WiMAX பிணையத்தில் சேர்</translation> <translation id="6547316139431024316">இந்த நீட்டிப்புக்காக மீண்டும் எச்சரிக்க வேண்டாம்</translation> <translation id="6547354035488017500">குறைந்தது 512 மெ.பை. இடத்தைக் காலியாக்கவும் அல்லது உங்கள் சாதனம் இயங்காது. இடத்தைக் காலியாக்க, சாதனத்தின் சேமிப்பகத்தில் இருந்து கோப்புகளை நீக்கவும்.</translation> <translation id="6549689063733911810">சமீபத்தியவை</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Linux கோப்புகளைப் பார்க்க முடியவில்லை</translation> <translation id="720110658997053098">இந்தச் சாதனத்தை, கியோஸ்க் பயன்முறையில் நிரந்தரமாக வைத்திரு</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' நீக்கப்பட்டது</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> ஐப் பதிவிறக்குகிறது...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{பக்கத்திலிருந்து வெளியேறு}other{பக்கங்களிலிருந்து வெளியேறு}}</translation> <translation id="7216409898977639127">செல்லுலார் வழங்குநர்</translation> @@ -4514,7 +4506,6 @@ <translation id="7909969815743704077">மறைநிலையில் பதிவிறக்கப்பட்டது</translation> <translation id="7910768399700579500">&புதிய கோப்புறை</translation> <translation id="7912080627461681647">சேவையகத்தில் உங்கள் கடவுச்சொல் மாற்றப்பட்டது. வெளியேறி, மீண்டும் உள்நுழையவும்.</translation> -<translation id="7912883689016444961">மொபைல் நெட்வொர்க்கை உள்ளமை</translation> <translation id="7915471803647590281">மறுமொழி அனுப்புவதற்கு முன், என்ன நடந்துகொண்டிருக்கிறது என்பதை எங்களிடம் தெரியப்படுத்துங்கள்.</translation> <translation id="7916556741383518510">கிளிக் செய்யும் போது</translation> <translation id="792514962475806987">டாக் செய்யப்பட்ட பெரிதாக்கியின் அளவை மாற்றுவதற்கான நிலை:</translation> @@ -4568,7 +4559,6 @@ <translation id="7988355189918024273">அணுகல்தன்மை அம்சங்களை இயக்கு</translation> <translation id="7994702968232966508">EAP முறை</translation> <translation id="799547531016638432">குறுக்குவழியை அகற்று</translation> -<translation id="7997479212858899587">அடையாளம்:</translation> <translation id="7997826902155442747">செயல்படுத்தல் முன்னுரிமை</translation> <translation id="7999229196265990314">பின்வரும் கோப்புகள் உருவாக்கப்பட்டன: @@ -4652,7 +4642,6 @@ <translation id="8105368624971345109">முடக்கு</translation> <translation id="8106045200081704138">என்னுடன் பகிர்ந்தவை</translation> <translation id="8107015733319732394">உங்கள் <ph name="DEVICE_TYPE" /> இல் Google Play ஸ்டோரை நிறுவுகிறது. இதற்குச் சில நிமிடங்கள் ஆகலாம்.</translation> -<translation id="8109930990200908494">பயனர் சான்றிதழுக்கு உள்நுழைவுத் தேவை.</translation> <translation id="8111155949205007504">இந்தக் கடவுச்சொல்லை உங்கள் iPhone உடன் பகிருங்கள்</translation> <translation id="8113043281354018522">உரிம வகையைத் தேர்வு செய்யவும்</translation> <translation id="8116190140324504026">மேலும் தகவல்கள்...</translation> @@ -4663,6 +4652,7 @@ <translation id="8118860139461251237">உங்கள் பதிவிறக்கங்களை நிர்வகிக்கவும்</translation> <translation id="81238879832906896">மஞ்சள் வெள்ளை மலர்</translation> <translation id="8124313775439841391">நிர்வகிக்கப்படும் ONC</translation> +<translation id="8125562866093998907">உங்கள் கணக்கின் பாதுகாப்பை மேலும் அதிகரிப்பதற்காக, தளம் உங்கள் பாதுகாப்புச் சாவியைச் சரிபார்க்க விரும்புகிறது.</translation> <translation id="813082847718468539">தள விவரங்களைக் காண்க</translation> <translation id="8131740175452115882">உறுதிப்படுத்து</translation> <translation id="8133676275609324831">கோப்புறையில் &காண்பி</translation> @@ -4773,7 +4763,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> உங்கள் கேமராவை அணுக விரும்புகிறதா எனக் கேட்கவும்</translation> <translation id="830868413617744215">பீட்டா</translation> <translation id="8309458809024885768">சான்றிதழ் ஏற்கனவே உள்ளது</translation> -<translation id="8309505303672555187">நெட்வொர்க்கைத் தேர்ந்தெடு:</translation> <translation id="8312871300878166382">கோப்புறையில் ஒட்டு</translation> <translation id="8317671367883557781">நெட்வொர்க் இணைப்பைச் சேர்</translation> <translation id="8319414634934645341">நீட்டிக்கப்பட்ட விசைப் பயன்பாடு</translation> @@ -4848,7 +4837,6 @@ <translation id="8451512073679317615">அசிஸ்டண்ட்</translation> <translation id="8452135315243592079">சிம் கார்டு இல்லை</translation> <translation id="8453482423012550001">$1 உருப்படிகளை நகலெடுக்கிறது...</translation> -<translation id="8454288007744638700">அல்லது, புதிய நெட்வொர்க்கைத் தேர்ந்தெடுக்கவும்:</translation> <translation id="845627346958584683">காலாவதியாகும் நேரம்</translation> <translation id="8456681095658380701">தவறான பெயர்</translation> <translation id="8457451314607652708">புத்தகக்குறிகளை இறக்குமதி செய்</translation> @@ -4912,6 +4900,7 @@ <translation id="855081842937141170">தாவலைப் பொருத்து</translation> <translation id="8551388862522347954">உரிமங்கள்</translation> <translation id="8553342806078037065">பிற பயனர்களை நிர்வகி</translation> +<translation id="8554899698005018844">மொழி இல்லை</translation> <translation id="855773602626431402">சாண்ட்பாக்ஸ் செய்யப்படாத செருகுநிரல் இந்தப் பக்கத்தில் இயக்கப்படுவதிலிருந்து தடுக்கப்பட்டது.</translation> <translation id="8557930019681227453">மேனிஃபெஸ்ட்</translation> <translation id="8559694214572302298">இமேஜ் டீகோடர்</translation> @@ -4949,7 +4938,6 @@ <translation id="862727964348362408">இடைநீக்கப்பட்டது</translation> <translation id="862750493060684461">CSS தற்காலிக சேமிப்பு</translation> <translation id="8627795981664801467">பாதுகாப்பான இணைப்புகள் மட்டும்</translation> -<translation id="8628085465172583869">சேவையக ஹோஸ்ட்பெயர்:</translation> <translation id="8630903300770275248">கண்காணிக்கப்படும் பயனரை இறக்குமதிசெய்</translation> <translation id="8631032106121706562">பெட்டல்ஸ்</translation> <translation id="8637542770513281060">உங்கள் கணினியில் பாதுகாப்பு மாட்யூல் உள்ளது. இது Chrome OS இல் உள்ள பல முக்கியமான பாதுகாப்பு அம்சங்களைச் செயல்படுத்தப் பயன்படுத்தப்படுகிறது. மேலும் அறிய, Chromebook உதவி மையத்திற்குச் செல்லவும்: https://support.google.com/chromebook/?p=sm</translation> @@ -5205,7 +5193,6 @@ <translation id="899403249577094719">Netscape சான்றிதழ் அடிப்படை URL</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> ஆல் நிர்வகிக்கப்படுகிறது</translation> <translation id="8996526648899750015">கணக்கைச் சேர்...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">டிஸ்க் பிரதியை உருவாக்குகிறது.</translation> <translation id="9003647077635673607">எல்லா இணையதளங்களிலும் அனுமதி</translation> <translation id="9003677638446136377">மீண்டும் சரிபார்க்கவும்</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb index c718199..0d1ff94a 100644 --- a/chrome/app/resources/generated_resources_te.xtb +++ b/chrome/app/resources/generated_resources_te.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">దాదాపు విరామ సమయం</translation> <translation id="1062407476771304334">భర్తీ చేయి</translation> -<translation id="1064835277883315402">వ్యక్తిగత నెట్వర్క్లో చేరండి</translation> <translation id="1064912851688322329">మీ Google ఖాతాను డిస్కనెక్ట్ చేస్తుంది</translation> <translation id="1067048845568873861">సృష్టించబడింది</translation> <translation id="1067291318998134776">Linux (బీటా)</translation> @@ -225,7 +224,6 @@ <translation id="1316136264406804862">శోధిస్తోంది...</translation> <translation id="1316495628809031177">సమకాలీకరణ పాజ్ చేయబడింది</translation> <translation id="1319979322914001937">Chrome వెబ్ స్టోర్ నుండి ఫిల్టర్ చేసిన పొడిగింపుల జాబితాను చూపే అనువర్తనం. జాబితాలో ఉన్న పొడిగింపులు అనువర్తనం నుండి నేరుగా ఇన్స్టాల్ చేయబడతాయి.</translation> -<translation id="132090119144658135">విషయ సరిపోలిక:</translation> <translation id="1326317727527857210">మీ ఇతర పరికరాల నుండి మీ ట్యాబ్లను పొందడానికి, Chromeకి సైన్ ఇన్ చేయండి.</translation> <translation id="1327074568633507428">Google మేఘ ముద్రణలో ప్రింటర్</translation> <translation id="1327977588028644528">గేట్వే</translation> @@ -372,6 +370,7 @@ <translation id="1531004739673299060">అనువర్తన విండో</translation> <translation id="1534389735079119190">ఎర్రర్: VMలోని కంటైనర్ని లోడ్ చేయడం విఫలమైంది.</translation> <translation id="15373452373711364">పెద్ద మౌస్ కర్సర్</translation> +<translation id="1540605929960647700">డెమో మోడ్ని ప్రారంభించండి</translation> <translation id="1543284117603151572">Edge నుండి దిగుమతి చేసినవి</translation> <translation id="1545177026077493356">స్వయంచాలక కియోస్క్ మోడ్</translation> <translation id="1545775234664667895">వ్యవస్థాపితమైన థీమ్ "<ph name="THEME_NAME" />"</translation> @@ -454,6 +453,7 @@ <translation id="1657406563541664238">Googleకు ఉపయోగ గణాంకాలు మరియు క్రాష్ నివేదికలను స్వయంచాలకంగా పంపడం ద్వారా <ph name="PRODUCT_NAME" />ను మరింత మెరుగుపరచడంలో సహాయపడండి</translation> <translation id="1658424621194652532">ఈ పేజీ మీ మైక్రోఫోన్ను ప్రాప్యత చేస్తోంది.</translation> <translation id="1660204651932907780">ధ్వనిని ప్లే చేయడానికి సైట్లను అనుమతించండి (సిఫార్సు చేయబడింది)</translation> +<translation id="1660938185063657230">మీ భద్రతా కీని ధృవీకరించండి</translation> <translation id="1661156625580498328">AES ఎన్క్రిప్షన్ను అమలు చేయి (సిఫార్సు చేయబడినది).</translation> <translation id="1661245713600520330">ఈ పేజీ ప్రధాన ప్రాసెస్లోకి లోడ్ చెయ్యబడిన అన్ని మాడ్యూళ్ళను మరియు తర్వాత లోడ్ చెయ్యడానికి నమోదు చెయ్యబడిన మాడ్యూళ్ళను జాబితా చేస్తుంది.</translation> <translation id="166179487779922818">పాస్వర్డ్ చాలా చిన్నదిగా ఉంది.</translation> @@ -471,6 +471,7 @@ <translation id="16815041330799488">క్లిప్బోర్డ్కు కాపీ చేసిన వచనం మరియు చిత్రాలను చూడటానికి సైట్లను అనుమతించవద్దు</translation> <translation id="1682548588986054654">క్రొత్త అజ్ఞాత విండో</translation> <translation id="168715261339224929">మీ బుక్మార్క్లను మీ అన్ని పరికరాలలోనూ పొందాలంటే, సమకాలీకరణను ఆన్ చేయండి.</translation> +<translation id="1688867105868176567">సైట్ డేటాని క్లియర్ చేయాలా?</translation> <translation id="1688935057616748272">అక్షరాన్ని టైప్ చేయండి</translation> <translation id="168991973552362966">సమీపంలోని ప్రింటర్ను జోడించండి</translation> <translation id="1689945336726856614">&URLని కాపీ చేయండి</translation> @@ -482,7 +483,6 @@ <translation id="1701062906490865540">ఈ వ్యక్తిని తీసివేయి</translation> <translation id="1706586824377653884">మీ నిర్వాహకులు జోడించారు</translation> <translation id="1706625117072057435">జూమ్ స్థాయిలు</translation> -<translation id="1707463636381878959">ఇతర వినియోగదారులతో ఈ నెట్వర్క్ను భాగస్వామ్యం చెయ్యి</translation> <translation id="1708338024780164500">(క్రియారహితం)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (స్థానికం)</translation> @@ -518,7 +518,6 @@ <translation id="175772926354468439">థీమ్ను ప్రారంభించు</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome వెబ్ స్టోర్లో చూడండి</translation> -<translation id="1758831820837444715">ఈథర్నెట్ నెట్వర్క్ను కాన్ఫిగర్ చేయండి</translation> <translation id="1763046204212875858">అనువర్తనం సత్వరమార్గాలను సృష్టించు</translation> <translation id="1763108912552529023">విశ్లేషణ కొనసాగించండి</translation> <translation id="1763808908432309942">కొత్త ట్యాబ్లో తెరవబడుతుంది</translation> @@ -577,8 +576,10 @@ <translation id="1839704667838141620">ఈ ఫైల్ భాగస్వామ్యం చేయబడే విధానాన్ని మార్చండి</translation> <translation id="1841545962859478868">పరికర నిర్వాహకుడు క్రింది వాటిని పర్యవేక్షించవచ్చు:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> నిలిపివేయబడింది</translation> +<translation id="1842766183094193446">మీరు ఖచ్చితంగా డెమో మోడ్ని ప్రారంభించాలనుకుంటున్నారా?</translation> <translation id="1844692022597038441">ఈ ఫైల్ ఆఫ్లైన్లో అందుబాటులో లేదు.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" />ని అమలు చేయడానికి కంట్రోల్ నొక్కి, క్లిక్ చేయండి</translation> +<translation id="1847880352285315359">సేవ్ చేయబడింది</translation> <translation id="1848219224579402567">మూత మూసి ఉన్నప్పుడు సైన్ అవుట్ చేయండి</translation> <translation id="184823282865851239">సైట్ అనుచితమైన ప్రకటనలను చూపడానికి ప్రయత్నిస్తే బ్లాక్ చేస్తుంది</translation> <translation id="1849186935225320012">ఈ పేజీ MIDI పరికరాలకు పూర్తి నియంత్రణను కలిగి ఉంది.</translation> @@ -676,6 +677,7 @@ <translation id="200544492091181894">మీరు దీన్ని తర్వాత ఎప్పుడైనా సెట్టింగ్లలో మార్చవచ్చు</translation> <translation id="2006638907958895361">లింక్ను <ph name="APP" />లో తెరువు</translation> <translation id="2007404777272201486">ఒక సమస్యను నివేదించండి...</translation> +<translation id="2016237810978710652">Linux ఫైల్లను తెరుస్తోంది...</translation> <translation id="2016430552235416146">సాంప్రదాయకం</translation> <translation id="2017334798163366053">పనితీరు డేటా సేకరణను నిలిపివేయి</translation> <translation id="2017836877785168846">చిరునామా బార్లో చరిత్రను మరియు స్వీయ పూరణలను క్లియర్ చేస్తుంది.</translation> @@ -769,6 +771,7 @@ <translation id="2151576029659734873">చెల్లని టాబ్ సూచిక ఎంటర్ చెయ్యబడింది.</translation> <translation id="2154484045852737596">కార్డ్ను సవరించండి</translation> <translation id="2154710561487035718">URLను కాపీ చెయ్యి</translation> +<translation id="2156283799932971644">కొంత సిస్టమ్ సమాచారం మరియు పేజీ కంటెంట్ను Googleకి పంపడం ద్వారా సురక్షిత బ్రౌజింగ్ని మెరుగుపరచడంలో మీరు సహాయపడవచ్చు.</translation> <translation id="215753907730220065">పూర్తి స్క్రీన్ను నిష్క్రమించు</translation> <translation id="2157875535253991059">ఈ పేజీ ఇప్పుడు పూర్తి స్క్రీన్లో ఉంది.</translation> <translation id="216169395504480358">Wi-Fiని జోడించండి...</translation> @@ -778,6 +781,7 @@ <translation id="2173801458090845390">ఈ పరికరానికి అభ్యర్థన IDను జోడించండి</translation> <translation id="2175042898143291048">ఎల్లప్పుడూ దీన్ని చేయి</translation> <translation id="2175607476662778685">శీఘ్ర ప్రాయోగిక పట్టీ</translation> +<translation id="2176087259161165020">ఇతర మూలాధారాలు</translation> <translation id="2177950615300672361">అజ్ఞాత ట్యాబ్: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" />లోని <ph name="PEPPER_PLUGIN_NAME" /> మీ కంప్యూటర్ని యాక్సెస్ చేయాలనుకుంటోంది</translation> <translation id="2178614541317717477">CA రాజీ</translation> @@ -861,7 +865,6 @@ <translation id="2291643155573394834">తదుపరి ట్యాబ్</translation> <translation id="2292848386125228270">దయచేసి సాధారణ వినియోగదారుగా <ph name="PRODUCT_NAME" />ని ప్రారంభించండి. మీరు అభివృద్ధికి మూలమైన దాని వలె అమలు చేయాలనుకుంటే, --no-sandbox ఫ్లాగ్తో మళ్లీ అమలు చేయండి.</translation> <translation id="2294358108254308676">మీరు <ph name="PRODUCT_NAME" />ను వ్యవస్థాపించాలనుకుంటున్నారా?</translation> -<translation id="2296019197782308739">EAP విధానం:</translation> <translation id="2297705863329999812">ప్రింటర్లను వెతకండి</translation> <translation id="2300383962156589922"><ph name="APP_NAME" />ను అనుకూలీకరించండి మరియు నియంత్రించండి</translation> <translation id="2301382460326681002">పొడిగింపు మూలం డైరెక్టరీ చెల్లదు.</translation> @@ -909,6 +912,7 @@ <translation id="2366463953911599217">ఎర్రర్: <ph name="APP_NAME" />ని అన్ఇన్స్టాల్ చేయడం విఫలమైంది.</translation> <translation id="2367199180085172140">ఫైల్ షేర్ని జోడించండి</translation> <translation id="2367972762794486313">అనువర్తనాలను చూపు</translation> +<translation id="2369536625682139252">కుక్కీలు మినహా <ph name="SITE" /> నిల్వ చేసిన మొత్తం డేటా తొలగించబడుతుంది.</translation> <translation id="2371076942591664043">&పూర్తవగానే తెరువు</translation> <translation id="2377319039870049694">జాబితా వీక్షణకు మార్చు</translation> <translation id="2377667304966270281">Hard Faultలు</translation> @@ -918,7 +922,6 @@ <translation id="2379281330731083556">సిస్టమ్ డైలాగ్ ఉపయోగించి ముద్రించు ...<ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">పంపడానికి ముందు అడుగుతుంది (సిఫార్సు చేయబడింది)</translation> <translation id="2384436799579181135">లోపం సంభవించింది. దయచేసి మీ ప్రింటర్ని తనిఖీ చేసి మళ్లీ ప్రయత్నించండి.</translation> -<translation id="2385700042425247848">సేవ పేరు:</translation> <translation id="2387458720915042159">ప్రాక్సీ కనెక్షన్ రకం</translation> <translation id="2391419135980381625">ప్రామాణిక ఫాంట్</translation> <translation id="2391762656119864333">ఉపసంహరించు</translation> @@ -968,7 +971,6 @@ <translation id="247949520305900375">ఆడియోను భాగస్వామ్యం చేయి</translation> <translation id="2480868415629598489">మీరు కాపీ చేసి, అతికించే డేటాను సవరించడం</translation> <translation id="2482878487686419369">ప్రకటనలు</translation> -<translation id="2485056306054380289">సర్వర్ CA యోగ్యతాపత్రం:</translation> <translation id="2485422356828889247">వ్యవస్థాపనను తీసివెయ్యి</translation> <translation id="2487067538648443797">కొత్త బుక్మార్క్ను జోడించు</translation> <translation id="248861575772995840">మీ ఫోన్ను కనుగొనలేము. మీ <ph name="DEVICE_TYPE" /> యొక్క బ్లూటూత్ ఆన్ చేసి ఉన్నట్లు నిర్ధారించుకోండి. <a>మరింత తెలుసుకోండి</a></translation> @@ -1028,6 +1030,7 @@ <translation id="2566124945717127842">మీ <ph name="IDS_SHORT_PRODUCT_NAME" /> పరికరాన్ని కొత్త దాని వలె రీసెట్ చేయడానికి పవర్వాష్ చేయండి.</translation> <translation id="2567257616420533738">పాస్వర్డ్ సేవ్ చేయబడింది. <ph name="SAVED_PASSWORDS_LINK" />లో సేవ్ చేసిన పాస్వర్డ్లను చూడండి మరియు నిర్వహించండి</translation> <translation id="2568774940984945469">సమాచారబార్ కంటైనర్</translation> +<translation id="2570454805927264159">మీ అసిస్టెంట్ నుండి అత్యంత ఎక్కువ ప్రయోజనం పొందండి</translation> <translation id="257088987046510401">థీమ్లు</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" />కి చదవడానికి మాత్రమే ప్రాప్యత మంజూరు చేయబడింది.</translation> <translation id="2573269395582837871">చిత్రం మరియు పేరును ఎంచుకోండి</translation> @@ -1091,7 +1094,6 @@ <translation id="2653659639078652383">సమర్పించు</translation> <translation id="265390580714150011">ఫీల్డ్ విలువ</translation> <translation id="2654166010170466751">చెల్లింపు హ్యాండ్లర్లను ఇన్స్టాల్ చేయడానికి సైట్లను అనుమతించండి</translation> -<translation id="2655386581175833247">వినియోగదారు ప్రమాణపత్రం:</translation> <translation id="2660779039299703961">ఈవెంట్</translation> <translation id="266079277508604648">ప్రింటర్కి కనెక్ట్ చేయడం సాధ్యం కాదు. ప్రింటర్ని ఆన్ చేసినట్లు, దానిని Wi-Fi లేదా USB ద్వారా మీ Chromebookకి కనెక్ట్ చేసినట్లు నిర్ధారించుకోండి.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1324,6 +1326,7 @@ <translation id="3006881078666935414">వినియోగ డేటా లేదు</translation> <translation id="3007214526293698309">నిష్పత్తిని సరిచేయి</translation> <translation id="3007771295016901659">ట్యాబ్ యొక్క నకిలీని రూపొందించు</translation> +<translation id="3008272652534848354">అనుమతులను రీసెట్ చేయి</translation> <translation id="3009300415590184725">మొబైల్ డేటా సేవ సెటప్ ప్రాసెస్ను మీరు ఖచ్చితంగా రద్దు చేయాలనుకుంటున్నారా?</translation> <translation id="3009779501245596802">సూచికలోని డేటాబేస్లు</translation> <translation id="3010279545267083280">పాస్వర్డ్ తొలగించబడింది</translation> @@ -1390,7 +1393,6 @@ <translation id="3100609564180505575">మాడ్యూళ్ళు (<ph name="TOTAL_COUNT" />) - తెలిసిన వైరుధ్యాలు: <ph name="BAD_COUNT" />, అనుమానించినవి: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">తేదీ మరియు సమయం</translation> <translation id="310671807099593501">సైట్ బ్లూటూత్ని ఉపయోగిస్తోంది</translation> -<translation id="3108967419958202225">ఎంచుకోండి...</translation> <translation id="3115128645424181617">మీ ఫోన్ను కనుగొనలేము. అది చేతికి అందేంత దగ్గర్లో ఉందని మరియు బ్లూటూత్ ఆన్ చేసి ఉన్నట్లు నిర్ధారించుకోండి.</translation> <translation id="3115147772012638511">కాష్ కోసం వేచి ఉంది...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> సహాయం</translation> @@ -1435,7 +1437,6 @@ <translation id="3165390001037658081">కొన్ని క్యారియర్లు ఈ లక్షణాన్ని బ్లాక్ చేయవచ్చు.</translation> <translation id="316854673539778496">మీ అన్ని పరికరాలలో మీ అన్ని ఎక్స్టెన్షన్లను పొందాలంటే, సైన్ ఇన్ చేసి, సమకాలీకరణను ఆన్ చేయండి.</translation> <translation id="3170072451822350649">మీరు సైన్ ఇన్ చేయడాన్ని కూడా దాటవేయవచ్చు మరియు <ph name="LINK_START" />అతిథిగా బ్రౌజ్ చేయవచ్చు<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">పాస్వర్డ్ దాచుటకు క్లిక్ చేయండి</translation> <translation id="3177909033752230686">పేజీ భాష:</translation> <translation id="3181110748548073003">ముందుకు వెళ్లడానికి |<ph name="SHORTCUT" />| నొక్కండి</translation> <translation id="3182749001423093222">అక్షరక్రమ తనిఖీ</translation> @@ -1466,7 +1467,6 @@ <translation id="3236289833370040187">యాజమాన్యం <ph name="DESTINATION_DOMAIN" />కి బదిలీ చేయబడుతుంది.</translation> <translation id="323803881985677942">పొడిగింపు ఎంపికలను తెరువు</translation> <translation id="3241680850019875542">ప్యాక్ చెయ్యడానికి పొడిగింపు యొక్క మూలం డైరెక్టరీని ఎంచుకోండి. ఒక పొడిగింపును నవీకరించడానికి, మళ్ళీ ఉపయోగించడానికి వ్యక్తిగత కీ ఫైల్ను కూడా ఎంచుకోండి.</translation> -<translation id="3242765319725186192">ముందే-భాగస్వామ్యించిన కీ:</translation> <translation id="3244294424315804309">సౌండ్ని మ్యూట్ చేయడాన్ని కొనసాగించు</translation> <translation id="3245321423178950146">తెలియని కళాకారుడు</translation> <translation id="3246097286174000800">Smart Lockను ప్రయత్నించండి</translation> @@ -1599,7 +1599,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> కోసం మరిన్ని చర్యలు</translation> <translation id="3440761377721825626">మీ కంప్యూటర్ను ప్రాప్యత చేయడానికి సైట్ ప్లగిన్ను ఉపయోగించాలనుకున్నప్పుడు అడగాలి</translation> <translation id="3441653493275994384">స్క్రీన్</translation> -<translation id="3445830502289589282">ఫేజ్ 2 ప్రామాణీకరణం:</translation> <translation id="344630545793878684">అనేక వెబ్సైట్ల్లోని మీ డేటాను చదవండి</translation> <translation id="3449839693241009168"><ph name="EXTENSION_NAME" />కు ఆదేశాలను పంపడానికి <ph name="SEARCH_KEY" /> నొక్కండి</translation> <translation id="3450157232394774192">నిష్క్రియ స్థితి అధీన శాతం</translation> @@ -1640,7 +1639,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> లోపాలు.</translation> <translation id="3495660573538963482">Google సహాయకం సెట్టింగ్లు</translation> <translation id="3496213124478423963">దూరంగా జూమ్ చెయ్యి</translation> -<translation id="3504135463003295723">సమూహం పేరు:</translation> <translation id="3505030558724226696">పరికర ప్రాప్యతను ఉపసంహరించు</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" ప్రస్తుత అనుమతులు</translation> <translation id="3507547268929739059">Chromebook కోసం Linux యాప్లను తీసివేయండి</translation> @@ -1749,7 +1747,6 @@ <translation id="3661054927247347545">సైన్ ఇన్ ప్రమాణపత్రం చెల్లదు, విండో <ph name="MINUTES" /> : <ph name="SECONDS" /> వ్యవధిలో మూసివేయబడుతుంది</translation> <translation id="3664511988987167893">ఎక్స్టెన్షన్ చిహ్నం</translation> <translation id="3665589677786828986">మీ సెట్టింగ్ల్లో కొన్నింటిని మరో ప్రోగ్రామ్ పాడు చేసినట్లుగా Chrome గుర్తించింది, తర్వాత వాటిని వాటి అసలు డిఫాల్ట్లకు రీసెట్ చేసింది.</translation> -<translation id="3665842570601375360">భద్రత:</translation> <translation id="3668570675727296296">భాష సెట్టింగ్లు</translation> <translation id="3668823961463113931">హ్యాండ్లర్లు</translation> <translation id="3670229581627177274">బ్లూటూత్ను ఆన్ చేయండి</translation> @@ -1788,7 +1785,6 @@ <translation id="3726463242007121105">పరికరం తెరవడం సాధ్యం కాదు ఎందుకంటే దాని ఫైల్సిస్టమ్కు మద్దతు లేదు.</translation> <translation id="3727148787322499904">ఈ సెట్టింగ్ను మార్చడం వలన అన్ని భాగస్వామ్య నెట్వర్క్లు ప్రభావితం అవుతాయి</translation> <translation id="3727187387656390258">పాప్అప్ను పర్యవేక్షించు</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">పంక్తి <ph name="ERROR_LINE" />లో ఎర్రర్ ఉంది</translation> <translation id="3733127536501031542">దశ-పైకితో SSL సర్వర్</translation> <translation id="3737536731758327622">మీ డౌన్లోడ్లు ఇక్కడ కనిపిస్తాయి</translation> @@ -1863,7 +1859,6 @@ <translation id="38275787300541712">పూర్తయినప్పుడు Enter నొక్కండి</translation> <translation id="3827774300009121996">&పూర్తి స్క్రీన్</translation> <translation id="3828029223314399057">బుక్మార్క్లను శోధించు</translation> -<translation id="3829932584934971895">ప్రొవైడర్ రకం:</translation> <translation id="3830674330436234648">ప్లేబ్యాక్ అందుబాటులో లేదు</translation> <translation id="3831486154586836914">విండో స్థూలదృష్టి మోడ్లోకి ప్రవేశించారు</translation> <translation id="383161972796689579">ఈ పరికరం యొక్క యజమాని క్రొత్త వినియోగదారులను జోడించడం నిలిపివేసారు</translation> @@ -1884,6 +1879,7 @@ <translation id="3856921555429624101">డేటా వినియోగాన్ని గణించడం ముగిసింది</translation> <translation id="3857228364945137633">మీ ఫోన్ సమీపంలో ఉన్నప్పుడు మీ <ph name="DEVICE_TYPE" />ని పాస్వర్డ్ లేకుండా అన్లాక్ చేయడానికి Smart Lockను ప్రయత్నించండి.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: సమకాలీకరణ పాజ్ అయింది</translation> <translation id="3860381078714302691">Hangouts సమావేశానికి స్వాగతం</translation> <translation id="3862134173397075045">Chromeలో Cast అనుభవానికి స్వాగతం!</translation> <translation id="3862788408946266506">'kiosk_only' మానిఫెస్ట్ లక్షణం ఉన్న యాప్ని తప్పనిసరిగా Chrome OS కియోస్క్ మోడ్లో ఇన్స్టాల్ చేయాలి</translation> @@ -1961,7 +1957,6 @@ <translation id="3968261067169026421">నెట్వర్క్ని సెటప్ చేయడం సాధ్యపడలేదు</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">గణిస్తోంది...</translation> -<translation id="3974195870082915331">పాస్వర్డ్ చూపించడానికి క్లిక్ చేయండి</translation> <translation id="3975222297214566386">ఇన్పుట్ ఎంపికల బబుల్</translation> <translation id="397703832102027365">పూర్తి చేస్తోంది...</translation> <translation id="3979395879372752341">క్రొత్త పొడిగింపు జోడించబడింది (<ph name="EXTENSION_NAME" />)</translation> @@ -2003,6 +1998,7 @@ <translation id="4044612648082411741">మీ ప్రమాణపత్రం పాస్వర్డ్ను నమోదు చేయండి</translation> <translation id="404493185430269859">డిఫాల్ట్ శోధన ఇంజిన్</translation> <translation id="4047112090469382184">ఇది ఎలా సురక్షితంగా ఉంటుంది</translation> +<translation id="4051049974203704184">స్క్రీన్లో ఏముంది అన్న సమాచారం పొందండి</translation> <translation id="4052120076834320548">చిన్న</translation> <translation id="4055023634561256217">మీ పరికరాన్ని పవర్వాష్తో రీసెట్ చేయడానికి ముందు పునఃప్రారంభించడం అవసరం.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2031,6 +2027,7 @@ <translation id="4088095054444612037">సమూహానికి ఆమోదించు</translation> <translation id="4089235344645910861">సెట్టింగ్ సేవ్ చేయబడింది. సమకాలీకరణ ప్రారంభించబడింది.</translation> <translation id="4090103403438682346">ధృవీకృత ప్రాప్యతను ప్రారంభించండి</translation> +<translation id="4090947011087001172"><ph name="SITE" /> యొక్క సైట్ అనుమతులను రీసెట్ చేయాలా?</translation> <translation id="4091434297613116013">పేపర్ షీట్లు</translation> <translation id="4093955363990068916">స్థానిక ఫైల్:</translation> <translation id="4095507791297118304">ప్రాథమిక డిస్ప్లే</translation> @@ -2206,7 +2203,6 @@ <translation id="4419556793104466535">సమకాలీకరణ, వ్యక్తిగతీకరణ మరియు మరిన్నింటిని నియంత్రించండి</translation> <translation id="4421932782753506458">ఫ్లఫ్ఫీ</translation> <translation id="4422347585044846479">ఈ పేజీకి బుక్మార్క్ను సవరించు</translation> -<translation id="4423104065312875417">అదనపు ప్రసంగ ఇంజిన్లను ఇన్స్టాల్ చేయండి</translation> <translation id="4423376891418188461">సెట్టింగ్లను పునరుద్ధరించు</translation> <translation id="4423482519432579560">&అక్షరక్రమ తనిఖీ</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, మీ నిర్వాహకులకు మీరు మీ పాస్వర్డ్ను మార్చడం అవసరం.</translation> @@ -2231,7 +2227,6 @@ <translation id="4449996769074858870">ఈ ట్యాబ్ ఆడియోను ప్లే చేస్తోంది.</translation> <translation id="4450974146388585462">విశ్లేషించు</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" />లో వెతకండి లేదా URLని టైప్ చేయండి</translation> -<translation id="445923051607553918">Wi-Fi నెట్వర్క్లో చేరండి</translation> <translation id="4462159676511157176">అనుకూల పేరు సర్వర్లు</translation> <translation id="4467100756425880649">Chrome వెబ్ స్టోర్ గ్యాలరీ</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" />ని విస్తరింపజేయండి</translation> @@ -2366,6 +2361,7 @@ <translation id="4682551433947286597">వాల్పేపర్లు సైన్ ఇన్ స్క్రీన్లో కనిపిస్తాయి.</translation> <translation id="4684427112815847243">ప్రతి ఒక్కటి సమకాలీకరించండి</translation> <translation id="4689421377817139245">ఈ బుక్మార్క్ని మీ iPhoneకు సమకాలీకరించండి</translation> +<translation id="4690091457710545971"><Intel Wi-Fi ఫర్మ్వేర్ రూపొందించిన నాలుగు ఫైల్లు: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. మొదటి మూడు బైనరీ ఫైల్లు, వీటిలో రిజిస్టర్ డంప్లు ఉంటాయి మరియు వ్యక్తిగత లేదా పరికర సమాచారం కలిగి ఉండకుండా వీటిని Intel అందిస్తోంది. చివరి ఫైల్ Intel ఫర్మ్వేర్ అందిస్తుంది ఒక అమలు స్థితిగతి కనుగొనడం; ఇందులో వ్యక్తిగత లేదా పరికర గుర్తింపు సమాచారం తీసివేయబడింది, కానీ ఇది చాలా పెద్దదిగా ఉన్న కారణంగా ఇక్కడ ప్రదర్శించడం సాధ్యం కాదు. మీ పరికరంలో ఉన్న ఇటీవల Wi-Fi సమస్యలకు ప్రతిస్పందనగా ఈ ఫైల్లు రూపొందించబడ్డాయి మరియు ఈ సమస్యలను పరిష్కరించడంలో సహాయపడటం కోసం ఇవి Wi-Fiతో షేర్ చేయబడతాయి.></translation> <translation id="4692302215262324251">మీ <ph name="DEVICE_TYPE" /> ఎంటర్ప్రైజ్ నిర్వహణ కోసం <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ద్వారా విజయవంతంగా నమోదు చేయబడింది. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> ఇది అనుకోకుండా జరిగి ఉంటే, దయచేసి మద్దతు బృందాన్ని సంప్రదించండి.</translation> @@ -2623,6 +2619,7 @@ <translation id="5074318175948309511">కొత్త సెట్టింగ్లు ప్రభావంలోకి రావడానికి ముందు ఈ పేజీని మళ్లీ లోడ్ చేయాల్సి ఉండవచ్చు.</translation> <translation id="5075131525758602494">SIM PINను నమోదు చేయండి</translation> <translation id="5078638979202084724">అన్ని టాబ్లను బుక్మార్క్ చెయ్యి</translation> +<translation id="5079950360618752063">సూచించిన పాస్వర్డ్ని ఉపయోగించండి</translation> <translation id="5084230410268011727">చలనం మరియు కాంతి సర్దుబాటు సెన్సార్లను ఉపయోగించడానికి సైట్లను అనుమతించు</translation> <translation id="5085162214018721575">నవీకరణల కోసం తనిఖీ చేయడం</translation> <translation id="5086082738160935172">HID</translation> @@ -2661,6 +2658,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">ఈ అంశాన్ని తొలగించు</translation> <translation id="5139955368427980650">&తెరువు</translation> +<translation id="5142961317498132443">ప్రమాణీకరణ</translation> <translation id="5143374789336132547">"<ph name="EXTENSION_NAME" />" పొడిగింపు మీరు హోమ్ బటన్ను క్లిక్ చేసినప్పుడు చూపబడే పేజీని మార్చింది.</translation> <translation id="5143712164865402236">పూర్తి స్క్రీన్ను ఎంటర్ చెయ్యండి</translation> <translation id="5145331109270917438">సవరించబడిన తేదీ</translation> @@ -2831,7 +2829,6 @@ <translation id="5380103295189760361">ఆ మాడిఫైయర్ల కోసం కీబోర్డ్ సత్వరమార్గాలను చూడటానికి Control, Alt, Shiftలను నొక్కి ఉంచండి లేదా శోధించండి.</translation> <translation id="5382591305415226340">మద్దతు గల లింక్లను నిర్వహించండి</translation> <translation id="5384883051496921101">ఈ సైట్ అజ్ఞాత మోడ్ వెలుపల ఆప్తో సమాచారాన్ని భాగస్వామ్యం చేయబోతోంది.</translation> -<translation id="5388588172257446328">వినియోగదారు పేరు:</translation> <translation id="5388885445722491159">జత చేయబడింది</translation> <translation id="5389237414310520250">కొత్త వినియోగదారుని సృష్టించడం సాధ్యపడలేదు. దయచేసి మీ హార్డ్ డ్రైవ్ నిల్వ ఖాళీని మరియు అనుమతులను తనిఖీ చేసి, ఆపై మళ్లీ ప్రయత్నించండి.</translation> <translation id="5390100381392048184">ధ్వనిని ప్లే చేయడానికి సైట్లను అనుమతించండి</translation> @@ -2956,7 +2953,6 @@ <translation id="5551573675707792127">కీబోర్డ్ మరియు వచన ఇన్పుట్</translation> <translation id="5553089923092577885">సర్టిఫికెట్ విధాన మాపింగ్లు</translation> <translation id="5554489410841842733">ప్రస్తుత పేజీలో పొడిగింపు ఉండే వరకు ఈ చిహ్నం కనిపిస్తుంది.</translation> -<translation id="5554573843028719904">ఇతర Wi-Fi నెట్వర్క్...</translation> <translation id="5554720593229208774">ఇమెయిల్ ప్రమాణపత్రం అధికారి</translation> <translation id="5556206011531515970">మీ డిఫాల్ట్ బ్రౌజర్ను ఎంచుకోవడానికి తదుపరి క్లిక్ చేయండి.</translation> <translation id="5556459405103347317">రీలోడ్</translation> @@ -2997,7 +2993,6 @@ <translation id="5610038042047936818">కెమెరా మోడ్కు మార్చు</translation> <translation id="5612720917913232150"><ph name="URL" /> మీ కంప్యూటర్ స్థానాన్ని ఉపయోగించాలనుకుంటోంది</translation> <translation id="5612734644261457353">క్షమించండి, మీ పాస్వర్డ్ ఇప్పటికీ ధృవీకరించబడలేదు. గమనిక: మీరు మీ పాస్వర్డ్ను ఇటీవల మార్చి ఉంటే, మీరు సైన్ అవుట్ చేసిన తర్వాత మీ క్రొత్త పాస్వర్డ్ వర్తించబడుతుంది, దయచేసి ఇక్కడ పాత పాస్వర్డ్ను ఉపయోగించండి.</translation> -<translation id="5613695965848159202">అజ్ఞాత గుర్తింపు:</translation> <translation id="5614190747811328134">వినియోగదారు నోటీస్</translation> <translation id="561698261642843490">Firefoxని మూసివేయండి</translation> <translation id="5618075537869101857">అయ్యో, కియోస్క్ అనువర్తనాన్ని ప్రారంభించడం సాధ్యపడలేదు.</translation> @@ -3214,7 +3209,6 @@ <translation id="5941343993301164315">దయచేసి <ph name="TOKEN_NAME" />కు సైన్ ఇన్ చెయ్యండి.</translation> <translation id="5941711191222866238">కనిష్టీకరించు</translation> <translation id="5946591249682680882">నివేదిక ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">ప్రైవేట్ నెట్వర్క్ని జోడించు</translation> <translation id="5949544233750246342">ఫైల్ని అన్వయించడం సాధ్యపడలేదు</translation> <translation id="5955282598396714173">మీ పాస్వర్డ్ గడువు ముగిసింది. దచయేసి దీనిని మార్చడం కోసం సైన్ అవుట్ చేసి, సైన్ ఇన్ చేయండి.</translation> <translation id="5956585768868398362">మీరు ఆశిస్తున్న శోధన పేజీ ఇదేనా?</translation> @@ -3375,11 +3369,13 @@ <translation id="6198102561359457428">సైన్ అవుట్ చేసి, మళ్లీ సైన్ ఇన్ చేయండి...</translation> <translation id="6198252989419008588">పిన్ మార్పు</translation> <translation id="6199801702437275229">ఖాళీ సమాచారం కోసం వేచి ఉంది...</translation> +<translation id="6204015976622790023">మీ స్క్రీన్లో ఉన్న వాటికి సంబంధించి మీ అసిస్టెంట్ నుండి సంబంధిత సూచనలను చూడండి.</translation> <translation id="6205710420833115353">కొన్ని చర్యలకి అనుకున్నదాని కంటే ఎక్కువ సమయం పడుతోంది. మీరు వాటిని రద్దు చేయాలనుకుంటున్నారా?</translation> <translation id="6206311232642889873">చిత్రాన్ని కా&పీ చెయ్యి</translation> <translation id="6207200176136643843">డిఫాల్ట్ జూమ్ స్థాయికి రీసెట్ చేయి</translation> <translation id="620722923698527029">ఎల్లప్పుడూ ఈ రకమైన లింక్లను అనుబంధిత యాప్లో తెరువు</translation> <translation id="6207937957461833379">దేశం/ప్రాంతం</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: సమకాలీకరణ పని చేయడం లేదు</translation> <translation id="6212039847102026977">అధునాతన నెట్వర్క్ లక్షణాలను చూపు</translation> <translation id="6212168817037875041">ప్రదర్శనను ఆఫ్ చేయండి</translation> <translation id="6212752530110374741">ఇమెయిల్ లింక్</translation> @@ -3417,7 +3413,6 @@ <translation id="6263541650532042179">సమకాలీకరణను రీసెట్ చెయ్యండి</translation> <translation id="6264365405983206840">&అన్నీ ఎంచుకోండి</translation> <translation id="6264422956566238156">మీరు సింక్ని ఆన్ చేసారు</translation> -<translation id="6265930187414222160">పూర్తయింది! హానికరమైన సాఫ్ట్వేర్ తీసివేయబడింది.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" />కు మిమ్మల్ని మీరు ప్రమాణీకరించడానికి ఒక సర్టిఫికెట్ను ఎంచుకోండి</translation> <translation id="6268252012308737255"><ph name="APP" />తో తెరువు</translation> <translation id="6268747994388690914">HTML ఫైల్ నుండి బుక్మార్క్లను దిగుమతి చేయి...</translation> @@ -3524,7 +3519,6 @@ దయచేసి మీ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ఖాతాకి సైన్ ఇన్ చేయడం కొనసాగించడానికి "తదుపరి" క్లిక్ చేయండి.</translation> <translation id="6419546358665792306">ప్యాక్ చేయబడని పొడిగింపును లోడ్ చేయి</translation> <translation id="642282551015776456">ఈ పేరును ఫైల్ యొక్క ఫోల్డర్ పేరుగా ఉపయోగించలేము.</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox సెట్టింగ్లను తెరువు</translation> <translation id="6429384232893414837">అప్డేట్లో ఎర్రర్</translation> <translation id="6430814529589430811">Base64-ఎన్కోడ్ చేసిన ASCII, ఒక్క సర్టిఫికెట్</translation> @@ -3605,7 +3599,6 @@ <translation id="6544215763872433504">మీ కోసం Google సమర్పిత వెబ్ బ్రౌజర్</translation> <translation id="6545665334409411530">పునరావృత రేటు</translation> <translation id="6545834809683560467">చిరునామా పట్టీలో లేదా అనువర్తన లాంచర్ శోధన పెట్టెలో టైప్ చేసే శోధనలను మరియు URLలను పూర్తి చేయడంలో సహాయకరంగా ఉండటానికి సూచన సేవను ఉపయోగించండి</translation> -<translation id="6546686722964485737">WiMAX నెట్వర్క్లో చేరండి</translation> <translation id="6547316139431024316">ఈ పొడిగింపు కోసం మళ్లీ హెచ్చరించవద్దు</translation> <translation id="6547354035488017500">కనీసం 512 MB స్థలాన్ని ఖాళీగా ఉంచండి, లేదంటే మీ పరికరం ప్రతిస్పందనరహితం అవుతుంది. స్థలాన్ని ఖాళీ చేయడానికి, పరికర నిల్వ నుండి ఫైల్లను తొలగించండి.</translation> <translation id="6549689063733911810">ఇటీవల</translation> @@ -4024,7 +4017,6 @@ <translation id="7201014958346994077">Linux ఫైల్లను చూడటం సాధ్యపడలేదు</translation> <translation id="720110658997053098">ఈ పరికరాన్ని శాశ్వతంగా కియోస్క్ మోడ్లో ఉంచు</translation> <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' తొలగించబడింది</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" />ని డౌన్లోడ్ చేస్తోంది...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{పేజీ నుండి నిష్క్రమించు}other{పేజీల నుండి నిష్క్రమించు}}</translation> <translation id="7216409898977639127">సెల్యులార్ ప్రదాత</translation> @@ -4500,7 +4492,6 @@ <translation id="7909969815743704077">అజ్ఞాతంలో డౌన్లోడ్ చేయబడింది</translation> <translation id="7910768399700579500">&క్రొత్త ఫోల్డర్</translation> <translation id="7912080627461681647">సర్వర్లో మీ పాస్వర్డ్ మార్చబడింది. దచయేసి సైన్ అవుట్ చేసి, సైన్ ఇన్ చేయండి.</translation> -<translation id="7912883689016444961">మొబైల్ నెట్వర్క్ను కాన్ఫిగర్ చేయండి</translation> <translation id="7915471803647590281">దయచేసి అభిప్రాయాన్ని పంపడానికి ముందు ఏమి జరిగిందో మాకు చెప్పండి.</translation> <translation id="7916556741383518510">క్లిక్ చేసినప్పుడు</translation> <translation id="792514962475806987">డాక్ చేయబడిన జూమ్ స్థాయి:</translation> @@ -4553,7 +4544,6 @@ <translation id="7988355189918024273">సులభంగా ప్రాప్యత చేసే లక్షణాలను ప్రారంభించు</translation> <translation id="7994702968232966508">EAP పద్ధతి</translation> <translation id="799547531016638432">సత్వరమార్గాన్ని తీసివేయి</translation> -<translation id="7997479212858899587">గుర్తింపు:</translation> <translation id="7997826902155442747">ప్రాసెస్ ప్రాధాన్యత</translation> <translation id="7999229196265990314">ఈ క్రింది ఫైళ్ళను సృష్టించింది: @@ -4634,7 +4624,6 @@ <translation id="8105368624971345109">ఆఫ్ చేయి</translation> <translation id="8106045200081704138">నాతో భాగస్వామ్యం చేసినవి</translation> <translation id="8107015733319732394">మీ <ph name="DEVICE_TYPE" />లో Google Play స్టోర్ని ఇన్స్టాల్ చేస్తోంది. ఇందుకు కొన్ని నిమిషాలు పట్టవచ్చు.</translation> -<translation id="8109930990200908494">వినియోగదారు ప్రమాణపత్రం కోసం సైన్-ఇన్ చేయడం అవసరం.</translation> <translation id="8111155949205007504">మీ iPhoneతో ఈ పాస్వర్డ్ను భాగస్వామ్యం చేయండి</translation> <translation id="8113043281354018522">లైసెన్స్ రకాన్ని ఎంచుకోండి</translation> <translation id="8116190140324504026">మరింత సమాచారం...</translation> @@ -4645,6 +4634,7 @@ <translation id="8118860139461251237">మీ డౌన్లోడ్లను నిర్వహించండి</translation> <translation id="81238879832906896">పసుపు మరియు తెలుపు రంగు పుష్పం</translation> <translation id="8124313775439841391">నిర్వహిత ONC</translation> +<translation id="8125562866093998907">మీ ఖాతాకు అదనపు భద్రత కోసం సైట్ మీ భద్రతా కీని ధృవీకరించాలి.</translation> <translation id="813082847718468539">సైట్ సమాచారాన్ని వీక్షించండి</translation> <translation id="8131740175452115882">నిర్ధారించు</translation> <translation id="8133676275609324831">&ఫోల్డర్లో చూపించు</translation> @@ -4755,7 +4745,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> మీ కెమెరాను ప్రాప్యత చేయాలనుకుంటే నాకు తెలియజేయి</translation> <translation id="830868413617744215">బీటా</translation> <translation id="8309458809024885768">ప్రమాణపత్రం ఇప్పటికే ఉంది</translation> -<translation id="8309505303672555187">నెట్వర్క్ను ఎంచుకోండి:</translation> <translation id="8312871300878166382">ఫోల్డర్లోకి అతికించు</translation> <translation id="8317671367883557781">నెట్వర్క్ కనెక్షన్ను జోడించు</translation> <translation id="8319414634934645341">విస్తరించిన కీ ఉపయోగం</translation> @@ -4830,7 +4819,6 @@ <translation id="8451512073679317615">సహాయకం</translation> <translation id="8452135315243592079">SIM కార్డ్ లేదు</translation> <translation id="8453482423012550001">$1 అంశాలను కాపీ చేస్తోంది...</translation> -<translation id="8454288007744638700">లేదా, కొత్త నెట్వర్క్ను ఎంచుకోండి:</translation> <translation id="845627346958584683">గడువు సమయం</translation> <translation id="8456681095658380701">చెల్లని పేరు</translation> <translation id="8457451314607652708">బుక్మార్క్లను దిగుమతి చేయి</translation> @@ -4894,6 +4882,7 @@ <translation id="855081842937141170">టాబ్ను పిన్ చేయి</translation> <translation id="8551388862522347954">లైసెన్స్లు</translation> <translation id="8553342806078037065">ఇతర వ్యక్తులను నిర్వహించు</translation> +<translation id="8554899698005018844">భాష లేదు</translation> <translation id="855773602626431402">శాండ్బాక్స్ చేయని ప్లగిన్ ఈ పేజీలో అమలు కానీయకుండా నిరోధించబడింది.</translation> <translation id="8557930019681227453">మానిఫెస్ట్</translation> <translation id="8559694214572302298">ఇమేజ్ డీకోడర్</translation> @@ -4931,7 +4920,6 @@ <translation id="862727964348362408">తాత్కాలికంగా రద్దు చేయబడింది</translation> <translation id="862750493060684461">CSS కాష్</translation> <translation id="8627795981664801467">సురక్షిత కనెక్షన్ల మాత్రమే</translation> -<translation id="8628085465172583869">సర్వర్ హోస్ట్పేరు:</translation> <translation id="8630903300770275248">పర్యవేక్షించబడే వినియోగదారుని దిగుమతి చేయి</translation> <translation id="8631032106121706562">పూరేకులు</translation> <translation id="8637542770513281060">మీ కంప్యూటర్లో ఒక సురక్షిత మాడ్యూల్ ఉంది, Chrome OSలో అనేక కీలకమైన భద్రతా ఫీచర్లను అమలు చేయడానికి ఇది ఉపయోగించబడుతుంది. Chromebook సహాయ కేంద్రంలో దీని గురించి మరింత తెలుసుకోండి, ఇక్కడికి వెళ్లండి: https://support.google.com/chromebook/?p=sm</translation> @@ -5187,7 +5175,6 @@ <translation id="899403249577094719">Netscape సర్టిఫికెట్ ఆధార URL</translation> <translation id="8995603266996330174"><ph name="DOMAIN" /> ద్వారా నిర్వహించబడుతోంది</translation> <translation id="8996526648899750015">ఖాతాను జోడించండి...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">డిస్క్ ఇమేజ్ని సృష్టిస్తోంది.</translation> <translation id="9003647077635673607">అన్ని వెబ్సైట్ల్లో అనుమతించు</translation> <translation id="9003677638446136377">మళ్లీ తనిఖీ చేయి</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb index 216ae8d..703b557a 100644 --- a/chrome/app/resources/generated_resources_th.xtb +++ b/chrome/app/resources/generated_resources_th.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">เกือบถึงเวลาพักแล้ว</translation> <translation id="1062407476771304334">แทนที่</translation> -<translation id="1064835277883315402">เข้าร่วมเครือข่ายส่วนบุคคล</translation> <translation id="1064912851688322329">หยุดเชื่อมต่อบัญชี Google ของคุณ</translation> <translation id="1067048845568873861">สร้างแล้ว</translation> <translation id="1067291318998134776">Linux (เบต้า)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">กำลังค้นหา...</translation> <translation id="1316495628809031177">หยุดซิงค์ชั่วคราว</translation> <translation id="1319979322914001937">แอปที่แสดงรายการส่วนขยายที่ผ่านการกรองจากส่วนขยายของ Chrome เว็บสโตร์ในรายการนี้สามารถติดตั้งได้โดยตรงจากแอปนี้</translation> -<translation id="132090119144658135">หัวเรื่องที่ตรงกัน:</translation> <translation id="1326317727527857210">ลงชื่อเข้าใช้ Chrome เพื่อรับแท็บจากอุปกรณ์เครื่องอื่นๆ ของคุณ</translation> <translation id="1327074568633507428">เครื่องพิมพ์บน Google Cloud Print</translation> <translation id="1327977588028644528">เกตเวย์</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">หน้าต่างแอปพลิเคชัน</translation> <translation id="1534389735079119190">ข้อผิดพลาด: เริ่มคอนเทนเนอร์ภายใน VM ไม่สำเร็จ</translation> <translation id="15373452373711364">เคอร์เซอร์เมาส์ขนาดใหญ่</translation> +<translation id="1540605929960647700">เปิดใช้โหมดสาธิต</translation> <translation id="1543284117603151572">นำเข้าจาก Edge</translation> <translation id="1545177026077493356">โหมดคีออสก์อัตโนมัติ</translation> <translation id="1545775234664667895">ติดตั้งธีม "<ph name="THEME_NAME" />" แล้ว</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">ช่วยปรับปรุง <ph name="PRODUCT_NAME" /> ให้ดีขึ้นโดยการส่งสถิติการใช้งานและรายงานปัญหาไปยัง Google โดยอัตโนมัติ</translation> <translation id="1658424621194652532">หน้านี้กำลังเข้าถึงไมโครโฟนของคุณ</translation> <translation id="1660204651932907780">อนุญาตให้ไซต์เล่นเสียง (แนะนำ)</translation> +<translation id="1660938185063657230">ยืนยันกุญแจรักษาความปลอดภัย</translation> <translation id="1661156625580498328">บังคับใช้การเข้ารหัส AES (แนะนำ)</translation> <translation id="1661245713600520330">หน้าเว็บนี้แสดงรายการโมดูลทั้งหมดที่โหลดเข้ากระบวนการหลักและโมดูลที่ลงทะเบียนเพื่อโหลดในภายหลัง</translation> <translation id="166179487779922818">รหัสผ่านสั้นเกินไป</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">ไม่อนุญาตให้เว็บไซต์ดูข้อความและรูปภาพที่คัดลอกไปยังคลิปบอร์ด</translation> <translation id="1682548588986054654">หน้าต่างใหม่ที่ไม่ระบุตัวตน</translation> <translation id="168715261339224929">เปิดการซิงค์เพื่อรับบุ๊กมาร์กในอุปกรณ์ทุกเครื่องของคุณ</translation> +<translation id="1688867105868176567">ล้างข้อมูลเว็บไซต์ไหม</translation> <translation id="1688935057616748272">พิมพ์ตัวอักษร</translation> <translation id="168991973552362966">เพิ่มเครื่องพิมพ์ใกล้เคียง</translation> <translation id="1689945336726856614">คัดลอก &URL</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">นำบุคคลนี้ออก</translation> <translation id="1706586824377653884">เพิ่มโดยผู้ดูแลระบบ</translation> <translation id="1706625117072057435">ระดับการซูม</translation> -<translation id="1707463636381878959">แชร์เครือข่ายนี้กับผู้ใช้อื่น</translation> <translation id="1708338024780164500">(ไม่ใช้งาน)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (ดั้งเดิม)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">เปิดใช้งานธีม</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">ดูใน Chrome เว็บสโตร์</translation> -<translation id="1758831820837444715">กำหนดค่าเครือข่ายอีเทอร์เน็ต</translation> <translation id="1763046204212875858">สร้างทางลัดไปยังแอปพลิเคชัน</translation> <translation id="1763108912552529023">สำรวจต่อไป</translation> <translation id="1763808908432309942">เปิดในแท็บใหม่</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">เปลี่ยนวิธีการแชร์ไฟล์นี้</translation> <translation id="1841545962859478868">ผู้ดูแลระบบของอุปกรณ์อาจตรวจสอบรายการต่อไปนี้</translation> <translation id="1841705068325380214">ปิดใช้ <ph name="EXTENSION_NAME" /> แล้ว</translation> +<translation id="1842766183094193446">คุณแน่ใจไหมว่าต้องการเปิดใช้โหมดสาธิต</translation> <translation id="1844692022597038441">ไฟล์นี้ไม่สามารถใช้งานแบบออฟไลน์ได้</translation> <translation id="1846308012215045257">กด Control และคลิกเพื่อเรียกใช้ <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">บันทึกแล้ว</translation> <translation id="1848219224579402567">ออกจากระบบเมื่อปิดฝา</translation> <translation id="184823282865851239">บล็อกหากไซต์มักแสดงโฆษณาที่แทรก</translation> <translation id="1849186935225320012">หน้านี้มีสิทธิ์ควบคุมอุปกรณ์ MIDI เต็มรูปแบบ</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">คุณเปลี่ยนค่านี้ภายหลังได้ในการตั้งค่า</translation> <translation id="2006638907958895361">เปิดลิงก์ใน <ph name="APP" /></translation> <translation id="2007404777272201486">รายงานปัญหา...</translation> +<translation id="2016237810978710652">กำลังเปิดไฟล์ Linux...</translation> <translation id="2016430552235416146">ดั้งเดิม</translation> <translation id="2017334798163366053">ปิดใช้งานการเก็บรวบรวมข้อมูลผลการปฏิบัติงาน</translation> <translation id="2017836877785168846">ล้างประวัติการเข้าชมและการเติมข้อความอัตโนมัติในแถบที่อยู่เว็บ</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">แก้ไขบัตร</translation> <translation id="2154710561487035718">คัดลอก URL</translation> <translation id="2155772377859296191">ดูเหมือน <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">คุณช่วยปรับปรุง Safe Browsing ได้โดยส่งข้อมูลบางอย่างของระบบและเนื้อหาของหน้าให้ Google</translation> <translation id="215753907730220065">ออกจากการแสดงเต็มหน้าจอ</translation> <translation id="2157875535253991059">หน้าเว็บนี้แสดงแบบเต็มหน้าจอแล้ว</translation> <translation id="216169395504480358">เพิ่ม WiFi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">เพิ่มรหัสข้อกำหนดลงในอุปกรณ์นี้</translation> <translation id="2175042898143291048">แปลเสมอ</translation> <translation id="2175607476662778685">แถบเปิดใช้งานด่วน</translation> +<translation id="2176087259161165020">แหล่งที่มาอื่นๆ</translation> <translation id="2177950615300672361">แท็บไม่ระบุตัวตน: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> ใน <ph name="PEPPER_PLUGIN_DOMAIN" /> ต้องการเข้าถึงคอมพิวเตอร์ของคุณ</translation> <translation id="2178614541317717477">ผู้มีสิทธิ์ออกใบรับรองไม่สมบูรณ์</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">แท็บถัดไป</translation> <translation id="2292848386125228270">โปรดเริ่มต้น <ph name="PRODUCT_NAME" /> ในฐานะผู้ใช้ทั่วไป หากต้องการเรียกใช้ในฐานะผู้ใช้ระดับรากเพื่อการพัฒนา ให้เรียกใช้อีกครั้งโดยตั้งค่าสถานะเป็น no-sandbox</translation> <translation id="2294358108254308676">คุณต้องการติดตั้ง <ph name="PRODUCT_NAME" /> หรือไม่</translation> -<translation id="2296019197782308739">วิธีการ EAP:</translation> <translation id="2297705863329999812">ค้นหาเครื่องพิมพ์</translation> <translation id="2300383962156589922">ปรับแต่งและควบคุม <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">ไดเรกทอรีหลักของส่วนขยายไม่ถูกต้อง</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">ข้อผิดพลาด: ติดตั้ง <ph name="APP_NAME" /> ไม่สำเร็จ</translation> <translation id="2367199180085172140">เพิ่มการแชร์ไฟล์</translation> <translation id="2367972762794486313">แสดงแอป</translation> +<translation id="2369536625682139252">ข้อมูลทั้งหมด (ยกเว้นคุกกี้) ที่ <ph name="SITE" /> จัดเก็บไว้จะถูกลบออก</translation> <translation id="2371076942591664043">เปิดเมื่อเ&สร็จ</translation> <translation id="2377319039870049694">เปลี่ยนเป็นมุมมองรายการ</translation> <translation id="2377667304966270281">ฮาร์ดฟอลต์</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">พิมพ์โดยใช้ช่องโต้ตอบของระบบ... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">ถามก่อนที่จะส่ง (แนะนำ)</translation> <translation id="2384436799579181135">เกิดข้อผิดพลาด โปรดตรวจสอบเครื่องพิมพ์และลองอีกครั้ง</translation> -<translation id="2385700042425247848">ชื่อบริการ:</translation> <translation id="2387458720915042159">ประเภทการเชื่อมต่อพร็อกซี</translation> <translation id="2391419135980381625">แบบอักษรมาตรฐาน</translation> <translation id="2391762656119864333">เพิกถอน</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">แชร์เสียง</translation> <translation id="2480868415629598489">แก้ไขข้อมูลที่คุณคัดลอกและวาง</translation> <translation id="2482878487686419369">การแจ้งเตือน</translation> -<translation id="2485056306054380289">ใบรับรอง CA ของเซิร์ฟเวอร์:</translation> <translation id="2485422356828889247">ถอนการติดตั้ง</translation> <translation id="2487067538648443797">เพิ่มบุ๊กมาร์กใหม่</translation> <translation id="248861575772995840">ไม่พบโทรศัพท์ของคุณ โปรดตรวจสอบว่า <ph name="DEVICE_TYPE" /> เปิดบลูทูธอยู่ <a>เรียนรู้เพิ่มเติม</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Powerwash เพื่อรีเซ็ตอุปกรณ์ <ph name="IDS_SHORT_PRODUCT_NAME" /> ให้เหมือนใหม่</translation> <translation id="2567257616420533738">บันทึกรหัสผ่านแล้ว ดูและจัดการรหัสผ่านที่บันทึกไว้ได้ที่ <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">ที่เก็บแถบข้อมูล</translation> +<translation id="2570454805927264159">ใช้ประโยชน์สูงสุดจาก Assistant</translation> <translation id="257088987046510401">ธีม</translation> <translation id="2572032849266859634">ได้รับสิทธิ์ในการอ่าน <ph name="VOLUME_NAME" /> เท่านั้นแล้ว</translation> <translation id="2573269395582837871">เลือกรูปภาพและชื่อ</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">ส่ง</translation> <translation id="265390580714150011">ค่าฟิลด์ </translation> <translation id="2654166010170466751">อนุญาตให้เว็บไซต์ติดตั้งเครื่องจัดการการชำระเงิน</translation> -<translation id="2655386581175833247">ใบรับรองผู้ใช้:</translation> <translation id="2660779039299703961">กิจกรรม</translation> <translation id="266079277508604648">เชื่อมต่อเครื่องพิมพ์ไม่ได้ โปรดตรวจสอบว่าเครื่องพิมพ์เปิดอยู่และเชื่อมต่อกับ Chromebook ผ่าน Wi-Fi หรือ USB</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">ไม่มีข้อมูลการใช้งาน</translation> <translation id="3007214526293698309">คงอัตราส่วนเดิม</translation> <translation id="3007771295016901659">ทำซ้ำแท็บ</translation> +<translation id="3008272652534848354">รีเซ็ตสิทธิ์</translation> <translation id="3009300415590184725">คุณแน่ใจหรือไม่ว่าต้องการยกเลิกขั้นตอนการตั้งค่าบริการข้อมูลโทรศัพท์มือถือ</translation> <translation id="3009779501245596802">ฐานข้อมูลที่มีการจัดทำดัชนี</translation> <translation id="3010279545267083280">ลบรหัสผ่านแล้ว</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">โมดูล (<ph name="TOTAL_COUNT" />) - ความขัดแย้งที่ทราบ: <ph name="BAD_COUNT" />, ที่สงสัย: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">วันที่และเวลา</translation> <translation id="310671807099593501">เว็บไซต์กำลังใช้บลูทูธ</translation> -<translation id="3108967419958202225">เลือก...</translation> <translation id="3115128645424181617">ไม่พบโทรศัพท์ของคุณ โปรดตรวจสอบว่าโทรศัพท์อยู่ใกล้ๆ มือและเปิดบลูทูธอยู่</translation> <translation id="3115147772012638511">กำลังรอแคช...</translation> <translation id="3118319026408854581">ความช่วยเหลือของ <ph name="PRODUCT_NAME" /></translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">ผู้ให้บริการบางรายอาจบล็อกฟีเจอร์นี้</translation> <translation id="316854673539778496">ลงชื่อเข้าใช้และเปิดการซิงค์เพื่อรับส่วนขยายในอุปกรณ์ทุกเครื่องของคุณ</translation> <translation id="3170072451822350649">คุณสามารถข้ามการลงชื่อเข้าใช้และ<ph name="LINK_START" />เรียกดูในฐานะผู้เยี่ยมชม<ph name="LINK_END" />ได้ด้วย</translation> -<translation id="3177048931975664371">คลิกเพื่อซ่อนรหัสผ่าน</translation> <translation id="3177909033752230686">ภาษาหน้าเว็บ:</translation> <translation id="3181110748548073003">กด |<ph name="SHORTCUT" />| เพื่อไปข้างหน้า</translation> <translation id="3182749001423093222">ตรวจตัวสะกด</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">ระบบจะโอนการเป็นเจ้าของไปยัง <ph name="DESTINATION_DOMAIN" /></translation> <translation id="323803881985677942">เปิดตัวเลือกส่วนขยาย</translation> <translation id="3241680850019875542">เลือกไดเรกทอรีหลักของส่วนขยายที่จะแพค หากคุณต้องการอัปเดตส่วนขยาย ให้เลือกไฟล์กุญแจส่วนตัวที่จะใช้ซ้ำด้วย</translation> -<translation id="3242765319725186192">Pre-shared key:</translation> <translation id="3244294424315804309">ดำเนินการปิดเสียงไว้ต่อไป</translation> <translation id="3245321423178950146">ไม่ทราบศิลปิน</translation> <translation id="3246097286174000800">ลองใช้ Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">การดำเนินการเพิ่มเติมสำหรับ <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">ถามเมื่อเว็บไซต์ต้องการใช้ปลั๊กอินเพื่อเข้าถึงคอมพิวเตอร์ของคุณ</translation> <translation id="3441653493275994384">หน้าจอ</translation> -<translation id="3445830502289589282">การตรวจสอบสิทธิ์ขั้นที่ 2:</translation> <translation id="344630545793878684">อ่านข้อมูลบนเว็บไซต์จำนวนมาก</translation> <translation id="3449839693241009168">กด <ph name="SEARCH_KEY" /> เพื่อส่งคำสั่งไปที่ <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">เปอร์เซ็นต์การเกิดขึ้นของสถานะไม่มีการใช้งาน</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826">ข้อผิดพลาด <ph name="COUNT" /> รายการ</translation> <translation id="3495660573538963482">การตั้งค่า Google Assistant</translation> <translation id="3496213124478423963">ย่อ</translation> -<translation id="3504135463003295723">ชื่อกลุ่ม:</translation> <translation id="3505030558724226696">เพิกถอนสิทธิ์การเข้าถึงอุปกรณ์</translation> <translation id="3507421388498836150">สิทธิ์ปัจจุบันสำหรับ "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">นำแอป Linux สำหรับ Chromebook ออก</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">ใบรับรองการลงชื่อเข้าใช้ไม่ถูกต้อง หน้าต่างจะปิดใน <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">ไอคอนส่วนขยาย</translation> <translation id="3665589677786828986">Chrome ตรวจพบว่าการตั้งค่าของคุณบางส่วนได้รับความเสียหายจากโปรแกรมอื่น และรีเซ็ตการตั้งค่าเป็นค่าเริ่มต้นเดิม</translation> -<translation id="3665842570601375360">ความปลอดภัย:</translation> <translation id="3668570675727296296">การตั้งค่าภาษา</translation> <translation id="3668823961463113931">เครื่องจัดการ</translation> <translation id="3670229581627177274">เปิดบลูทูธ</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">ไม่สามารถเปิดอุปกรณ์นี้ได้ เนื่องจากไม่สนับสนุนระบบไฟล์ของอุปกรณ์นี้</translation> <translation id="3727148787322499904">การเปลี่ยนการตั้งค่านี้จะส่งผลกับเครือข่ายที่แชร์ทั้งหมด</translation> <translation id="3727187387656390258">ตรวจสอบป๊อปอัป</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">เกิดข้อผิดพลาดในบรรทัดที่ <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">เซิร์ฟเวอร์ SSL ที่มีการยกระดับความปลอดภัย</translation> <translation id="3737536731758327622">การดาวน์โหลดของคุณจะปรากฏที่นี่</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">กด Enter เมื่อเสร็จ</translation> <translation id="3827774300009121996">เ&ต็มหน้าจอ</translation> <translation id="3828029223314399057">ค้นหาบุ๊กมาร์ก</translation> -<translation id="3829932584934971895">ประเภทผู้ให้บริการ:</translation> <translation id="3830674330436234648">ไม่สามารถเล่นได้</translation> <translation id="3831486154586836914">เข้าสู่โหมดภาพรวมหน้าต่างแล้ว</translation> <translation id="383161972796689579">เจ้าของของอุปกรณ์นี้ปิดการใช้งานไม่ให้เพิ่มผู้ใช้ใหม่เข้าไป</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">สิ้นสุดการวัดการใช้อินเทอร์เน็ตแล้ว</translation> <translation id="3857228364945137633">ลองใช้ Smart Lock เพื่อปลดล็อก <ph name="DEVICE_TYPE" /> โดยไม่ต้องใช้รหัสผ่านเมื่อมีโทรศัพท์อยู่ใกล้ๆ</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: การซิงค์หยุดชั่วคราว</translation> <translation id="3860381078714302691">ยินดีต้อนรับสู่การประชุม Hangouts </translation> <translation id="3862134173397075045">ยินดีต้อนรับสู่ประสบการณ์การใช้ Cast ใน Chrome!</translation> <translation id="3862788408946266506">ต้องติดตั้งแอปที่มีแอตทริบิวต์ไฟล์ Manifest ที่ชื่อ "kiosk_only" ในโหมดคีออสก์ของ Chrome OS</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">ไม่สามารถตั้งค่าเครือข่าย</translation> <translation id="3970114302595058915">รหัส</translation> <translation id="397105322502079400">กำลังคำนวณ...</translation> -<translation id="3974195870082915331">คลิกเพื่อแสดงรหัสผ่าน</translation> <translation id="3975222297214566386">ลูกโป่งตัวเลือกการป้อนข้อมูล</translation> <translation id="397703832102027365">กำลังสิ้นสุดการทำงาน...</translation> <translation id="3979395879372752341">เพิ่มส่วนขยายใหม่แล้ว (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">ป้อนรหัสผ่านใบรับรอง</translation> <translation id="404493185430269859">เครื่องมือค้นหาเริ่มต้น</translation> <translation id="4047112090469382184">ฟีเจอร์นี้มีความปลอดภัยอย่างไร</translation> +<translation id="4051049974203704184">ดูข้อมูลเกี่ยวกับสิ่งที่อยู่ในหน้าจอ</translation> <translation id="4052120076834320548">ขนาดจิ๋ว</translation> <translation id="4055023634561256217">ต้องรีสตาร์ทก่อน จึงจะสามารถรีเซ็ตอุปกรณ์ของคุณด้วย Powerwash ได้</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">ยอมรับสำหรับกลุ่ม</translation> <translation id="4089235344645910861">บันทึกการตั้งค่าและเริ่มซิงค์แล้ว</translation> <translation id="4090103403438682346">เปิดใช้การเข้าถึงที่ได้รับการยืนยัน</translation> +<translation id="4090947011087001172">รีเซ็ตสิทธิ์เว็บไซต์สำหรับ <ph name="SITE" /> ไหม</translation> <translation id="4091434297613116013">หน้ากระดาษ</translation> <translation id="4093955363990068916">ไฟล์ในเครื่อง:</translation> <translation id="4095507791297118304">การแสดงผลหลัก</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">ควบคุมการซิงค์ การปรับเปลี่ยนในแบบของคุณ และอื่นๆ</translation> <translation id="4421932782753506458">ฟลัฟฟี</translation> <translation id="4422347585044846479">แก้ไขบุ๊กมาร์กสำหรับหน้านี้</translation> -<translation id="4423104065312875417">ติดตั้งเครื่องมืออ่านออกเสียงเพิ่มเติม</translation> <translation id="4423376891418188461">กู้คืนการตั้งค่า</translation> <translation id="4423482519432579560">&ตรวจการสะกด</translation> <translation id="442397852638519243"><ph name="USER_NAME" /> ผู้ดูแลระบบต้องการให้คุณเปลี่ยนรหัสผ่าน</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">แท็บนี้กำลังเล่นเสียง</translation> <translation id="4450974146388585462">วินิจฉัย</translation> <translation id="4453946976636652378">ค้นหาใน <ph name="SEARCH_ENGINE_NAME" /> หรือพิมพ์ URL</translation> -<translation id="445923051607553918">เข้าร่วมเครือข่าย Wi-Fi</translation> <translation id="4462159676511157176">เซิร์ฟเวอร์ชื่อที่กำหนดเอง</translation> <translation id="4467100756425880649">แกลเลอรี Chrome เว็บสโตร์</translation> <translation id="4467101674048705704">ขยาย <ph name="FOLDER_NAME" /></translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">วอลเปเปอร์ที่ปรากฏบนหน้าจอการลงชื่อเข้าใช้</translation> <translation id="4684427112815847243">ซิงค์ทุกอย่าง</translation> <translation id="4689421377817139245">ซิงค์บุ๊กมาร์กนี้กับ iPhone ของคุณ</translation> +<translation id="4690091457710545971"><มีไฟล์ 4 ไฟล์ที่สร้างขึ้นโดยเฟิร์มแวร์ Wi-Fi ของ Intel ได้แก่ csr.lst, fh_regs.lst, radio_reg.lst และ monitor.lst.sysmon โดย 3 ไฟล์แรกเป็นไฟล์ไบนารีที่มี Register Dump ซึ่งผ่านการยืนยันโดย Intel เพื่อไม่ให้รวมข้อมูลส่วนตัวหรือข้อมูลที่ระบุอุปกรณ์ ส่วนไฟล์สุดท้ายเป็นการติดตามการทำงานจากเฟิร์มแวร์ของ Intel โดยมีการลบข้อมูลส่วนตัวหรือข้อมูลที่ระบุอุปกรณ์ออกไปแล้ว แต่ไฟล์มีขนาดใหญ่เกินกว่าที่จะแสดงตรงนี้ได้ ไฟล์เหล่านี้สร้างขึ้นมาเพื่อตอบสนองต่อปัญหา Wi-Fi ล่าสุดในอุปกรณ์ของคุณและระบบจะแชร์ไฟล์กับ Intel เพื่อช่วยแก้ปัญหาเหล่านี้></translation> <translation id="4692302215262324251">ลงทะเบียน <ph name="DEVICE_TYPE" /> ของคุณสำหรับการจัดการองค์กรโดย <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> เรียบร้อยแล้ว <ph name="LINE_BREAK_AND_EMPTY_LINE" /> โปรดติดต่อทีมสนับสนุนหากนี่เป็นการดำเนินการที่ไม่คาดคิด</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">อาจต้องโหลดหน้านี้ซ้ำก่อนที่การตั้งค่าใหม่จะมีผล</translation> <translation id="5075131525758602494">ป้อน PIN ของซิม</translation> <translation id="5078638979202084724">บุ๊กมาร์กแท็บทั้งหมด</translation> +<translation id="5079950360618752063">ใช้รหัสผ่านที่แนะนำ</translation> <translation id="5084230410268011727">อนุญาตให้เว็บไซต์ใช้เซ็นเซอร์จับความเคลื่อนไหวและเซ็นเซอร์แสง</translation> <translation id="5085162214018721575">กำลังตรวจสอบการอัปเดต</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">ลบรายการนี้</translation> <translation id="5139955368427980650">เ&ปิด</translation> +<translation id="5142961317498132443">การตรวจสอบสิทธิ์</translation> <translation id="5143374789336132547">ส่วนขยาย "<ph name="EXTENSION_NAME" />" ได้เปลี่ยนหน้าที่จะแสดงเมื่อคุณคลิกปุ่มหน้าแรก</translation> <translation id="5143712164865402236">เข้าสู่โหมดเต็มหน้าจอ</translation> <translation id="5145331109270917438">วันที่แก้ไข</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">กด Control Alt Shift หรือ Search ค้างไว้เพื่อดูแป้นพิมพ์ลัดสำหรับคีย์ตัวปรับแต่ง</translation> <translation id="5382591305415226340">จัดการลิงก์ที่สนับสนุน</translation> <translation id="5384883051496921101">ไซต์นี้กำลังจะแชร์ข้อมูลกับแอปนอกโหมดไม่ระบุตัวตน</translation> -<translation id="5388588172257446328">ชื่อผู้ใช้:</translation> <translation id="5388885445722491159">จับคู่</translation> <translation id="5389237414310520250">ไม่สามารถสร้างผู้ใช้ใหม่ได้ โปรดตรวจสอบพื้นที่ว่างในฮาร์ดไดรฟ์และสิทธิ์ของคุณ แล้วลองอีกครั้ง</translation> <translation id="5390100381392048184">อนุญาตให้ไซต์เล่นเสียง</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">แป้นพิมพ์และการป้อนข้อความ</translation> <translation id="5553089923092577885">การจับคู่นโยบายใบรับรอง</translation> <translation id="5554489410841842733">ไอคอนนี้จะมองเห็นได้เมื่อส่วนขยายสามารถทำงานบนหน้าปัจจุบันได้</translation> -<translation id="5554573843028719904">เครือข่าย Wi-Fi อื่น...</translation> <translation id="5554720593229208774">ผู้ออกใบรับรองอีเมล</translation> <translation id="5556206011531515970">คลิก "ถัดไป" เพื่อเลือกเบราว์เซอร์เริ่มต้นของคุณ</translation> <translation id="5556459405103347317">โหลดใหม่</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">เปลี่ยนเป็นโหมดกล้อง</translation> <translation id="5612720917913232150"><ph name="URL" /> ต้องการใช้ตำแหน่งเครื่องคอมพิวเตอร์ของคุณ</translation> <translation id="5612734644261457353">ขออภัย ยังคงไม่สามารถยืนยันรหัสผ่านของคุณได้ หมายเหตุ: หากเมื่อเร็วๆ นี้คุณเปลี่ยนแปลงรหัสผ่าน รหัสผ่านใหม่ของคุณจะมีผลเมื่อคุณออกจากระบบ โปรดใช้รหัสผ่านเดิมที่นี่</translation> -<translation id="5613695965848159202">ข้อมูลประจำตัวที่ไม่ระบุตัวตน:</translation> <translation id="5614190747811328134">ประกาศสำหรับผู้ใช้</translation> <translation id="561698261642843490">ปิด Firefox</translation> <translation id="5618075537869101857">แย่จริง ไม่สามารถเรียกใช้แอปพลิเคชันคีออสก์ได้</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">โปรดลงชื่อเข้าใช้ <ph name="TOKEN_NAME" /></translation> <translation id="5941711191222866238">ย่อ</translation> <translation id="5946591249682680882">รหัสรายงาน <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">เพิ่มเครือข่ายส่วนบุคคล</translation> <translation id="5949544233750246342">ไม่สามารถแยกวิเคราะห์ไฟล์</translation> <translation id="5955282598396714173">รหัสผ่านหมดอายุ โปรดออกจากระบบแล้วลงชื่อเข้าใช้อีกครั้งเพื่อเปลี่ยนรหัสผ่าน</translation> <translation id="5956585768868398362">นี่คือหน้าค้นหาที่คุณต้องการใช่ไหม</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">ออกจากระบบแล้วลงชื่อเข้าใช้อีกครั้ง...</translation> <translation id="6198252989419008588">เปลี่ยน PIN</translation> <translation id="6199801702437275229">กำลังรอข้อมูลพื้นที่...</translation> +<translation id="6204015976622790023">ดูคำแนะนำที่เกี่ยวข้องจาก Assistant เกี่ยวกับสิ่งที่อยู่ในหน้าจอ</translation> <translation id="6205710420833115353">การดำเนินการบางอย่างใช้เวลานานกว่าที่คาดไว้ คุณต้องการล้มเลิกไหม</translation> <translation id="6206311232642889873">คัดลอ&กรูปภาพ</translation> <translation id="6207200176136643843">รีเซ็ตเป็นระดับการซูมเริ่มต้น</translation> <translation id="620722923698527029">เปิดลิงก์ประเภทนี้ในแอปที่เกี่ยวข้องเสมอ</translation> <translation id="6207937957461833379">ประเทศ/เขตการปกครอง</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: การซิงค์ไม่ทำงาน</translation> <translation id="6212039847102026977">แสดงคุณสมบัติเครือข่ายขั้นสูง</translation> <translation id="6212168817037875041">ปิดจอแสดงผล</translation> <translation id="6212752530110374741">ส่งลิงก์ทางอีเมล</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">รีเซ็ตการซิงค์</translation> <translation id="6264365405983206840">เลือก&ทั้งหมด</translation> <translation id="6264422956566238156">เปิดการซิงค์แล้ว</translation> -<translation id="6265930187414222160">เสร็จแล้ว! นำซอฟต์แวร์ที่เป็นอันตรายออกไปแล้ว</translation> <translation id="6267166720438879315">เลือกใบรับรองเพื่อตรวจสอบตัวคุณเองต่อ <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">เปิดด้วย <ph name="APP" /></translation> <translation id="6268747994388690914">นำเข้าบุ๊กมาร์กจากไฟล์ HTML...</translation> @@ -3537,7 +3532,6 @@ โปรดคลิก "ถัดไป" เพื่อลงชื่อเข้าใช้บัญชี <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ของคุณต่อ</translation> <translation id="6419546358665792306">โหลดส่วนขยายที่แตกไฟล์แล้ว</translation> <translation id="642282551015776456">ชื่อนี้ไม่สามารถใช้เป็นชื่อไฟล์ของโฟลเดอร์</translation> -<translation id="6423239382391657905">เปิด VPN</translation> <translation id="6426200009596957090">เปิดการตั้งค่า ChromeVox</translation> <translation id="6429384232893414837">เกิดข้อผิดพลาดในการอัปเดต</translation> <translation id="6430814529589430811">Base64-encoded ASCII, ใบรับรองเดี่ยว</translation> @@ -3618,7 +3612,6 @@ <translation id="6544215763872433504">เว็บเบราว์เซอร์โดย Google สำหรับคุณ</translation> <translation id="6545665334409411530">อัตราการพิมพ์ซ้ำ</translation> <translation id="6545834809683560467">ใช้บริการคาดคะเนที่จะช่วยเติมข้อความค้นหาและ URL ที่พิมพ์ลงในแถบที่อยู่เว็บหรือช่องค้นหาของเครื่องเรียกใช้งานแอป</translation> -<translation id="6546686722964485737">เข้าร่วมเครือข่าย Wimax</translation> <translation id="6547316139431024316">ไม่ต้องเตือนอีกสำหรับส่วนขยายนี้</translation> <translation id="6547354035488017500">เพิ่มพื้นที่ว่างบนอุปกรณ์อย่างน้อย 512 MB มิฉะนั้นอุปกรณ์ของคุณอาจไม่ตอบสนอง หากต้องการเพิ่มพื้นที่ว่าง ให้ลบไฟล์ออกจากพื้นที่เก็บข้อมูลของอุปกรณ์</translation> <translation id="6549689063733911810">ล่าสุด</translation> @@ -4037,7 +4030,6 @@ <translation id="7201014958346994077">ดูไฟล์ Linux ไม่ได้</translation> <translation id="720110658997053098">เก็บอุปกรณ์นี้ไว้ในโหมดคีออสก์อย่างถาวร</translation> <translation id="7201118060536064622">ลบ "<ph name="DELETED_ITEM_NAME" />" แล้ว</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">กำลังดาวน์โหลด <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{หน้าที่ออกไป}other{หน้าที่ออกไป}}</translation> <translation id="7216409898977639127">ผู้ให้บริการเครือข่ายมือถือ</translation> @@ -4515,7 +4507,6 @@ <translation id="7909969815743704077">ดาวน์โหลดในโหมดไม่ระบุตัวตนแล้ว</translation> <translation id="7910768399700579500">โ&ฟลเดอร์ใหม่</translation> <translation id="7912080627461681647">มีการเปลี่ยนรหัสผ่านของคุณในเซิร์ฟเวอร์ โปรดออกจากระบบแล้วลงชื่อเข้าใช้อีกครั้ง</translation> -<translation id="7912883689016444961">กำหนดค่าเครือข่ายมือถือ</translation> <translation id="7915471803647590281">โปรดแจ้งให้เราทราบถึงสิ่งที่เกิดขึ้นก่อนส่งความคิดเห็น</translation> <translation id="7916556741383518510">เมื่อคลิก</translation> <translation id="792514962475806987">ระดับการซูมหน้าจอบางส่วน:</translation> @@ -4569,7 +4560,6 @@ <translation id="7988355189918024273">เปิดการใช้งานฟีเจอร์การเข้าถึง</translation> <translation id="7994702968232966508">วิธีการ EAP</translation> <translation id="799547531016638432">ลบทางลัด</translation> -<translation id="7997479212858899587">ข้อมูลประจำตัว:</translation> <translation id="7997826902155442747">ลำดับความสำคัญของกระบวนการ</translation> <translation id="7999229196265990314">สร้างไฟล์ต่อไปนี้: @@ -4653,7 +4643,6 @@ <translation id="8105368624971345109">ปิด</translation> <translation id="8106045200081704138">ที่แชร์กับฉัน</translation> <translation id="8107015733319732394">กำลังติดตั้ง Google Play Store ใน <ph name="DEVICE_TYPE" /> อาจใช้เวลาสักครู่</translation> -<translation id="8109930990200908494">ต้องลงชื่อเข้าใช้สำหรับใบรับรองผู้ใช้</translation> <translation id="8111155949205007504">แชร์รหัสผ่านนี้กับ iPhone</translation> <translation id="8113043281354018522">เลือกประเภทใบอนุญาต</translation> <translation id="8116190140324504026">เพิ่มเติม...</translation> @@ -4664,6 +4653,7 @@ <translation id="8118860139461251237">จัดการการดาวน์โหลดของคุณ</translation> <translation id="81238879832906896">ดอกไม้สีเหลืองแซมขาว</translation> <translation id="8124313775439841391">ONC ที่มีการจัดการ</translation> +<translation id="8125562866093998907">เว็บไซต์ต้องการยืนยันกุญแจรักษาความปลอดภัยเพื่อเพิ่มการรักษาความปลอดภัยให้บัญชี</translation> <translation id="813082847718468539">ดูข้อมูลเว็บไซต์</translation> <translation id="8131740175452115882">ยืนยัน</translation> <translation id="8133676275609324831">แ&สดงในโฟลเดอร์</translation> @@ -4774,7 +4764,6 @@ <translation id="8308179586020895837">ถามว่า <ph name="HOST" /> ต้องการเข้าถึงกล้องของคุณไหม</translation> <translation id="830868413617744215">เบต้า</translation> <translation id="8309458809024885768">มีใบรับรองนี้อยู่แล้ว</translation> -<translation id="8309505303672555187">เลือกเครือข่าย:</translation> <translation id="8312871300878166382">วางลงในโฟลเดอร์</translation> <translation id="8317671367883557781">เพิ่มการเชื่อมต่อเครือข่าย</translation> <translation id="8319414634934645341">การใช้คีย์เพิ่มเติม</translation> @@ -4849,7 +4838,6 @@ <translation id="8451512073679317615">Assistant</translation> <translation id="8452135315243592079">ไม่มีซิมการ์ด</translation> <translation id="8453482423012550001">กำลังคัดลอก $1 รายการ...</translation> -<translation id="8454288007744638700">หรือเลือกเครือข่ายใหม่:</translation> <translation id="845627346958584683">เวลาหมดอายุ</translation> <translation id="8456681095658380701">ชื่อไม่ถูกต้อง</translation> <translation id="8457451314607652708">นำเข้าบุ๊กมาร์ก</translation> @@ -4913,6 +4901,7 @@ <translation id="855081842937141170">ตรึงแท็บ</translation> <translation id="8551388862522347954">ใบอนุญาต</translation> <translation id="8553342806078037065">จัดการบุคคลอื่นๆ</translation> +<translation id="8554899698005018844">ไม่มีภาษา</translation> <translation id="855773602626431402">ปลั๊กอินที่ไม่ได้อยู่ในแซนด์บ็อกซ์ถูกป้องกันไม่ให้ทำงานในหน้าเว็บนี้</translation> <translation id="8557930019681227453">ไฟล์ Manifest</translation> <translation id="8559694214572302298">ตัวถอดรหัสรูปภาพ</translation> @@ -4950,7 +4939,6 @@ <translation id="862727964348362408">ระงับไว้ชั่วคราว</translation> <translation id="862750493060684461">แคช CSS</translation> <translation id="8627795981664801467">สำหรับการเชื่อมต่อที่ปลอดภัยเท่านั้น</translation> -<translation id="8628085465172583869">ชื่อโฮสต์เซิร์ฟเวอร์:</translation> <translation id="8630903300770275248">นำเข้าผู้ใช้ภายใต้การดูแล</translation> <translation id="8631032106121706562">พีทอล</translation> <translation id="8637542770513281060">คอมพิวเตอร์ของคุณมีโมดูลความปลอดภัย ซึ่งใช้เพื่อนำฟีเจอร์การรักษาความปลอดภัยที่สำคัญจำนวนมากมาใช้ใน Chrome OS โปรดไปที่ศูนย์ช่วยเหลือของ Chromebook เพื่อเรียนรู้เพิ่มเติม: https://support.google.com/chromebook/?p=sm</translation> @@ -5206,7 +5194,6 @@ <translation id="899403249577094719">URL ที่อ้างอิงใบรับรองของ Netscape</translation> <translation id="8995603266996330174">จัดการโดย <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">เพิ่มบัญชี...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">กำลังสร้างดิสก์อิมเมจ</translation> <translation id="9003647077635673607">อนุญาตบนทุกเว็บไซต์</translation> <translation id="9003677638446136377">ตรวจสอบอีกครั้ง</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index 30fa92d..9c93ff1 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Mola verme zamanı yaklaştı</translation> <translation id="1062407476771304334">Değiştir</translation> -<translation id="1064835277883315402">Özel ağa katıl</translation> <translation id="1064912851688322329">Google Hesabınızın bağlantısını kesin</translation> <translation id="1067048845568873861">Oluşturulduğu tarih</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Aranıyor...</translation> <translation id="1316495628809031177">Senkronizasyon duraklatıldı</translation> <translation id="1319979322914001937">Chrome Web Mağazası'ndaki uzantıların filtrelenmiş listesini gösteren bir uygulama. Listedeki uzantılar doğrudan uygulamadan yüklenebilir.</translation> -<translation id="132090119144658135">Konu Eşleştirmesi:</translation> <translation id="1326317727527857210">Diğer cihazlarınızdaki sekmelerinize ulaşmak için Chrome'da oturum açın.</translation> <translation id="1327074568633507428">Google Cloud Print'teki yazıcı</translation> <translation id="1327977588028644528">Ağ geçidi</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">Uygulama Penceresi</translation> <translation id="1534389735079119190">HATA: VM içindeki kapsayıcı başlatılamadı.</translation> <translation id="15373452373711364">Büyük fare imleci</translation> +<translation id="1540605929960647700">Demo modunu etkinleştir</translation> <translation id="1543284117603151572">Edge'den Aktarıldı</translation> <translation id="1545177026077493356">Otomatik Kiosk Modu</translation> <translation id="1545775234664667895">"<ph name="THEME_NAME" />" teması yüklendi</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Google'a otomatik olarak kullanım istatistikleri ve kilitlenme raporları göndererek <ph name="PRODUCT_NAME" /> ürününü iyileştirmemize yardımcı olun.</translation> <translation id="1658424621194652532">Bu sayfa mikrofonunuza erişiyor.</translation> <translation id="1660204651932907780">Sitelerin ses çalmasına izin ver (önerilir)</translation> +<translation id="1660938185063657230">Güvenlik Anahtarınızı doğrulayın</translation> <translation id="1661156625580498328">AES şifrelemesini uygula (önerilir).</translation> <translation id="1661245713600520330">Bu sayfada, ana işleme yüklenen tüm modüller ve ilerideki bir noktada yüklenmek için kaydedilmiş modüller listelenir.</translation> <translation id="166179487779922818">Şifre çok kısa.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Sitelerin panoya kopyalanan metin ve resimleri görmesine izin verme</translation> <translation id="1682548588986054654">Yeni Gizli Pencere</translation> <translation id="168715261339224929">Yer işaretlerinize tüm cihazlarınızda ulaşmak için senkronizasyonu açın.</translation> +<translation id="1688867105868176567">Site verileri temizlensin mi?</translation> <translation id="1688935057616748272">Bir harf yazın</translation> <translation id="168991973552362966">Yakındaki bir yazıcıyı ekleyin</translation> <translation id="1689945336726856614">&URL'yi Kopyala</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Bu kişiyi kaldır</translation> <translation id="1706586824377653884">Yöneticiniz tarafından eklendi</translation> <translation id="1706625117072057435">Yakınlaştırma seviyeleri</translation> -<translation id="1707463636381878959">Bu ağı diğer kullanıcılarla paylaş</translation> <translation id="1708338024780164500">(Etkin değil)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (Kimlik: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Yerel)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Temayı etkinleştir</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Chrome Web Mağazası'nda göster</translation> -<translation id="1758831820837444715">Ethernet ağını yapılandırın</translation> <translation id="1763046204212875858">Uygulama kısayolları oluşturun</translation> <translation id="1763108912552529023">Keşfetmeye devam et</translation> <translation id="1763808908432309942">Yeni bir sekmede açılır</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Bu dosyanın paylaşılma biçimini değiştirin.</translation> <translation id="1841545962859478868">Cihaz yöneticisi aşağıdakileri izleyebilir:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> devre dışı bırakıldı</translation> +<translation id="1842766183094193446">Demo modunu etkinleştirmek istediğinizden emin misiniz?</translation> <translation id="1844692022597038441">Bu dosya çevrimdışı kullanılamıyor.</translation> <translation id="1846308012215045257"><ph name="PLUGIN_NAME" /> eklentisini çalıştırmak için Control tuşuyla birlikte tıklayın</translation> +<translation id="1847880352285315359">Kaydedildi</translation> <translation id="1848219224579402567">Kapak kapatıldığında oturumu kapat</translation> <translation id="184823282865851239">Site, araya giren reklamlar gösterme eğiliminde olduğunda engelle</translation> <translation id="1849186935225320012">Bu sayfa MIDI cihazları üzerinde tam denetime sahip.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Bunu daha sonra ayarlarda değiştirebilirsiniz</translation> <translation id="2006638907958895361">Bağlantıyı <ph name="APP" /> uygulamasında aç</translation> <translation id="2007404777272201486">Sorun Bildirin...</translation> +<translation id="2016237810978710652">Linux Dosyaları Açılıyor...</translation> <translation id="2016430552235416146">Geleneksel</translation> <translation id="2017334798163366053">Performans verisi toplamayı devre dışı bırak</translation> <translation id="2017836877785168846">Geçmişi ve adres çubuğundaki otomatik tamamlama bilgilerini temizler.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Kartı düzenle</translation> <translation id="2154710561487035718">URL'yi Kopyala</translation> <translation id="2155772377859296191"><ph name="WIDTH" /> x <ph name="HEIGHT" /> şeklinde görünür</translation> +<translation id="2156283799932971644">Google'a bazı sistem bilgilerini ve sayfa içeriklerini göndererek Güvenli Tarama'nın iyileştirilmesine yardımcı olabilirsiniz.</translation> <translation id="215753907730220065">Tam Ekrandan Çık</translation> <translation id="2157875535253991059">Bu sayfa artık tam ekran.</translation> <translation id="216169395504480358">Kablosuz Ekle...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Bu cihaza talep kimliği ekleyin</translation> <translation id="2175042898143291048">Bunu her zaman yap</translation> <translation id="2175607476662778685">Hızlı başlat çubuğu</translation> +<translation id="2176087259161165020">Diğer kaynaklar</translation> <translation id="2177950615300672361">Gizli Sekmesi: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> alanındaki <ph name="PEPPER_PLUGIN_NAME" /> eklentisi bilgisayarınıza erişmek istiyor</translation> <translation id="2178614541317717477">CA Uzlaşması</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Sonraki sekme</translation> <translation id="2292848386125228270">Lütfen <ph name="PRODUCT_NAME" /> uygulamasını normal bir kullanıcı olarak başlatın. Geliştirme amacıyla uygulamayı root kullanıcı olarak çalıştırmanız gerekiyorsa korumasız alan seçeneğini işaretleyerek yeniden çalıştırın.</translation> <translation id="2294358108254308676"><ph name="PRODUCT_NAME" /> ürününü yüklemek istiyor musunuz?</translation> -<translation id="2296019197782308739">EAP yöntemi:</translation> <translation id="2297705863329999812">Yazıcı ara</translation> <translation id="2300383962156589922"><ph name="APP_NAME" /> uygulamasını özelleştirin ve denetleyin</translation> <translation id="2301382460326681002">Uzantı kök dizini geçersiz.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">HATA: <ph name="APP_NAME" /> uygulamasının yüklemesi kaldırılamadı.</translation> <translation id="2367199180085172140">Dosya Paylaşımı Ekle</translation> <translation id="2367972762794486313">Uygulamaları göster</translation> +<translation id="2369536625682139252"><ph name="SITE" /> web sitesinin depoladığı tüm veriler silinecek</translation> <translation id="2371076942591664043">İşlem tamamlandığın&da aç</translation> <translation id="2377319039870049694">Liste görünümüne geç</translation> <translation id="2377667304966270281">Donanım Hataları</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Sistem iletişim kutusunu kullanarak yazdır... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Göndermeden önce sor (önerilir)</translation> <translation id="2384436799579181135">Bir hata oluştu. Lütfen yazıcınızı kontrol edin ve tekrar deneyin.</translation> -<translation id="2385700042425247848">Hizmet adı:</translation> <translation id="2387458720915042159">Proxy bağlantısı türü</translation> <translation id="2391419135980381625">Standart yazı tipi</translation> <translation id="2391762656119864333">İptal et</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Sesi paylaş</translation> <translation id="2480868415629598489">Kopyaladığınız ve yapıştırdığınız verileri değiştirme</translation> <translation id="2482878487686419369">Bildirimler</translation> -<translation id="2485056306054380289">Sunucu CA sertifikası:</translation> <translation id="2485422356828889247">Yüklemeyi Kaldır</translation> <translation id="2487067538648443797">Yeni yer işareti ekle</translation> <translation id="248861575772995840">Telefonunuz bulunamıyor. <ph name="DEVICE_TYPE" /> cihazınızın Bluetooth'unun açık olduğundan emin olun. <a>Daha fazla bilgi</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842"><ph name="IDS_SHORT_PRODUCT_NAME" /> cihazınızı yeni alındığı günkü haline sıfırlamak için Powerwash'ı kullanın.</translation> <translation id="2567257616420533738">Şifre kaydedildi. Kayıtlı şifreleri <ph name="SAVED_PASSWORDS_LINK" /> adresinden görüntüleyin ve yönetin</translation> <translation id="2568774940984945469">Bilgi Çubuğu Kapsayıcı</translation> +<translation id="2570454805927264159">Asistanınızdan en iyi şekilde yararlanın</translation> <translation id="257088987046510401">Temalar</translation> <translation id="2572032849266859634"><ph name="VOLUME_NAME" /> birimine salt okunur erişim izni verildi.</translation> <translation id="2573269395582837871">Bir resim ve ad seçin</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Gönder</translation> <translation id="265390580714150011">Alan Değeri</translation> <translation id="2654166010170466751">Sitelerin ödeme işleyici yüklemesine izin ver</translation> -<translation id="2655386581175833247">Kullanıcı sertifikası:</translation> <translation id="2660779039299703961">Etkinlik</translation> <translation id="266079277508604648">Yazıcıya bağlanılamıyor. Yazıcının açık olduğundan ve kablosuz ağ üzerinden veya USB kablosuyla Chromebook'unuza bağlı olduğundan emin olun.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Kullanım verisi yok</translation> <translation id="3007214526293698309">Oranı sabitle</translation> <translation id="3007771295016901659">Sekmeyi Çoğalt</translation> +<translation id="3008272652534848354">İzinleri sıfırla</translation> <translation id="3009300415590184725">Mobil veri hizmeti kurulum işlemini iptal etmek istediğinizden emin misiniz?</translation> <translation id="3009779501245596802">Dizine alınmış veritabanları</translation> <translation id="3010279545267083280">Şifre silindi</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Modüller (<ph name="TOTAL_COUNT" />) - Bilinen çakışmalar: <ph name="BAD_COUNT" />, şüpheli: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Tarih ve saat</translation> <translation id="310671807099593501">Site, Bluetooth bağlantısını kullanıyor</translation> -<translation id="3108967419958202225">Seç...</translation> <translation id="3115128645424181617">Telefonunuz bulunamıyor. Telefonunuzun yakında olduğundan ve Bluetooth'un açık olduğundan emin olun.</translation> <translation id="3115147772012638511">Önbellek bekleniyor...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> Yardım</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Bazı operatörler bu özelliği engelleyebilir.</translation> <translation id="316854673539778496">Tüm uzantılarınızı tüm cihazlarınızda almak için oturum açın ve senkronizasyonu etkinleştirin.</translation> <translation id="3170072451822350649">Ayrıca, oturum açmayı atlayabilir ve <ph name="LINK_START" />misafir olarak göz atabilirsiniz<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Şifreyi gizlemek için tıklayın</translation> <translation id="3177909033752230686">Sayfanın Dili:</translation> <translation id="3181110748548073003">İlerlemek için |<ph name="SHORTCUT" />| tuşuna basın.</translation> <translation id="3182749001423093222">Yazım denetimi</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Sahiplik <ph name="DESTINATION_DOMAIN" /> alanına aktarılacak.</translation> <translation id="323803881985677942">Uzantı seçeneklerini aç</translation> <translation id="3241680850019875542">Paketlenecek uzantının kök dizinini seçin. Bir uzantıyı güncellemek için tekrar kullanılacak özel anahtar dosyasını da seçin.</translation> -<translation id="3242765319725186192">Önceden paylaşılan anahtar:</translation> <translation id="3244294424315804309">Sesi kapatmaya devam et</translation> <translation id="3245321423178950146">Bilinmeyen Sanatçı</translation> <translation id="3246097286174000800">Smart Lock'u deneyin</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476"><ph name="BOOKMARK_NAME" /> ile ilgili diğer işlemler</translation> <translation id="3440761377721825626">Bir site, bilgisayarıma erişmek için eklenti kullanmak istediğinde bana sor</translation> <translation id="3441653493275994384">Ekran</translation> -<translation id="3445830502289589282">2. aşama kimlik doğrulaması:</translation> <translation id="344630545793878684">Birden fazla web sitesindeki verilerinize erişme</translation> <translation id="3449839693241009168">Komutları <ph name="EXTENSION_NAME" /> uygulamasına göndermek için <ph name="SEARCH_KEY" /> tuşuna basın</translation> <translation id="3450157232394774192">Boşta Kalma Durumu Kullanma Yüzdesi</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> hata.</translation> <translation id="3495660573538963482">Google Asistan ayarları</translation> <translation id="3496213124478423963">Uzaklaştır</translation> -<translation id="3504135463003295723">Grup adı:</translation> <translation id="3505030558724226696">Cihaz erişimini iptal et</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" için Geçerli İzinler</translation> <translation id="3507547268929739059">Chromebook için Linux Uygulamalarını Kaldırın</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Oturum açma sertifikası geçerli değil, pencere <ph name="MINUTES" /> dakika <ph name="SECONDS" /> saniye içinde kapanacak</translation> <translation id="3664511988987167893">Uzantı Simgesi</translation> <translation id="3665589677786828986">Chrome, bazı ayarlarınızın başka bir program tarafından bozulduğunu algıladı ve onları orijinal varsayılan değerlerine sıfırladı.</translation> -<translation id="3665842570601375360">Güvenlik:</translation> <translation id="3668570675727296296">Dil ayarları</translation> <translation id="3668823961463113931">İşleyiciler</translation> <translation id="3670229581627177274">Bluetooth'u aç</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Bu cihaz, dosya sistemi desteklenmediğinden açılamıyor.</translation> <translation id="3727148787322499904">Bu ayarı değiştirmek tüm paylaşılan ağları etkiler</translation> <translation id="3727187387656390258">Pop-up'ı incele</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900"><ph name="ERROR_LINE" />. satırda hata</translation> <translation id="3733127536501031542">İlerlemeli SSL Sunucusu</translation> <translation id="3737536731758327622">İndirdikleriniz burada görünür</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Bittiğinde Enter tuşuna basın</translation> <translation id="3827774300009121996">&Tam Ekran</translation> <translation id="3828029223314399057">Yer işaretlerinde ara</translation> -<translation id="3829932584934971895">Sağlayıcı türü:</translation> <translation id="3830674330436234648">Oynatma mevcut değil</translation> <translation id="3831486154586836914">Pencere genel bakış moduna girildi</translation> <translation id="383161972796689579">Bu cihazın sahibi yeni kullanıcıların eklenmesini devre dışı bıraktı</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Veri kullanım ölçümü sona erdi</translation> <translation id="3857228364945137633">Telefonunuz yakındayken şifre girmeden <ph name="DEVICE_TYPE" /> cihazınızın kilidini açmak için Smart Lock'u deneyin.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Senkronizasyon duraklatıldı</translation> <translation id="3860381078714302691">Hangouts Meet'e hoş geldiniz</translation> <translation id="3862134173397075045">Chrome'da Google Cast deneyimine hoş geldiniz!</translation> <translation id="3862788408946266506">"kiosk_only" manifest özelliğine sahip uygulamalar ChromeOS kiosk modunda yüklenmelidir</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Ağ ayarlanamadı</translation> <translation id="3970114302595058915">Kimlik</translation> <translation id="397105322502079400">Hesaplanııyor...</translation> -<translation id="3974195870082915331">Şifreyi göstermek için tıklayın</translation> <translation id="3975222297214566386">Giriş seçenekleri balonu</translation> <translation id="397703832102027365">Sonlandırılıyor...</translation> <translation id="3979395879372752341">Yeni uzantı eklendi (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Sertifika şifrenizi girin</translation> <translation id="404493185430269859">Varsayılan arama motoru</translation> <translation id="4047112090469382184">Güvenliği nasıl sağlanır?</translation> +<translation id="4051049974203704184">Ekranınızdakilerle ilgili bilgi alın</translation> <translation id="4052120076834320548">Çok küçük</translation> <translation id="4055023634561256217">Cihazınızın Powerwash ile sıfırlanabilmesi için yeniden başlatılması gerekir.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Grup için kabul et</translation> <translation id="4089235344645910861">Ayarlar kaydedildi. Senkronizasyon başladı.</translation> <translation id="4090103403438682346">Doğrulanmış Erişimi Etkinleştir</translation> +<translation id="4090947011087001172"><ph name="SITE" /> için site izinleri sıfırlansın mı?</translation> <translation id="4091434297613116013">yaprak</translation> <translation id="4093955363990068916">Yerel dosya:</translation> <translation id="4095507791297118304">Birincil ekran</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Senkronizasyon, kişiselleştirme ve daha fazla özelliği kontrol edin</translation> <translation id="4421932782753506458">Mırnav</translation> <translation id="4422347585044846479">Bu sayfanın yer işaretini düzenle</translation> -<translation id="4423104065312875417">Ek konuşma motorlarını yükle</translation> <translation id="4423376891418188461">Ayarları Geri Yükle</translation> <translation id="4423482519432579560">&Yazım denetimi</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, yöneticiniz şifrenizi değiştirmenizi zorunlu tutuyor.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">Bu sekmede ses çalınıyor.</translation> <translation id="4450974146388585462">Teşhis Et</translation> <translation id="4453946976636652378"><ph name="SEARCH_ENGINE_NAME" /> üzerinde arayın veya bir URL yazın</translation> -<translation id="445923051607553918">Kablosuz ağa bağlan</translation> <translation id="4462159676511157176">Özel ad sunucuları</translation> <translation id="4467100756425880649">Chrome Web Mağazası Galerisi</translation> <translation id="4467101674048705704"><ph name="FOLDER_NAME" /> klasörünü genişlet</translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Duvar kağıtları Oturum Açma Ekranında görüntülenir.</translation> <translation id="4684427112815847243">Her şeyi senkronize et</translation> <translation id="4689421377817139245">Bu yer işaretini iPhone'unuzla senkronize edin</translation> +<translation id="4690091457710545971"><Intel Kablosuz donanım yazılımı tarafından dört dosya oluşturuldu: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. İlk üç dosya, kayıt dökümlerini içeren ikili dosyalardır ve Intel, bu dosyalarda kimlik veya cihaz bilgilerini tanımlayan bilgilerin yer almadığını teyit etmektedir. Son dosya, Intel donanım yazılımındaki bir yürütme izidir. Bu dosyadaki kimlik ve cihaz bilgileri temizlenmiştir, ancak dosya burada görüntülenemeyecek kadar büyüktür. Bu dosyalar, cihazınızla ilgili son kablosuz bağlantı sorunlarına yanıt olarak oluşturulmuştur ve bu sorunların giderilmesinde yardımcı olması için Intel ile paylaşılacaktır.></translation> <translation id="4692302215262324251"><ph name="DEVICE_TYPE" /> cihazınız kurumsal olarak <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tarafından yönetilmek üzere başarıyla kaydedildi. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Bu beklemediğiniz bir durumsa lütfen destek ekibiyle iletişim kurun.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Yeni ayarların geçerli olması için bu sayfanın tekrar yüklenmesi gerekebilir.</translation> <translation id="5075131525758602494">SIM PIN kodunu girin</translation> <translation id="5078638979202084724">Tüm sekmelere yer işareti koy</translation> +<translation id="5079950360618752063">Önerilen şifreyi kullan</translation> <translation id="5084230410268011727">Sitelerin hareket ve ışık sensörlerini kullanmasına izin ver</translation> <translation id="5085162214018721575">Güncellemeler denetleniyor</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Bu öğeyi sil</translation> <translation id="5139955368427980650">&Aç</translation> +<translation id="5142961317498132443">Kimlik Doğrulama</translation> <translation id="5143374789336132547">"<ph name="EXTENSION_NAME" />" uzantısı Ana Sayfa düğmesini tıkladığınızda gösterilecek sayfayı değiştirdi.</translation> <translation id="5143712164865402236">Tam Ekrana Geç</translation> <translation id="5145331109270917438">Değiştirilme tarihi</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Bu değiştiricilere ait klavye kısayollarını görmek için Ctrl, Alt, ÜstKrktr veya Arama tuşunu basılı tutun.</translation> <translation id="5382591305415226340">Desteklenen bağlantıları yönet</translation> <translation id="5384883051496921101">Bu site, gizli mod dışında bir uygulama ile bilgi paylaşımında bulunmak üzere.</translation> -<translation id="5388588172257446328">Kullanıcı adı:</translation> <translation id="5388885445722491159">Eşleştirilmiş</translation> <translation id="5389237414310520250">Yeni kullanıcı oluşturulamadı. Lütfen sabit disk alanınızı ve izinlerinizi kontrol edin ve tekrar deneyin.</translation> <translation id="5390100381392048184">Sitelerin ses çalmasına izin ver</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Klavye ve metin girişi</translation> <translation id="5553089923092577885">Sertifika Politikası Eşlemeleri</translation> <translation id="5554489410841842733">Bu simge, uzantı mevcut sayfayı etkileyebildiğinde görünür.</translation> -<translation id="5554573843028719904">Diğer kablosuz ağlar...</translation> <translation id="5554720593229208774">E-posta Sertifika Yetkilisi</translation> <translation id="5556206011531515970">Varsayılan tarayıcınızı seçmek için İleri'yi tıklayın.</translation> <translation id="5556459405103347317">Yeniden Yükle</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Kamera moduna geç</translation> <translation id="5612720917913232150"><ph name="URL" />, bilgisayarınızın konumunu kullanmak istiyor</translation> <translation id="5612734644261457353">Maalesef şifreniz hâlâ doğrulanamadı. Not: Şifrenizi yakın zamanda değiştirdiyseniz, yeni şifreniz çıkış yapmanızdan sonra geçerli olacaktır. Lütfen burada eski şifrenizi kullanın.</translation> -<translation id="5613695965848159202">Anonim kimlik:</translation> <translation id="5614190747811328134">Kullanıcı Bildirimi</translation> <translation id="561698261642843490">Firefox'u Kapat</translation> <translation id="5618075537869101857">Hata, kiosk uygulaması başlatılamadı.</translation> @@ -3228,7 +3223,6 @@ <translation id="5941343993301164315">Lütfen şurada oturum açın: <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Simge durumuna küçült</translation> <translation id="5946591249682680882">Rapor kimliği <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Özel ağ ekle</translation> <translation id="5949544233750246342">Dosya ayrıştırılamıyor</translation> <translation id="5955282598396714173">Şifrenizin süresi doldu. Şifrenizi değiştirmek için lütfen oturumu kapatıp tekrar oturum açın.</translation> <translation id="5956585768868398362">Bu beklediğiniz arama sayfası mı?</translation> @@ -3389,11 +3383,13 @@ <translation id="6198102561359457428">Oturumu kapatıp tekrar açın...</translation> <translation id="6198252989419008588">PIN'i değiştir</translation> <translation id="6199801702437275229">Alan bilgileri bekleniyor...</translation> +<translation id="6204015976622790023">Asistanınızdan ekranınızdakilerle alakalı önerileri görebilirsiniz.</translation> <translation id="6205710420833115353">Bazı işlemler beklenenden daha uzun sürüyor. Bunları iptal etmek istiyor musunuz?</translation> <translation id="6206311232642889873">Resmi Kop&yala</translation> <translation id="6207200176136643843">Varsayılan yakınlaştırma seviyesine sıfırla</translation> <translation id="620722923698527029">Bu tür bağlantıları her zaman ilişkili uygulamada aç</translation> <translation id="6207937957461833379">Ülke/Bölge</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Senkronizasyon çalışmıyor</translation> <translation id="6212039847102026977">Gelişmiş ağ özelliklerini göster</translation> <translation id="6212168817037875041">Ekranı kapat</translation> <translation id="6212752530110374741">Bağlantıyı E-posta ile Gönder</translation> @@ -3431,7 +3427,6 @@ <translation id="6263541650532042179">senkronizasyonu sıfırla</translation> <translation id="6264365405983206840">&Tümünü Seç</translation> <translation id="6264422956566238156">Senkronizasyonu açtınız</translation> -<translation id="6265930187414222160">Bitti! Zararlı yazılım kaldırıldı.</translation> <translation id="6267166720438879315"><ph name="HOST_NAME" /> sunucusunda kimliğinizi doğrulamak için bir sertifika seçin</translation> <translation id="6268252012308737255"><ph name="APP" /> ile aç</translation> <translation id="6268747994388690914">Yer İşaretlerini HTML Dosyasından İçe Aktar...</translation> @@ -3538,7 +3533,6 @@ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hesabınızda oturum açmaya devam etmek için lütfen "İleri"yi tıklayın.</translation> <translation id="6419546358665792306">Paketlenmemiş öğe yükle</translation> <translation id="642282551015776456">Bu ad, dosya veya klasör adı olarak kullanılamaz</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">ChromeVox ayarlarını aç</translation> <translation id="6429384232893414837">Güncelleme hatası</translation> <translation id="6430814529589430811">Base64 kodlu ASCII, tek sertifika</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">Sizin için Google'dan web tarayıcısı</translation> <translation id="6545665334409411530">Yineleme hızı</translation> <translation id="6545834809683560467">Adres çubuğuna veya Uygulama Başlatıcı arama kutusuna yazılan aramaların ve URL'lerin tamamlanmasına yardımcı olması için bir tahmin hizmeti kullan</translation> -<translation id="6546686722964485737">WiMAX ağına katıl</translation> <translation id="6547316139431024316">Bu uzantı için bir daha uyarma</translation> <translation id="6547354035488017500">En az 512 MB alan boşaltmazsanız cihazınız yanıt vermemeye başlayacaktır. Yer açmak için cihazın depolama alanındaki dosyaları silin.</translation> <translation id="6549689063733911810">En son</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Linux Dosyaları görüntülenemiyor</translation> <translation id="720110658997053098">Bu cihazı kalıcı olarak kiosk modunda tut</translation> <translation id="7201118060536064622">"<ph name="DELETED_ITEM_NAME" />" silindi</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> indiriliyor...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Sayfadan çık}other{Sayfalardan çık}}</translation> <translation id="7216409898977639127">Hücresel sağlayıcı</translation> @@ -4515,7 +4507,6 @@ <translation id="7909969815743704077">Gizli modda indirildi</translation> <translation id="7910768399700579500">&Yeni klasör</translation> <translation id="7912080627461681647">Şifreniz sunucuda değiştirildi. Lütfen oturumu kapatıp tekrar açın.</translation> -<translation id="7912883689016444961">Mobil ağı yapılandır</translation> <translation id="7915471803647590281">Geri bildirimi göndermeden önce lütfen bize ne olduğunu söyleyin.</translation> <translation id="7916556741383518510">Tıklandığında</translation> <translation id="792514962475806987">Yerleştirilmişken yakınlaştırma düzeyi:</translation> @@ -4569,7 +4560,6 @@ <translation id="7988355189918024273">Erişilebilirlik özelliklerini etkinleştir</translation> <translation id="7994702968232966508">EAP yöntemi</translation> <translation id="799547531016638432">Kısayolu kaldır</translation> -<translation id="7997479212858899587">Kimlik:</translation> <translation id="7997826902155442747">Süreç Önceliği</translation> <translation id="7999229196265990314">Aşağıdaki dosyalar oluşturuldu: @@ -4653,7 +4643,6 @@ <translation id="8105368624971345109">Kapat</translation> <translation id="8106045200081704138">Benimle paylaşılanlar</translation> <translation id="8107015733319732394">Google Play Store <ph name="DEVICE_TYPE" /> cihazınıza yükleniyor. Bu işlem birkaç dakika sürebilir.</translation> -<translation id="8109930990200908494">Kullanıcı sertifikası için oturum açılması gerekir.</translation> <translation id="8111155949205007504">Bu şifreyi iPhone'unuz ile paylaşın</translation> <translation id="8113043281354018522">Lisans türünü seçin</translation> <translation id="8116190140324504026">Daha fazla bilgi...</translation> @@ -4664,6 +4653,7 @@ <translation id="8118860139461251237">İndirilen öğelerinizi yönetme</translation> <translation id="81238879832906896">Sarı ve beyaz çiçek</translation> <translation id="8124313775439841391">Yönetilen ONC</translation> +<translation id="8125562866093998907">Site, hesabınızla ilgili ek güvenlik için Güvenlik Anahtarınızı doğrulamak istiyor.</translation> <translation id="813082847718468539">Site bilgilerini görüntüle</translation> <translation id="8131740175452115882">Onayla</translation> <translation id="8133676275609324831">Klasörde &göster</translation> @@ -4774,7 +4764,6 @@ <translation id="8308179586020895837"><ph name="HOST" /> sitesi kamerama erişmek isterse sor</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Sertifika zaten var</translation> -<translation id="8309505303672555187">Ağ seçin:</translation> <translation id="8312871300878166382">Klasörünün içine yapıştır</translation> <translation id="8317671367883557781">Ağ bağlantısı ekle</translation> <translation id="8319414634934645341">Uzatılmış Anahtar Kullanımı</translation> @@ -4849,7 +4838,6 @@ <translation id="8451512073679317615">asistan</translation> <translation id="8452135315243592079">SIM kart yok</translation> <translation id="8453482423012550001">$1 öğe kopyalanıyor...</translation> -<translation id="8454288007744638700">Veya yeni bir ağ seçin:</translation> <translation id="845627346958584683">Son Kullanma Tarihi</translation> <translation id="8456681095658380701">Geçersiz ad</translation> <translation id="8457451314607652708">Yer işaretlerini içe aktar</translation> @@ -4913,6 +4901,7 @@ <translation id="855081842937141170">Sekmeyi iğnele</translation> <translation id="8551388862522347954">Lisanslar</translation> <translation id="8553342806078037065">Diğer kişileri yönet</translation> +<translation id="8554899698005018844">Dil yok</translation> <translation id="855773602626431402">Korumalı alanda olmayan bir eklentinin bu sayfada çalışması engellendi.</translation> <translation id="8557930019681227453">Manifest</translation> <translation id="8559694214572302298">Görsel Kod Çözücüsü</translation> @@ -4950,7 +4939,6 @@ <translation id="862727964348362408">Askıya alındı</translation> <translation id="862750493060684461">CSS önbelleği</translation> <translation id="8627795981664801467">Yalnızca güvenli bağlantılar</translation> -<translation id="8628085465172583869">Sunucu ana makine adı:</translation> <translation id="8630903300770275248">Denetlenen kullanıcıyı içe aktar</translation> <translation id="8631032106121706562">Çiçek</translation> <translation id="8637542770513281060">Bilgisayarınızda, Chrome OS'teki pek çok kritik güvenlik özelliğini uygulamak için kullanılan bir güvenli modül bulunmaktadır. Daha fazla bilgi edinmek için Chromebook Yardım Merkezi'ni ziyaret edin: https://support.google.com/chromebook/?p=sm</translation> @@ -5206,7 +5194,6 @@ <translation id="899403249577094719">Netscape Sertifikası Temel URL'si</translation> <translation id="8995603266996330174">Yöneten: <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Hesap ekle...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Disk görüntüsü oluşturuluyor.</translation> <translation id="9003647077635673607">Tüm web sitelerinde izin ver</translation> <translation id="9003677638446136377">Tekrar kontrol et</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb index c65b0cd3..9c524570 100644 --- a/chrome/app/resources/generated_resources_uk.xtb +++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK-код</translation> <translation id="1061904396131502319">Невдовзі час зробити перерву</translation> <translation id="1062407476771304334">Замінити</translation> -<translation id="1064835277883315402">Приєднатися до приватної мережі</translation> <translation id="1064912851688322329">Від’єднатися від облікового запису Google</translation> <translation id="1067048845568873861">Створено</translation> <translation id="1067291318998134776">Linux (бета-версія)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Пошук...</translation> <translation id="1316495628809031177">Синхронізацію призупинено</translation> <translation id="1319979322914001937">Додаток, який показує відфільтрований список розширень із Веб-магазину Chrome. Розширення в цьому списку може встановлювати прямо з додатка.</translation> -<translation id="132090119144658135">Збіг суб’єкта:</translation> <translation id="1326317727527857210">Щоб мати доступ до вкладок з інших пристроїв, увійдіть в обліковий запис Chrome.</translation> <translation id="1327074568633507428">Принтер у Google Cloud Print</translation> <translation id="1327977588028644528">Шлюз</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">додатка</translation> <translation id="1534389735079119190">ПОМИЛКА. Не вдалося запустити контейнер у віртуальній машині.</translation> <translation id="15373452373711364">Великий курсор миші</translation> +<translation id="1540605929960647700">Увімкніть демонстраційний режим</translation> <translation id="1543284117603151572">Імпортовано з Edge</translation> <translation id="1545177026077493356">Автоматичний режим термінала</translation> <translation id="1545775234664667895">Встановлено тему "<ph name="THEME_NAME" />"</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">Допоможіть покращити <ph name="PRODUCT_NAME" />, автоматично надсилаючи статистику використання та звіти про аварійне завершення роботи в Google</translation> <translation id="1658424621194652532">Ця сторінка має доступ до вашого мікрофона.</translation> <translation id="1660204651932907780">Дозволити сайтам відтворювати звук (рекомендується)</translation> +<translation id="1660938185063657230">Підтвердьте ключ безпеки</translation> <translation id="1661156625580498328">Застосувати шифрування AES (рекомендовано).</translation> <translation id="1661245713600520330">На цій сторінці вказано всі модулі, завантажені в основний процес, і модулі, зареєстровані для пізнішого завантаження.</translation> <translation id="166179487779922818">Пароль закороткий.</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">Не дозволяти сайтам переглядати тексти й зображення в буфері обміну</translation> <translation id="1682548588986054654">Нове анонімне вікно</translation> <translation id="168715261339224929">Щоб мати доступ до закладок на всіх своїх пристроях, увімкніть синхронізацію.</translation> +<translation id="1688867105868176567">Очистити дані сайту?</translation> <translation id="1688935057616748272">Введіть символ</translation> <translation id="168991973552362966">Додати принтер поблизу</translation> <translation id="1689945336726856614">Скопіювати &URL-адресу</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">Видалити цього користувача</translation> <translation id="1706586824377653884">Додано адміністратором</translation> <translation id="1706625117072057435">Рівні масштабування</translation> -<translation id="1707463636381878959">Надавати іншим користувачам доступ до цієї мережі</translation> <translation id="1708338024780164500">(Неактивне)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ідентифікатор: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" />x<ph name="HEIGHT" /> (оригінальна)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">Увімкнути тему</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Переглянути у Веб-магазині Chrome</translation> -<translation id="1758831820837444715">Налаштувати мережу Ethernet</translation> <translation id="1763046204212875858">Створити ярлики програми</translation> <translation id="1763108912552529023">Продовжити</translation> <translation id="1763808908432309942">Відкриється в новій вкладці</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">Змінити налаштування доступу до цього файлу</translation> <translation id="1841545962859478868">Адміністратор пристрою може відстежувати таку інформацію:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> вимкнено</translation> +<translation id="1842766183094193446">Увімкнути демонстраційний режим?</translation> <translation id="1844692022597038441">Цей файл не доступний в режимі офлайн.</translation> <translation id="1846308012215045257">Натисніть клавішу Control, щоб запустити плагін <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Збережено</translation> <translation id="1848219224579402567">Виходити з облікового запису, коли кришка закрита</translation> <translation id="184823282865851239">Блокувати, якщо сайт часто показує нав’язливі оголошення</translation> <translation id="1849186935225320012">Ця сторінка повністю контролює пристрої MIDI.</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">Це можна змінити пізніше в налаштуваннях</translation> <translation id="2006638907958895361">Відкрити посилання в додатку <ph name="APP" /></translation> <translation id="2007404777272201486">Повідомити про проблему...</translation> +<translation id="2016237810978710652">Відкриваються файли Linux…</translation> <translation id="2016430552235416146">Традиційне</translation> <translation id="2017334798163366053">Вимкнути збір даних про ефективність</translation> <translation id="2017836877785168846">Очищує історію й автозавершення в адресному рядку.</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">Редагувати картку</translation> <translation id="2154710561487035718">Копіювати URL-адресу</translation> <translation id="2155772377859296191"><ph name="WIDTH" />x<ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Ви можете допомогти покращити Безпечний перегляд, надсилаючи в Google деяку інформацію про систему та вміст сторінок.</translation> <translation id="215753907730220065">Вийти з повноекранного режиму</translation> <translation id="2157875535253991059">Ця сторінка зараз у повноекранному режимі.</translation> <translation id="216169395504480358">Додати Wi-Fi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">Додати ідентифікатор заявки на цей пристрій</translation> <translation id="2175042898143291048">Завжди виконувати цю дію</translation> <translation id="2175607476662778685">Панель швидкого запуску</translation> +<translation id="2176087259161165020">Інші джерела</translation> <translation id="2177950615300672361">Анонімна вкладка: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724">Плагін <ph name="PEPPER_PLUGIN_NAME" /> із сайту <ph name="PEPPER_PLUGIN_DOMAIN" /> хоче отримати доступ до вашого комп’ютера</translation> <translation id="2178614541317717477">Дискредитація ЦС</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">Наступна вкладка</translation> <translation id="2292848386125228270">Почніть роботу з <ph name="PRODUCT_NAME" /> як звичайний користувач. Щоб запустити програму для розробки з кореневого каталогу, перезапустіть її, поставивши прапорець біля опції "--не в ізольованому програмному середовищі".</translation> <translation id="2294358108254308676">Установити <ph name="PRODUCT_NAME" />?</translation> -<translation id="2296019197782308739">Метод EAP:</translation> <translation id="2297705863329999812">Пошук принтерів</translation> <translation id="2300383962156589922">Налаштування та керування <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Кореневий каталог розширення недійсний.</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">ПОМИЛКА. Не вдалося видалити <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Додати файл для спільного доступу</translation> <translation id="2367972762794486313">Показати програми</translation> +<translation id="2369536625682139252">Усі дані, збережені сайтом <ph name="SITE" />, буде видалено (окрім файлів cookie).</translation> <translation id="2371076942591664043">Відкрити коли &виконано</translation> <translation id="2377319039870049694">Список</translation> <translation id="2377667304966270281">Помилка жорсткого диска</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">Друкувати за допомогою діалогового вікна системи... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Запитувати, перш ніж надсилати (рекомендується)</translation> <translation id="2384436799579181135">Сталася помилка. Перевірте принтер і повторіть спробу.</translation> -<translation id="2385700042425247848">Назва служби:</translation> <translation id="2387458720915042159">Тип з’єднання з проксі-сервером</translation> <translation id="2391419135980381625">Стандартний шрифт</translation> <translation id="2391762656119864333">Анулювати</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">Поділитись аудіо</translation> <translation id="2480868415629598489">Змінювати дані, які копіюються</translation> <translation id="2482878487686419369">Сповіщення</translation> -<translation id="2485056306054380289">Сертифікат ЦС для сервера:</translation> <translation id="2485422356828889247">Видалити</translation> <translation id="2487067538648443797">Додати нову закладку</translation> <translation id="248861575772995840">Не вдається знайти телефон. Переконайтеся, що на пристрої <ph name="DEVICE_TYPE" /> увімкнено Bluetooth. <a>Докладніше</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Виконайте Powerwash, щоб відновити заводські налаштування пристрою <ph name="IDS_SHORT_PRODUCT_NAME" />.</translation> <translation id="2567257616420533738">Пароль збережено. Переглядайте збережені паролі та керуйте ними на сторінці <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Контейнер інформаційної панелі</translation> +<translation id="2570454805927264159">Користуйтеся всіма перевагами Асистента</translation> <translation id="257088987046510401">Теми</translation> <translation id="2572032849266859634">Надано доступ лише для перегляду (<ph name="VOLUME_NAME" />).</translation> <translation id="2573269395582837871">Виберіть зображення та ім’я</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">Надіслати</translation> <translation id="265390580714150011">Значення поля</translation> <translation id="2654166010170466751">Дозволити сайтам встановлювати обробники платежів</translation> -<translation id="2655386581175833247">Сертифікат користувача:</translation> <translation id="2660779039299703961">Подія</translation> <translation id="266079277508604648">Не вдається під’єднатися до принтера. Перевірте, чи принтер увімкнено та під’єднано до Chromebook через Wi-Fi або USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">Немає даних про використання</translation> <translation id="3007214526293698309">Виправити формат</translation> <translation id="3007771295016901659">Ідентична вкладка</translation> +<translation id="3008272652534848354">Скинути дозволи</translation> <translation id="3009300415590184725">Дійсно скасувати процес налаштування служби передавання мобільних даних?</translation> <translation id="3009779501245596802">Проіндексовані бази даних</translation> <translation id="3010279545267083280">Пароль видалено</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">Модулі (<ph name="TOTAL_COUNT" />) – відомих конфліктів: <ph name="BAD_COUNT" />, імовірних: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Дата та час</translation> <translation id="310671807099593501">Сайт використовує Bluetooth</translation> -<translation id="3108967419958202225">Вибрати...</translation> <translation id="3115128645424181617">Не вдається знайти телефон. Переконайтеся, що він поблизу та на ньому ввімкнено Bluetooth.</translation> <translation id="3115147772012638511">...</translation> <translation id="3118319026408854581">Довідка <ph name="PRODUCT_NAME" /></translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">Деякі оператори можуть блокувати цю функцію.</translation> <translation id="316854673539778496">Щоб мати доступ до розширень на всіх своїх пристроях, увійдіть в обліковий запис і ввімкніть синхронізацію.</translation> <translation id="3170072451822350649">Можна також пропустити вхід і <ph name="LINK_START" />працювати в режимі "Гість"<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Натисніть, щоб сховати пароль</translation> <translation id="3177909033752230686">Мова сторінки:</translation> <translation id="3181110748548073003">Натисніть клавіші |<ph name="SHORTCUT" />|, щоб перейти далі</translation> <translation id="3182749001423093222">Перевірка правопису</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">Право власності буде передано в домен <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Відкрити параметри розширень</translation> <translation id="3241680850019875542">Виберіть кореневий каталог для пакування розширення. Щоб оновити розширення, також виберіть файл секретного ключа для повторного використання.</translation> -<translation id="3242765319725186192">Спільний ключ:</translation> <translation id="3244294424315804309">Не вмикати звук</translation> <translation id="3245321423178950146">Невідомий виконавець</translation> <translation id="3246097286174000800">Спробуйте Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">Інші дії для закладки <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Запитувати, якщо сайт хоче запустити плагін на комп’ютері</translation> <translation id="3441653493275994384">Екран</translation> -<translation id="3445830502289589282">2-га фаза автентифікації:</translation> <translation id="344630545793878684">Переглядати ваші дані на декількох веб-сайтах</translation> <translation id="3449839693241009168">Натисніть <ph name="SEARCH_KEY" />, щоб надіслати команди для розширення <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Відсоток заряду акумулятора, який використовує неактивний стан</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826">Помилок: <ph name="COUNT" />.</translation> <translation id="3495660573538963482">Налаштування Google Асистента</translation> <translation id="3496213124478423963">Зменшити</translation> -<translation id="3504135463003295723">Назва групи:</translation> <translation id="3505030558724226696">Скасувати доступ до пристрою</translation> <translation id="3507421388498836150">Поточні дозволи розширення <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Видалити додатки Linux для Chromebook</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">Сертифікат входу недійсний. Вікно закриється через <ph name="MINUTES" />:<ph name="SECONDS" /></translation> <translation id="3664511988987167893">Значок розширення</translation> <translation id="3665589677786828986">Chrome виявив, що інша програма пошкодила деякі ваші налаштування, і відновив початкові налаштування за умовчанням.</translation> -<translation id="3665842570601375360">Безпека:</translation> <translation id="3668570675727296296">Налаштування мови</translation> <translation id="3668823961463113931">Обробники</translation> <translation id="3670229581627177274">Увімкніть Bluetooth</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">Не вдається відкрити пристрій, оскільки його файлова система не підтримується.</translation> <translation id="3727148787322499904">Зміна цього налаштування вплине на всі спільні мережі</translation> <translation id="3727187387656390258">Перевірити спливаюче вікно</translation> -<translation id="3728067901555601989">Одноразовий пароль (OTP):</translation> <translation id="3732078975418297900">Помилка в рядку <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">SSL-сервер із підвищенням</translation> <translation id="3737536731758327622">Тут відображатимуться ваші завантаження</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">Закінчивши, натисніть клавішу Enter</translation> <translation id="3827774300009121996">&На весь екран</translation> <translation id="3828029223314399057">Пошук закладок</translation> -<translation id="3829932584934971895">Тип постачальника:</translation> <translation id="3830674330436234648">Немає даних для відтворення</translation> <translation id="3831486154586836914">Ви ввійшли в режим огляду вікна</translation> <translation id="383161972796689579">Власник цього пристрою вимкнув можливість додавати нових користувачів</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">Використання трафіку більше не відстежується</translation> <translation id="3857228364945137633">Спробуйте розблокувати пристрій <ph name="DEVICE_TYPE" /> за допомогою Smart Lock, не вводячи пароль, коли телефон поблизу.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: синхронізацію призупинено</translation> <translation id="3860381078714302691">Вітаємо в Hangouts Meet</translation> <translation id="3862134173397075045">Вітаємо в Cast для Chrome!</translation> <translation id="3862788408946266506">Додаток з атрибутом маніфесту "kiosk_only" потрібно встановлювати в режимі термінала ОС Chrome</translation> @@ -1969,7 +1965,6 @@ <translation id="3968261067169026421">Не вдалося налаштувати мережу</translation> <translation id="3970114302595058915">ІДЕНТИФІКАТОР</translation> <translation id="397105322502079400">Обчислення...</translation> -<translation id="3974195870082915331">Натисніть, щоб показати пароль</translation> <translation id="3975222297214566386">Спливаюча підказка з опціями введення</translation> <translation id="397703832102027365">Завершення...</translation> <translation id="3979395879372752341">Додано нове розширення (<ph name="EXTENSION_NAME" />)</translation> @@ -2011,6 +2006,7 @@ <translation id="4044612648082411741">Введіть пароль сертифіката</translation> <translation id="404493185430269859">Пошукова система за умовчанням</translation> <translation id="4047112090469382184">Наскільки це безпечно</translation> +<translation id="4051049974203704184">Отримуйте інформацію про вміст на екрані</translation> <translation id="4052120076834320548">Дуже малий</translation> <translation id="4055023634561256217">Перш ніж відновити налаштування за допомогою функції "Очищення", потрібно перезапустити пристрій.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2039,6 +2035,7 @@ <translation id="4088095054444612037">Прийняти для групи</translation> <translation id="4089235344645910861">Налаштування збережено. Почато синхронізацію.</translation> <translation id="4090103403438682346">Увімкнути перевірений доступ</translation> +<translation id="4090947011087001172">Скинути дозволи для сайту <ph name="SITE" />?</translation> <translation id="4091434297613116013">аркуші паперу</translation> <translation id="4093955363990068916">Локальний файл:</translation> <translation id="4095507791297118304">Основний дисплей</translation> @@ -2215,7 +2212,6 @@ <translation id="4419556793104466535">Керування синхронізацією, персоналізацією тощо</translation> <translation id="4421932782753506458">Киця</translation> <translation id="4422347585044846479">Редагувати закладку для цієї сторінки</translation> -<translation id="4423104065312875417">Установити додаткові системи синтезу мовлення</translation> <translation id="4423376891418188461">Відновити налаштування</translation> <translation id="4423482519432579560">&Перевірка правопису</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, ваш адміністратор просить змінити пароль.</translation> @@ -2240,7 +2236,6 @@ <translation id="4449996769074858870">На цій вкладці відтворюється аудіофайл.</translation> <translation id="4450974146388585462">Діагностувати</translation> <translation id="4453946976636652378">Шукайте в <ph name="SEARCH_ENGINE_NAME" /> або введіть URL-адресу</translation> -<translation id="445923051607553918">Увійти в мережу Wi-Fi</translation> <translation id="4462159676511157176">Імена серверів – персоналізовано</translation> <translation id="4467100756425880649">Галерея Веб-магазину Chrome</translation> <translation id="4467101674048705704">Розгорнути папку "<ph name="FOLDER_NAME" />"</translation> @@ -2376,6 +2371,7 @@ <translation id="4682551433947286597">Фонові малюнки з’являються на екрані входу.</translation> <translation id="4684427112815847243">Синхронізувати все</translation> <translation id="4689421377817139245">Синхронізуйте цю закладку з iPhone</translation> +<translation id="4690091457710545971"><Мікропрограма Wi-Fi від Intel згенерувала чотири файли: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Перші три – це двійкові файли, що містять дані розвантаження пам’яті реєстру та не включають особисту інформацію й відомості, за якими можна ідентифікувати пристрій (як стверджує компанія Intel). Останній файл – це трасування виконання мікропрограми Intel; з нього стерто всю особисту інформацію й дані, за якими можна ідентифікувати пристрій, але він завеликий, щоб відображатися тут. Ці файли згенеровано у відповідь на нещодавні проблеми з Wi-Fi на пристрої. Їх буде надіслано в Intel, щоб допомогти вирішити ці проблеми.></translation> <translation id="4692302215262324251">Ваш пристрій <ph name="DEVICE_TYPE" /> зареєстровано для корпоративного керування в домені <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Якщо ви не очікували цього, зв’яжіться зі службою підтримки.</translation> @@ -2635,6 +2631,7 @@ <translation id="5074318175948309511">Щоб нові налаштування почали діяти, можливо, потрібно буде оновити цю сторінку.</translation> <translation id="5075131525758602494">Введіть PIN-код SIM-карти</translation> <translation id="5078638979202084724">Позначити закладками всі вкладки</translation> +<translation id="5079950360618752063">Використати запропонований пароль</translation> <translation id="5084230410268011727">Надати сайтам доступ до датчиків руху й світла</translation> <translation id="5085162214018721575">Перевірка наявності оновлень</translation> <translation id="5086082738160935172">HID</translation> @@ -2673,6 +2670,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Видалити цей елемент</translation> <translation id="5139955368427980650">&Відкрити</translation> +<translation id="5142961317498132443">Автентифікація</translation> <translation id="5143374789336132547">Розширення "<ph name="EXTENSION_NAME" />" змінило сторінку, яка відкривається під час натискання кнопки "Домашня сторінка".</translation> <translation id="5143712164865402236">Увійти в повноекранний режим</translation> <translation id="5145331109270917438">Дата змінення</translation> @@ -2843,7 +2841,6 @@ <translation id="5380103295189760361">Утримуйте клавіші Control, Alt, Shift або клавішу Пошук, щоб побачити комбінації клавіш для цих модифікаторів.</translation> <translation id="5382591305415226340">Керувати підтримуваними посиланнями</translation> <translation id="5384883051496921101">Цей сайт збирається надіслати інформацію в додаток, у якому вимкнено режим анонімного перегляду.</translation> -<translation id="5388588172257446328">Ім’я користувача:</translation> <translation id="5388885445722491159">Парні</translation> <translation id="5389237414310520250">Не вдалося створити нового користувача. Перевірте наявність місця на жорсткому диску та дозволи, а потім повторіть спробу.</translation> <translation id="5390100381392048184">Дозволити сайтам відтворювати звук</translation> @@ -2968,7 +2965,6 @@ <translation id="5551573675707792127">Клавіатура та введення тексту</translation> <translation id="5553089923092577885">Зіставлення політик сертифікатів</translation> <translation id="5554489410841842733">Ця піктограма відображатиметься, коли розширення зможе працювати на поточній сторінці.</translation> -<translation id="5554573843028719904">Інша мережа Wi-Fi ...</translation> <translation id="5554720593229208774">Центр сертифікації електронної пошти</translation> <translation id="5556206011531515970">Натисніть "Далі", щоб вибрати веб-переглядач за умовчанням.</translation> <translation id="5556459405103347317">Перезавантажити</translation> @@ -3009,7 +3005,6 @@ <translation id="5610038042047936818">Увімкнути режим камери</translation> <translation id="5612720917913232150">Сайт <ph name="URL" /> хоче отримати доступ до геоданих вашого комп’ютера</translation> <translation id="5612734644261457353">На жаль, поки не вдалося підтвердити ваш пароль. Зверніть увагу: якщо ви нещодавно змінили пароль, новий пароль буде застосовано, щойно ви вийдете з облікового запису. Скористайтеся тут старим паролем.</translation> -<translation id="5613695965848159202">Анонімна ідентифікація:</translation> <translation id="5614190747811328134">Примітка для користувача</translation> <translation id="561698261642843490">Закрити Firefox</translation> <translation id="5618075537869101857">На жаль, не вдалося запустити програму для терміналів.</translation> @@ -3227,7 +3222,6 @@ <translation id="5941343993301164315">Увійдіть у <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Зменшити</translation> <translation id="5946591249682680882">Ідентифікатор звіту: <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Додати приватну мережу</translation> <translation id="5949544233750246342">Не вдається виконати синтаксичний аналіз файлу</translation> <translation id="5955282598396714173">Термін дії пароля минув. Щоб змінити пароль, вийдіть і знову ввійдіть в обліковий запис.</translation> <translation id="5956585768868398362">Це сторінка пошуку, яку ви очікували?</translation> @@ -3388,11 +3382,13 @@ <translation id="6198102561359457428">Вийти, а потім увійти знову...</translation> <translation id="6198252989419008588">Змінити PIN-код</translation> <translation id="6199801702437275229">Очікування даних про вільне місце...</translation> +<translation id="6204015976622790023">Отримуйте доречні пропозиції Асистента щодо вмісту на екрані.</translation> <translation id="6205710420833115353">Деякі операції тривають довше, ніж очікувалось. Скасувати їх?</translation> <translation id="6206311232642889873">Копіюват&и зображення</translation> <translation id="6207200176136643843">Відновити масштаб за умовчанням</translation> <translation id="620722923698527029">Завжди відкривати ці типи посилань у пов’язаному додатку</translation> <translation id="6207937957461833379">Країна або регіон</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: синхронізація не працює</translation> <translation id="6212039847102026977">Показати розширені параметри мережі</translation> <translation id="6212168817037875041">Вимкнути дисплей</translation> <translation id="6212752530110374741">Надіслати посилання електронною поштою</translation> @@ -3430,7 +3426,6 @@ <translation id="6263541650532042179">скинути синхронізацію</translation> <translation id="6264365405983206840">Вибрати &всі</translation> <translation id="6264422956566238156">Ви ввімкнули синхронізацію</translation> -<translation id="6265930187414222160">Готово. Шкідливе програмне забезпечення видалено.</translation> <translation id="6267166720438879315">Виберіть сертифікат, щоб ідентифікувати себе на <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Відкрити за допомогою додатка <ph name="APP" /></translation> <translation id="6268747994388690914">Імпортувати закладки з файлу HTML...</translation> @@ -3537,7 +3532,6 @@ Натисніть "Далі", щоб увійти в обліковий запис <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />.</translation> <translation id="6419546358665792306">Завантажити розпаковане розширення</translation> <translation id="642282551015776456">Не може використовуватися як ім’я файлу чи назва папки</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Відкрити налаштування ChromeVox</translation> <translation id="6429384232893414837">Помилка оновлення</translation> <translation id="6430814529589430811">ASCII Base64-кодування, єдиний сертифікат</translation> @@ -3618,7 +3612,6 @@ <translation id="6544215763872433504">Веб-переглядач від Google для вас</translation> <translation id="6545665334409411530">Частота повторів</translation> <translation id="6545834809683560467">Використовувати підказки для завершення пошукових запитів і URL-адрес, введених в адресний рядок або вікно пошуку на панелі запуску додатків</translation> -<translation id="6546686722964485737">Приєднатися до мережі WiMAX</translation> <translation id="6547316139431024316">Більше не попереджати для цього розширення</translation> <translation id="6547354035488017500">Звільніть принаймні 512 МБ пам’яті, інакше пристрій перестане відповідати. Щоб звільнити місце, видаліть файли з пам’яті пристрою.</translation> <translation id="6549689063733911810">Останні</translation> @@ -4037,7 +4030,6 @@ <translation id="7201014958346994077">Не вдалося переглянути файли Linux</translation> <translation id="720110658997053098">Назавжди перевести цей пристрій у режим термінала</translation> <translation id="7201118060536064622">Елемент "<ph name="DELETED_ITEM_NAME" />" видалено</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Завантаження плагіна <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Закрити сторінку}one{Закрити сторінки}few{Закрити сторінки}many{Закрити сторінки}other{Закрити сторінки}}</translation> <translation id="7216409898977639127">Постачальник мобільного зв’язку</translation> @@ -4515,7 +4507,6 @@ <translation id="7909969815743704077">Завантажено в режимі анонімного перегляду</translation> <translation id="7910768399700579500">&Нова папка</translation> <translation id="7912080627461681647">Ваш пароль змінено на сервері. Вийдіть і знову ввійдіть в обліковий запис.</translation> -<translation id="7912883689016444961">Налаштувати мобільну мережу</translation> <translation id="7915471803647590281">Перед тим як надіслати відгук, повідомте нас, що відбувається.</translation> <translation id="7916556741383518510">Після натискання</translation> <translation id="792514962475806987">Рівень масштабування закріпленої лупи:</translation> @@ -4569,7 +4560,6 @@ <translation id="7988355189918024273">Увімкнути функції доступності</translation> <translation id="7994702968232966508">Метод EAP</translation> <translation id="799547531016638432">Видалити ярлик</translation> -<translation id="7997479212858899587">Ідентифікаційна інформація:</translation> <translation id="7997826902155442747">Пріоритет обробки</translation> <translation id="7999229196265990314">Створено такі файли: @@ -4653,7 +4643,6 @@ <translation id="8105368624971345109">Вимкнути</translation> <translation id="8106045200081704138">Відкриті для мене</translation> <translation id="8107015733319732394">Встановлення додатка Google Play Store на ваш <ph name="DEVICE_TYPE" />. Це може зайняти кілька хвилин.</translation> -<translation id="8109930990200908494">Потрібно ввійти, щоб отримати сертифікат користувача.</translation> <translation id="8111155949205007504">Надішліть цей пароль на пристрій iPhone</translation> <translation id="8113043281354018522">Виберіть тип ліцензії</translation> <translation id="8116190140324504026">Докладніше...</translation> @@ -4664,6 +4653,7 @@ <translation id="8118860139461251237">Керувати вашими завантаженнями</translation> <translation id="81238879832906896">Жовто-біла квітка</translation> <translation id="8124313775439841391">Керований ONC</translation> +<translation id="8125562866093998907">Сайт хоче підтвердити ваш ключ безпеки, щоб покращити захист облікового запису.</translation> <translation id="813082847718468539">Перегляд інформації про сайт</translation> <translation id="8131740175452115882">Підтвердити</translation> <translation id="8133676275609324831">&Показати в папці</translation> @@ -4774,7 +4764,6 @@ <translation id="8308179586020895837">Запитувати, якщо хост <ph name="HOST" /> хоче отримати доступ до вашої камери</translation> <translation id="830868413617744215">Бета-версія</translation> <translation id="8309458809024885768">Сертифікат уже існує</translation> -<translation id="8309505303672555187">Виберіть мережу:</translation> <translation id="8312871300878166382">Вставити в папку</translation> <translation id="8317671367883557781">Додати з’єднання з мережею</translation> <translation id="8319414634934645341">Використання розширеного ключа</translation> @@ -4849,7 +4838,6 @@ <translation id="8451512073679317615">асистент</translation> <translation id="8452135315243592079">Немає SIM-карти</translation> <translation id="8453482423012550001">Копіювання елементів ($1)…</translation> -<translation id="8454288007744638700">Або виберіть нову мережу:</translation> <translation id="845627346958584683">Закінчення терміну дії</translation> <translation id="8456681095658380701">Недійсне ім’я</translation> <translation id="8457451314607652708">Імпортувати закладки</translation> @@ -4913,6 +4901,7 @@ <translation id="855081842937141170">Закріпити вкладку</translation> <translation id="8551388862522347954">Ліцензії</translation> <translation id="8553342806078037065">Керувати іншими користувачами</translation> +<translation id="8554899698005018844">Мову не вибрано</translation> <translation id="855773602626431402">На цій сторінці заблоковано запуск плагіна з неізольованим програмним середовищем.</translation> <translation id="8557930019681227453">Маніфест</translation> <translation id="8559694214572302298">Декодер зображень</translation> @@ -4950,7 +4939,6 @@ <translation id="862727964348362408">Призупинено</translation> <translation id="862750493060684461">Кеш CSS</translation> <translation id="8627795981664801467">Лише захищені з’єднання</translation> -<translation id="8628085465172583869">Ім’я хосту сервера:</translation> <translation id="8630903300770275248">Імпортувати контрольованого користувача</translation> <translation id="8631032106121706562">Ромашка</translation> <translation id="8637542770513281060">Ваш комп’ютер містить модуль безпеки, який виконує багато важливих функцій захисту в ОС Chrome. Щоб дізнатися більше, відвідайте Довідковий центр Chromebook: https://support.google.com/chromebook/?p=sm</translation> @@ -5206,7 +5194,6 @@ <translation id="899403249577094719">Основна URL-адреса сертифіката Netscape</translation> <translation id="8995603266996330174">Керується доменом <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Додати обліковий запис…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Створюється образ диска.</translation> <translation id="9003647077635673607">Дозволити на всіх веб-сайтах</translation> <translation id="9003677638446136377">Перевірити ще раз</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index acceb9d3..509fb68 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">Sắp đến giờ nghỉ giải lao</translation> <translation id="1062407476771304334">Thay thế</translation> -<translation id="1064835277883315402">Tham gia mạng riêng</translation> <translation id="1064912851688322329">Ngắt kết nối Tài khoản Google của bạn</translation> <translation id="1067048845568873861">Đã tạo</translation> <translation id="1067291318998134776">Linux (Beta)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">Đang tìm kiếm...</translation> <translation id="1316495628809031177">Quá trình đồng bộ hóa hiện tạm dừng</translation> <translation id="1319979322914001937">Ứng dụng hiển thị danh sách các tiện ích đã lọc từ Cửa hàng Chrome trực tuyến. Có thể cài đặt các tiện ích trong danh sách ngay từ ứng dụng.</translation> -<translation id="132090119144658135">Khớp với chủ đề:</translation> <translation id="1326317727527857210">Để có các tab từ các thiết bị khác của bạn, hãy đăng nhập vào Chrome.</translation> <translation id="1327074568633507428">Máy in trên Google Cloud Print</translation> <translation id="1327977588028644528">Cổng vào</translation> @@ -377,6 +375,7 @@ <translation id="1531004739673299060">Cửa sổ ứng dụng</translation> <translation id="1534389735079119190">LỖI: Không khởi động được bộ chứa bên trong máy ảo.</translation> <translation id="15373452373711364">Con trỏ chuột lớn</translation> +<translation id="1540605929960647700">Bật chế độ trình diễn</translation> <translation id="1543284117603151572">Được nhập từ Edge</translation> <translation id="1545177026077493356">Chế độ kiosk tự động</translation> <translation id="1545775234664667895">Đã cài đặt chủ đề "<ph name="THEME_NAME" />"</translation> @@ -460,6 +459,7 @@ <translation id="1657406563541664238">Trợ giúp cải thiện <ph name="PRODUCT_NAME" /> bằng cách tự động gửi cho Google thống kê sử dụng và báo cáo sự cố</translation> <translation id="1658424621194652532">Trang này đang truy cập micrô của bạn.</translation> <translation id="1660204651932907780">Cho phép các trang web phát âm thanh (được đề xuất)</translation> +<translation id="1660938185063657230">Xác minh khóa bảo mật của bạn</translation> <translation id="1661156625580498328">Thực thi mã hóa AES (khuyên dùng).</translation> <translation id="1661245713600520330">Trang này liệt kê tất cả các mô-đun được tải vào quy trình chính và các mô-đun được đăng ký để tải sau này.</translation> <translation id="166179487779922818">Mật khẩu quá ngắn.</translation> @@ -477,6 +477,7 @@ <translation id="16815041330799488">Không cho phép các trang web xem văn bản và hình ảnh đã sao chép sang khay nhớ tạm</translation> <translation id="1682548588986054654">Cửa sổ ẩn danh mới</translation> <translation id="168715261339224929">Để sử dụng dấu trang trên tất cả các thiết bị của bạn, hãy bật đồng bộ hóa.</translation> +<translation id="1688867105868176567">Xóa dữ liệu trang web?</translation> <translation id="1688935057616748272">Nhập một chữ cái</translation> <translation id="168991973552362966">Thêm máy in ở gần</translation> <translation id="1689945336726856614">Sao chép &URL</translation> @@ -488,7 +489,6 @@ <translation id="1701062906490865540">Xóa người này</translation> <translation id="1706586824377653884">Do quản trị viên thêm</translation> <translation id="1706625117072057435">Mức thu phóng</translation> -<translation id="1707463636381878959">Chia sẻ mạng này với những người dùng khác</translation> <translation id="1708338024780164500">(Không hoạt động)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Gốc)</translation> @@ -524,7 +524,6 @@ <translation id="175772926354468439">Bật chủ đề</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">Xem trong Cửa hàng Chrome trực tuyến</translation> -<translation id="1758831820837444715">Định cấu hình mạng Ethernet</translation> <translation id="1763046204212875858">Tạo các lối tắt cho ứng dụng</translation> <translation id="1763108912552529023">Tiếp tục khám phá</translation> <translation id="1763808908432309942">Mở trong một tab mới</translation> @@ -583,8 +582,10 @@ <translation id="1839704667838141620">Thay đổi cách chia sẻ tệp này</translation> <translation id="1841545962859478868">Quản trị viên thiết bị có thể theo dõi các vấn đề sau đây:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> đã bị vô hiệu hóa</translation> +<translation id="1842766183094193446">Bạn có chắc chắn muốn bật chế độ trình diễn không?</translation> <translation id="1844692022597038441">Tệp này không có khi ngoại tuyến.</translation> <translation id="1846308012215045257">Giữ Control khi nhấp để chạy <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">Đã lưu</translation> <translation id="1848219224579402567">Đăng xuất khi đóng nắp</translation> <translation id="184823282865851239">Chặn nếu trang web thường hiển thị quảng cáo xâm nhập</translation> <translation id="1849186935225320012">Trang này có quyền kiểm soát toàn bộ thiết bị MIDI.</translation> @@ -682,6 +683,7 @@ <translation id="200544492091181894">Bạn luôn có thể thay đổi tùy chọn này trong mục cài đặt</translation> <translation id="2006638907958895361">Mở liên kết trong <ph name="APP" /></translation> <translation id="2007404777272201486">Báo cáo sự cố...</translation> +<translation id="2016237810978710652">Đang mở tệp Linux...</translation> <translation id="2016430552235416146">Truyền thống</translation> <translation id="2017334798163366053">Tắt tính năng thu thập dữ liệu hoạt động</translation> <translation id="2017836877785168846">Xóa lịch sử và tự động hoàn thành trong thanh địa chỉ.</translation> @@ -776,6 +778,7 @@ <translation id="2154484045852737596">Chỉnh sửa thẻ</translation> <translation id="2154710561487035718">Sao chép URL</translation> <translation id="2155772377859296191">Có vẻ như là <ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">Bạn có thể giúp cải tiến tính năng Duyệt web an toàn bằng cách gửi một số thông tin hệ thống và nội dung trang tới Google.</translation> <translation id="215753907730220065">Thoát khỏi Chế độ Toàn màn hình</translation> <translation id="2157875535253991059">Trang này hiện ở chế độ toàn màn hình.</translation> <translation id="216169395504480358">Thêm Wi-Fi...</translation> @@ -785,6 +788,7 @@ <translation id="2173801458090845390">Thêm ID yêu cầu vào thiết bị này</translation> <translation id="2175042898143291048">Luôn làm điều này</translation> <translation id="2175607476662778685">Thanh khởi động nhanh</translation> +<translation id="2176087259161165020">Nguồn khác</translation> <translation id="2177950615300672361">Tab ẩn danh: <ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_NAME" /> trên <ph name="PEPPER_PLUGIN_DOMAIN" /> muốn truy cập vào máy tính của bạn</translation> <translation id="2178614541317717477">Lộ CA</translation> @@ -868,7 +872,6 @@ <translation id="2291643155573394834">Tab tiếp theo</translation> <translation id="2292848386125228270">Vui lòng khởi động <ph name="PRODUCT_NAME" /> với tư cách người dùng bình thường. Nếu bạn cần chạy dưới dạng chương trình gốc để phát triển, hãy chạy lại bằng cờ --không có-hộp cát.</translation> <translation id="2294358108254308676">Bạn có muốn cài đặt không <ph name="PRODUCT_NAME" /> không?</translation> -<translation id="2296019197782308739">Phương pháp EAP:</translation> <translation id="2297705863329999812">Tìm kiếm máy in</translation> <translation id="2300383962156589922">Tùy chỉnh và kiểm soát <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">Thư mục gốc của tiện ích không hợp lệ.</translation> @@ -916,6 +919,7 @@ <translation id="2366463953911599217">LỖI: Không gỡ cài đặt được <ph name="APP_NAME" />.</translation> <translation id="2367199180085172140">Thêm Chia sẻ tệp</translation> <translation id="2367972762794486313">Hiển thị ứng dụng</translation> +<translation id="2369536625682139252">Tất cả dữ liệu do <ph name="SITE" /> lưu trữ sẽ bị xóa, ngoại trừ cookie.</translation> <translation id="2371076942591664043">Mở khi &hoàn tất</translation> <translation id="2377319039870049694">Chuyển sang chế độ xem danh sách</translation> <translation id="2377667304966270281">Lỗi phần cứng</translation> @@ -925,7 +929,6 @@ <translation id="2379281330731083556">In bằng hộp thoại hệ thống... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">Hỏi trước khi gửi (được đề xuất)</translation> <translation id="2384436799579181135">Đã xảy ra lỗi. Vui lòng kiểm tra máy in của bạn và thử lại.</translation> -<translation id="2385700042425247848">Tên dịch vụ:</translation> <translation id="2387458720915042159">Loại kết nối proxy</translation> <translation id="2391419135980381625">Phông chữ tiêu chuẩn</translation> <translation id="2391762656119864333">Thu hồi</translation> @@ -976,7 +979,6 @@ <translation id="247949520305900375">Chia sẻ âm thanh</translation> <translation id="2480868415629598489">Sửa đổi dữ liệu bạn sao chép và dán</translation> <translation id="2482878487686419369">Thông báo</translation> -<translation id="2485056306054380289">Chứng chỉ CA máy chủ:</translation> <translation id="2485422356828889247">Gỡ cài đặt</translation> <translation id="2487067538648443797">Thêm dấu trang mới</translation> <translation id="248861575772995840">Không thể tìm thấy điện thoại của bạn. Hãy đảm bảo Bluetooth của <ph name="DEVICE_TYPE" /> đang bật. <a>Tìm hiểu thêm</a></translation> @@ -1037,6 +1039,7 @@ <translation id="2566124945717127842">Powerwash để đặt lại thiết bị <ph name="IDS_SHORT_PRODUCT_NAME" /> của bạn giống như mới.</translation> <translation id="2567257616420533738">Đã lưu mật khẩu. Xem và quản lý mật khẩu đã lưu tại <ph name="SAVED_PASSWORDS_LINK" /></translation> <translation id="2568774940984945469">Bộ chứa Thanh thông tin</translation> +<translation id="2570454805927264159">Khai thác tối đa Trợ lý của bạn</translation> <translation id="257088987046510401">Chủ đề</translation> <translation id="2572032849266859634">Quyền truy cập chỉ đọc vào <ph name="VOLUME_NAME" /> đã được cấp.</translation> <translation id="2573269395582837871">Chọn ảnh và tên</translation> @@ -1100,7 +1103,6 @@ <translation id="2653659639078652383">Gửi</translation> <translation id="265390580714150011">Giá trị Trường</translation> <translation id="2654166010170466751">Cho phép các trang web cài đặt trình xử lý thanh toán</translation> -<translation id="2655386581175833247">Chứng chỉ người dùng:</translation> <translation id="2660779039299703961">Sự kiện</translation> <translation id="266079277508604648">Không thể kết nối với máy in. Hãy kiểm tra để đảm bảo rằng bạn đã bật máy in cũng như đã kết nối máy in với Chromebook qua Wi-Fi hoặc USB.</translation> <translation id="2661146741306740526">16x9</translation> @@ -1333,6 +1335,7 @@ <translation id="3006881078666935414">Không có dữ liệu sử dụng</translation> <translation id="3007214526293698309">Cố định tỷ lệ</translation> <translation id="3007771295016901659">Sao chép tab</translation> +<translation id="3008272652534848354">Đặt lại quyền</translation> <translation id="3009300415590184725">Bạn có chắc chắn muốn hủy quá trình thiết lập dịch vụ dữ liệu di động không?</translation> <translation id="3009779501245596802">Cơ sở dữ liệu được lập chỉ mục</translation> <translation id="3010279545267083280">Đã xóa mật khẩu</translation> @@ -1399,7 +1402,6 @@ <translation id="3100609564180505575">Mô-đun (<ph name="TOTAL_COUNT" />) - Các xung đột đã biết: <ph name="BAD_COUNT" />, bị nghi ngờ: <ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">Ngày và giờ</translation> <translation id="310671807099593501">Trang web đang sử dụng Bluetooth</translation> -<translation id="3108967419958202225">Chọn...</translation> <translation id="3115128645424181617">Không thể tìm thấy điện thoại của bạn. Hãy đảm bảo rằng điện thoại ở trong tầm tay và Bluetooth đang bật.</translation> <translation id="3115147772012638511">Đang chờ bộ nhớ đệm…</translation> <translation id="3118319026408854581">Trợ giúp <ph name="PRODUCT_NAME" /></translation> @@ -1444,7 +1446,6 @@ <translation id="3165390001037658081">Một số nhà cung cấp dịch vụ có thể chặn tính năng này.</translation> <translation id="316854673539778496">Để có tất cả các tiện ích trên mọi thiết bị của bạn, hãy đăng nhập rồi bật tính năng đồng bộ hóa.</translation> <translation id="3170072451822350649">Bạn cũng có thể bỏ qua việc đăng nhập và <ph name="LINK_START" />duyệt với tư cách khách<ph name="LINK_END" />.</translation> -<translation id="3177048931975664371">Nhấp để ẩn mật khẩu</translation> <translation id="3177909033752230686">Ngôn ngữ trang:</translation> <translation id="3181110748548073003">Nhấn |<ph name="SHORTCUT" />| để tiến lên</translation> <translation id="3182749001423093222">Kiểm tra chính tả</translation> @@ -1475,7 +1476,6 @@ <translation id="3236289833370040187">Sẽ chuyển quyền sở hữu sang <ph name="DESTINATION_DOMAIN" />.</translation> <translation id="323803881985677942">Mở tùy chọn tiện ích</translation> <translation id="3241680850019875542">Chọn thư mục gốc của tiện ích để đóng gói. Để cập nhật tiện ích, bạn cũng chọn tệp khóa cá nhân để sử dụng lại.</translation> -<translation id="3242765319725186192">Khóa chia sẻ trước:</translation> <translation id="3244294424315804309">Tiếp tục tắt tiếng</translation> <translation id="3245321423178950146">Nghệ sĩ không xác định</translation> <translation id="3246097286174000800">Dùng thử Smart Lock</translation> @@ -1608,7 +1608,6 @@ <translation id="3440663250074896476">Thao tác khác cho <ph name="BOOKMARK_NAME" /></translation> <translation id="3440761377721825626">Hỏi khi một trang web muốn sử dụng plugin để truy cập máy tính của bạn</translation> <translation id="3441653493275994384">Màn hình</translation> -<translation id="3445830502289589282">Xác thực giai đoạn 2:</translation> <translation id="344630545793878684">Đọc dữ liệu của bạn trên một số trang web</translation> <translation id="3449839693241009168">Bấm <ph name="SEARCH_KEY" /> để gửi lệnh đến <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Phần trăm sử dụng ở trạng thái không hoạt động</translation> @@ -1649,7 +1648,6 @@ <translation id="3495304270784461826"><ph name="COUNT" /> lỗi.</translation> <translation id="3495660573538963482">Cài đặt Trợ lý Google</translation> <translation id="3496213124478423963">Thu Nhỏ</translation> -<translation id="3504135463003295723">Tên nhóm:</translation> <translation id="3505030558724226696">Thu hồi quyền truy cập thiết bị</translation> <translation id="3507421388498836150">Quyền hiện tại cho "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Xóa ứng dụng Linux cho Chromebook</translation> @@ -1758,7 +1756,6 @@ <translation id="3661054927247347545">Chứng chỉ đăng nhập không hợp lệ, cửa sổ sẽ đóng sau <ph name="MINUTES" /> : <ph name="SECONDS" /></translation> <translation id="3664511988987167893">Biểu tượng tiện ích</translation> <translation id="3665589677786828986">Chrome phát hiện thấy rằng một số cài đặt của bạn đã bị lỗi do một chương trình khác gây ra và đặt lại các cài đặt đó về giá trị mặc định ban đầu.</translation> -<translation id="3665842570601375360">Bảo mật:</translation> <translation id="3668570675727296296">Cài đặt ngôn ngữ</translation> <translation id="3668823961463113931">Trình xử lý</translation> <translation id="3670229581627177274">Bật Bluetooth</translation> @@ -1797,7 +1794,6 @@ <translation id="3726463242007121105">Thiết bị này không thể mở được vì hệ thống tệp của thiết bị không được hỗ trợ.</translation> <translation id="3727148787322499904">Việc thay đổi cài đặt này sẽ ảnh hưởng đến tất cả các mạng chia sẻ</translation> <translation id="3727187387656390258">Kiểm tra cửa sổ bật lên</translation> -<translation id="3728067901555601989">OTP:</translation> <translation id="3732078975418297900">Lỗi trên dòng <ph name="ERROR_LINE" /></translation> <translation id="3733127536501031542">Máy chủ SSL với Step-up</translation> <translation id="3737536731758327622">Các bản tải xuống của bạn xuất hiện ở đây</translation> @@ -1872,7 +1868,6 @@ <translation id="38275787300541712">Nhấn Enter khi hoàn tất</translation> <translation id="3827774300009121996">&Toàn Màn hình</translation> <translation id="3828029223314399057">Tìm kiếm dấu trang</translation> -<translation id="3829932584934971895">Loại nhà cung cấp:</translation> <translation id="3830674330436234648">Không thể phát lại</translation> <translation id="3831486154586836914">Đã vào chế độ tổng quan cửa sổ</translation> <translation id="383161972796689579">Chủ sở hữu của thiết bị này đã vô hiệu hóa thêm người dùng mới</translation> @@ -1893,6 +1888,7 @@ <translation id="3856921555429624101">Đã kết thúc đo lường mức sử dụng dữ liệu</translation> <translation id="3857228364945137633">Dùng thử Smart Lock để mở khóa <ph name="DEVICE_TYPE" /> của bạn mà không cần mật khẩu khi điện thoại của bạn ở gần.</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />: Đã tạm dừng đồng bộ hóa</translation> <translation id="3860381078714302691">Chào mừng bạn đến với Hangouts Meet</translation> <translation id="3862134173397075045">Chào mừng bạn đến với trải nghiệm Truyền trong Chrome!</translation> <translation id="3862788408946266506">Phải cài đặt ứng dụng có thuộc tính tệp kê khai 'kiosk_only' ở chế độ kiosk Chrome OS</translation> @@ -1970,7 +1966,6 @@ <translation id="3968261067169026421">Không thể thiết lập mạng</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">Đang tính...</translation> -<translation id="3974195870082915331">Nhấp để hiển thị mật khẩu</translation> <translation id="3975222297214566386">Bong bóng tùy chọn nhập</translation> <translation id="397703832102027365">Đang hoàn tất...</translation> <translation id="3979395879372752341">Đã thêm tiện ích mới (<ph name="EXTENSION_NAME" />)</translation> @@ -2012,6 +2007,7 @@ <translation id="4044612648082411741">Nhập mật khẩu chứng chỉ của bạn</translation> <translation id="404493185430269859">Công cụ tìm kiếm mặc định</translation> <translation id="4047112090469382184">Tính năng này an toàn như thế nào</translation> +<translation id="4051049974203704184">Nhận thông tin về nội dung trên màn hình</translation> <translation id="4052120076834320548">Rất nhỏ</translation> <translation id="4055023634561256217">Cần khởi động lại trước khi có thể đặt lại thiết bị của bạn bằng Powerwash.</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2040,6 +2036,7 @@ <translation id="4088095054444612037">Chấp nhận cho nhóm</translation> <translation id="4089235344645910861">Đã lưu cài đặt. Đã bắt đầu đồng bộ hóa.</translation> <translation id="4090103403438682346">Bật quyền truy cập đã xác minh</translation> +<translation id="4090947011087001172">Đặt lại quyền của trang web cho <ph name="SITE" />?</translation> <translation id="4091434297613116013">trang giấy</translation> <translation id="4093955363990068916">Tệp cục bộ:</translation> <translation id="4095507791297118304">Màn hình chính</translation> @@ -2093,7 +2090,7 @@ <translation id="4193154014135846272">Tài liệu Google</translation> <translation id="4194570336751258953">Cho phép gõ để nhấp</translation> <translation id="4195643157523330669">Mở bằng tab mới</translation> -<translation id="4195814663415092787">Tiếp tục từ điểm bạn đã dừng lại</translation> +<translation id="4195814663415092787">Tiếp tục từ nơi bạn đã dừng lại</translation> <translation id="4197674956721858839">Chọn file nén zip</translation> <translation id="4198146608511578238">Bạn chỉ cần giữ biểu tượng Trình khởi chạy để nói chuyện với Trợ lý Google của mình.</translation> <translation id="4200689466366162458">Từ tùy chỉnh</translation> @@ -2216,7 +2213,6 @@ <translation id="4419556793104466535">Kiểm soát tính năng đồng bộ hóa, cá nhân hóa, v.v.</translation> <translation id="4421932782753506458">Mèo con dễ thương</translation> <translation id="4422347585044846479">Chỉnh sửa dấu trang của trang này</translation> -<translation id="4423104065312875417">Cài đặt thêm các công cụ chuyển văn bản sang lời nói</translation> <translation id="4423376891418188461">Khôi phục cài đặt</translation> <translation id="4423482519432579560">&Kiểm tra chính tả</translation> <translation id="442397852638519243"><ph name="USER_NAME" />, quản trị viên của bạn yêu cầu bạn thay đổi mật khẩu của mình.</translation> @@ -2241,7 +2237,6 @@ <translation id="4449996769074858870">Tab này đang phát âm thanh.</translation> <translation id="4450974146388585462">Chẩn đoán</translation> <translation id="4453946976636652378">Tìm kiếm <ph name="SEARCH_ENGINE_NAME" /> hoặc nhập một URL</translation> -<translation id="445923051607553918">Tham gia mạng Wi-Fi</translation> <translation id="4462159676511157176">Máy chủ có tên tùy chỉnh</translation> <translation id="4467100756425880649">Thư viện của Cửa hàng Chrome trực tuyến</translation> <translation id="4467101674048705704">Mở rộng <ph name="FOLDER_NAME" /></translation> @@ -2377,6 +2372,7 @@ <translation id="4682551433947286597">Hình nền xuất hiện trên màn hình đăng nhập.</translation> <translation id="4684427112815847243">Đồng bộ hóa mọi thứ</translation> <translation id="4689421377817139245">Đồng bộ hóa dấu trang này với iPhone của bạn</translation> +<translation id="4690091457710545971"><Bốn tệp do chương trình cơ sở Intel Wi-Fi tạo ra: csr.lst, fh_regs.lst, radio_reg.lst, monitor.lst.sysmon. Ba tệp đầu tiên là tệp nhị phân có chứa báo cáo đăng ký và được Intel xác nhận không chứa thông tin cá nhân hoặc thông tin nhận dạng thiết bị. Tệp cuối cùng là dấu vết thực thi từ chương trình cơ sở Intel; tệp này đã được xóa mọi thông tin nhận dạng cá nhân hoặc thiết bị, nhưng kích thước tệp quá lớn nên không hiển thị được ở đây. Các tệp này được tạo do các sự cố Wi-Fi xảy ra gần đây với thiết bị của bạn và sẽ được chia sẻ với Intel để giúp khắc phục các sự cố này.></translation> <translation id="4692302215262324251"><ph name="DEVICE_TYPE" /> của bạn đã được đăng ký thành công cho quản lý doanh nghiệp <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />. <ph name="LINE_BREAK_AND_EMPTY_LINE" /> Nếu không mong muốn việc này, vui lòng liên hệ với bộ phận hỗ trợ.</translation> @@ -2636,6 +2632,7 @@ <translation id="5074318175948309511">Có thể cần phải tải lại trang này trước khi cài đặt mới có hiệu lực.</translation> <translation id="5075131525758602494">Nhập mã PIN của SIM</translation> <translation id="5078638979202084724">Đánh dấu trang tất cả các tab</translation> +<translation id="5079950360618752063">Sử dụng mật khẩu đề xuất</translation> <translation id="5084230410268011727">Cho phép các trang web sử dụng cảm biến chuyển động và ánh sáng</translation> <translation id="5085162214018721575">Đang kiểm tra bản cập nhật</translation> <translation id="5086082738160935172">HID</translation> @@ -2674,6 +2671,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">Xóa mục này</translation> <translation id="5139955368427980650">&Mở</translation> +<translation id="5142961317498132443">Xác thực</translation> <translation id="5143374789336132547">Tiện ích "<ph name="EXTENSION_NAME" />" đã thay đổi trang nào sẽ hiển thị khi bạn nhấp vào nút Trang chủ.</translation> <translation id="5143712164865402236">Vào Chế độ Toàn Màn hình</translation> <translation id="5145331109270917438">Ngày sửa đổi</translation> @@ -2844,7 +2842,6 @@ <translation id="5380103295189760361">Giữ Control, Alt, Shift hoặc Tìm kiếm để xem phím tắt dành cho các phím bổ trợ đó.</translation> <translation id="5382591305415226340">Quản lý liên kết được hỗ trợ</translation> <translation id="5384883051496921101">Trang web này sắp chia sẻ thông tin với một ứng dụng bên ngoài chế độ ẩn danh.</translation> -<translation id="5388588172257446328">Tên người dùng:</translation> <translation id="5388885445722491159">Được ghép nối</translation> <translation id="5389237414310520250">Không thể tạo người dùng mới. Vui lòng kiểm tra dung lượng ổ đĩa cứng và quyền của bạn rồi thử lại.</translation> <translation id="5390100381392048184">Cho phép các trang web phát âm thanh</translation> @@ -2969,7 +2966,6 @@ <translation id="5551573675707792127">Bàn phím và phương thức nhập văn bản</translation> <translation id="5553089923092577885">Ánh xạ Chính sách của Chứng chỉ</translation> <translation id="5554489410841842733">Biểu tượng này sẽ hiển thị khi tiện ích có thể hoạt động trên trang hiện tại.</translation> -<translation id="5554573843028719904">Mạng Wi-Fi khác...</translation> <translation id="5554720593229208774">Tổ chức phát hành chứng chỉ email</translation> <translation id="5556206011531515970">Nhấp tiếp theo để chọn trình duyệt mặc định của bạn.</translation> <translation id="5556459405103347317">Tải lại</translation> @@ -3010,7 +3006,6 @@ <translation id="5610038042047936818">Chuyển sang chế độ máy ảnh</translation> <translation id="5612720917913232150"><ph name="URL" /> muốn sử dụng thông tin vị trí máy tính của bạn</translation> <translation id="5612734644261457353">Rất tiếc, mật khẩu của bạn vẫn không thể xác minh được. Lưu ý: nếu gần đây bạn đã thay đổi mật khẩu của bạn, mật khẩu mới của bạn sẽ vẫn được áp dụng khi bạn đăng xuất, vui lòng sử dụng mật khẩu cũ của bạn tại đây.</translation> -<translation id="5613695965848159202">Danh tính ẩn danh:</translation> <translation id="5614190747811328134">Thông báo Người dùng</translation> <translation id="561698261642843490">Đóng Firefox</translation> <translation id="5618075537869101857">Rất tiếc, không thể chạy ứng dụng kiosk.</translation> @@ -3228,7 +3223,6 @@ <translation id="5941343993301164315">Vui lòng đăng nhập vào <ph name="TOKEN_NAME" />.</translation> <translation id="5941711191222866238">Thu nhỏ</translation> <translation id="5946591249682680882">ID báo cáo <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">Thêm mạng riêng</translation> <translation id="5949544233750246342">Không thể phân tích cú pháp tệp</translation> <translation id="5955282598396714173">Mật khẩu của bạn đã hết hạn. Vui lòng đăng xuất rồi đăng nhập lại để thay đổi mật khẩu.</translation> <translation id="5956585768868398362">Đây có phải là trang tìm kiếm bạn muốn không?</translation> @@ -3389,11 +3383,13 @@ <translation id="6198102561359457428">Đăng xuất rồi đăng nhập lại...</translation> <translation id="6198252989419008588">Thay đổi mã PIN</translation> <translation id="6199801702437275229">Đang chờ thông tin dung lượng...</translation> +<translation id="6204015976622790023">Xem đề xuất liên quan đến nội dung trên màn hình từ Trợ lý của bạn</translation> <translation id="6205710420833115353">Một số tác vụ đang diễn ra lâu hơn thông thường. Bạn có muốn hủy các tác vụ này không?</translation> <translation id="6206311232642889873">Sao ché&p Hình ảnh</translation> <translation id="6207200176136643843">Đặt lại về mức thu phóng mặc định</translation> <translation id="620722923698527029">Luôn mở những loại liên kết này trong ứng dụng được liên kết</translation> <translation id="6207937957461833379">Quốc gia/vùng</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />: Tính năng đồng bộ hóa hiện không hoạt động</translation> <translation id="6212039847102026977">Hiển thị thuộc tính mạng nâng cao</translation> <translation id="6212168817037875041">Tắt màn hình</translation> <translation id="6212752530110374741">Gửi liên kết qua email</translation> @@ -3431,7 +3427,6 @@ <translation id="6263541650532042179">đặt lại đồng bộ hóa</translation> <translation id="6264365405983206840">Chọn &Tất cả</translation> <translation id="6264422956566238156">Bạn đã bật Đồng bộ hóa</translation> -<translation id="6265930187414222160">Xong! Đã loại bỏ phần mềm độc hại.</translation> <translation id="6267166720438879315">Chọn một chứng chỉ để xác thực bạn với <ph name="HOST_NAME" /></translation> <translation id="6268252012308737255">Mở bằng <ph name="APP" /></translation> <translation id="6268747994388690914">Nhập dấu trang từ tệp HTML...</translation> @@ -3538,7 +3533,6 @@ Vui lòng nhấp vào "Tiếp theo" để tiếp tục đăng nhập vào tài khoản <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> của bạn.</translation> <translation id="6419546358665792306">Tải tiện ích đã giải nén</translation> <translation id="642282551015776456">Không thể sử dụng tên này làm tên tệp trong thư mục</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">Mở cài đặt ChromeVox</translation> <translation id="6429384232893414837">Lỗi cập nhật</translation> <translation id="6430814529589430811">ASCII được mã hóa base64, chứng chỉ đơn</translation> @@ -3619,7 +3613,6 @@ <translation id="6544215763872433504">Trình duyệt web của Google, dành cho bạn</translation> <translation id="6545665334409411530">Tốc độ lặp lại</translation> <translation id="6545834809683560467">Sử dụng dịch vụ gợi ý để giúp hoàn thành các tìm kiếm và URL được nhập vào thanh địa chỉ hoặc hộp tìm kiếm của trình chạy ứng dụng</translation> -<translation id="6546686722964485737">Tham gia mạng Wimax</translation> <translation id="6547316139431024316">Không cảnh báo lại đối với tiện ích này</translation> <translation id="6547354035488017500">Hãy giải phóng ít nhất 512 MB dung lượng, nếu không thiết bị sẽ không phản hồi. Để giải phóng dung lượng, hãy xóa các tệp khỏi bộ nhớ thiết bị.</translation> <translation id="6549689063733911810">Gần đây</translation> @@ -4038,7 +4031,6 @@ <translation id="7201014958346994077">Không thể xem tệp Linux</translation> <translation id="720110658997053098">Vĩnh viễn giữ thiết bị này ở chế độ kiosk</translation> <translation id="7201118060536064622">Đã xóa '<ph name="DELETED_ITEM_NAME" />'</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">Đang tải xuống <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Thoát khỏi trang}other{Thoát khỏi các trang}}</translation> <translation id="7216409898977639127">Nhà cung cấp dịch vụ di động</translation> @@ -4516,7 +4508,6 @@ <translation id="7909969815743704077">Đã tải xuống ở chế độ Ẩn danh</translation> <translation id="7910768399700579500">&Thư mục mới</translation> <translation id="7912080627461681647">Đã thay đổi mật khẩu của bạn trên máy chủ. Vui lòng đăng xuất rồi đăng nhập lại.</translation> -<translation id="7912883689016444961">Định cấu hình mạng di động</translation> <translation id="7915471803647590281">Vui lòng cho chúng tôi biết điều đang xảy ra trước khi gửi phản hồi.</translation> <translation id="7916556741383518510">Khi nhấp chuột</translation> <translation id="792514962475806987">Mức thu phóng ở vị trí cố định:</translation> @@ -4570,7 +4561,6 @@ <translation id="7988355189918024273">Bật các tính năng hỗ trợ truy cập</translation> <translation id="7994702968232966508">Phương pháp EAP</translation> <translation id="799547531016638432">Xóa lối tắt</translation> -<translation id="7997479212858899587">Nhận dạng:</translation> <translation id="7997826902155442747">Mức độ ưu tiên quá trình</translation> <translation id="7999229196265990314">Đã tạo các tệp sau: @@ -4654,7 +4644,6 @@ <translation id="8105368624971345109">Tắt</translation> <translation id="8106045200081704138">Được chia sẻ với tôi</translation> <translation id="8107015733319732394">Đang cài đặt Cửa hàng Google Play trên <ph name="DEVICE_TYPE" /> của bạn. Quá trình này có thể mất vài phút.</translation> -<translation id="8109930990200908494">Yêu cầu đăng nhập đối với chứng nhận người dùng.</translation> <translation id="8111155949205007504">Chia sẻ mật khẩu này với iPhone của bạn</translation> <translation id="8113043281354018522">Chọn loại giấy phép</translation> <translation id="8116190140324504026">Thông tin khác...</translation> @@ -4665,6 +4654,7 @@ <translation id="8118860139461251237">Quản lý bản tải xuống của bạn</translation> <translation id="81238879832906896">Hoa màu vàng và trắng</translation> <translation id="8124313775439841391">ONC được quản lý</translation> +<translation id="8125562866093998907">Trang web muốn xác minh Khóa bảo mật để tăng cường bảo mật cho tài khoản của bạn.</translation> <translation id="813082847718468539">Xem thông tin trang web</translation> <translation id="8131740175452115882">Xác nhận</translation> <translation id="8133676275609324831">&Hiển thị trong thư mục</translation> @@ -4775,7 +4765,6 @@ <translation id="8308179586020895837">Hỏi nếu <ph name="HOST" /> muốn truy cập máy ảnh của bạn</translation> <translation id="830868413617744215">Beta</translation> <translation id="8309458809024885768">Chứng chỉ đã tồn tại</translation> -<translation id="8309505303672555187">Chọn mạng:</translation> <translation id="8312871300878166382">Dán vào thư mục</translation> <translation id="8317671367883557781">Thêm kết nối mạng</translation> <translation id="8319414634934645341">Sử dụng Khoá Mở rộng</translation> @@ -4850,7 +4839,6 @@ <translation id="8451512073679317615">trợ lý</translation> <translation id="8452135315243592079">Thiếu thẻ SIM</translation> <translation id="8453482423012550001">Đang sao chép $1 mục...</translation> -<translation id="8454288007744638700">Hoặc chọn một mạng mới:</translation> <translation id="845627346958584683">Thời gian hết hạn</translation> <translation id="8456681095658380701">Tên không hợp lệ</translation> <translation id="8457451314607652708">Nhập dấu trang</translation> @@ -4914,6 +4902,7 @@ <translation id="855081842937141170">Ghim tab</translation> <translation id="8551388862522347954">Giấy phép</translation> <translation id="8553342806078037065">Quản lý những người khác</translation> +<translation id="8554899698005018844">Không có ngôn ngữ nào</translation> <translation id="855773602626431402">Plugin không có hộp cát bị ngăn không cho chạy trên trang này.</translation> <translation id="8557930019681227453">Tệp kê khai</translation> <translation id="8559694214572302298">Trình giải mã hình ảnh</translation> @@ -4951,7 +4940,6 @@ <translation id="862727964348362408">Bị tạm ngưng</translation> <translation id="862750493060684461">Bộ nhớ đệm CSS</translation> <translation id="8627795981664801467">Chỉ kết nối an toàn</translation> -<translation id="8628085465172583869">Tên máy chủ:</translation> <translation id="8630903300770275248">Nhập người dùng được giám sát</translation> <translation id="8631032106121706562">Cánh hoa</translation> <translation id="8637542770513281060">Máy tính của bạn chứa một mô-đun an toàn dùng để triển khai nhiều tính năng bảo mật quan trọng trong Chrome OS. Hãy truy cập Trung tâm trợ giúp Chromebook để tìm hiểu thêm: https://support.google.com/chromebook/?p=sm</translation> @@ -5207,7 +5195,6 @@ <translation id="899403249577094719">URL Cơ sở Chứng chỉ Netscape</translation> <translation id="8995603266996330174">Được quản lý bởi <ph name="DOMAIN" /></translation> <translation id="8996526648899750015">Thêm tài khoản...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">Đang tạo hình ảnh đĩa.</translation> <translation id="9003647077635673607">Cho phép trên tất cả các trang web</translation> <translation id="9003677638446136377">Kiểm tra lại</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb index c32fd300..630b2e7 100644 --- a/chrome/app/resources/generated_resources_zh-CN.xtb +++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">快到休息时间了</translation> <translation id="1062407476771304334">替换</translation> -<translation id="1064835277883315402">加入专用网络</translation> <translation id="1064912851688322329">取消与您的 Google 帐号的关联</translation> <translation id="1067048845568873861">创建时间</translation> <translation id="1067291318998134776">Linux(测试版)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">正在搜索...</translation> <translation id="1316495628809031177">同步已暂停</translation> <translation id="1319979322914001937">此应用可以显示一个列表,其中会列出从 Chrome 网上应用店中筛选出来的扩展程序。您可以直接通过此应用安装列出的扩展程序。</translation> -<translation id="132090119144658135">主题匹配:</translation> <translation id="1326317727527857210">要在您的其他设备上访问您的标签页,请登录 Chrome。</translation> <translation id="1327074568633507428">Google 云打印中的打印机</translation> <translation id="1327977588028644528">网关</translation> @@ -373,6 +371,7 @@ <translation id="1531004739673299060">应用窗口</translation> <translation id="1534389735079119190">错误:未能成功启动 VM 内的容器。</translation> <translation id="15373452373711364">大号鼠标光标</translation> +<translation id="1540605929960647700">启用演示模式</translation> <translation id="1543284117603151572">从 Edge 导入的书签</translation> <translation id="1545177026077493356">自动自助服务终端模式</translation> <translation id="1545775234664667895">已安装主题背景“<ph name="THEME_NAME" />”</translation> @@ -456,6 +455,7 @@ <translation id="1657406563541664238">将使用情况统计信息和崩溃报告自动发送给 Google,帮助我们完善 <ph name="PRODUCT_NAME" /></translation> <translation id="1658424621194652532">此网页正在使用您的麦克风。</translation> <translation id="1660204651932907780">允许网站播放声音(推荐)</translation> +<translation id="1660938185063657230">验证您的安全密钥</translation> <translation id="1661156625580498328">强制执行 AES 加密(推荐)。</translation> <translation id="1661245713600520330">此网页列出了已加载主进程中的所有模块以及稍后要加载的模块。</translation> <translation id="166179487779922818">密码太短。</translation> @@ -473,6 +473,7 @@ <translation id="16815041330799488">不允许网站查看复制到剪贴板的文字和图片</translation> <translation id="1682548588986054654">打开新的无痕式窗口</translation> <translation id="168715261339224929">要想将您的书签同步到您的所有设备上,请开启同步功能。</translation> +<translation id="1688867105868176567">要清除网站数据吗?</translation> <translation id="1688935057616748272">请输入一个字母</translation> <translation id="168991973552362966">添加附近的打印机</translation> <translation id="1689945336726856614">复制网址(&U)</translation> @@ -484,7 +485,6 @@ <translation id="1701062906490865540">移除此用户</translation> <translation id="1706586824377653884">此图标是由管理员添加的</translation> <translation id="1706625117072057435">缩放级别</translation> -<translation id="1707463636381878959">与其他用户共享此网络</translation> <translation id="1708338024780164500">(无效)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" />(ID:<ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" />(原生)</translation> @@ -520,7 +520,6 @@ <translation id="175772926354468439">启用主题背景</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">在 Chrome 网上应用店中查看详情</translation> -<translation id="1758831820837444715">配置以太网</translation> <translation id="1763046204212875858">创建应用快捷方式</translation> <translation id="1763108912552529023">继续了解</translation> <translation id="1763808908432309942">在新标签页中打开</translation> @@ -579,8 +578,10 @@ <translation id="1839704667838141620">更改此文件的分享方式</translation> <translation id="1841545962859478868">此设备的管理员可能会监控以下各项:</translation> <translation id="1841705068325380214"><ph name="EXTENSION_NAME" /> 已被禁用</translation> +<translation id="1842766183094193446">确定要启用演示模式吗?</translation> <translation id="1844692022597038441">此文件无法在离线模式下播放。</translation> <translation id="1846308012215045257">按住 Ctrl 键的同时点击即可运行 <ph name="PLUGIN_NAME" /></translation> +<translation id="1847880352285315359">已保存</translation> <translation id="1848219224579402567">在盖被合上之后退出</translation> <translation id="184823282865851239">如果网站常常会展示侵扰性广告则阻止</translation> <translation id="1849186935225320012">此页面可以完全控制 MIDI 设备。</translation> @@ -678,6 +679,7 @@ <translation id="200544492091181894">以后,您随时可在“设置”中更改此设置</translation> <translation id="2006638907958895361">在<ph name="APP" />中打开链接</translation> <translation id="2007404777272201486">报告问题...</translation> +<translation id="2016237810978710652">正在打开 Linux 文件…</translation> <translation id="2016430552235416146">传统</translation> <translation id="2017334798163366053">停用性能数据收集</translation> <translation id="2017836877785168846">清除历史记录和地址栏中的自动填充项。</translation> @@ -772,6 +774,7 @@ <translation id="2154484045852737596">修改支付卡</translation> <translation id="2154710561487035718">复制网址</translation> <translation id="2155772377859296191">有效分辨率:<ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">您可以选择向 Google 发送一些系统信息和网页内容,以帮助我们改进安全浏览功能。</translation> <translation id="215753907730220065">退出全屏模式</translation> <translation id="2157875535253991059">此网页现处于全屏模式。</translation> <translation id="216169395504480358">添加 Wi-Fi...</translation> @@ -781,6 +784,7 @@ <translation id="2173801458090845390">向此设备添加申请 ID</translation> <translation id="2175042898143291048">一律执行此操作</translation> <translation id="2175607476662778685">快速启动栏</translation> +<translation id="2176087259161165020">其他来源</translation> <translation id="2177950615300672361">隐身标签页:<ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> 上的“<ph name="PEPPER_PLUGIN_NAME" />”想访问您的计算机</translation> <translation id="2178614541317717477">CA 泄漏</translation> @@ -864,7 +868,6 @@ <translation id="2291643155573394834">下一标签页</translation> <translation id="2292848386125228270">请以普通用户的身份启动 <ph name="PRODUCT_NAME" />。如果您出于开发目的,需要以根用户的身份运行 Chrome,请使用 --no-sandbox 标记重新运行 Chrome。</translation> <translation id="2294358108254308676">要安装<ph name="PRODUCT_NAME" />吗?</translation> -<translation id="2296019197782308739">EAP 方法:</translation> <translation id="2297705863329999812">搜索打印机</translation> <translation id="2300383962156589922">自定义和控制<ph name="APP_NAME" /></translation> <translation id="2301382460326681002">扩展程序根目录无效。</translation> @@ -912,6 +915,7 @@ <translation id="2366463953911599217">错误:未能成功卸载“<ph name="APP_NAME" />”。</translation> <translation id="2367199180085172140">添加文件共享</translation> <translation id="2367972762794486313">显示应用</translation> +<translation id="2369536625682139252">即将删除 <ph name="SITE" /> 存储的所有数据(Cookie 除外)。</translation> <translation id="2371076942591664043">完成时打开(&D)</translation> <translation id="2377319039870049694">切换到列表视图</translation> <translation id="2377667304966270281">硬故障数</translation> @@ -921,7 +925,6 @@ <translation id="2379281330731083556">使用系统对话框进行打印...<ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">发送前先询问(推荐)</translation> <translation id="2384436799579181135">出错了。请检查您的打印机,然后重试。</translation> -<translation id="2385700042425247848">服务名称:</translation> <translation id="2387458720915042159">代理连接类型</translation> <translation id="2391419135980381625">标准字体</translation> <translation id="2391762656119864333">撤消</translation> @@ -972,7 +975,6 @@ <translation id="247949520305900375">分享音频</translation> <translation id="2480868415629598489">修改您复制和粘贴的数据</translation> <translation id="2482878487686419369">通知</translation> -<translation id="2485056306054380289">服务器CA证书:</translation> <translation id="2485422356828889247">卸载</translation> <translation id="2487067538648443797">添加新书签</translation> <translation id="248861575772995840">找不到您的手机。请确保已为您的 <ph name="DEVICE_TYPE" /> 开启蓝牙。<a>了解详情</a></translation> @@ -1033,6 +1035,7 @@ <translation id="2566124945717127842">Powerwash会将您的<ph name="IDS_SHORT_PRODUCT_NAME" />设备重置为初始状态。</translation> <translation id="2567257616420533738">密码已保存。您可在 <ph name="SAVED_PASSWORDS_LINK" /> 上查看和管理已保存的密码</translation> <translation id="2568774940984945469">信息栏容器</translation> +<translation id="2570454805927264159">充分利用您的 Google 助理</translation> <translation id="257088987046510401">主题背景</translation> <translation id="2572032849266859634">已授予对 <ph name="VOLUME_NAME" />的只读权限。</translation> <translation id="2573269395582837871">选择照片和名字</translation> @@ -1095,7 +1098,6 @@ <translation id="2653659639078652383">提交</translation> <translation id="265390580714150011">字段值</translation> <translation id="2654166010170466751">允许网站安装付款处理程序</translation> -<translation id="2655386581175833247">用户证书:</translation> <translation id="2660779039299703961">事件</translation> <translation id="266079277508604648">无法连接到打印机。请确保该打印机已开机且已通过 Wi-Fi 或 USB 连接到您的 Chromebook。</translation> <translation id="2661146741306740526">16x9</translation> @@ -1328,6 +1330,7 @@ <translation id="3006881078666935414">无使用情况数据</translation> <translation id="3007214526293698309">更正宽高比</translation> <translation id="3007771295016901659">复制标签</translation> +<translation id="3008272652534848354">重置权限</translation> <translation id="3009300415590184725">确定要取消移动数据服务安装过程吗?</translation> <translation id="3009779501245596802">索引型数据库</translation> <translation id="3010279545267083280">密码已删除</translation> @@ -1394,7 +1397,6 @@ <translation id="3100609564180505575">模块数 (<ph name="TOTAL_COUNT" />) - 已知冲突数:<ph name="BAD_COUNT" />,可疑冲突数:<ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">日期和时间</translation> <translation id="310671807099593501">该网站正在使用蓝牙</translation> -<translation id="3108967419958202225">选择...</translation> <translation id="3115128645424181617">找不到您的手机。请确保它就在您身边且已开启蓝牙。</translation> <translation id="3115147772012638511">正在等待存入缓存...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" />帮助</translation> @@ -1439,7 +1441,6 @@ <translation id="3165390001037658081">有些运营商可能会屏蔽此功能。</translation> <translation id="316854673539778496">要将您的所有扩展程序同步到您的所有设备上,请登录您的帐号并开启同步功能。</translation> <translation id="3170072451822350649">您也可以跳过登录步骤,<ph name="LINK_START" />以访客身份浏览<ph name="LINK_END" />。</translation> -<translation id="3177048931975664371">点击可隐藏密码</translation> <translation id="3177909033752230686">网页语言:</translation> <translation id="3181110748548073003">按 |<ph name="SHORTCUT" />| 即可前进</translation> <translation id="3182749001423093222">拼写检查</translation> @@ -1470,7 +1471,6 @@ <translation id="3236289833370040187">所有权将被转移到 <ph name="DESTINATION_DOMAIN" />。</translation> <translation id="323803881985677942">打开扩展程序选项</translation> <translation id="3241680850019875542">选择要打包的扩展程序的根目录。要更新某个扩展程序,还需选择要再次使用的私有密钥文件。</translation> -<translation id="3242765319725186192">预共享密钥:</translation> <translation id="3244294424315804309">继续保持静音</translation> <translation id="3245321423178950146">未知艺术家</translation> <translation id="3246097286174000800">试用 Smart Lock</translation> @@ -1601,7 +1601,6 @@ <translation id="3440663250074896476">显示可对“<ph name="BOOKMARK_NAME" />”执行的更多操作</translation> <translation id="3440761377721825626">当网站要使用插件访问您的计算机时询问您</translation> <translation id="3441653493275994384">屏幕</translation> -<translation id="3445830502289589282">阶段 2 身份验证</translation> <translation id="344630545793878684">读取您在一些网站上的数据</translation> <translation id="3449839693241009168">按 <ph name="SEARCH_KEY" /> 可向<ph name="EXTENSION_NAME" />发送命令</translation> <translation id="3450157232394774192">闲置状态占用率</translation> @@ -1642,7 +1641,6 @@ <translation id="3495304270784461826"><ph name="COUNT" />个错误。</translation> <translation id="3495660573538963482">Google 智能助理设置</translation> <translation id="3496213124478423963">缩小</translation> -<translation id="3504135463003295723">群组名称:</translation> <translation id="3505030558724226696">撤消对设备的访问权限</translation> <translation id="3507421388498836150">“<ph name="EXTENSION_NAME" />”目前拥有的权限</translation> <translation id="3507547268929739059">从 Chromebook 中移除 Linux 应用</translation> @@ -1751,7 +1749,6 @@ <translation id="3661054927247347545">登录证书无效,窗口将在 <ph name="MINUTES" /> 分 <ph name="SECONDS" /> 秒后关闭</translation> <translation id="3664511988987167893">扩展程序图标</translation> <translation id="3665589677786828986">Chrome检测到您的部分设置被其他程序篡改了,因此已将这些设置重置为原始默认设置。</translation> -<translation id="3665842570601375360">安全:</translation> <translation id="3668570675727296296">语言设置</translation> <translation id="3668823961463113931">处理程序</translation> <translation id="3670229581627177274">开启蓝牙</translation> @@ -1790,7 +1787,6 @@ <translation id="3726463242007121105">系统不支持此设备的文件系统,因此无法打开此设备。</translation> <translation id="3727148787322499904">更改此设置将会影响所有共享网络</translation> <translation id="3727187387656390258">审查弹出内容</translation> -<translation id="3728067901555601989">一次性密码:</translation> <translation id="3732078975418297900">第 <ph name="ERROR_LINE" /> 行存在错误</translation> <translation id="3733127536501031542">带有递升式验证机制的 SSL 服务器</translation> <translation id="3737536731758327622">您的下载内容会显示在此处</translation> @@ -1865,7 +1861,6 @@ <translation id="38275787300541712">完成后按 Enter</translation> <translation id="3827774300009121996">全屏幕(&F)</translation> <translation id="3828029223314399057">搜索书签</translation> -<translation id="3829932584934971895">提供商类型:</translation> <translation id="3830674330436234648">无法播放</translation> <translation id="3831486154586836914">已进入窗口概览模式</translation> <translation id="383161972796689579">此设备的所有者已禁止添加新用户</translation> @@ -1886,6 +1881,7 @@ <translation id="3856921555429624101">已停止衡量数据使用情况</translation> <translation id="3857228364945137633">当您的手机就在附近时,您便可尝试使用 Smart Lock(无需使用密码)来解锁您的 <ph name="DEVICE_TYPE" />。</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />:已暂停同步</translation> <translation id="3860381078714302691">欢迎使用 Hangouts Meet</translation> <translation id="3862134173397075045">欢迎体验 Chrome 中的投射功能!</translation> <translation id="3862788408946266506">具有“kiosk_only”这项清单属性的应用必须在 Chrome 操作系统自助服务终端模式下进行安装</translation> @@ -1962,7 +1958,6 @@ <translation id="3968261067169026421">无法设置网络</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">正在计算...</translation> -<translation id="3974195870082915331">点击可显示密码</translation> <translation id="3975222297214566386">输入法选项气泡</translation> <translation id="397703832102027365">正在完成...</translation> <translation id="3979395879372752341">已添加新扩展程序(<ph name="EXTENSION_NAME" />)</translation> @@ -2004,6 +1999,7 @@ <translation id="4044612648082411741">输入您的证书密码</translation> <translation id="404493185430269859">默认搜索引擎</translation> <translation id="4047112090469382184">此功能如何保障安全</translation> +<translation id="4051049974203704184">获取屏幕上内容的相关信息</translation> <translation id="4052120076834320548">最小</translation> <translation id="4055023634561256217">使用 Powerwash 重置您的设备之前必须重新启动该设备。</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2032,6 +2028,7 @@ <translation id="4088095054444612037">代表群组接受</translation> <translation id="4089235344645910861">设置已保存。已开始同步。</translation> <translation id="4090103403438682346">允许已通过验证的访问凭证</translation> +<translation id="4090947011087001172">要重置 <ph name="SITE" /> 的网站权限吗?</translation> <translation id="4091434297613116013">张纸</translation> <translation id="4093955363990068916">本地文件:</translation> <translation id="4095507791297118304">主显示屏</translation> @@ -2208,7 +2205,6 @@ <translation id="4419556793104466535">控制同步、个性化和其他服务</translation> <translation id="4421932782753506458">猫咪</translation> <translation id="4422347585044846479">修改此页的书签</translation> -<translation id="4423104065312875417">安装其他语音引擎</translation> <translation id="4423376891418188461">还原设置</translation> <translation id="4423482519432579560">拼写检查(&S)</translation> <translation id="442397852638519243"><ph name="USER_NAME" />,您的管理员要求您更改密码。</translation> @@ -2233,7 +2229,6 @@ <translation id="4449996769074858870">该标签页正在播放音频。</translation> <translation id="4450974146388585462">诊断</translation> <translation id="4453946976636652378">在<ph name="SEARCH_ENGINE_NAME" />中搜索,或者输入一个网址</translation> -<translation id="445923051607553918">加入Wi-Fi网络</translation> <translation id="4462159676511157176">自定义域名服务器</translation> <translation id="4467100756425880649">Chrome 网上应用店扩展程序列表</translation> <translation id="4467101674048705704">展开“<ph name="FOLDER_NAME" />”</translation> @@ -2369,6 +2364,7 @@ <translation id="4682551433947286597">登录屏幕上显示的壁纸。</translation> <translation id="4684427112815847243">同步所有数据类型</translation> <translation id="4689421377817139245">将此书签同步到您的 iPhone</translation> +<translation id="4690091457710545971"><Intel Wi-Fi 固件生成了四个文件:csr.lst、fh_regs.lst、radio_reg.lst 和 monitor.lst.sysmon。前三个文件是包含注册表转储的二进制文件,且 Intel 表示其中并未包含任何个人信息或设备标识信息。最后一个文件是 Intel 固件的执行跟踪记录,其中的个人信息或设备标识信息已全部遭到清除,但由于文件过大而无法显示在这里。如果您的设备最近发生过 Wi-Fi 问题,系统便会生成这些文件,且会将文件提供给 Intel 以协助排查相关问题。></translation> <translation id="4692302215262324251"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 已为您的 <ph name="DEVICE_TYPE" /> 成功注册企业管理服务。 <ph name="LINE_BREAK_AND_EMPTY_LINE" /> 如果您不希望如此,请与支持团队联系。</translation> @@ -2627,6 +2623,7 @@ <translation id="5074318175948309511">您可能需要重新加载此页面,才能使新设置生效。</translation> <translation id="5075131525758602494">输入 SIM 卡 PIN 码</translation> <translation id="5078638979202084724">为所有标签页添加书签</translation> +<translation id="5079950360618752063">使用建议的密码</translation> <translation id="5084230410268011727">允许网站使用动态传感器和光传感器</translation> <translation id="5085162214018721575">正在检查更新</translation> <translation id="5086082738160935172">HID</translation> @@ -2665,6 +2662,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">删除此项</translation> <translation id="5139955368427980650">打开(&O)</translation> +<translation id="5142961317498132443">身份验证</translation> <translation id="5143374789336132547">“<ph name="EXTENSION_NAME" />”扩展程序更改了您点击“主页”按钮后系统显示的页面。</translation> <translation id="5143712164865402236">进入全屏模式</translation> <translation id="5145331109270917438">修改日期</translation> @@ -2830,7 +2828,6 @@ <translation id="5380103295189760361">按住 Ctrl、Alt、Shift 或 Search 键,即可查看这些辅助键的键盘快捷键。</translation> <translation id="5382591305415226340">管理支持的链接</translation> <translation id="5384883051496921101">该网站即将与某个并非处于隐身模式下的应用共享信息。</translation> -<translation id="5388588172257446328">用户名:</translation> <translation id="5388885445722491159">已配对</translation> <translation id="5389237414310520250">无法创建新用户。请检查您的硬盘空间和权限,然后重试。</translation> <translation id="5390100381392048184">允许网站播放声音</translation> @@ -2955,7 +2952,6 @@ <translation id="5551573675707792127">键盘和文字输入</translation> <translation id="5553089923092577885">证书政策映射</translation> <translation id="5554489410841842733">如果该扩展程序可以在当前网页上运行,则会显示此图标。</translation> -<translation id="5554573843028719904">其他Wi-Fi网络...</translation> <translation id="5554720593229208774">电子邮件证书授权中心</translation> <translation id="5556206011531515970">点击“下一步”选择您的默认浏览器。</translation> <translation id="5556459405103347317">重新加载</translation> @@ -2996,7 +2992,6 @@ <translation id="5610038042047936818">切换到相机模式</translation> <translation id="5612720917913232150"><ph name="URL" /> 想使用您计算机的位置信息</translation> <translation id="5612734644261457353">抱歉,我们仍然无法验证您的密码。提示:如果您刚刚改了密码,新密码将在您退出后应用。请在此使用您的旧密码。</translation> -<translation id="5613695965848159202">匿名身份:</translation> <translation id="5614190747811328134">用户须知</translation> <translation id="561698261642843490">关闭 Firefox</translation> <translation id="5618075537869101857">糟糕!无法启动该自助服务终端应用。</translation> @@ -3214,7 +3209,6 @@ <translation id="5941343993301164315">请登录 <ph name="TOKEN_NAME" />。</translation> <translation id="5941711191222866238">最小化</translation> <translation id="5946591249682680882">报告ID:<ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">添加专用网络</translation> <translation id="5949544233750246342">无法解析文件</translation> <translation id="5955282598396714173">您的密码已过期。请退出并重新登录以更改密码。</translation> <translation id="5956585768868398362">这是您想要的搜索页面吗?</translation> @@ -3375,11 +3369,13 @@ <translation id="6198102561359457428">退出后重新登录...</translation> <translation id="6198252989419008588">更改 PIN</translation> <translation id="6199801702437275229">等待存储空间信息...</translation> +<translation id="6204015976622790023">查看 Google 助理提供的与您屏幕内容相关的建议。</translation> <translation id="6205710420833115353">某些操作所用的时间超出预期。要取消这些操作吗?</translation> <translation id="6206311232642889873">复制图片(&Y)</translation> <translation id="6207200176136643843">重置为默认缩放级别</translation> <translation id="620722923698527029">始终在关联的应用中打开这些类型的链接</translation> <translation id="6207937957461833379">国家/地区</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />:同步功能无法正常运行</translation> <translation id="6212039847102026977">显示高级网络属性</translation> <translation id="6212168817037875041">关闭显示屏</translation> <translation id="6212752530110374741">通过电子邮件发送链接</translation> @@ -3417,7 +3413,6 @@ <translation id="6263541650532042179">重置同步设置</translation> <translation id="6264365405983206840">全选(&A)</translation> <translation id="6264422956566238156">您已开启同步功能</translation> -<translation id="6265930187414222160">大功告成!有害软件已被移除。</translation> <translation id="6267166720438879315">请选择证书,以在 <ph name="HOST_NAME" /> 上对您本人进行身份验证</translation> <translation id="6268252012308737255">使用<ph name="APP" />打开</translation> <translation id="6268747994388690914">从 HTML 文件导入书签...</translation> @@ -3524,7 +3519,6 @@ 请点击“下一步”,继续使用您的 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 帐号登录。</translation> <translation id="6419546358665792306">加载已解压的扩展程序</translation> <translation id="642282551015776456">该名称可能无法用作文件名或文件夹名</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">打开 ChromeVox 设置</translation> <translation id="6429384232893414837">更新错误</translation> <translation id="6430814529589430811">Base64 编码 ASCII,单一证书</translation> @@ -3604,7 +3598,6 @@ <translation id="6544215763872433504">Google 为您开发的网络浏览器</translation> <translation id="6545665334409411530">重复速度</translation> <translation id="6545834809683560467">在地址栏或应用启动器搜索框中输入搜索字词和网址时,借助联想查询服务自动补齐相关内容</translation> -<translation id="6546686722964485737">加入 WiMAX 网络</translation> <translation id="6547316139431024316">不再为此扩展程序发出此警告</translation> <translation id="6547354035488017500">请至少释放 512 MB 的空间,否则您的设备将无响应。要释放空间,请将文件从设备存储空间中删除。</translation> <translation id="6549689063733911810">我最近用过</translation> @@ -4023,7 +4016,6 @@ <translation id="7201014958346994077">无法查看 Linux 文件</translation> <translation id="720110658997053098">让此设备永久处于自助服务终端模式</translation> <translation id="7201118060536064622">已删除“<ph name="DELETED_ITEM_NAME" />”</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">正在下载 <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{退出网页}other{退出网页}}</translation> <translation id="7216409898977639127">移动网络服务提供商</translation> @@ -4499,7 +4491,6 @@ <translation id="7909969815743704077">已在隐身模式下进行下载</translation> <translation id="7910768399700579500">新建文件夹(&N)</translation> <translation id="7912080627461681647">您已在服务器上更改密码。请先退出,然后重新登录。</translation> -<translation id="7912883689016444961">配置移动网络</translation> <translation id="7915471803647590281">请先告诉我们所发生的情况,然后再发送反馈。</translation> <translation id="7916556741383518510">点击时</translation> <translation id="792514962475806987">停靠的放大镜的缩放级别:</translation> @@ -4553,7 +4544,6 @@ <translation id="7988355189918024273">启用辅助功能</translation> <translation id="7994702968232966508">EAP 方法</translation> <translation id="799547531016638432">删除快捷方式</translation> -<translation id="7997479212858899587">身份:</translation> <translation id="7997826902155442747">进程优先级</translation> <translation id="7999229196265990314">已创建以下文件: @@ -4637,7 +4627,6 @@ <translation id="8105368624971345109">关闭</translation> <translation id="8106045200081704138">与我共享</translation> <translation id="8107015733319732394">正在在您的 <ph name="DEVICE_TYPE" /> 上安装 Google Play 商店。这可能需要几分钟的时间。</translation> -<translation id="8109930990200908494">需提供用户证书才能登录。</translation> <translation id="8111155949205007504">将此密码发送到您的 iPhone</translation> <translation id="8113043281354018522">选择许可类型</translation> <translation id="8116190140324504026">详情...</translation> @@ -4648,6 +4637,7 @@ <translation id="8118860139461251237">管理您的下载内容</translation> <translation id="81238879832906896">黄色和白色花朵</translation> <translation id="8124313775439841391">受管理的 ONC</translation> +<translation id="8125562866093998907">该网站想验证您的安全密钥,以提高您帐号的安全性。</translation> <translation id="813082847718468539">查看网站信息</translation> <translation id="8131740175452115882">确认</translation> <translation id="8133676275609324831">在文件夹中显示(&S)</translation> @@ -4758,7 +4748,6 @@ <translation id="8308179586020895837">当 <ph name="HOST" /> 想要使用摄像头时询问我</translation> <translation id="830868413617744215">测试版</translation> <translation id="8309458809024885768">证书已存在</translation> -<translation id="8309505303672555187">选择网络:</translation> <translation id="8312871300878166382">粘贴到文件夹中</translation> <translation id="8317671367883557781">添加网络连接</translation> <translation id="8319414634934645341">扩展密钥用法</translation> @@ -4833,7 +4822,6 @@ <translation id="8451512073679317615">智能助理</translation> <translation id="8452135315243592079">缺少 SIM 卡</translation> <translation id="8453482423012550001">正在复制$1项内容…</translation> -<translation id="8454288007744638700">或者,选择一个新网络:</translation> <translation id="845627346958584683">失效时间</translation> <translation id="8456681095658380701">名称无效</translation> <translation id="8457451314607652708">导入书签</translation> @@ -4897,6 +4885,7 @@ <translation id="855081842937141170">固定标签页</translation> <translation id="8551388862522347954">许可</translation> <translation id="8553342806078037065">管理其他用户</translation> +<translation id="8554899698005018844">无语言</translation> <translation id="855773602626431402">某个未经过沙盒屏蔽的插件已被禁止在此页上运行。</translation> <translation id="8557930019681227453">由应用缓存指定的网址</translation> <translation id="8559694214572302298">图片解码器</translation> @@ -4934,7 +4923,6 @@ <translation id="862727964348362408">已暂停</translation> <translation id="862750493060684461">CSS 缓存</translation> <translation id="8627795981664801467">仅限安全连接</translation> -<translation id="8628085465172583869">服务器主机名:</translation> <translation id="8630903300770275248">导入受监管用户</translation> <translation id="8631032106121706562">花朵</translation> <translation id="8637542770513281060">您的计算机包含一个安全模块,该模块可用于在 Chrome 操作系统中实施许多关键的安全功能。要了解详情,请访问 Chromebook 帮助中心:https://support.google.com/chromebook/?p=sm</translation> @@ -5190,7 +5178,6 @@ <translation id="899403249577094719">Netscape 证书基本网址</translation> <translation id="8995603266996330174">由 <ph name="DOMAIN" /> 管理</translation> <translation id="8996526648899750015">添加帐号…</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">正在创建磁盘映像。</translation> <translation id="9003647077635673607">允许在所有网站上运行脚本</translation> <translation id="9003677638446136377">再次检查</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb index 4318993..2fe9d90 100644 --- a/chrome/app/resources/generated_resources_zh-TW.xtb +++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -44,7 +44,6 @@ <translation id="1058262162121953039">PUK</translation> <translation id="1061904396131502319">快到休息時間了</translation> <translation id="1062407476771304334">取代</translation> -<translation id="1064835277883315402">加入私人網路</translation> <translation id="1064912851688322329">中斷你「Google 帳戶」的連線</translation> <translation id="1067048845568873861">建立時間</translation> <translation id="1067291318998134776">Linux (測試版)</translation> @@ -227,7 +226,6 @@ <translation id="1316136264406804862">搜尋中...</translation> <translation id="1316495628809031177">已暫停同步處理</translation> <translation id="1319979322914001937">這個應用程式會顯示經過篩選的 Chrome 線上應用程式商店擴充功能清單。使用者可以直接透過應用程式安裝清單中的擴充功能。</translation> -<translation id="132090119144658135">主題比對:</translation> <translation id="1326317727527857210">如要存取您在其他裝置上開啟的分頁,請登入 Chrome。</translation> <translation id="1327074568633507428">Google 雲端列印中的印表機</translation> <translation id="1327977588028644528">閘道</translation> @@ -376,6 +374,7 @@ <translation id="1531004739673299060">應用程式視窗</translation> <translation id="1534389735079119190">錯誤:無法啟動 VM 中的容器。</translation> <translation id="15373452373711364">大型滑鼠游標</translation> +<translation id="1540605929960647700">啟用示範模式</translation> <translation id="1543284117603151572">從 Edge 匯入的書籤</translation> <translation id="1545177026077493356">自動 Kiosk 模式</translation> <translation id="1545775234664667895">已安裝「<ph name="THEME_NAME" />」主題</translation> @@ -459,6 +458,7 @@ <translation id="1657406563541664238">只要自動傳送使用統計資料及當機報告給 Google,就能助我們一臂之力,讓「<ph name="PRODUCT_NAME" />」更臻完美</translation> <translation id="1658424621194652532">這個網頁正在存取你的麥克風。</translation> <translation id="1660204651932907780">允許網站播放音訊 (建議)</translation> +<translation id="1660938185063657230">驗證安全金鑰</translation> <translation id="1661156625580498328">強制執行 AES 加密 (建議使用)。</translation> <translation id="1661245713600520330">這個頁面列出了所有已載入主要程序中的模組,以及已註冊於日後載入的模組。</translation> <translation id="166179487779922818">密碼太短。</translation> @@ -476,6 +476,7 @@ <translation id="16815041330799488">禁止網站讀取已複製到剪貼簿的文字和圖片</translation> <translation id="1682548588986054654">新增無痕式視窗</translation> <translation id="168715261339224929">如要將書籤同步到所有裝置,請開啟同步處理功能。</translation> +<translation id="1688867105868176567">要清除網站資料嗎?</translation> <translation id="1688935057616748272">請輸入英文字母</translation> <translation id="168991973552362966">新增鄰近印表機</translation> <translation id="1689945336726856614">複製網址(&U)</translation> @@ -487,7 +488,6 @@ <translation id="1701062906490865540">移除這個使用者</translation> <translation id="1706586824377653884">由管理員新增</translation> <translation id="1706625117072057435">縮放等級</translation> -<translation id="1707463636381878959">與其他使用者共用這個網路</translation> <translation id="1708338024780164500">(無法使用)</translation> <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID:<ph name="ID_PH" />)</translation> <translation id="1709106626015023981"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (原生)</translation> @@ -523,7 +523,6 @@ <translation id="175772926354468439">啟用主題</translation> <translation id="1758018619400202187">EAP-TLS</translation> <translation id="17584710573359123">前往 Chrome 線上應用程式商店查看</translation> -<translation id="1758831820837444715">設定乙太網路</translation> <translation id="1763046204212875858">建立應用程式捷徑</translation> <translation id="1763108912552529023">繼續探索</translation> <translation id="1763808908432309942">在新分頁中開啟</translation> @@ -582,8 +581,10 @@ <translation id="1839704667838141620">變更這些檔案的共用方式。</translation> <translation id="1841545962859478868">裝置管理員可能會監控下列項目:</translation> <translation id="1841705068325380214">「<ph name="EXTENSION_NAME" />」已停用</translation> +<translation id="1842766183094193446">確定要啟用示範模式嗎?</translation> <translation id="1844692022597038441">這個檔案無法離線瀏覽。</translation> <translation id="1846308012215045257">按下 Ctrl 鍵並點選即可執行「<ph name="PLUGIN_NAME" />」</translation> +<translation id="1847880352285315359">已儲存</translation> <translation id="1848219224579402567">蓋上機蓋時登出帳戶</translation> <translation id="184823282865851239">針對經常顯示侵入式廣告的網站封鎖廣告</translation> <translation id="1849186935225320012">這個網頁可完整控制 MIDI 裝置。</translation> @@ -681,6 +682,7 @@ <translation id="200544492091181894">日後你隨時可以在設定中進行變更</translation> <translation id="2006638907958895361">在「<ph name="APP" />」中開啟連結</translation> <translation id="2007404777272201486">回報問題...</translation> +<translation id="2016237810978710652">正在開啟 Linux 檔案...</translation> <translation id="2016430552235416146">傳統</translation> <translation id="2017334798163366053">停用效能資料收集</translation> <translation id="2017836877785168846">將歷史記錄和自動即時查詢從網址列中清除。</translation> @@ -775,6 +777,7 @@ <translation id="2154484045852737596">編輯卡片資訊</translation> <translation id="2154710561487035718">複製網址</translation> <translation id="2155772377859296191">螢幕解析度:<ph name="WIDTH" /> x <ph name="HEIGHT" /></translation> +<translation id="2156283799932971644">你可以將部分系統資訊和網頁內容傳送給 Google,協助我們改善安全瀏覽功能。</translation> <translation id="215753907730220065">結束全螢幕</translation> <translation id="2157875535253991059">這個頁面已顯示為全螢幕。</translation> <translation id="216169395504480358">新增 WiFi...</translation> @@ -784,6 +787,7 @@ <translation id="2173801458090845390">新增這部裝置的申請 ID</translation> <translation id="2175042898143291048">一律執行這項操作</translation> <translation id="2175607476662778685">快速啟動列</translation> +<translation id="2176087259161165020">其他來源</translation> <translation id="2177950615300672361">無痕式分頁:<ph name="TAB_NAME" /></translation> <translation id="2178098616815594724"><ph name="PEPPER_PLUGIN_DOMAIN" /> 的「<ph name="PEPPER_PLUGIN_NAME" />」要求存取你的電腦</translation> <translation id="2178614541317717477">CA 洩露</translation> @@ -867,7 +871,6 @@ <translation id="2291643155573394834">下一個分頁</translation> <translation id="2292848386125228270">請以一般使用者身分啟用 <ph name="PRODUCT_NAME" />。開發時,如要以 root 身分執行,請使用 --no-sandbox 標記重新執行。</translation> <translation id="2294358108254308676">是否要安裝「<ph name="PRODUCT_NAME" />」?</translation> -<translation id="2296019197782308739">EAP 方法:</translation> <translation id="2297705863329999812">搜尋印表機</translation> <translation id="2300383962156589922">自訂及控制 <ph name="APP_NAME" /></translation> <translation id="2301382460326681002">擴充功能根目錄無效。</translation> @@ -915,6 +918,7 @@ <translation id="2366463953911599217">錯誤:無法解除安裝「<ph name="APP_NAME" />」。</translation> <translation id="2367199180085172140">新增檔案共用</translation> <translation id="2367972762794486313">顯示應用程式</translation> +<translation id="2369536625682139252">即將刪除 <ph name="SITE" /> 儲存的所有資料 (Cookie 除外)。</translation> <translation id="2371076942591664043">完成後開啟(&D)</translation> <translation id="2377319039870049694">切換為清單檢視</translation> <translation id="2377667304966270281">硬性錯誤數</translation> @@ -924,7 +928,6 @@ <translation id="2379281330731083556">使用系統對話方塊進行列印... <ph name="SHORTCUT_KEY" /></translation> <translation id="2381756643783702095">傳送前詢問我 (建議)</translation> <translation id="2384436799579181135">發生錯誤。請檢查你的印表機,然後再試一次。</translation> -<translation id="2385700042425247848">服務名稱:</translation> <translation id="2387458720915042159">Proxy 連線類型</translation> <translation id="2391419135980381625">標準字型</translation> <translation id="2391762656119864333">撤銷</translation> @@ -975,7 +978,6 @@ <translation id="247949520305900375">分享音訊</translation> <translation id="2480868415629598489">修改你複製和貼上的資料</translation> <translation id="2482878487686419369">通知</translation> -<translation id="2485056306054380289">伺服器 CA 憑證:</translation> <translation id="2485422356828889247">解除安裝</translation> <translation id="2487067538648443797">新增書籤</translation> <translation id="248861575772995840">找不到你的手機。請確定已開啟 <ph name="DEVICE_TYPE" /> 的藍牙功能。<a>瞭解詳情</a></translation> @@ -1036,6 +1038,7 @@ <translation id="2566124945717127842">Powerwash 會將你的 <ph name="IDS_SHORT_PRODUCT_NAME" /> 裝置重設並恢復為原廠設定。</translation> <translation id="2567257616420533738">密碼已儲存。你可以前往 <ph name="SAVED_PASSWORDS_LINK" /> 查看及管理已儲存的密碼</translation> <translation id="2568774940984945469">資訊列容器</translation> +<translation id="2570454805927264159">充分運用 Google 助理的各項功能</translation> <translation id="257088987046510401">主題</translation> <translation id="2572032849266859634">已授予 <ph name="VOLUME_NAME" /> 的唯讀權限。</translation> <translation id="2573269395582837871">選擇圖片和名稱</translation> @@ -1099,7 +1102,6 @@ <translation id="2653659639078652383">提交</translation> <translation id="265390580714150011">欄位值</translation> <translation id="2654166010170466751">允許網站安裝付款處理常式</translation> -<translation id="2655386581175833247">使用者憑證:</translation> <translation id="2660779039299703961">活動</translation> <translation id="266079277508604648">無法連上印表機。請確認印表機已開啟,且已透過 Wi-Fi 或 USB 連上 Chromebook。</translation> <translation id="2661146741306740526">16x9</translation> @@ -1332,6 +1334,7 @@ <translation id="3006881078666935414">沒有使用情況資料</translation> <translation id="3007214526293698309">修正比例</translation> <translation id="3007771295016901659">複製分頁</translation> +<translation id="3008272652534848354">重設權限</translation> <translation id="3009300415590184725">你確定要取消行動數據服務設定程序嗎?</translation> <translation id="3009779501245596802">索引資料庫</translation> <translation id="3010279545267083280">已刪除密碼</translation> @@ -1398,7 +1401,6 @@ <translation id="3100609564180505575">模組數 (<ph name="TOTAL_COUNT" />) - 已知衝突數目:<ph name="BAD_COUNT" />,可疑衝突數目:<ph name="SUSPICIOUS_COUNT" /></translation> <translation id="3101709781009526431">日期與時間</translation> <translation id="310671807099593501">網站正在使用藍牙</translation> -<translation id="3108967419958202225">選擇...</translation> <translation id="3115128645424181617">找不到你的手機。請確定手機在適當距離範圍內,且藍牙功能已開啟。</translation> <translation id="3115147772012638511">等候快取...</translation> <translation id="3118319026408854581"><ph name="PRODUCT_NAME" />說明</translation> @@ -1443,7 +1445,6 @@ <translation id="3165390001037658081">部分電信業者可能會封鎖這項功能。</translation> <translation id="316854673539778496">如要將擴充功能同步到所有裝置,請登入並開啟同步處理功能。</translation> <translation id="3170072451822350649">你也可以略過登入程序,<ph name="LINK_START" />以訪客身分瀏覽<ph name="LINK_END" />。</translation> -<translation id="3177048931975664371">按這裡隱藏密碼</translation> <translation id="3177909033752230686">網頁語言:</translation> <translation id="3181110748548073003">按下 |<ph name="SHORTCUT" />| 即可繼續</translation> <translation id="3182749001423093222">拼字檢查</translation> @@ -1474,7 +1475,6 @@ <translation id="3236289833370040187">擁有權將轉移至 <ph name="DESTINATION_DOMAIN" />。</translation> <translation id="323803881985677942">開啟擴充功能選項</translation> <translation id="3241680850019875542">請選取要封裝的擴充功能根目錄。如要更新擴充功能,請一併選取要重複使用的秘密金鑰。</translation> -<translation id="3242765319725186192">預先共用金鑰:</translation> <translation id="3244294424315804309">繼續維持靜音</translation> <translation id="3245321423178950146">演出者不明</translation> <translation id="3246097286174000800">試試 Smart Lock</translation> @@ -1607,7 +1607,6 @@ <translation id="3440663250074896476">更多可對「<ph name="BOOKMARK_NAME" />」執行的動作</translation> <translation id="3440761377721825626">當網站要使用外掛程式存取您的電腦時,必須先詢問您</translation> <translation id="3441653493275994384">螢幕</translation> -<translation id="3445830502289589282">第 2 階段驗證:</translation> <translation id="344630545793878684">讀取你在多個網站上產生的資料</translation> <translation id="3449839693241009168">按下「<ph name="SEARCH_KEY" />」即可將指令傳送給 <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">閒置狀態占用率</translation> @@ -1648,7 +1647,6 @@ <translation id="3495304270784461826">發生 <ph name="COUNT" /> 個錯誤。</translation> <translation id="3495660573538963482">Google 助理設定</translation> <translation id="3496213124478423963">縮小</translation> -<translation id="3504135463003295723">群組名稱:</translation> <translation id="3505030558724226696">撤銷裝置存取權</translation> <translation id="3507421388498836150">「<ph name="EXTENSION_NAME" />」目前擁有的權限</translation> <translation id="3507547268929739059">移除 Chromebook 的 Linux 應用程式</translation> @@ -1757,7 +1755,6 @@ <translation id="3661054927247347545">登入憑證無效,視窗將於 <ph name="MINUTES" /> : <ph name="SECONDS" /> 後關閉</translation> <translation id="3664511988987167893">擴充功能圖示</translation> <translation id="3665589677786828986">Chrome 偵測到另一個程式竄改了部分瀏覽器設定,現已將這些設定重設為原始預設值。</translation> -<translation id="3665842570601375360">安全性:</translation> <translation id="3668570675727296296">語言設定</translation> <translation id="3668823961463113931">處理常式</translation> <translation id="3670229581627177274">開啟藍牙功能</translation> @@ -1796,7 +1793,6 @@ <translation id="3726463242007121105">這個裝置所用的檔案系統不受支援,因此系統無法開啟這個裝置。</translation> <translation id="3727148787322499904">變更這項設定會影響所有共用網路</translation> <translation id="3727187387656390258">檢查彈出式視窗</translation> -<translation id="3728067901555601989">動態密碼:</translation> <translation id="3732078975418297900">第 <ph name="ERROR_LINE" /> 行有錯誤</translation> <translation id="3733127536501031542">具有 Step-Up 功能的 SSL 伺服器</translation> <translation id="3737536731758327622">你的下載內容會顯示在這裡</translation> @@ -1871,7 +1867,6 @@ <translation id="38275787300541712">完成時請按下 Enter 鍵</translation> <translation id="3827774300009121996">全螢幕(&F)</translation> <translation id="3828029223314399057">搜尋書籤</translation> -<translation id="3829932584934971895">供應商類型:</translation> <translation id="3830674330436234648">無法播放</translation> <translation id="3831486154586836914">已進入視窗總覽模式</translation> <translation id="383161972796689579">裝置擁有者已停用新增使用者功能</translation> @@ -1892,6 +1887,7 @@ <translation id="3856921555429624101">已停止監測數據用量</translation> <translation id="3857228364945137633">當手機在適當距離範圍內時,不需密碼即可使用 Smart Lock 為你的 <ph name="DEVICE_TYPE" /> 解鎖。</translation> <translation id="3857773447683694438">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</translation> +<translation id="3860104611854310167"><ph name="PROFILE_NAME" />:已暫停同步處理</translation> <translation id="3860381078714302691">歡迎使用 Hangouts Meet</translation> <translation id="3862134173397075045">歡迎在 Chrome 中體驗 Cast 服務!</translation> <translation id="3862788408946266506">含有「kiosk_only」資訊清單屬性的應用程式只能在 Chrome 作業系統 Kiosk 模式中安裝</translation> @@ -1968,7 +1964,6 @@ <translation id="3968261067169026421">無法設定網路</translation> <translation id="3970114302595058915">ID</translation> <translation id="397105322502079400">計算中…</translation> -<translation id="3974195870082915331">按這裡顯示密碼</translation> <translation id="3975222297214566386">輸入選項方塊</translation> <translation id="397703832102027365">即將完成...</translation> <translation id="3979395879372752341">已新增以下擴充功能:<ph name="EXTENSION_NAME" /></translation> @@ -2010,6 +2005,7 @@ <translation id="4044612648082411741">輸入您的憑證密碼</translation> <translation id="404493185430269859">預設搜尋引擎</translation> <translation id="4047112090469382184">這項功能如何確保裝置安全性</translation> +<translation id="4051049974203704184">取得畫面上內容的相關資訊</translation> <translation id="4052120076834320548">最小</translation> <translation id="4055023634561256217">你必須先重新啟動裝置,才能透過 Powerwash 重設裝置。</translation> <translation id="4057041477816018958"><ph name="SPEED" /> - <ph name="RECEIVED_AMOUNT" /></translation> @@ -2038,6 +2034,7 @@ <translation id="4088095054444612037">接受群組邀請</translation> <translation id="4089235344645910861">設定儲存完畢,已開始同步處理。</translation> <translation id="4090103403438682346">啟用已驗證存取權</translation> +<translation id="4090947011087001172">要重設 <ph name="SITE" /> 的網站權限嗎?</translation> <translation id="4091434297613116013">張紙</translation> <translation id="4093955363990068916">本機檔案:</translation> <translation id="4095507791297118304">主要顯示畫面</translation> @@ -2214,7 +2211,6 @@ <translation id="4419556793104466535">管理同步處理、個人化功能等更多設定</translation> <translation id="4421932782753506458">毛毛</translation> <translation id="4422347585044846479">編輯此網頁的書籤</translation> -<translation id="4423104065312875417">安裝其他語音引擎</translation> <translation id="4423376891418188461">還原設定</translation> <translation id="4423482519432579560">拼字檢查(&S)</translation> <translation id="442397852638519243"><ph name="USER_NAME" />,管理員要求你變更密碼。</translation> @@ -2239,7 +2235,6 @@ <translation id="4449996769074858870">這個分頁正在播放音訊。</translation> <translation id="4450974146388585462">診斷</translation> <translation id="4453946976636652378">執行 <ph name="SEARCH_ENGINE_NAME" /> 搜尋或輸入網址</translation> -<translation id="445923051607553918">加入 Wi-Fi 網路</translation> <translation id="4462159676511157176">自訂名稱伺服器</translation> <translation id="4467100756425880649">Chrome 線上應用程式商店擴充功能庫</translation> <translation id="4467101674048705704">展開「<ph name="FOLDER_NAME" />」</translation> @@ -2375,6 +2370,7 @@ <translation id="4682551433947286597">登入畫面上顯示的桌布。</translation> <translation id="4684427112815847243">同步處理所有資料</translation> <translation id="4689421377817139245">將這個書籤同步到 iPhone 上</translation> +<translation id="4690091457710545971"><Intel Wi-Fi 韌體產生了 4 個檔案:csr.lst、fh_regs.lst、radio_reg.lst 和 monitor.lst.sysmon。前三個檔案為包含暫存器傾印的二進位檔案,且 Intel 表示當中並未包含任何個人資訊或裝置識別資訊。最後一個檔案是 Intel 韌體的執行追蹤記錄,其中的個人資訊或裝置識別資訊已全部遭到清除,但由於檔案過大而無法顯示在這裡。這些檔案的產生原因是裝置的 Wi-Fi 最近出現問題所導致,系統會將檔案提供給 Intel 以協助排解這些問題。></translation> <translation id="4692302215262324251">你的 <ph name="DEVICE_TYPE" /> 已成功註冊企業管理服務,由以下網域管理:<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />。 <ph name="LINE_BREAK_AND_EMPTY_LINE" /> 如果這是未預期的情況,請與支援小組聯絡。</translation> @@ -2633,6 +2629,7 @@ <translation id="5074318175948309511">你可能需要重新載入這個網頁,新設定才會生效。</translation> <translation id="5075131525758602494">輸入 SIM 卡的 PIN 碼</translation> <translation id="5078638979202084724">將所有分頁加入書籤</translation> +<translation id="5079950360618752063">使用建議的密碼</translation> <translation id="5084230410268011727">允許網站使用動作感應器和光源感應器</translation> <translation id="5085162214018721575">正在檢查有無更新</translation> <translation id="5086082738160935172">HID</translation> @@ -2671,6 +2668,7 @@ <translation id="5136529877787728692">F7</translation> <translation id="5137501176474113045">刪除此項目</translation> <translation id="5139955368427980650">開啟(&O)</translation> +<translation id="5142961317498132443">驗證</translation> <translation id="5143374789336132547">擴充功能「<ph name="EXTENSION_NAME" />」已變更您點選 [首頁] 按鈕時所顯示的網頁。</translation> <translation id="5143712164865402236">進入全螢幕</translation> <translation id="5145331109270917438">修改日期</translation> @@ -2841,7 +2839,6 @@ <translation id="5380103295189760361">按住 Ctrl、Alt、Shift 鍵或搜尋鍵,即可查看這些輔助功能的鍵盤快速鍵。</translation> <translation id="5382591305415226340">管理支援的連結</translation> <translation id="5384883051496921101">這個網站即將與外部應用程式分享資訊,分享時會自動退出無痕模式。</translation> -<translation id="5388588172257446328">使用者名稱:</translation> <translation id="5388885445722491159">已配對</translation> <translation id="5389237414310520250">無法建立新的使用者。請檢查您的硬碟空間和權限,然後再試一次。</translation> <translation id="5390100381392048184">允許網站播放音訊</translation> @@ -2966,7 +2963,6 @@ <translation id="5551573675707792127">鍵盤與文字輸入</translation> <translation id="5553089923092577885">憑證政策對應關聯</translation> <translation id="5554489410841842733">當擴充功能適用於目前網頁時,即會顯示此圖示。</translation> -<translation id="5554573843028719904">其他 Wi-Fi 網路...</translation> <translation id="5554720593229208774">電子郵件憑證授權單位</translation> <translation id="5556206011531515970">按一下 [下一步] 選擇你的預設瀏覽器。</translation> <translation id="5556459405103347317">重新載入</translation> @@ -3007,7 +3003,6 @@ <translation id="5610038042047936818">切換至相機模式</translation> <translation id="5612720917913232150"><ph name="URL" /> 要求使用電腦的位置資訊</translation> <translation id="5612734644261457353">很抱歉,系統仍然無法驗證你的密碼。注意:如果你的密碼最近有所異動,新密碼會在你登出後立即生效,目前請在這裡使用舊密碼。</translation> -<translation id="5613695965848159202">匿名身分:</translation> <translation id="5614190747811328134">使用者通知</translation> <translation id="561698261642843490">關閉 Firefox</translation> <translation id="5618075537869101857">糟糕,無法啟動 Kiosk 應用程式。</translation> @@ -3225,7 +3220,6 @@ <translation id="5941343993301164315">請登入 <ph name="TOKEN_NAME" />。</translation> <translation id="5941711191222866238">縮到最小</translation> <translation id="5946591249682680882">報表 ID <ph name="WEBRTC_LOG_REPORT_ID" /></translation> -<translation id="5948544841277865110">新增私人網路</translation> <translation id="5949544233750246342">無法剖析檔案</translation> <translation id="5955282598396714173">你的密碼已過期。如要變更密碼,請先登出然後重新登入。</translation> <translation id="5956585768868398362">這是你想要的搜尋頁面嗎?</translation> @@ -3386,11 +3380,13 @@ <translation id="6198102561359457428">登出然後再次登入...</translation> <translation id="6198252989419008588">變更 PIN</translation> <translation id="6199801702437275229">正在等待空間資訊...</translation> +<translation id="6204015976622790023">查看 Google 助理根據畫面內容提供的實用建議。</translation> <translation id="6205710420833115353">部分作業所需時間超出預期。你想中斷這些作業嗎?</translation> <translation id="6206311232642889873">複製圖片(&Y)</translation> <translation id="6207200176136643843">重設為預設縮放等級</translation> <translation id="620722923698527029">一律使用相關聯的應用程式開啟這類連結</translation> <translation id="6207937957461833379">國家/地區</translation> +<translation id="6211495400987308581"><ph name="PROFILE_NAME" />:同步處理功能無法正常運作</translation> <translation id="6212039847102026977">顯示進階網路屬性</translation> <translation id="6212168817037875041">關閉螢幕</translation> <translation id="6212752530110374741">透過電子郵件傳送連結</translation> @@ -3428,7 +3424,6 @@ <translation id="6263541650532042179">重設同步處理</translation> <translation id="6264365405983206840">選取全部(&A)</translation> <translation id="6264422956566238156">已開啟同步處理功能</translation> -<translation id="6265930187414222160">大功告成!已移除有害軟體。</translation> <translation id="6267166720438879315">請選取你在 <ph name="HOST_NAME" /> 的驗證憑證</translation> <translation id="6268252012308737255">使用「<ph name="APP" />」開啟</translation> <translation id="6268747994388690914">從 HTML 檔案匯入書籤...</translation> @@ -3535,7 +3530,6 @@ 請點選 [下一步] 繼續登入您的 <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 帳戶。</translation> <translation id="6419546358665792306">載入未封裝項目</translation> <translation id="642282551015776456">無法使用這個名稱做為檔案名稱或資料夾名稱</translation> -<translation id="6423239382391657905">OpenVPN</translation> <translation id="6426200009596957090">開啟 ChromeVox 設定</translation> <translation id="6429384232893414837">更新錯誤</translation> <translation id="6430814529589430811">Base64-編碼 ASCII,單一憑證</translation> @@ -3615,7 +3609,6 @@ <translation id="6544215763872433504">Google 提供的網路瀏覽器,滿足你的需求</translation> <translation id="6545665334409411530">重複頻率</translation> <translation id="6545834809683560467">使用預測查詢字串服務,讓系統協助完成你在網址列或應用程式啟動器搜尋框中輸入的搜尋字串或網址</translation> -<translation id="6546686722964485737">加入 Wimax 網路</translation> <translation id="6547316139431024316">不要再顯示這項擴充功能的相關警告訊息</translation> <translation id="6547354035488017500">請釋出至少 512 MB 的空間,否則裝置會無回應。如要釋出空間,請刪除裝置儲存空間內的檔案。</translation> <translation id="6549689063733911810">近期</translation> @@ -4034,7 +4027,6 @@ <translation id="7201014958346994077">無法查看 Linux 檔案</translation> <translation id="720110658997053098">讓裝置永久使用 Kiosk 模式</translation> <translation id="7201118060536064622">已刪除「<ph name="DELETED_ITEM_NAME" />」</translation> -<translation id="7205869271332034173">SSID:</translation> <translation id="7206693748120342859">正在下載 <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{離開網頁}other{離開網頁}}</translation> <translation id="7216409898977639127">行動網路提供者</translation> @@ -4511,7 +4503,6 @@ <translation id="7909969815743704077">已在無痕模式中下載</translation> <translation id="7910768399700579500">新增資料夾(&N)</translation> <translation id="7912080627461681647">伺服器上的密碼已變更。請先登出然後重新登入。</translation> -<translation id="7912883689016444961">設定行動網路</translation> <translation id="7915471803647590281">請將發生的狀況告訴我們,然後再提供意見。</translation> <translation id="7916556741383518510">點擊時</translation> <translation id="792514962475806987">停駐縮放比例:</translation> @@ -4565,7 +4556,6 @@ <translation id="7988355189918024273">啟用協助工具功能</translation> <translation id="7994702968232966508">EAP 方法</translation> <translation id="799547531016638432">移除捷徑</translation> -<translation id="7997479212858899587">身分識別:</translation> <translation id="7997826902155442747">處理優先順序</translation> <translation id="7999229196265990314">已建立下列檔案: @@ -4649,7 +4639,6 @@ <translation id="8105368624971345109">關閉</translation> <translation id="8106045200081704138">與我共用的項目</translation> <translation id="8107015733319732394">正在為 <ph name="DEVICE_TYPE" /> 安裝 Google Play 商店。這可能需要幾分鐘時間。</translation> -<translation id="8109930990200908494">需要使用者憑證才能登入。</translation> <translation id="8111155949205007504">透過 iPhone 分享這個密碼</translation> <translation id="8113043281354018522">選擇授權類型</translation> <translation id="8116190140324504026">更多資訊...</translation> @@ -4660,6 +4649,7 @@ <translation id="8118860139461251237">管理下載內容</translation> <translation id="81238879832906896">黃色和白色花朵</translation> <translation id="8124313775439841391">管理化 ONC</translation> +<translation id="8125562866093998907">這個網站要求驗證你的安全金鑰,以便為你的帳戶提供多一層防護。</translation> <translation id="813082847718468539">查看網站資訊</translation> <translation id="8131740175452115882">確認</translation> <translation id="8133676275609324831">在資料夾中顯示(&S)</translation> @@ -4770,7 +4760,6 @@ <translation id="8308179586020895837">當 <ph name="HOST" /> 要求存取攝影機時詢問我。</translation> <translation id="830868413617744215">測試版</translation> <translation id="8309458809024885768">憑證已存在</translation> -<translation id="8309505303672555187">選擇網路:</translation> <translation id="8312871300878166382">貼入資料夾</translation> <translation id="8317671367883557781">新增網路連線</translation> <translation id="8319414634934645341">擴充金鑰使用方法</translation> @@ -4845,7 +4834,6 @@ <translation id="8451512073679317615">小幫手</translation> <translation id="8452135315243592079">找不到 SIM 卡</translation> <translation id="8453482423012550001">正在複製 $1 個項目...</translation> -<translation id="8454288007744638700">或選取新的網路:</translation> <translation id="845627346958584683">到期時間</translation> <translation id="8456681095658380701">名稱無效</translation> <translation id="8457451314607652708">匯入書籤</translation> @@ -4909,6 +4897,7 @@ <translation id="855081842937141170">固定分頁</translation> <translation id="8551388862522347954">授權</translation> <translation id="8553342806078037065">管理其他使用者</translation> +<translation id="8554899698005018844">未指定語言</translation> <translation id="855773602626431402">已禁止這個網頁執行無沙箱防護的外掛程。</translation> <translation id="8557930019681227453">資訊清單</translation> <translation id="8559694214572302298">影像解碼器</translation> @@ -4946,7 +4935,6 @@ <translation id="862727964348362408">已暫停</translation> <translation id="862750493060684461">CSS 快取</translation> <translation id="8627795981664801467">僅傳送安全性連線的 Cookie</translation> -<translation id="8628085465172583869">伺服器主機名稱:</translation> <translation id="8630903300770275248">匯入受監管的使用者</translation> <translation id="8631032106121706562">朵朵</translation> <translation id="8637542770513281060">你的電腦含有安全模組,用於實作 Chrome 作業系統中許多重要的安全性功能。如需瞭解詳情,請造訪 Chromebook 說明中心:https://support.google.com/chromebook/?p=sm</translation> @@ -5202,7 +5190,6 @@ <translation id="899403249577094719">Netscape 憑證基底網址</translation> <translation id="8995603266996330174">由 <ph name="DOMAIN" /> 管理</translation> <translation id="8996526648899750015">新增帳戶...</translation> -<translation id="8997135628821231"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />] (<ph name="DEVICE" />)</translation> <translation id="8998788483361403036">正在建立磁碟映像檔</translation> <translation id="9003647077635673607">允許在所有網站上執行</translation> <translation id="9003677638446136377">重新檢查</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hi.xtb b/chrome/app/resources/google_chrome_strings_hi.xtb index 8bce10b..a3e05dc 100644 --- a/chrome/app/resources/google_chrome_strings_hi.xtb +++ b/chrome/app/resources/google_chrome_strings_hi.xtb
@@ -52,9 +52,9 @@ <translation id="2290095356545025170">क्या आप वाकई Google Chrome को विस्थापित करना चाहते हैं?</translation> <translation id="2309047409763057870">यह Google Chrome का द्वितीयक इंस्टॉलेशन है और इसे आपका डिफ़ॉल्ट ब्राउज़र नहीं बनाया जा सकता.</translation> <translation id="2334084861041072223">कॉपीराइट <ph name="YEAR" /> Google Inc. सर्वाधिकार सुरक्षित.</translation> -<translation id="2346876346033403680">इस कंप्यूटर पर किसी अन्य व्यक्ति ने <ph name="ACCOUNT_EMAIL_LAST" /> के रूप में Chrome में प्रवेश किया था. यदि वह आपका खाता नहीं है, तो अपनी जानकारी अलग रखने के लिए आप एक नया Chrome उपयोगकर्ता बना सकते हैं. +<translation id="2346876346033403680">इस कंप्यूटर पर किसी अन्य व्यक्ति ने <ph name="ACCOUNT_EMAIL_LAST" /> के रूप में Chrome में साइन इन किया था. अगर वह आपका खाता नहीं है तो, अपनी जानकारी अलग रखने के लिए आप एक नया 'Chrome उपयोगकर्ता' बना सकते हैं. -किसी भी तरह प्रवेश करने से बुकमार्क, इतिहास, और अन्य सेटिंग जैसी Chrome जानकारी <ph name="ACCOUNT_EMAIL_NEW" /> में मर्ज हो जाएगी.</translation> +किसी भी तरह साइन इन करने से बुकमार्क, इतिहास, और अन्य सेटिंग जैसी 'Chrome जानकारी' <ph name="ACCOUNT_EMAIL_NEW" /> में मर्ज हो जाएगी.</translation> <translation id="2348335408836342058">Chrome को इस साइट के लिए आपका कैमरा और माइक्रोफ़ोन एक्सेस करने की अनुमति चाहिए</translation> <translation id="2397416548179033562">Chrome मेनू दिखाएं</translation> <translation id="2429317896000329049">Google Chrome आपका डेटा समन्वयित नहीं कर सका क्योंकि समन्वयन आपके डोमेन के लिए उपलब्ध नहीं है.</translation> @@ -235,7 +235,7 @@ <translation id="7855730255114109580">Google Chrome अप टू डेट है</translation> <translation id="7888186132678118370">Chrome को अपने टास्कबार में पिन करें</translation> <translation id="7890208801193284374">यदि आप कंप्यूटर शेयर करते हैं, तो मित्र और परिवार अलग-अलग ब्राउज़ कर सकते हैं और Chrome को जैसा चाहें सेट कर सकते हैं.</translation> -<translation id="7896673875602241923">इस कंप्यूटर पर पहले किसी अन्य व्यक्ति ने <ph name="ACCOUNT_EMAIL_LAST" /> के रूप में Chrome में प्रवेश किया है. अपनी जानकारी अलग रखने के लिए कृपया नया Chrome उपयोगकर्ता बनाएं.</translation> +<translation id="7896673875602241923">इस कंप्यूटर पर पहले किसी और ने <ph name="ACCOUNT_EMAIL_LAST" /> के रूप में Chrome में साइन इन किया है. अपनी जानकारी अलग रखने के लिए कृपया नया 'Chrome उपयोगकर्ता' बनाएं.</translation> <translation id="7908168227788431038">लगभग अप टू डेट हो गया है! अपडेट करना पूरा करने के लिए Google Chrome को पुन: लॉन्च करें.</translation> <translation id="7962410387636238736">इस कंप्यूटर को अब Google Chrome के अपडेट नहीं मिलेंगे क्योंकि Windows XP और Windows Vista अब काम नहीं करते हैं</translation> <translation id="8005540215158006229">Chrome लगभग तैयार है.</translation>
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp index 007f3de..7de2352 100644 --- a/chrome/app/settings_chromium_strings.grdp +++ b/chrome/app/settings_chromium_strings.grdp
@@ -90,7 +90,7 @@ For added security, Chromium will encrypt your data. </message> <message name="IDS_SETTINGS_SYNC_DISCONNECT_TITLE" desc="The title of the dialog to stop syncing and sign out."> - Sign out of Chromium + Sign out of Chromium? </message> <if expr="not chromeos"> <message name="IDS_SETTINGS_SYNC_SIGN_IN_PROMPT_WITH_NO_ACCOUNT" desc="The text displayed to prompt users to sign in to Chromium.">
diff --git a/chrome/app/settings_google_chrome_strings.grdp b/chrome/app/settings_google_chrome_strings.grdp index 63f3b42..aee7aef 100644 --- a/chrome/app/settings_google_chrome_strings.grdp +++ b/chrome/app/settings_google_chrome_strings.grdp
@@ -90,7 +90,7 @@ For added security, Google Chrome will encrypt your data </message> <message name="IDS_SETTINGS_SYNC_DISCONNECT_TITLE" desc="The title of the dialog to stop syncing and sign out."> - Sign out of Chrome + Sign out of Chrome? </message> <if expr="not chromeos"> <message name="IDS_SETTINGS_SYNC_SIGN_IN_PROMPT_WITH_NO_ACCOUNT" desc="The text displayed to prompt users to sign in to Chrome.">
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 98d6107..c17faeb2 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -310,9 +310,6 @@ <message name="IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION" desc="In the settings tab, the text next to the checkbox to highlight the focused object to make it easier to see."> Highlight the object with keyboard focus when it changes </message> - <message name="IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_HEADING" desc="In the settings tab, the heading above settings related to the keyboard."> - Keyboard - </message> <message name="IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_AND_TEXT_INPUT_HEADING" desc="In the settings tab, the heading above settings related to the keyboard and other text input."> Keyboard and text input </message> @@ -2964,12 +2961,6 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_CONFIRMATION" desc="Text for the dialog that warns about clearing storage used by a site (excluding cookies)."> All data stored by <ph name="SITE">$1<ex>www.example.com</ex></ph> will be deleted, except for cookies. </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_DIALOG_TITLE" desc="Title of the dialog that warns about resetting all permissions for a group of sites."> - Reset site permissions? - </message> - <message name="IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_CONFIRMATION" desc="Text for the dialog that warns about resetting all permissions for a group of sites."> - Sites under <ph name="SITE_GROUP_NAME">$1<ex>google.co.uk</ex></ph> will also be reset. - </message> <message name="IDS_SETTINGS_SITE_SETTINGS_COOKIE_REMOVE_MULTIPLE" desc="Text for the dialog that warns about deleting all site data."> This will delete any data stored on your device for all the sites shown. Do you want to continue? </message> @@ -3389,11 +3380,8 @@ <message name="IDS_SETTINGS_PROFILE_SHORTCUT_TOGGLE_LABEL" desc="Label of the toggle that creates or removes a desktop shortcut for the profile."> Show desktop shortcut </message> - <message name="IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_TITLE" desc="The text to display on the title of the dialog to turn off sync."> - Turn off sync - </message> - <message name="IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_CONFIRM" desc="The text to display on the confirm button of the dialog to turn off sync."> - Continue + <message name="IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE" desc="The text to display on the title of the dialog to turn off sync and sign out."> + Turn off sync and sign out? </message> <message name="IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_MANAGED_CONFIRM" desc="The text to display on the confirm button of the dialog to turn off sync, when the profile is managed by admin."> Clear and continue @@ -3415,6 +3403,9 @@ <message name="IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION" desc="The text to display in the Sign out of Chrome dialog to stop syncing for non-managed profiles."> 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 and can be managed on <ph name="BEGIN_LINK"><a href="$1" target="_blank"><ex><a href="$1" target="_blank"></ex></ph>Google Dashboard<ph name="END_LINK"></a><ex></a></ex></ph>. </message> + <message name="IDS_SETTINGS_SYNC_DISCONNECT_AND_SIGN_OUT_EXPLANATION" desc="The text to display in the Sign out of Chrome dialog to stop syncing and sign-out for non-managed profiles."> + This will sign you out of your Google accounts. 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 and can be managed on <ph name="BEGIN_LINK"><a href="$1" target="_blank"><ex><a href="$1" target="_blank"></ex></ph>Google Dashboard<ph name="END_LINK"></a><ex></a></ex></ph>. + </message> <message name="IDS_SETTINGS_SYNC_DISCONNECT_EXPAND_ACCESSIBILITY_LABEL" desc="Label for the button in the Sign out of Chrome dialog that toggles showing the profile stats. Only visible by screen reader software."> Show profile stats </message>
diff --git a/chrome/app/theme/default_100_percent/chromium/translate_round_32.png b/chrome/app/theme/default_100_percent/chromium/translate_round_32.png new file mode 100644 index 0000000..723806d4 --- /dev/null +++ b/chrome/app/theme/default_100_percent/chromium/translate_round_32.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/chromium/translate_round_32.png b/chrome/app/theme/default_200_percent/chromium/translate_round_32.png new file mode 100644 index 0000000..11466dc --- /dev/null +++ b/chrome/app/theme/default_200_percent/chromium/translate_round_32.png Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 61ad6a1..2b8fab5 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -220,6 +220,7 @@ <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_EASYUNLOCK_ENABLED" file="cros/notification_easyunlock_enabled.png" /> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_EASYUNLOCK_PROMO" file="cros/notification_easyunlock_promo.png" /> </if> + <structure type="chrome_scaled_image" name="IDR_OMNIBOX_TRANSLATION_ROUND" file="chromium/translate_round_32.png" /> <if expr="is_macosx"> <structure type="chrome_scaled_image" name="IDR_OVERLAY_DROP_SHADOW" file="mac/overlay_drop_shadow.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_KEYWORD_HINT_TAB" file="mac/omnibox_keyword_hint_tab.png" />
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index ef9f5e7c5..20c5f72e 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1528,6 +1528,8 @@ "translate/translate_service.h", "undo/bookmark_undo_service_factory.cc", "undo/bookmark_undo_service_factory.h", + "unified_consent/chrome_unified_consent_service_client.cc", + "unified_consent/chrome_unified_consent_service_client.h", "unified_consent/unified_consent_service_factory.cc", "unified_consent/unified_consent_service_factory.h", "update_client/chrome_update_query_params_delegate.cc", @@ -1903,8 +1905,6 @@ "android/android_theme_resources.h", "android/app_hooks.cc", "android/app_hooks.h", - "android/appmenu/app_menu_drag_helper.cc", - "android/appmenu/app_menu_drag_helper.h", "android/background_sync_launcher_android.cc", "android/background_sync_launcher_android.h", "android/background_tab_manager.cc", @@ -4320,7 +4320,6 @@ "../android/java/src/org/chromium/chrome/browser/WarmupManager.java", "../android/java/src/org/chromium/chrome/browser/WebContentsFactory.java", "../android/java/src/org/chromium/chrome/browser/accessibility/FontSizePrefs.java", - "../android/java/src/org/chromium/chrome/browser/appmenu/AppMenuDragHelper.java", "../android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java", "../android/java/src/org/chromium/chrome/browser/autofill/AutofillLogger.java", "../android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index f519f9bf..f1eb0718 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -42,6 +42,7 @@ "+mash/public/mojom", "+media/audio", # For media audio hang monitor. "+media/base", # For media switches + "+media/capabilities", # For InMemoryVideoDecodeStatsDB "+media/cdm/cdm_paths.h", "+media/capture", "+media/midi", # For midi switches
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 1107a0f..70e0444 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/predictors/loading_predictor_config.h" #include "chrome/browser/predictors/resource_prefetch_common.h" #include "chrome/browser/prerender/prerender_field_trial.h" +#include "chrome/browser/resource_coordinator/tab_manager_features.h" #include "chrome/browser/search/ntp_features.h" #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h" #include "chrome/browser/ui/blocked_content/tab_under_navigation_throttle.h" @@ -120,6 +121,7 @@ #include "services/device/public/cpp/device_features.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/network_switches.h" +#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" #include "services/service_manager/sandbox/switches.h" #include "third_party/blink/public/common/experiments/memory_ablation_experiment.h" #include "third_party/libaom/av1_buildflags.h" @@ -860,47 +862,6 @@ arraysize(kAutofillCreditCardLastUsedDateFeatureVariationExpDate), nullptr}}; -const FeatureEntry::FeatureParam kMemoryAblation5MiB_512[] = { - {blink::kMemoryAblationFeatureSizeParam, "5242880"}, - {blink::kMemoryAblationFeatureMaxRAMParam, "512"}}; -const FeatureEntry::FeatureParam kMemoryAblation10MiB_512_1024[] = { - {blink::kMemoryAblationFeatureSizeParam, "10485760"}, - {blink::kMemoryAblationFeatureMinRAMParam, "512"}, - {blink::kMemoryAblationFeatureMaxRAMParam, "1024"}}; -const FeatureEntry::FeatureParam kMemoryAblation20MiB_1024_2048[] = { - {blink::kMemoryAblationFeatureSizeParam, "20971520"}, - {blink::kMemoryAblationFeatureMinRAMParam, "1024"}, - {blink::kMemoryAblationFeatureMaxRAMParam, "2048"}}; -const FeatureEntry::FeatureParam kMemoryAblation30MiB[] = { - {blink::kMemoryAblationFeatureSizeParam, "31457280"}}; -const FeatureEntry::FeatureParam kMemoryAblation40MiB_512_4096[] = { - {blink::kMemoryAblationFeatureSizeParam, "41943040"}, - {blink::kMemoryAblationFeatureMinRAMParam, "512"}, - {blink::kMemoryAblationFeatureMaxRAMParam, "4096"}}; -const FeatureEntry::FeatureParam kMemoryAblation50MiB_2048_4096[] = { - {blink::kMemoryAblationFeatureSizeParam, "52428800"}, - {blink::kMemoryAblationFeatureMinRAMParam, "2048"}, - {blink::kMemoryAblationFeatureMaxRAMParam, "4096"}}; -const FeatureEntry::FeatureParam kMemoryAblation100MiB_4096[] = { - {blink::kMemoryAblationFeatureSizeParam, "104857600"}, - {blink::kMemoryAblationFeatureMinRAMParam, "4096"}}; - -const FeatureEntry::FeatureVariation kMemoryAblationFeatureVariations[] = { - {"5 MiB (RAM <= 512)", kMemoryAblation5MiB_512, - arraysize(kMemoryAblation5MiB_512), nullptr}, - {"10 MiB (512 <= RAM <= 1024)", kMemoryAblation10MiB_512_1024, - arraysize(kMemoryAblation10MiB_512_1024), nullptr}, - {"20 MiB (1024 <= RAM <= 2048)", kMemoryAblation20MiB_1024_2048, - arraysize(kMemoryAblation20MiB_1024_2048), nullptr}, - {"30 MiB (any RAM)", kMemoryAblation30MiB, arraysize(kMemoryAblation30MiB), - nullptr}, - {"40 MiB (512 <= RAM <= 4096)", kMemoryAblation40MiB_512_4096, - arraysize(kMemoryAblation40MiB_512_4096), nullptr}, - {"50 MiB (2048 <= RAM <= 4096)", kMemoryAblation50MiB_2048_4096, - arraysize(kMemoryAblation50MiB_2048_4096), nullptr}, - {"100 MiB (RAM >= 4096)", kMemoryAblation100MiB_4096, - arraysize(kMemoryAblation100MiB_4096), nullptr}}; - #if defined(OS_ANDROID) const FeatureEntry::FeatureParam kPersistentMenuItemEnabled[] = { {"persistent_menu_item_enabled", "true"}}; @@ -1162,6 +1123,24 @@ }; #endif // defined(OS_ANDROID) +#if !defined(OS_ANDROID) +const FeatureEntry::FeatureParam kProactiveTabFreezeAndDiscard_FreezeOnly[] = { + {resource_coordinator:: + kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscard, + "false"}}; +const FeatureEntry::FeatureParam + kProactiveTabFreezeAndDiscard_FreezeAndDiscard[] = { + {resource_coordinator:: + kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscard, + "true"}}; + +const FeatureEntry::FeatureVariation kProactiveTabFreezeAndDiscardVariations[] = + {{"Freeze only", kProactiveTabFreezeAndDiscard_FreezeOnly, + base::size(kProactiveTabFreezeAndDiscard_FreezeOnly), nullptr}, + {"Freeze and discard", kProactiveTabFreezeAndDiscard_FreezeAndDiscard, + base::size(kProactiveTabFreezeAndDiscard_FreezeAndDiscard), nullptr}}; +#endif + // RECORDING USER METRICS FOR FLAGS: // ----------------------------------------------------------------------------- // The first line of the entry is the internal name. @@ -1465,7 +1444,7 @@ #if defined(OS_CHROMEOS) {"ash-enable-cursor-motion-blur", flag_descriptions::kEnableCursorMotionBlurName, - flag_descriptions::kEnableCursorMotionBlurDescription, kOsAll, + flag_descriptions::kEnableCursorMotionBlurDescription, kOsCrOS, SINGLE_VALUE_TYPE(ash::switches::kAshEnableCursorMotionBlur)}, {"ash-enable-docked-magnifier", flag_descriptions::kEnableDockedMagnifierName, @@ -1846,6 +1825,9 @@ flag_descriptions::kTranslateRankerEnforcementName, flag_descriptions::kTranslateRankerEnforcementDescription, kOsAll, FEATURE_VALUE_TYPE(translate::kTranslateRankerEnforcement)}, + {"translate", flag_descriptions::kTranslateUIName, + flag_descriptions::kTranslateUIDescription, kOsAll, + FEATURE_VALUE_TYPE(translate::kTranslateUI)}, #if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) && !defined(OS_CHROMEOS) {"enable-native-notifications", flag_descriptions::kNotificationsNativeFlagName, @@ -3053,12 +3035,6 @@ MULTI_VALUE_TYPE(kAshUiModeChoices)}, #endif // OS_CHROMEOS - {"memory-ablation", flag_descriptions::kMemoryAblationName, - flag_descriptions::kMemoryAblationDescription, kOsAll, - FEATURE_WITH_PARAMS_VALUE_TYPE(blink::kMemoryAblationFeature, - kMemoryAblationFeatureVariations, - "MemoryAblation")}, - #if defined(OS_ANDROID) {"enable-command-line-on-non-rooted-devices", flag_descriptions::kEnableCommandLineOnNonRootedName, @@ -3963,6 +3939,26 @@ flag_descriptions::kEnableEphemeralFlashPermissionDescription, kOsDesktop, SINGLE_VALUE_TYPE(switches::kEnableEphemeralFlashPermission)}, +#if !defined(OS_ANDROID) + {"infinite-session-restore", flag_descriptions::kInfiniteSessionRestoreName, + flag_descriptions::kInfiniteSessionRestoreDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kInfiniteSessionRestore)}, + {"page-almost-idle", flag_descriptions::kPageAlmostIdleName, + flag_descriptions::kPageAlmostIdleDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kPageAlmostIdle)}, + {"proactive-tab-freeze-and-discard", + flag_descriptions::kProactiveTabFreezeAndDiscardName, + flag_descriptions::kProactiveTabFreezeAndDiscardDescription, kOsDesktop, + FEATURE_WITH_PARAMS_VALUE_TYPE( + features::kProactiveTabFreezeAndDiscard, + kProactiveTabFreezeAndDiscardVariations, + features::kProactiveTabFreezeAndDiscard.name)}, + {"site-characteristics-database", + flag_descriptions::kSiteCharacteristicsDatabaseName, + flag_descriptions::kSiteCharacteristicsDatabaseDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kSiteCharacteristicsDatabase)}, +#endif + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc b/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc index bef00cf..5345f78 100644 --- a/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc +++ b/chrome/browser/accessibility/accessibility_extension_api_browsertest.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "ui/base/ui_base_features.h" namespace extensions { @@ -13,7 +13,7 @@ #if defined(OS_CHROMEOS) IN_PROC_BROWSER_TEST_F(AccessibilityPrivateApiTest, SendSyntheticKeyEvent) { // Not yet supported on mash. - if (chromeos::GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return; ASSERT_TRUE(RunExtensionSubtest("accessibility_private/",
diff --git a/chrome/browser/android/OWNERS b/chrome/browser/android/OWNERS index 731c0eaba..132a6d7 100644 --- a/chrome/browser/android/OWNERS +++ b/chrome/browser/android/OWNERS
@@ -1,6 +1,5 @@ bauerb@chromium.org dtrainor@chromium.org -mariakhomenko@chromium.org nyquist@chromium.org tedchoc@chromium.org yfriedman@chromium.org
diff --git a/chrome/browser/android/appmenu/app_menu_drag_helper.cc b/chrome/browser/android/appmenu/app_menu_drag_helper.cc deleted file mode 100644 index ef17bd1..0000000 --- a/chrome/browser/android/appmenu/app_menu_drag_helper.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/metrics/histogram_macros.h" -#include "jni/AppMenuDragHelper_jni.h" - -using base::android::JavaParamRef; - -// static -void JNI_AppMenuDragHelper_RecordAppMenuTouchDuration( - JNIEnv* env, - const JavaParamRef<jclass>& jcaller, - jlong time_ms) { - UMA_HISTOGRAM_TIMES("WrenchMenu.TouchDuration", - base::TimeDelta::FromMilliseconds(time_ms)); -}
diff --git a/chrome/browser/android/content/content_utils.cc b/chrome/browser/android/content/content_utils.cc index 06a62d4b..4a3267c 100644 --- a/chrome/browser/android/content/content_utils.cc +++ b/chrome/browser/android/content/content_utils.cc
@@ -6,8 +6,6 @@ #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "chrome/common/chrome_content_client.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/user_agent.h" #include "jni/ContentUtils_jni.h" static base::android::ScopedJavaLocalRef<jstring> @@ -16,17 +14,3 @@ const base::android::JavaParamRef<jclass>& clazz) { return base::android::ConvertUTF8ToJavaString(env, GetUserAgent()); } - -static void JNI_ContentUtils_SetUserAgentOverride( - JNIEnv* env, - const base::android::JavaParamRef<jclass>& clazz, - const base::android::JavaParamRef<jobject>& jweb_contents) { - const char kLinuxInfoStr[] = "X11; Linux x86_64"; - ChromeContentClient content_client; - std::string product = content_client.GetProduct(); - std::string spoofed_ua = - content::BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product); - content::WebContents* web_contents = - content::WebContents::FromJavaWebContents(jweb_contents); - web_contents->SetUserAgentOverride(spoofed_ua, false); -}
diff --git a/chrome/browser/android/explore_sites/explore_sites_bridge.cc b/chrome/browser/android/explore_sites/explore_sites_bridge.cc index 0c0d902..7d39ada 100644 --- a/chrome/browser/android/explore_sites/explore_sites_bridge.cc +++ b/chrome/browser/android/explore_sites/explore_sites_bridge.cc
@@ -16,10 +16,11 @@ #include "chrome/browser/search/suggestions/image_decoder_impl.h" #include "components/image_fetcher/core/image_fetcher.h" #include "components/image_fetcher/core/image_fetcher_impl.h" +#include "content/public/browser/storage_partition.h" #include "jni/ExploreSitesBridge_jni.h" #include "jni/ExploreSitesCategoryTile_jni.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/image/image.h" @@ -113,10 +114,11 @@ const JavaParamRef<jobject>& j_callback_obj) { Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); GURL icon_url(ConvertJavaStringToUTF8(env, j_url)); - scoped_refptr<net::URLRequestContextGetter> request_context = - profile->GetRequestContext(); + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory = + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess(); auto image_fetcher = std::make_unique<image_fetcher::ImageFetcherImpl>( - std::make_unique<suggestions::ImageDecoderImpl>(), request_context.get()); + std::make_unique<suggestions::ImageDecoderImpl>(), url_loader_factory); // |image_fetcher| will be owned by the callback and gets destroyed at the end // of the callback. image_fetcher::ImageFetcher* image_fetcher_ptr = image_fetcher.get();
diff --git a/chrome/browser/android/explore_sites/ntp_json_fetcher.cc b/chrome/browser/android/explore_sites/ntp_json_fetcher.cc index 2cd122d..c8e5ce5b 100644 --- a/chrome/browser/android/explore_sites/ntp_json_fetcher.cc +++ b/chrome/browser/android/explore_sites/ntp_json_fetcher.cc
@@ -12,6 +12,7 @@ #include "base/metrics/field_trial_params.h" #include "base/values.h" #include "chrome/browser/android/chrome_feature_list.h" +#include "chrome/browser/android/explore_sites/url_util.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/service_manager_connection.h" @@ -28,27 +29,6 @@ namespace { -std::string GetBaseURLFromFieldTrial() { - const char kBaseURLOption[] = "base_url"; - const char kDefaultBaseUrl[] = - "https://explore-sites-ux-research.appspot.com"; - std::string field_trial_param = base::GetFieldTrialParamValueByFeature( - chrome::android::kExploreSites, kBaseURLOption); - if (field_trial_param.empty()) - return kDefaultBaseUrl; - return field_trial_param; -} - -GURL GetExploreSitesNtpURL() { - const char kNtpJsonPath[] = "/ntp.json"; - std::string path(kNtpJsonPath); - - GURL base_url(GetBaseURLFromFieldTrial()); - GURL::Replacements replacements; - replacements.SetPathStr(path); - return base_url.ReplaceComponents(replacements); -} - const int kMaxRetries = 3; const int kMaxJsonSize = 1000000; // 1Mb @@ -86,7 +66,7 @@ "This feature is only enabled explicitly by flag." })"); auto resource_request = std::make_unique<network::ResourceRequest>(); - resource_request->url = GetExploreSitesNtpURL(); + resource_request->url = GetNtpURL(); simple_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), traffic_annotation); network::mojom::URLLoaderFactory* loader_factory = @@ -139,7 +119,7 @@ } void NTPJsonFetcher::OnJsonParseError(const std::string& error) { - DVLOG(1) << "Unable to parse NTP JSON from " << GetExploreSitesNtpURL() + DVLOG(1) << "Unable to parse NTP JSON from " << GetNtpURL() << " error: " << error; std::move(callback_).Run(nullptr); }
diff --git a/chrome/browser/android/feed/feed_host_service_factory.cc b/chrome/browser/android/feed/feed_host_service_factory.cc index 260b494..56a35d5 100644 --- a/chrome/browser/android/feed/feed_host_service_factory.cc +++ b/chrome/browser/android/feed/feed_host_service_factory.cc
@@ -71,11 +71,10 @@ identity_manager, api_key, storage_partition->GetURLLoaderFactoryForBrowserProcess()); - scoped_refptr<net::URLRequestContextGetter> request_context = - profile->GetRequestContext(); - auto image_fetcher = std::make_unique<image_fetcher::ImageFetcherImpl>( - std::make_unique<suggestions::ImageDecoderImpl>(), request_context.get()); + std::make_unique<suggestions::ImageDecoderImpl>(), + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess()); base::FilePath feed_dir(profile->GetPath().Append(kFeedFolder)); auto image_database = std::make_unique<FeedImageDatabase>(feed_dir);
diff --git a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc index fb6c0e1..0f3ac648 100644 --- a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc +++ b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.cc
@@ -16,6 +16,22 @@ #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "jni/InstantAppsInfoBarDelegate_jni.h" +#include "ui/base/page_transition_types.h" + +namespace { + +bool PageTransitionInitiatedByUser( + content::NavigationHandle* navigation_handle) { + auto page_transition = navigation_handle->GetPageTransition(); + return navigation_handle->HasUserGesture() || + (page_transition & ui::PAGE_TRANSITION_FORWARD_BACK) || + (page_transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) || + (page_transition & ui::PAGE_TRANSITION_HOME_PAGE) || + ui::PageTransitionCoreTypeIs(page_transition, + ui::PAGE_TRANSITION_TYPED); +} + +} // namespace InstantAppsInfoBarDelegate::~InstantAppsInfoBarDelegate() {} @@ -39,7 +55,7 @@ bool instant_app_is_default) : content::WebContentsObserver(web_contents), url_(url), - has_navigated_away_from_launch_url_(false), + user_navigated_away_from_launch_url_(false), instant_app_is_default_(instant_app_is_default) { JNIEnv* env = base::android::AttachCurrentThread(); java_delegate_.Reset(Java_InstantAppsInfoBarDelegate_create(env)); @@ -90,9 +106,11 @@ void InstantAppsInfoBarDelegate::DidStartNavigation( content::NavigationHandle* navigation_handle) { - if (!GURL(url_).EqualsIgnoringRef( + if (!user_navigated_away_from_launch_url_ && + !GURL(url_).EqualsIgnoringRef( navigation_handle->GetWebContents()->GetURL())) { - has_navigated_away_from_launch_url_ = true; + user_navigated_away_from_launch_url_ = + PageTransitionInitiatedByUser(navigation_handle); } } @@ -105,7 +123,7 @@ bool InstantAppsInfoBarDelegate::ShouldExpire( const NavigationDetails& details) const { - return has_navigated_away_from_launch_url_ && + return user_navigated_away_from_launch_url_ && ConfirmInfoBarDelegate::ShouldExpire(details); }
diff --git a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h index 19e129d..c04ad25 100644 --- a/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h +++ b/chrome/browser/android/instantapps/instant_apps_infobar_delegate.h
@@ -50,7 +50,7 @@ base::android::ScopedJavaGlobalRef<jobject> java_delegate_; base::android::ScopedJavaGlobalRef<jobject> data_; std::string url_; - bool has_navigated_away_from_launch_url_; + bool user_navigated_away_from_launch_url_; bool instant_app_is_default_; DISALLOW_COPY_AND_ASSIGN(InstantAppsInfoBarDelegate);
diff --git a/chrome/browser/android/locale/OWNERS b/chrome/browser/android/locale/OWNERS index d758086..94b86d4 100644 --- a/chrome/browser/android/locale/OWNERS +++ b/chrome/browser/android/locale/OWNERS
@@ -1 +1 @@ -mariakhomenko@chromium.org +yusufo@chromium.org
diff --git a/chrome/browser/android/metrics/OWNERS b/chrome/browser/android/metrics/OWNERS index b618f9a..3dc913a 100644 --- a/chrome/browser/android/metrics/OWNERS +++ b/chrome/browser/android/metrics/OWNERS
@@ -1,4 +1,3 @@ asvitkine@chromium.org -mariakhomenko@chromium.org # COMPONENT: Internals>Metrics
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc index 9ca6aab4..fd6fb396 100644 --- a/chrome/browser/android/tab_android.cc +++ b/chrome/browser/android/tab_android.cc
@@ -436,6 +436,7 @@ env, jweb_contents_delegate); web_contents_delegate_->LoadProgressChanged(web_contents(), 0); web_contents()->SetDelegate(web_contents_delegate_.get()); + notification_registrar_.Add( this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
diff --git a/chrome/browser/android/vr/vr_shell_gl.cc b/chrome/browser/android/vr/vr_shell_gl.cc index 50696bf..b2e4462 100644 --- a/chrome/browser/android/vr/vr_shell_gl.cc +++ b/chrome/browser/android/vr/vr_shell_gl.cc
@@ -863,7 +863,6 @@ showing_vr_dialog_ = true; vr_dialog_input_delegate_.reset(new PlatformUiInputDelegate(input_handler)); vr_dialog_input_delegate_->SetSize(width, height); - vr_dialog_input_delegate_->SetPlatformController(controller_.get()); ui_->SetAlertDialogEnabled(true, vr_dialog_input_delegate_.get(), width / content_tex_buffer_size_.width(), height / content_tex_buffer_size_.width()); @@ -1024,7 +1023,6 @@ void VrShellGl::GvrInit(gvr_context* gvr_api) { gvr_api_ = gvr::GvrApi::WrapNonOwned(gvr_api); controller_.reset(new VrController(gvr_api)); - ui_->OnPlatformControllerInitialized(controller_.get()); MetricsUtilAndroid::LogVrViewerType(gvr_api_->GetViewerType()); @@ -1254,6 +1252,11 @@ controller_model.touchpad_touch_position = gfx::PointF(controller_->TouchPosX(), controller_->TouchPosY()); controller_model.app_button_long_pressed = app_button_long_pressed_; + controller_model.last_orientation_timestamp = + controller_->GetLastOrientationTimestamp(); + controller_model.last_touch_timestamp = controller_->GetLastTouchTimestamp(); + controller_model.last_button_timestamp = + controller_->GetLastButtonTimestamp(); if (!test_controller_model_queue_.empty()) { cached_test_controller_model_ = test_controller_model_queue_.front();
diff --git a/chrome/browser/ash_service_registry.cc b/chrome/browser/ash_service_registry.cc index c4f62e7..e49da3c 100644 --- a/chrome/browser/ash_service_registry.cc +++ b/chrome/browser/ash_service_registry.cc
@@ -67,14 +67,12 @@ void RegisterOutOfProcessServices( ContentBrowserClient::OutOfProcessServiceMap* services) { - if (base::FeatureList::IsEnabled(features::kMash)) { - RegisterOutOfProcessServicesImpl(kCommonServices, - base::size(kCommonServices), services); + RegisterOutOfProcessServicesImpl(kCommonServices, base::size(kCommonServices), + services); + if (base::FeatureList::IsEnabled(features::kMash) || + base::FeatureList::IsEnabled(features::kOopAsh)) { RegisterOutOfProcessServicesImpl(kMashServices, base::size(kMashServices), services); - } else { - RegisterOutOfProcessServicesImpl(kCommonServices, - base::size(kCommonServices), services); } } @@ -91,7 +89,8 @@ (*services)[ash::mojom::kPrefConnectorServiceName] = info; } - if (base::FeatureList::IsEnabled(features::kMash)) + if (base::FeatureList::IsEnabled(features::kMash) || + base::FeatureList::IsEnabled(features::kOopAsh)) return; (*services)[ash::mojom::kServiceName] =
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index d2fb3a3..c61a9acd 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -145,9 +145,7 @@ #include "chrome/browser/chrome_browser_main_mac.h" #endif -#if defined(OS_CHROMEOS) -#include "chrome/browser/ui/ash/ash_util.h" -#else +#if !defined(OS_CHROMEOS) #include "ui/message_center/message_center.h" #endif
diff --git a/chrome/browser/browser_process_platform_part_chromeos.cc b/chrome/browser/browser_process_platform_part_chromeos.cc index 61447ca..b472611 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.cc +++ b/chrome/browser/browser_process_platform_part_chromeos.cc
@@ -12,7 +12,6 @@ #include "base/time/tick_clock.h" #include "chrome/browser/ash_service_registry.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/chrome_service_name.h" #include "chrome/browser/chromeos/login/session/chrome_session_manager.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h" @@ -46,6 +45,7 @@ #include "services/ui/public/cpp/input_devices/input_device_controller.h" #include "services/ui/public/cpp/input_devices/input_device_controller_client.h" #include "services/ui/public/interfaces/constants.mojom.h" +#include "ui/base/ui_base_features.h" BrowserProcessPlatformPart::BrowserProcessPlatformPart() : created_profile_helper_(false), @@ -200,10 +200,9 @@ ui::InputDeviceControllerClient* BrowserProcessPlatformPart::GetInputDeviceControllerClient() { if (!input_device_controller_client_) { - const std::string service_name = - chromeos::GetAshConfig() == ash::Config::CLASSIC - ? chromeos::kChromeServiceName - : ui::mojom::kServiceName; + const std::string service_name = features::IsAshInBrowserProcess() + ? chromeos::kChromeServiceName + : ui::mojom::kServiceName; input_device_controller_client_ = std::make_unique<ui::InputDeviceControllerClient>( content::ServiceManagerConnection::GetForProcess()->GetConnector(),
diff --git a/chrome/browser/chrome_content_browser_client_browsertest_chromeos.cc b/chrome/browser/chrome_content_browser_client_browsertest_chromeos.cc index 2729fcdb..919e9b8 100644 --- a/chrome/browser/chrome_content_browser_client_browsertest_chromeos.cc +++ b/chrome/browser/chrome_content_browser_client_browsertest_chromeos.cc
@@ -10,13 +10,13 @@ #include "base/files/file_util.h" #include "base/run_loop.h" #include "base/threading/thread_restrictions.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/browser/browser_child_process_host_iterator.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" #include "content/public/common/process_type.h" +#include "ui/base/ui_base_features.h" using content::BrowserChildProcessHostIterator; using content::BrowserThread; @@ -53,7 +53,7 @@ // Verifies that mash service child processes use in-process breakpad crash // dumping. IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientMashTest, CrashReporter) { - if (chromeos::GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) return; // Child process management lives on the IO thread.
diff --git a/chrome/browser/chrome_main_browsertest.cc b/chrome/browser/chrome_main_browsertest.cc index e644e67..6b9a6cc675 100644 --- a/chrome/browser/chrome_main_browsertest.cc +++ b/chrome/browser/chrome_main_browsertest.cc
@@ -55,7 +55,7 @@ GURL url = net::FilePathToFileURL(test_file_path); content::WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(url, tab->GetController().GetActiveEntry()->GetVirtualURL()); + ASSERT_EQ(url, tab->GetVisibleURL()); } // ChromeMainTest.SecondLaunchWithIncognitoUrl is flaky on Win and Linux.
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 57cc941..601f66f 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -467,8 +467,6 @@ "arc/voice_interaction/voice_interaction_controller_client.h", "arc/wallpaper/arc_wallpaper_service.cc", "arc/wallpaper/arc_wallpaper_service.h", - "ash_config.cc", - "ash_config.h", "attestation/attestation_ca_client.cc", "attestation/attestation_ca_client.h", "attestation/attestation_policy_observer.cc", @@ -642,6 +640,8 @@ "file_manager/app_id.h", "file_manager/arc_file_tasks.cc", "file_manager/arc_file_tasks.h", + "file_manager/crostini_file_tasks.cc", + "file_manager/crostini_file_tasks.h", "file_manager/file_browser_handlers.cc", "file_manager/file_browser_handlers.h", "file_manager/file_tasks.cc", @@ -1065,9 +1065,6 @@ "login/screens/network_error.cc", "login/screens/network_error.h", "login/screens/network_error_view.h", - "login/screens/network_screen.cc", - "login/screens/network_screen.h", - "login/screens/network_view.h", "login/screens/recommend_apps_screen.cc", "login/screens/recommend_apps_screen.h", "login/screens/recommend_apps_screen_view.h", @@ -1099,6 +1096,9 @@ "login/screens/wait_for_container_ready_screen.cc", "login/screens/wait_for_container_ready_screen.h", "login/screens/wait_for_container_ready_screen_view.h", + "login/screens/welcome_screen.cc", + "login/screens/welcome_screen.h", + "login/screens/welcome_view.h", "login/screens/wrong_hwid_screen.cc", "login/screens/wrong_hwid_screen.h", "login/screens/wrong_hwid_screen_view.h", @@ -1826,10 +1826,10 @@ "login/screens/mock_error_screen.h", "login/screens/mock_model_view_channel.cc", "login/screens/mock_model_view_channel.h", - "login/screens/mock_network_screen.cc", - "login/screens/mock_network_screen.h", "login/screens/mock_update_screen.cc", "login/screens/mock_update_screen.h", + "login/screens/mock_welcome_screen.cc", + "login/screens/mock_welcome_screen.h", "scoped_set_running_on_chromeos_for_testing.cc", "scoped_set_running_on_chromeos_for_testing.h", ] @@ -2025,8 +2025,8 @@ "login/quick_unlock/pin_storage_prefs_unittest.cc", "login/quick_unlock/quick_unlock_storage_unittest.cc", "login/saml/saml_offline_signin_limiter_unittest.cc", - "login/screens/network_screen_unittest.cc", "login/screens/update_screen_unittest.cc", + "login/screens/welcome_screen_unittest.cc", "login/signin/merge_session_load_page_unittest.cc", "login/signin_partition_manager_unittest.cc", "login/supervised/supervised_user_authentication_unittest.cc",
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index dae1e72..d0f3242 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -38,7 +38,6 @@ #include "chrome/browser/chromeos/accessibility/select_to_speak_event_handler.h" #include "chrome/browser/chromeos/accessibility/switch_access_event_handler.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/api/braille_display_private/stub_braille_controller.h" @@ -81,6 +80,7 @@ #include "ui/accessibility/ax_enum_util.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_features.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_observer.h" #include "url/gurl.h" @@ -320,7 +320,7 @@ return; // TODO(crbug.com/594887): Fix for mash by moving pref into ash. - if (GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return; // Update system tray menu visibility. @@ -860,7 +860,7 @@ bool show_message) { // Sticky keys is implemented only in ash. // TODO(dpolukhin): support Athena, crbug.com/408733. - if (GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { ash::Shell::Get()->sticky_keys_controller()->SetModifiersEnabled( manager->IsISOLevel5ShiftUsedByCurrentInputMethod(), manager->IsAltGrUsedByCurrentInputMethod()); @@ -999,7 +999,7 @@ callback_list_.Notify(details); // TODO(crbug.com/594887): Fix for mash by moving pref into ash. - if (GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return; if (details.notification_type == ACCESSIBILITY_TOGGLE_DICTATION) {
diff --git a/chrome/browser/chromeos/accessibility/chromevox_panel.cc b/chrome/browser/chromeos/accessibility/chromevox_panel.cc index 58136f63..02756b7 100644 --- a/chrome/browser/chromeos/accessibility/chromevox_panel.cc +++ b/chrome/browser/chromeos/accessibility/chromevox_panel.cc
@@ -9,7 +9,6 @@ #include "ash/public/interfaces/constants.mojom.h" #include "base/macros.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/data_use_measurement/data_use_web_contents_observer.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" @@ -19,6 +18,7 @@ #include "extensions/browser/view_type_utils.h" #include "extensions/common/constants.h" #include "services/service_manager/public/cpp/connector.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/views/controls/webview/webview.h" @@ -109,7 +109,7 @@ // TODO(jamescook|fsamuel): Fix this. It causes a white flash when opening the // window. The underlying problem is FrameToken plumbing, see // ui::ws::ServerWindow::OnFrameTokenChanged. https://crbug.com/771331 - if (chromeos::GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) widget_->Show(); }
diff --git a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc index 90b03f1..1d9a23d7 100644 --- a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc
@@ -33,6 +33,7 @@ #include "extensions/browser/notification_types.h" #include "extensions/browser/process_manager.h" #include "services/service_manager/public/cpp/connector.h" +#include "ui/base/material_design/material_design_controller.h" #include "ui/events/test/event_generator.h" #include "url/url_constants.h" @@ -80,16 +81,24 @@ SpeechMonitor speech_monitor_; std::unique_ptr<ui::test::EventGenerator> generator_; + gfx::Rect GetWebContentsBounds() const { + // TODO(katie): Find a way to get the exact bounds programmatically. + gfx::Rect bounds = browser()->window()->GetBounds(); + const int top_inset = ui::MaterialDesignController::IsRefreshUi() ? 75 : 50; + bounds.Inset(8, 8, top_inset, 8); + return bounds; + } + void ActivateSelectToSpeakInWindowBounds(std::string url) { ui_test_utils::NavigateToURL(browser(), GURL(url)); - gfx::Rect bounds = browser()->window()->GetBounds(); + gfx::Rect bounds = GetWebContentsBounds(); - // Hold down Search and click a few pixels into the window bounds. + // Hold down Search and drag over the web contents to select everything. generator_->PressKey(ui::VKEY_LWIN, 0 /* flags */); - generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 50); + generator_->MoveMouseTo(bounds.x(), bounds.y()); generator_->PressLeftButton(); - generator_->MoveMouseTo(bounds.x() + bounds.width() - 8, - bounds.y() + bounds.height() - 8); + generator_->MoveMouseTo(bounds.x() + bounds.width(), + bounds.y() + bounds.height()); generator_->ReleaseLeftButton(); generator_->ReleaseKey(ui::VKEY_LWIN, 0 /* flags */); } @@ -183,11 +192,11 @@ // start speech. ui_test_utils::NavigateToURL( browser(), GURL("data:text/html;charset=utf-8,<p>This is some text</p>")); - gfx::Rect bounds = browser()->window()->GetBounds(); - generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 8); + gfx::Rect bounds = GetWebContentsBounds(); + generator_->MoveMouseTo(bounds.x(), bounds.y()); generator_->PressLeftButton(); - generator_->MoveMouseTo(bounds.x() + bounds.width() - 8, - bounds.y() + bounds.height() - 8); + generator_->MoveMouseTo(bounds.x() + bounds.width(), + bounds.y() + bounds.height()); generator_->ReleaseLeftButton(); EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), @@ -292,10 +301,10 @@ ui_test_utils::NavigateToURL(browser(), GURL("data:text/html;charset=utf-8," "<p>This is some text</p>")); - gfx::Rect bounds = browser()->window()->GetBounds(); + gfx::Rect bounds = GetWebContentsBounds(); PrepareToWaitForFocusRingChanged(); generator_->PressKey(ui::VKEY_LWIN, 0 /* flags */); - generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 50); + generator_->MoveMouseTo(bounds.x(), bounds.y()); generator_->PressLeftButton(); // Expect a focus ring to have been drawn. @@ -305,28 +314,28 @@ gfx::Rect target_bounds = focus_rings.at(0)->layer()->GetTargetBounds(); // Make sure it's in a reasonable position. - EXPECT_LT(abs(target_bounds.x() - (bounds.x() + 8)), 50); - EXPECT_LT(abs(target_bounds.y() - (bounds.y() + 50)), 50); + EXPECT_LT(abs(target_bounds.x() - bounds.x()), 50); + EXPECT_LT(abs(target_bounds.y() - bounds.y()), 50); EXPECT_LT(target_bounds.width(), 50); EXPECT_LT(target_bounds.height(), 50); // Move the mouse. PrepareToWaitForFocusRingChanged(); - generator_->MoveMouseTo(bounds.x() + 108, bounds.y() + 158); + generator_->MoveMouseTo(bounds.x() + 100, bounds.y() + 100); // Expect focus ring to have moved with the mouse. // The size should have grown to be over 100 (the rect is now size 100, // and the focus ring has some buffer). Position should be unchanged. WaitForFocusRingChanged(); target_bounds = focus_rings.at(0)->layer()->GetTargetBounds(); - EXPECT_LT(abs(target_bounds.x() - (bounds.x() + 8)), 50); - EXPECT_LT(abs(target_bounds.y() - (bounds.y() + 50)), 50); + EXPECT_LT(abs(target_bounds.x() - bounds.x()), 50); + EXPECT_LT(abs(target_bounds.y() - bounds.y()), 50); EXPECT_GT(target_bounds.width(), 100); EXPECT_GT(target_bounds.height(), 100); // Move the mouse smaller again, it should shrink. PrepareToWaitForFocusRingChanged(); - generator_->MoveMouseTo(bounds.x() + 18, bounds.y() + 68); + generator_->MoveMouseTo(bounds.x() + 10, bounds.y() + 18); WaitForFocusRingChanged(); target_bounds = focus_rings.at(0)->layer()->GetTargetBounds(); EXPECT_LT(target_bounds.width(), 50); @@ -366,7 +375,6 @@ ui_test_utils::NavigateToURL( browser(), GURL("data:text/html;charset=utf-8,<p>This is some text</p>")); - gfx::Rect bounds = browser()->window()->GetBounds(); // Tap Search and click a few pixels into the window bounds. generator_->PressKey(ui::VKEY_LWIN, 0 /* flags */); @@ -374,10 +382,11 @@ // Sticky keys should remember the 'search' key was clicked, so STS is // actually in a capturing mode now. - generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 50); + gfx::Rect bounds = GetWebContentsBounds(); + generator_->MoveMouseTo(bounds.x(), bounds.y()); generator_->PressLeftButton(); - generator_->MoveMouseTo(bounds.x() + bounds.width() - 8, - bounds.y() + bounds.height() - 8); + generator_->MoveMouseTo(bounds.x() + bounds.width(), + bounds.y() + bounds.height()); generator_->ReleaseLeftButton(); EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(),
diff --git a/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc b/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc index d981eac..3b84b73c 100644 --- a/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc +++ b/chrome/browser/chromeos/accessibility/select_to_speak_event_handler_unittest.cc
@@ -11,7 +11,6 @@ #include "ash/test/ash_test_helper.h" #include "ash/test/ash_test_views_delegate.h" #include "base/macros.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" #include "chrome/test/base/testing_profile.h" #include "ui/aura/test/aura_test_base.h"
diff --git a/chrome/browser/chromeos/accessibility/sticky_keys_browsertest.cc b/chrome/browser/chromeos/accessibility/sticky_keys_browsertest.cc index 814be94..735f6ac 100644 --- a/chrome/browser/chromeos/accessibility/sticky_keys_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/sticky_keys_browsertest.cc
@@ -27,6 +27,7 @@ #include "components/omnibox/browser/omnibox_view.h" #include "components/prefs/pref_service.h" #include "ui/aura/window_event_dispatcher.h" +#include "ui/base/material_design/material_design_controller.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/native_widget_types.h" @@ -139,6 +140,12 @@ } IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, CtrlClickHomeButton) { + if (ui::MaterialDesignController::IsRefreshUi()) { + // TODO(bsep): crbug.com/853990 Running the message loop in ClickOnView hits + // a DCHECK in cc::layer for unknown reasons. Needs investigation. + return; + } + // Show home page button. browser()->profile()->GetPrefs()->SetBoolean(prefs::kShowHomeButton, true); TabStripModel* tab_strip_model = browser()->tab_strip_model();
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc index 8c8fa051..4690706 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.cc
@@ -24,7 +24,6 @@ #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" #include "chrome/browser/chromeos/arc/voice_interaction/highlighter_controller_client.h" #include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h" #include "chrome/browser/profiles/profile.h" @@ -45,6 +44,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" +#include "ui/base/ui_base_features.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_owner.h" #include "ui/compositor/layer_tree_owner.h" @@ -113,7 +113,7 @@ // Exclude metalayer-related layers. This will also include other layers // under kShellWindowId_OverlayContainer which is fine. // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { aura::Window* overlay_container = ash::Shell::GetContainer( root_window, ash::kShellWindowId_OverlayContainer); if (overlay_container != nullptr) @@ -284,7 +284,7 @@ // Since ARC currently only runs in primary display, we restrict // the screenshot to it. // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { std::move(callback).Run(std::vector<uint8_t>{}); return; } @@ -576,7 +576,7 @@ bool ArcVoiceInteractionFrameworkService::IsHomescreenActive() { // Homescreen is considered to be active if there are no active windows. // TODO(crbug.com/757012): Mash support. - if (chromeos::GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return false; return !ash::Shell::Get()->activation_client()->GetActiveWindow(); }
diff --git a/chrome/browser/chromeos/ash_config.cc b/chrome/browser/chromeos/ash_config.cc deleted file mode 100644 index 0c18f36f..0000000 --- a/chrome/browser/chromeos/ash_config.cc +++ /dev/null
@@ -1,25 +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 "chrome/browser/chromeos/ash_config.h" - -#include "ui/base/ui_base_features.h" - -namespace chromeos { - -namespace { - -ash::Config ComputeAshConfig() { - return base::FeatureList::IsEnabled(features::kMash) ? ash::Config::MASH - : ash::Config::CLASSIC; -} - -} // namespace - -ash::Config GetAshConfig() { - static const ash::Config config = ComputeAshConfig(); - return config; -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/ash_config.h b/chrome/browser/chromeos/ash_config.h deleted file mode 100644 index e34ac5e..0000000 --- a/chrome/browser/chromeos/ash_config.h +++ /dev/null
@@ -1,17 +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 CHROME_BROWSER_CHROMEOS_ASH_CONFIG_H_ -#define CHROME_BROWSER_CHROMEOS_ASH_CONFIG_H_ - -#include "ash/public/cpp/config.h" - -namespace chromeos { - -// Returns the configuration of ash begin run. -ash::Config GetAshConfig(); - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_ASH_CONFIG_H_
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index f34ad68..dcb37d7 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -44,7 +44,6 @@ #include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h" #include "chrome/browser/chromeos/arc/arc_service_launcher.h" #include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/boot_times_recorder.h" #include "chrome/browser/chromeos/dbus/chrome_proxy_resolution_service_provider_delegate.h" #include "chrome/browser/chromeos/dbus/chrome_virtual_file_request_service_provider_delegate.h" @@ -317,7 +316,7 @@ DBusThreadManager::Get()->GetSystemBus(), chromeos::DBusThreadManager::Get()->IsUsingFakes()); - if (GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { // In Mash, power policy is sent to powerd by ash. PowerPolicyController::Initialize( DBusThreadManager::Get()->GetPowerManagerClient()); @@ -425,7 +424,7 @@ vm_applications_service_.reset(); drive_file_stream_service_.reset(); PowerDataCollector::Shutdown(); - if (GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) PowerPolicyController::Shutdown(); device::BluetoothAdapterFactory::Shutdown(); bluez::BluezDBusManager::Shutdown(); @@ -742,7 +741,7 @@ AccessibilityManager::Initialize(); - if (chromeos::GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { // Initialize magnification manager before ash tray is created. And this // must be placed after UserManager::SessionStarted(); // TODO(sad): These components expects the ash::Shell instance to be @@ -1006,7 +1005,7 @@ spoken_feedback_event_rewriter_delegate_ = std::make_unique<SpokenFeedbackEventRewriterDelegate>(); - if (chromeos::GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { // TODO(mash): Support EventRewriterController; see crbug.com/647781 ash::EventRewriterController* event_rewriter_controller = ash::Shell::Get()->event_rewriter_controller(); @@ -1088,7 +1087,7 @@ // Detach D-Bus clients before DBusThreadManager is shut down. idle_action_warning_observer_.reset(); - if (chromeos::GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) MagnificationManager::Shutdown(); media::SoundsManager::Shutdown(); @@ -1136,7 +1135,7 @@ // ChromeBrowserMainPartsLinux::PostMainMessageLoopRun(). arc_service_launcher_.reset(); - if (chromeos::GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) AccessibilityManager::Shutdown(); input_method::Shutdown();
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc index d42375b..2f27455a5 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.cc +++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/component_updater/cros_component_installer_chromeos.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/extensions/application_launch.h" #include "chromeos/dbus/concierge_client.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -705,12 +706,16 @@ std::string vm_name, std::string container_name, std::string desktop_file_id, + const std::vector<std::string>& files, LaunchContainerApplicationCallback callback) { vm_tools::cicerone::LaunchContainerApplicationRequest request; request.set_owner_id(CryptohomeIdForProfile(profile)); request.set_vm_name(std::move(vm_name)); request.set_container_name(std::move(container_name)); request.set_desktop_file_id(std::move(desktop_file_id)); + std::copy( + files.begin(), files.end(), + google::protobuf::RepeatedFieldBackInserter(request.mutable_files())); GetCiceroneClient()->LaunchContainerApplication( std::move(request), @@ -759,10 +764,10 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } -void CrostiniManager::LaunchContainerTerminal( - Profile* profile, - const std::string& vm_name, - const std::string& container_name) { +// static +GURL CrostiniManager::GenerateVshInCroshUrl(Profile* profile, + const std::string& vm_name, + const std::string& container_name) { std::string vsh_crosh = base::StringPrintf( "chrome-extension://%s/html/crosh.html?command=vmshell", kCrostiniCroshBuiltinAppId); @@ -780,7 +785,12 @@ vsh_crosh, vm_name_param, container_name_param, owner_id_param}; GURL vsh_in_crosh_url(base::JoinString(pieces, "&args[]=")); + return vsh_in_crosh_url; +} +// static +AppLaunchParams CrostiniManager::GenerateTerminalAppLaunchParams( + Profile* profile) { const extensions::Extension* crosh_extension = extensions::ExtensionRegistry::Get(profile)->GetInstalledExtension( kCrostiniCroshBuiltinAppId); @@ -790,7 +800,29 @@ WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_APP_LAUNCHER); launch_params.override_app_name = AppNameFromCrostiniAppId(kCrostiniTerminalId); + return launch_params; +} +Browser* CrostiniManager::CreateContainerTerminal( + const AppLaunchParams& launch_params, + const GURL& vsh_in_crosh_url) { + return CreateApplicationWindow(launch_params, vsh_in_crosh_url); +} + +void CrostiniManager::ShowContainerTerminal( + const AppLaunchParams& launch_params, + const GURL& vsh_in_crosh_url, + Browser* browser) { + ShowApplicationWindow(launch_params, vsh_in_crosh_url, browser); +} + +void CrostiniManager::LaunchContainerTerminal( + Profile* profile, + const std::string& vm_name, + const std::string& container_name) { + GURL vsh_in_crosh_url = + GenerateVshInCroshUrl(profile, vm_name, container_name); + AppLaunchParams launch_params = GenerateTerminalAppLaunchParams(profile); OpenApplicationWindow(launch_params, vsh_in_crosh_url); }
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.h b/chrome/browser/chromeos/crostini/crostini_manager.h index c0b3555..c8d9b07 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.h +++ b/chrome/browser/chromeos/crostini/crostini_manager.h
@@ -15,6 +15,8 @@ #include "base/memory/singleton.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/extensions/app_launch_params.h" #include "chromeos/dbus/cicerone/cicerone_service.pb.h" #include "chromeos/dbus/cicerone_client.h" #include "chromeos/dbus/concierge/service.pb.h" @@ -114,6 +116,14 @@ // Checks if the cros-termina component is installed. static bool IsCrosTerminaInstalled(); + // Generate the URL for Crostini terminal application. + static GURL GenerateVshInCroshUrl(Profile* profile, + const std::string& vm_name, + const std::string& container_name); + + // Generate AppLaunchParams for the Crostini terminal application. + static AppLaunchParams GenerateTerminalAppLaunchParams(Profile* profile); + // Starts the Concierge service. |callback| is called after the method call // finishes. void StartConcierge(StartConciergeCallback callback); @@ -187,6 +197,7 @@ std::string vm_name, std::string container_name, std::string desktop_file_id, + const std::vector<std::string>& files, LaunchContainerApplicationCallback callback); // Asynchronously gets app icons as specified by their desktop file ids. @@ -207,6 +218,16 @@ std::string cryptohome_id, GetContainerSshKeysCallback callback); + // Create the crosh-in-a-window that displays a shell in an container on a VM. + Browser* CreateContainerTerminal(const AppLaunchParams& launch_params, + const GURL& vsh_in_crosh_url); + + // Shows the already created crosh-in-a-window that displays a shell in an + // already running container on a VM. + void ShowContainerTerminal(const AppLaunchParams& launch_params, + const GURL& vsh_in_crosh_url, + Browser* browser); + // Launches the crosh-in-a-window that displays a shell in an already running // container on a VM. void LaunchContainerTerminal(Profile* profile,
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.cc b/chrome/browser/chromeos/crostini/crostini_registry_service.cc index 99148e0..3720425 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service.cc +++ b/chrome/browser/chromeos/crostini/crostini_registry_service.cc
@@ -83,12 +83,12 @@ return result; } -std::vector<std::string> ListToStringVector(const base::Value* list) { - std::vector<std::string> result; +std::set<std::string> ListToStringSet(const base::Value* list) { + std::set<std::string> result; if (!list) return result; for (const base::Value& value : list->GetList()) - result.emplace_back(value.GetString()); + result.insert(value.GetString()); return result; } @@ -254,11 +254,10 @@ return LocalizedString(kAppCommentKey); } -std::vector<std::string> CrostiniRegistryService::Registration::MimeTypes() - const { +std::set<std::string> CrostiniRegistryService::Registration::MimeTypes() const { if (pref_.is_none()) return {}; - return ListToStringVector( + return ListToStringSet( pref_.FindKeyOfType(kAppMimeTypesKey, base::Value::Type::LIST)); }
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service.h b/chrome/browser/chromeos/crostini/crostini_registry_service.h index f4a2307..1f0a704 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service.h +++ b/chrome/browser/chromeos/crostini/crostini_registry_service.h
@@ -79,7 +79,7 @@ std::string Name() const; std::string Comment() const; - std::vector<std::string> MimeTypes() const; + std::set<std::string> MimeTypes() const; bool NoDisplay() const; base::Time InstallTime() const;
diff --git a/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc b/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc index a72203ae..a9da451 100644 --- a/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc +++ b/chrome/browser/chromeos/crostini/crostini_registry_service_unittest.cc
@@ -81,7 +81,7 @@ std::string container_name = "awesomecontainer"; std::map<std::string, std::string> name = {{"", "Vim"}}; std::map<std::string, std::string> comment = {{"", "Edit text files"}}; - std::vector<std::string> mime_types = {"text/plain", "text/x-python"}; + std::set<std::string> mime_types = {"text/plain", "text/x-python"}; bool no_display = true; std::string app_id = CrostiniTestHelper::GenerateAppId(
diff --git a/chrome/browser/chromeos/crostini/crostini_test_helper.cc b/chrome/browser/chromeos/crostini/crostini_test_helper.cc index 982a298..4a27b10d 100644 --- a/chrome/browser/chromeos/crostini/crostini_test_helper.cc +++ b/chrome/browser/chromeos/crostini/crostini_test_helper.cc
@@ -17,15 +17,23 @@ namespace crostini { CrostiniTestHelper::CrostiniTestHelper(Profile* profile) - : registry_service_( + : profile_(profile), + registry_service_( crostini::CrostiniRegistryServiceFactory::GetForProfile(profile)) { + SetCrostiniUIAllowedForTesting(true); EnableCrostini(profile); + current_apps_.set_vm_name(kCrostiniDefaultVmName); + current_apps_.set_container_name(kCrostiniDefaultContainerName); +} + +CrostiniTestHelper::~CrostiniTestHelper() { + DisableCrostini(profile_); + SetCrostiniUIAllowedForTesting(false); } void CrostiniTestHelper::SetupDummyApps() { - current_apps_ = BasicAppList("dummy1", kCrostiniDefaultVmName, - kCrostiniDefaultContainerName); // This updates the registry for us. + AddApp(BasicApp("dummy1")); AddApp(BasicApp("dummy2")); }
diff --git a/chrome/browser/chromeos/crostini/crostini_test_helper.h b/chrome/browser/chromeos/crostini/crostini_test_helper.h index 16629e8..f4556a9 100644 --- a/chrome/browser/chromeos/crostini/crostini_test_helper.h +++ b/chrome/browser/chromeos/crostini/crostini_test_helper.h
@@ -20,8 +20,10 @@ // simple interface to add, update, and remove apps from the registry. class CrostiniTestHelper { public: - // For convenience, instantiating this enables Crostini. + // For convenience, instantiating this enables Crostini and also calls + // SetCrostiniUIAllowedForTesting(true). The destructor resets these. explicit CrostiniTestHelper(Profile*); + ~CrostiniTestHelper(); // Creates the apps named "dummy1" and "dummy2" in the default container. void SetupDummyApps(); @@ -56,6 +58,7 @@ private: void UpdateRegistry(); + Profile* profile_; vm_tools::apps::ApplicationList current_apps_; CrostiniRegistryService* registry_service_; };
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc index cf1f49df..962fdae 100644 --- a/chrome/browser/chromeos/crostini/crostini_util.cc +++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -6,6 +6,7 @@ #include "base/callback.h" #include "base/feature_list.h" +#include "base/files/file_path.h" #include "base/metrics/histogram_functions.h" #include "base/strings/string_util.h" #include "chrome/browser/chromeos/crostini/crostini_app_launch_observer.h" @@ -19,6 +20,8 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/shelf_spinner_controller.h" #include "chrome/browser/ui/ash/launcher/shelf_spinner_item_controller.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/common/chrome_features.h" #include "components/prefs/pref_service.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -62,10 +65,13 @@ } void OnCrostiniRestarted(const std::string& app_id, + Browser* browser, base::OnceClosure callback, crostini::ConciergeClientResult result) { if (result != crostini::ConciergeClientResult::SUCCESS) { OnLaunchFailed(app_id); + if (browser && browser->window()) + browser->window()->Close(); return; } std::move(callback).Run(); @@ -77,16 +83,25 @@ OnLaunchFailed(app_id); } -void LaunchTerminal(Profile* profile) { - crostini::CrostiniManager::GetInstance()->LaunchContainerTerminal( - profile, kCrostiniDefaultVmName, kCrostiniDefaultContainerName); +Browser* CreateTerminal(const AppLaunchParams& launch_params, + const GURL& vsh_in_crosh_url) { + return crostini::CrostiniManager::GetInstance()->CreateContainerTerminal( + launch_params, vsh_in_crosh_url); +} + +void ShowTerminal(const AppLaunchParams& launch_params, + const GURL& vsh_in_crosh_url, + Browser* browser) { + crostini::CrostiniManager::GetInstance()->ShowContainerTerminal( + launch_params, vsh_in_crosh_url, browser); } void LaunchContainerApplication( Profile* profile, const std::string& app_id, crostini::CrostiniRegistryService::Registration registration, - int64_t display_id) { + int64_t display_id, + const std::vector<std::string>& files) { ChromeLauncherController* chrome_launcher_controller = ChromeLauncherController::instance(); DCHECK_NE(chrome_launcher_controller, nullptr); @@ -96,7 +111,7 @@ observer->OnAppLaunchRequested(registration.DesktopFileId(), display_id); crostini::CrostiniManager::GetInstance()->LaunchContainerApplication( profile, registration.VmName(), registration.ContainerName(), - registration.DesktopFileId(), + registration.DesktopFileId(), files, base::BindOnce(OnContainerApplicationLaunched, app_id)); } @@ -134,6 +149,13 @@ void LaunchCrostiniApp(Profile* profile, const std::string& app_id, int64_t display_id) { + LaunchCrostiniApp(profile, app_id, display_id, std::vector<std::string>()); +} + +void LaunchCrostiniApp(Profile* profile, + const std::string& app_id, + int64_t display_id, + const std::vector<std::string>& files) { auto* crostini_manager = crostini::CrostiniManager::GetInstance(); crostini::CrostiniRegistryService* registry_service = crostini::CrostiniRegistryServiceFactory::GetForProfile(profile); @@ -150,7 +172,9 @@ const std::string container_name = registration->ContainerName(); base::OnceClosure launch_closure; + Browser* browser = nullptr; if (app_id == kCrostiniTerminalId) { + DCHECK(files.empty()); RecordAppLaunchHistogram(CrostiniAppLaunchAppType::kTerminal); if (!crostini_manager->IsCrosTerminaInstalled() || @@ -159,12 +183,21 @@ return; } - launch_closure = base::BindOnce(&LaunchTerminal, profile); + GURL vsh_in_crosh_url = crostini::CrostiniManager::GenerateVshInCroshUrl( + profile, vm_name, container_name); + AppLaunchParams launch_params = + crostini::CrostiniManager::GenerateTerminalAppLaunchParams(profile); + // Create the terminal here so it's created in the right display. If the + // browser creation is delayed into the callback the root window for new + // windows setting can be changed due to the launcher or shelf dismissal. + Browser* browser = CreateTerminal(launch_params, vsh_in_crosh_url); + launch_closure = + base::BindOnce(&ShowTerminal, launch_params, vsh_in_crosh_url, browser); } else { RecordAppLaunchHistogram(CrostiniAppLaunchAppType::kRegisteredApp); launch_closure = base::BindOnce(&LaunchContainerApplication, profile, app_id, - std::move(*registration), display_id); + std::move(*registration), display_id, std::move(files)); } // Update the last launched time. @@ -179,7 +212,8 @@ crostini_manager->RestartCrostini( profile, vm_name, container_name, - base::BindOnce(OnCrostiniRestarted, app_id, std::move(launch_closure))); + base::BindOnce(OnCrostiniRestarted, app_id, browser, + std::move(launch_closure))); } std::string CryptohomeIdForProfile(Profile* profile) { @@ -200,6 +234,10 @@ return container_username; } +base::FilePath HomeDirectoryForProfile(Profile* profile) { + return base::FilePath("/home/" + ContainerUserNameForProfile(profile)); +} + std::string AppNameFromCrostiniAppId(const std::string& id) { return kCrostiniAppNamePrefix + id; }
diff --git a/chrome/browser/chromeos/crostini/crostini_util.h b/chrome/browser/chromeos/crostini/crostini_util.h index 34fb75c..9e22264 100644 --- a/chrome/browser/chromeos/crostini/crostini_util.h +++ b/chrome/browser/chromeos/crostini/crostini_util.h
@@ -9,6 +9,10 @@ #include "base/optional.h" +namespace base { +class FilePath; +} // namespace base + class Profile; // Enables/disables overriding IsCrostiniUIAllowedForProfile's normal @@ -33,6 +37,14 @@ const std::string& app_id, int64_t display_id); +// Launch a Crostini App with a given set of files, given as absolute paths in +// the container. For apps which can only be launched with a single file, +// launch multiple instances. +void LaunchCrostiniApp(Profile* profile, + const std::string& app_id, + int64_t display_id, + const std::vector<std::string>& files); + // Retrieves cryptohome_id from profile. std::string CryptohomeIdForProfile(Profile* profile); @@ -40,6 +52,9 @@ // profile->GetProfileUserName() email address. std::string ContainerUserNameForProfile(Profile* profile); +// Returns the home directory within the container for a given profile. +base::FilePath HomeDirectoryForProfile(Profile* profile); + // The Terminal opens Crosh but overrides the Browser's app_name so that we can // identify it as the Crostini Terminal. In the future, we will also use these // for Crostini apps marked Terminal=true in their .desktop file.
diff --git a/chrome/browser/chromeos/display/output_protection_delegate.cc b/chrome/browser/chromeos/display/output_protection_delegate.cc index 7c3d886..0ab519c 100644 --- a/chrome/browser/chromeos/display/output_protection_delegate.cc +++ b/chrome/browser/chromeos/display/output_protection_delegate.cc
@@ -6,9 +6,9 @@ #include "chrome/browser/chromeos/display/output_protection_controller_ash.h" #include "chrome/browser/chromeos/display/output_protection_controller_mus.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/display/types/display_constants.h" @@ -99,7 +99,7 @@ if (!window) return false; - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) controller_ = std::make_unique<OutputProtectionControllerMus>(); else controller_ = std::make_unique<OutputProtectionControllerAsh>();
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc index 6d9fe79..d8d74ec4 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -676,11 +676,12 @@ std::make_unique<bool>(metadata->available_offline); properties_->present = std::make_unique<bool>(metadata->available_offline); properties_->dirty = std::make_unique<bool>(metadata->dirty); - properties_->hosted = std::make_unique<bool>(metadata->hosted); - properties_->present = - std::make_unique<bool>(metadata->available_offline || metadata->hosted); - properties_->available_when_metered = - std::make_unique<bool>(metadata->available_offline || metadata->hosted); + properties_->hosted = std::make_unique<bool>( + metadata->type == drivefs::mojom::FileMetadata::Type::kHosted); + properties_->present = std::make_unique<bool>(metadata->available_offline || + *properties_->hosted); + properties_->available_when_metered = std::make_unique<bool>( + metadata->available_offline || *properties_->hosted); properties_->pinned = std::make_unique<bool>(metadata->pinned); properties_->shared = std::make_unique<bool>(metadata->shared); properties_->starred = std::make_unique<bool>(metadata->starred); @@ -721,6 +722,21 @@ std::make_unique<int32_t>(metadata->image_metadata->rotation); } } + + properties_->can_delete = + std::make_unique<bool>(metadata->capabilities->can_delete); + properties_->can_rename = + std::make_unique<bool>(metadata->capabilities->can_rename); + properties_->can_add_children = + std::make_unique<bool>(metadata->capabilities->can_add_children); + + // Only set the |can_copy| capability for hosted documents; for other files, + // we must have read access, so |can_copy| is implicitly true. + properties_->can_copy = std::make_unique<bool>( + !*properties_->hosted || metadata->capabilities->can_copy); + properties_->can_share = + std::make_unique<bool>(metadata->capabilities->can_share); + if (metadata->thumbnail) { base::PostTaskAndReplyWithResult( FROM_HERE,
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc index 7c1e726..b847d20 100644 --- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc +++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -28,7 +28,6 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/wallpaper_controller_client.h" #include "chrome/common/chrome_paths.h" #include "chrome/grit/generated_resources.h" @@ -886,4 +885,4 @@ } Respond(TwoArguments(image_info.ToValue(), std::make_unique<Value>(next_resume_token))); -} \ No newline at end of file +}
diff --git a/chrome/browser/chromeos/file_manager/crostini_file_tasks.cc b/chrome/browser/chromeos/file_manager/crostini_file_tasks.cc new file mode 100644 index 0000000..e659ea2f --- /dev/null +++ b/chrome/browser/chromeos/file_manager/crostini_file_tasks.cc
@@ -0,0 +1,116 @@ +// Copyright (c) 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/chromeos/file_manager/crostini_file_tasks.h" + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/base64.h" +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/chromeos/crostini/crostini_registry_service.h" +#include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" +#include "chrome/browser/chromeos/file_manager/app_id.h" +#include "chrome/browser/chromeos/file_manager/path_util.h" +#include "extensions/browser/entry_info.h" +#include "storage/browser/fileapi/file_system_url.h" +#include "ui/base/layout.h" +#include "ui/display/types/display_constants.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/image_skia_operations.h" +#include "url/gurl.h" + +namespace file_manager { +namespace file_tasks { + +void FindCrostiniTasks(Profile* profile, + const std::vector<extensions::EntryInfo>& entries, + std::vector<FullTaskDescriptor>* result_list, + base::OnceClosure completion_closure) { + if (!IsCrostiniUIAllowedForProfile(profile)) { + std::move(completion_closure).Run(); + return; + } + + // We currently don't support opening directories or files not already inside + // the Crostini directories. + base::FilePath crostini_mount = util::GetCrostiniMountDirectory(profile); + for (const extensions::EntryInfo& entry : entries) { + if (!crostini_mount.IsParent(entry.path) || + entry.path.EndsWithSeparator()) { + std::move(completion_closure).Run(); + return; + } + } + + std::set<std::string> target_mime_types; + for (const extensions::EntryInfo& entry : entries) + target_mime_types.insert(entry.mime_type); + + crostini::CrostiniRegistryService* registry_service = + crostini::CrostiniRegistryServiceFactory::GetForProfile(profile); + for (const std::string& app_id : registry_service->GetRegisteredAppIds()) { + crostini::CrostiniRegistryService::Registration registration = + *registry_service->GetRegistration(app_id); + + const std::set<std::string>& supported_mime_types = + registration.MimeTypes(); + bool had_unsupported_mime_type = false; + for (const std::string& target_mime_type : target_mime_types) { + if (supported_mime_types.find(target_mime_type) != + supported_mime_types.end()) + continue; + had_unsupported_mime_type = true; + break; + } + if (had_unsupported_mime_type) + continue; + + // TODO(timloh): Add support for Crostini icons + result_list->push_back(FullTaskDescriptor( + TaskDescriptor(app_id, TASK_TYPE_CROSTINI_APP, kCrostiniAppActionID), + registration.Name(), + extensions::api::file_manager_private::Verb::VERB_OPEN_WITH, GURL(), + false /* is_default */, false /* is_generic */)); + } + + std::move(completion_closure).Run(); +} + +void ExecuteCrostiniTask( + Profile* profile, + const TaskDescriptor& task, + const std::vector<storage::FileSystemURL>& file_system_urls, + const FileTaskFinishedCallback& done) { + DCHECK(IsCrostiniUIAllowedForProfile(profile)); + + base::FilePath folder(util::GetCrostiniMountPointName(profile)); + + std::vector<std::string> files; + for (const storage::FileSystemURL& file_system_url : file_system_urls) { + DCHECK(file_system_url.mount_type() == storage::kFileSystemTypeExternal); + DCHECK(file_system_url.type() == storage::kFileSystemTypeNativeLocal); + + // Reformat virtual_path() + // from <mount_label>/path/to/file + // to /<home-directory>/path/to/file + base::FilePath result = HomeDirectoryForProfile(profile); + bool success = + folder.AppendRelativePath(file_system_url.virtual_path(), &result); + DCHECK(success); + files.emplace_back(result.AsUTF8Unsafe()); + } + + LaunchCrostiniApp(profile, task.app_id, display::kInvalidDisplayId, files); +} + +} // namespace file_tasks +} // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/crostini_file_tasks.h b/chrome/browser/chromeos/file_manager/crostini_file_tasks.h new file mode 100644 index 0000000..d590d25 --- /dev/null +++ b/chrome/browser/chromeos/file_manager/crostini_file_tasks.h
@@ -0,0 +1,47 @@ +// Copyright (c) 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_CHROMEOS_FILE_MANAGER_CROSTINI_FILE_TASKS_H_ +#define CHROME_BROWSER_CHROMEOS_FILE_MANAGER_CROSTINI_FILE_TASKS_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "chrome/browser/chromeos/file_manager/file_tasks.h" + +class Profile; + +namespace extensions { +struct EntryInfo; +} + +namespace storage { +class FileSystemURL; +} + +namespace file_manager { +namespace file_tasks { + +// Crostini apps all use the same action ID. +constexpr char kCrostiniAppActionID[] = "open-with"; + +// Finds the Crostini tasks that can handle |entries|, appends them to +// |result_list|, and calls back to |callback| once finished. +void FindCrostiniTasks(Profile* profile, + const std::vector<extensions::EntryInfo>& entries, + std::vector<FullTaskDescriptor>* result_list, + base::OnceClosure completion_closure); + +// Executes the specified task by Crostini. +void ExecuteCrostiniTask( + Profile* profile, + const TaskDescriptor& task, + const std::vector<storage::FileSystemURL>& file_system_urls, + const FileTaskFinishedCallback& done); + +} // namespace file_tasks +} // namespace file_manager + +#endif // CHROME_BROWSER_CHROMEOS_FILE_MANAGER_CROSTINI_FILE_TASKS_H_
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index ff05505..6e6c075c 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -163,7 +163,6 @@ TestCase("audioOpenDownloads").InGuestMode(), TestCase("audioOpenDownloads"), TestCase("audioOpenDrive"), - TestCase("audioOpenDrive").EnableDriveFs(), TestCase("audioAutoAdvanceDrive"), TestCase("audioRepeatAllModeSingleFileDrive"), TestCase("audioNoRepeatModeSingleFileDrive"), @@ -183,8 +182,7 @@ FilesAppBrowserTest, ::testing::Values(TestCase("imageOpenDownloads").InGuestMode(), TestCase("imageOpenDownloads"), - TestCase("imageOpenDrive"), - TestCase("imageOpenDrive").EnableDriveFs())); + TestCase("imageOpenDrive"))); WRAPPED_INSTANTIATE_TEST_CASE_P( CreateNewFolder, /* create_new_folder.js */
diff --git a/chrome/browser/chromeos/file_manager/file_tasks.cc b/chrome/browser/chromeos/file_manager/file_tasks.cc index 51501ef4..ce2245c 100644 --- a/chrome/browser/chromeos/file_manager/file_tasks.cc +++ b/chrome/browser/chromeos/file_manager/file_tasks.cc
@@ -14,10 +14,12 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/drive/file_task_executor.h" #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/file_manager/arc_file_tasks.h" +#include "chrome/browser/chromeos/file_manager/crostini_file_tasks.h" #include "chrome/browser/chromeos/file_manager/file_browser_handlers.h" #include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/chromeos/file_manager/open_util.h" @@ -61,6 +63,7 @@ const char kFileHandlerTaskType[] = "app"; const char kDriveAppTaskType[] = "drive"; const char kArcAppTaskType[] = "arc"; +const char kCrostiniAppTaskType[] = "crostini"; // Drive apps always use the action ID. const char kDriveAppActionID[] = "open-with"; @@ -76,6 +79,8 @@ return kDriveAppTaskType; case TASK_TYPE_ARC_APP: return kArcAppTaskType; + case TASK_TYPE_CROSTINI_APP: + return kCrostiniAppTaskType; case TASK_TYPE_UNKNOWN: case NUM_TASK_TYPE: break; @@ -94,6 +99,8 @@ return TASK_TYPE_DRIVE_APP; if (str == kArcAppTaskType) return TASK_TYPE_ARC_APP; + if (str == kCrostiniAppTaskType) + return TASK_TYPE_CROSTINI_APP; return TASK_TYPE_UNKNOWN; } @@ -336,6 +343,12 @@ return true; } + if (task.task_type == TASK_TYPE_CROSTINI_APP) { + DCHECK_EQ(kCrostiniAppActionID, task.action_id); + ExecuteCrostiniTask(profile, task, file_urls, done); + return true; + } + // drive::FileTaskExecutor is responsible to handle drive tasks. if (task.task_type == TASK_TYPE_DRIVE_APP) { DCHECK_EQ(kDriveAppActionID, task.action_id); @@ -597,16 +610,21 @@ const std::vector<GURL>& file_urls, const FindTasksCallback& callback, std::unique_ptr<std::vector<FullTaskDescriptor>> result_list) { + std::vector<FullTaskDescriptor>* result_list_ptr = result_list.get(); + // 3. Continues from FindAllTypesOfTasks. Find and append file handler tasks. - FindFileHandlerTasks(profile, entries, result_list.get()); + FindFileHandlerTasks(profile, entries, result_list_ptr); // 4. Find and append file browser handler tasks. We know there aren't // duplicates because "file_browser_handlers" and "file_handlers" shouldn't // be used in the same manifest.json. - FindFileBrowserHandlerTasks(profile, file_urls, result_list.get()); + FindFileBrowserHandlerTasks(profile, file_urls, result_list_ptr); - // Done. Apply post-filtering and callback. - PostProcessFoundTasks(profile, entries, callback, std::move(result_list)); + // 5. Find and append Crostini tasks. + FindCrostiniTasks(profile, entries, result_list_ptr, + // Done. Apply post-filtering and callback. + base::BindOnce(PostProcessFoundTasks, profile, entries, + callback, std::move(result_list))); } void FindAllTypesOfTasks(Profile* profile,
diff --git a/chrome/browser/chromeos/file_manager/file_tasks.h b/chrome/browser/chromeos/file_manager/file_tasks.h index 41cb8f3..eb18ed8 100644 --- a/chrome/browser/chromeos/file_manager/file_tasks.h +++ b/chrome/browser/chromeos/file_manager/file_tasks.h
@@ -46,7 +46,8 @@ // }, // { // "driveApp": false, -// "iconUrl": "chrome://extension-icon/hhaomjibdihmijegdhdafkllkbggdgoj/16/1", +// "iconUrl": +// "chrome://extension-icon/hhaomjibdihmijegdhdafkllkbggdgoj/16/1", // "isDefault": true, // "taskId": "hhaomjibdihmijegdhdafkllkbggdgoj|file|gallery", // "title": "__MSG_OPEN_ACTION__" @@ -85,12 +86,13 @@ // - "app" - File handler - app declaring "file_handlers" in manifest.json. // - "drive" - Drive App // - "arc" - ARC App +// - "crostini" - Crostini App // // <task-action-id> is an ID string used for identifying actions provided // from a single Chrome Extension/App. In other words, a single // Chrome/Extension can provide multiple file handlers hence each of them -// needs to have a unique action ID. For Drive apps, <task-action-id> is -// always "open-with". +// needs to have a unique action ID. For Drive and Crostini apps, +// <task-action-id> is always "open-with". // // HOW TASKS ARE EXECUTED? // @@ -146,6 +148,7 @@ TASK_TYPE_FILE_HANDLER, TASK_TYPE_DRIVE_APP, TASK_TYPE_ARC_APP, + TASK_TYPE_CROSTINI_APP, // The enum values must be kept in sync with FileManagerTaskType in // tools/metrics/histograms/enums.xml. Since enums for histograms are // append-only (for keeping the number consistent across versions), new values
diff --git a/chrome/browser/chromeos/file_manager/file_tasks_unittest.cc b/chrome/browser/chromeos/file_manager/file_tasks_unittest.cc index 53f1196f..8f059ad 100644 --- a/chrome/browser/chromeos/file_manager/file_tasks_unittest.cc +++ b/chrome/browser/chromeos/file_manager/file_tasks_unittest.cc
@@ -12,8 +12,10 @@ #include "base/command_line.h" #include "base/run_loop.h" #include "base/values.h" +#include "chrome/browser/chromeos/crostini/crostini_test_helper.h" #include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/file_manager/app_id.h" +#include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -21,6 +23,8 @@ #include "chrome/browser/extensions/test_extension_system.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_concierge_client.h" #include "components/drive/drive_app_registry.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" @@ -1247,5 +1251,122 @@ EXPECT_EQ(Verb::VERB_PACK_WITH, tasks[0].task_verb()); } +// Test using the test extension system, which needs lots of setup. +class FileManagerFileTasksCrostiniTest + : public FileManagerFileTasksComplexTest { + protected: + FileManagerFileTasksCrostiniTest() + : crostini_test_helper_(&test_profile_), + crostini_folder_(util::GetCrostiniMountDirectory(&test_profile_)) { + chromeos::DBusThreadManager::GetSetterForTesting()->SetConciergeClient( + std::make_unique<chromeos::FakeConciergeClient>()); + + vm_tools::apps::App text_app = + crostini::CrostiniTestHelper::BasicApp("text_app"); + *text_app.add_mime_types() = "text/plain"; + crostini_test_helper_.AddApp(text_app); + + vm_tools::apps::App image_app = + crostini::CrostiniTestHelper::BasicApp("image_app"); + *image_app.add_mime_types() = "image/gif"; + *image_app.add_mime_types() = "image/jpeg"; + *image_app.add_mime_types() = "image/jpg"; + *image_app.add_mime_types() = "image/png"; + crostini_test_helper_.AddApp(image_app); + + vm_tools::apps::App gif_app = + crostini::CrostiniTestHelper::BasicApp("gif_app"); + *gif_app.add_mime_types() = "image/gif"; + crostini_test_helper_.AddApp(gif_app); + + text_app_id_ = crostini::CrostiniTestHelper::GenerateAppId("text_app"); + image_app_id_ = crostini::CrostiniTestHelper::GenerateAppId("image_app"); + gif_app_id_ = crostini::CrostiniTestHelper::GenerateAppId("gif_app"); + } + + crostini::CrostiniTestHelper crostini_test_helper_; + base::FilePath crostini_folder_; + std::string text_app_id_; + std::string image_app_id_; + std::string gif_app_id_; +}; + +TEST_F(FileManagerFileTasksCrostiniTest, BasicFiles) { + std::vector<extensions::EntryInfo> entries{ + {crostini_folder_.Append("foo.txt"), "text/plain", false}}; + std::vector<GURL> file_urls{ + GURL("filesystem:chrome-extension://id/dir/foo.txt")}; + + std::vector<FullTaskDescriptor> tasks; + FindAllTypesOfTasksSynchronousWrapper().Call(&test_profile_, nullptr, entries, + file_urls, &tasks); + ASSERT_EQ(1U, tasks.size()); + EXPECT_EQ(text_app_id_, tasks[0].task_descriptor().app_id); + + // Multiple text files + entries.emplace_back(crostini_folder_.Append("bar.txt"), "text/plain", false); + file_urls.emplace_back("filesystem:chrome-extension://id/dir/bar.txt"); + FindAllTypesOfTasksSynchronousWrapper().Call(&test_profile_, nullptr, entries, + file_urls, &tasks); + ASSERT_EQ(1U, tasks.size()); + EXPECT_EQ(text_app_id_, tasks[0].task_descriptor().app_id); +} + +TEST_F(FileManagerFileTasksCrostiniTest, Directories) { + std::vector<extensions::EntryInfo> entries{ + {crostini_folder_.Append("dir"), "", true}}; + std::vector<GURL> file_urls{GURL("filesystem:chrome-extension://id/dir/dir")}; + std::vector<FullTaskDescriptor> tasks; + FindAllTypesOfTasksSynchronousWrapper().Call(&test_profile_, nullptr, entries, + file_urls, &tasks); + EXPECT_EQ(0U, tasks.size()); + + entries.emplace_back(crostini_folder_.Append("foo.txt"), "text/plain", false); + file_urls.emplace_back("filesystem:chrome-extension://id/dir/foo.txt"); + FindAllTypesOfTasksSynchronousWrapper().Call(&test_profile_, nullptr, entries, + file_urls, &tasks); + EXPECT_EQ(0U, tasks.size()); +} + +TEST_F(FileManagerFileTasksCrostiniTest, MultipleMatches) { + std::vector<extensions::EntryInfo> entries{ + {crostini_folder_.Append("foo.gif"), "image/gif", false}, + {crostini_folder_.Append("bar.gif"), "image/gif", false}}; + std::vector<GURL> file_urls{ + GURL("filesystem:chrome-extension://id/dir/foo.gif"), + GURL("filesystem:chrome-extension://id/dir/bar.gif")}; + + std::vector<FullTaskDescriptor> tasks; + FindAllTypesOfTasksSynchronousWrapper().Call(&test_profile_, nullptr, entries, + file_urls, &tasks); + // The returned values happen to be ordered alphabetically by app_id, so we + // rely on this to keep the test simple. + EXPECT_LT(gif_app_id_, image_app_id_); + ASSERT_EQ(2U, tasks.size()); + EXPECT_EQ(gif_app_id_, tasks[0].task_descriptor().app_id); + EXPECT_EQ(image_app_id_, tasks[1].task_descriptor().app_id); +} + +TEST_F(FileManagerFileTasksCrostiniTest, MultipleTypes) { + std::vector<extensions::EntryInfo> entries{ + {crostini_folder_.Append("foo.gif"), "image/gif", false}, + {crostini_folder_.Append("bar.png"), "image/png", false}}; + std::vector<GURL> file_urls{ + GURL("filesystem:chrome-extension://id/dir/foo.gif"), + GURL("filesystem:chrome-extension://id/dir/bar.png")}; + + std::vector<FullTaskDescriptor> tasks; + FindAllTypesOfTasksSynchronousWrapper().Call(&test_profile_, nullptr, entries, + file_urls, &tasks); + ASSERT_EQ(1U, tasks.size()); + EXPECT_EQ(image_app_id_, tasks[0].task_descriptor().app_id); + + entries.emplace_back(crostini_folder_.Append("qux.mp4"), "video/mp4", false); + file_urls.emplace_back("filesystem:chrome-extension://id/dir/qux.mp4"); + FindAllTypesOfTasksSynchronousWrapper().Call(&test_profile_, nullptr, entries, + file_urls, &tasks); + EXPECT_EQ(0U, tasks.size()); +} + } // namespace file_tasks } // namespace file_manager.
diff --git a/chrome/browser/chromeos/file_manager/open_with_browser.cc b/chrome/browser/chromeos/file_manager/open_with_browser.cc index c557559..fe9323a 100644 --- a/chrome/browser/chromeos/file_manager/open_with_browser.cc +++ b/chrome/browser/chromeos/file_manager/open_with_browser.cc
@@ -143,7 +143,7 @@ drivefs::mojom::FileMetadataPtr metadata) { if (error != drive::FILE_ERROR_OK) return; - if (!metadata->hosted) { + if (metadata->type != drivefs::mojom::FileMetadata::Type::kHosted) { OpenGDocUrlFromFile(file_path, profile); return; }
diff --git a/chrome/browser/chromeos/file_manager/path_util.cc b/chrome/browser/chromeos/file_manager/path_util.cc index 974653b..d8da192 100644 --- a/chrome/browser/chromeos/file_manager/path_util.cc +++ b/chrome/browser/chromeos/file_manager/path_util.cc
@@ -123,6 +123,10 @@ "_"); } +base::FilePath GetCrostiniMountDirectory(Profile* profile) { + return base::FilePath("/media/fuse/" + GetCrostiniMountPointName(profile)); +} + bool ConvertPathToArcUrl(const base::FilePath& path, GURL* arc_url_out) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/chromeos/file_manager/path_util.h b/chrome/browser/chromeos/file_manager/path_util.h index 8975f29..5118279 100644 --- a/chrome/browser/chromeos/file_manager/path_util.h +++ b/chrome/browser/chromeos/file_manager/path_util.h
@@ -46,6 +46,9 @@ // The canonical mount point name for crostini "Linux Files" folder. std::string GetCrostiniMountPointName(Profile* profile); +// The actual directory the crostini "Linux Files" folder is mounted. +base::FilePath GetCrostiniMountDirectory(Profile* profile); + // DEPRECATED. Use |ConvertToContentUrls| instead. // While this function can convert paths under Downloads, /media/removable // and /special/drive, this CANNOT convert paths under ARC media directories
diff --git a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc index 2a4993a..d510305d 100644 --- a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc +++ b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc
@@ -12,8 +12,8 @@ #include "ash/wm/window_util.h" #include "base/logging.h" #include "chrome/browser/chromeos/input_method/mode_indicator_controller.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "ui/base/ime/ime_bridge.h" +#include "ui/base/ui_base_features.h" #include "ui/chromeos/ime/infolist_window.h" #include "ui/views/widget/widget.h" @@ -46,7 +46,7 @@ return; gfx::NativeView parent = nullptr; - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { aura::Window* active_window = ash::wm::GetActiveWindow(); parent = ash::Shell::GetContainer( active_window ? active_window->GetRootWindow()
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc index a334947..2691f04 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -15,7 +15,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/base/ime/candidate_window.h" @@ -25,6 +24,7 @@ #include "ui/base/ime/composition_text.h" #include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/text_input_flags.h" +#include "ui/base/ui_base_features.h" #include "ui/chromeos/ime/input_method_menu_item.h" #include "ui/chromeos/ime/input_method_menu_manager.h" #include "ui/events/event.h" @@ -218,7 +218,7 @@ void InputMethodEngine::HideInputView() { // TODO(mash): Support virtual keyboard under MASH. There is no // KeyboardController in the browser process under MASH. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { auto* keyboard_controller = keyboard::KeyboardController::Get(); if (keyboard_controller->enabled()) { keyboard_controller->HideKeyboardByUser(); @@ -232,7 +232,7 @@ ->EnableInputView(); // TODO(mash): Support virtual keyboard under MASH. There is no // KeyboardController in the browser process under MASH. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { auto* keyboard_controller = keyboard::KeyboardController::Get(); if (keyboard_controller->enabled()) keyboard_controller->Reload();
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc index 24e72124..a04a34d8 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -27,14 +27,12 @@ #include "base/sys_info.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h" #include "chrome/browser/chromeos/language_preferences.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chromeos/system/devicemode.h" @@ -48,6 +46,7 @@ #include "ui/base/ime/chromeos/ime_keyboard_mus.h" #include "ui/base/ime/chromeos/input_method_delegate.h" #include "ui/base/ime/ime_bridge.h" +#include "ui/base/ui_base_features.h" #include "ui/chromeos/ime/input_method_menu_item.h" #include "ui/chromeos/ime/input_method_menu_manager.h" #include "ui/keyboard/keyboard_controller.h" @@ -1094,7 +1093,7 @@ // TODO(mash): Support virtual keyboard under MASH. There is no // KeyboardController in the browser process under MASH. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { auto* keyboard_controller = keyboard::KeyboardController::Get(); if (keyboard_controller->enabled()) keyboard_controller->Reload();
diff --git a/chrome/browser/chromeos/input_method/mode_indicator_controller.cc b/chrome/browser/chromeos/input_method/mode_indicator_controller.cc index 6adac19..a5a2ade 100644 --- a/chrome/browser/chromeos/input_method/mode_indicator_controller.cc +++ b/chrome/browser/chromeos/input_method/mode_indicator_controller.cc
@@ -9,11 +9,11 @@ #include "ash/wm/window_util.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chromeos/ash_config.h" #include "mojo/public/cpp/bindings/type_converter.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" #include "ui/base/ime/chromeos/input_method_util.h" +#include "ui/base/ui_base_features.h" namespace chromeos { namespace input_method { @@ -96,7 +96,7 @@ // though it is created by Chrome. // TODO(crbug.com/738531): Consider moving the ModeIndicatorView into ash. const int container_id = ash::kShellWindowId_SettingBubbleContainer; - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { using ui::mojom::WindowManager; params->mus_properties[WindowManager::kContainerId_InitProperty] = mojo::ConvertTo<std::vector<uint8_t>>(container_id);
diff --git a/chrome/browser/chromeos/locale_change_guard_unittest.cc b/chrome/browser/chromeos/locale_change_guard_unittest.cc index a7c02802..fc9a37e4 100644 --- a/chrome/browser/chromeos/locale_change_guard_unittest.cc +++ b/chrome/browser/chromeos/locale_change_guard_unittest.cc
@@ -29,6 +29,7 @@ "br", // Breton "bs", // Bosnian "ca", // Catalan + "ceb", // Cebuano "ckb", // Sorani (Kurdish-Arabic) "co", // Corsican "cs", // Czech @@ -55,10 +56,12 @@ "hi", // Hindi "hmn", // Hmong "hr", // Croatian + "ht", // Haitian Creole "hu", // Hungarian "hy", // Armenian "ia", // Interlingua "id", // Indonesian + "ig", // Igbo "is", // Icelandic "ja", // Japanese "jv", // Javanese @@ -75,6 +78,8 @@ "lo", // Laothian "lt", // Lithuanian "lv", // Latvian + "mg", // Malagasy + "mi", // Maori "mk", // Macedonian "ml", // Malayalam "mn", // Mongolian @@ -82,11 +87,13 @@ "mr", // Marathi "ms", // Malay "mt", // Maltese + "my", // Burmese "nb", // Norwegian (Bokmal) "ne", // Nepali "nl", // Dutch "nn", // Norwegian (Nynorsk) "no", // Norwegian + "ny", // Nyanja "oc", // Occitan "om", // Oromo "or", // Oriya
diff --git a/chrome/browser/chromeos/login/active_directory_login_browsertest.cc b/chrome/browser/chromeos/login/active_directory_login_browsertest.cc index e2a9c1c..24fb7fe 100644 --- a/chrome/browser/chromeos/login/active_directory_login_browsertest.cc +++ b/chrome/browser/chromeos/login/active_directory_login_browsertest.cc
@@ -54,7 +54,8 @@ constexpr char kAdMoreOptionsButton[] = "moreOptionsBtn"; constexpr char kAdUserInput[] = "userInput"; constexpr char kAdPasswordInput[] = "passwordInput"; -constexpr char kAdButton[] = "button"; +constexpr char kAdCredsButton[] = "adCreds /deep/ #button"; +constexpr char kAdPasswordChangeButton[] = "button"; constexpr char kAdWelcomMessage[] = "welcomeMsg"; constexpr char kAdAutocompleteRealm[] = "userInput /deep/ #domainLabel"; @@ -288,7 +289,7 @@ ".value='" + username + "'"); js_checker().ExecuteAsync(JSElement(kAdOfflineAuthId, kAdPasswordInput) + ".value='" + password + "'"); - js_checker().Evaluate(JSElement(kAdOfflineAuthId, kAdButton) + + js_checker().Evaluate(JSElement(kAdOfflineAuthId, kAdCredsButton) + ".fire('tap')"); } @@ -306,8 +307,9 @@ js_checker().ExecuteAsync( JSElement(kAdPasswordChangeId, kAdNewPassword2Input) + ".value='" + new_password2 + "'"); - js_checker().Evaluate(JSElement(kAdPasswordChangeId, kAdButton) + - ".fire('tap')"); + js_checker().Evaluate( + JSElement(kAdPasswordChangeId, kAdPasswordChangeButton) + + ".fire('tap')"); } void SetupActiveDirectoryJSNotifications() {
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc index 306878ba..ee49c21 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.cc +++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chromeos/settings/cros_settings_names.h" @@ -41,6 +40,7 @@ #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/common/features/feature_session_type.h" #include "net/base/network_change_notifier.h" +#include "ui/base/ui_base_features.h" #include "ui/keyboard/keyboard_util.h" namespace chromeos { @@ -320,7 +320,7 @@ profile_->InitChromeOSPreferences(); // Reset virtual keyboard to use IME engines in app profile early. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { if (keyboard::IsKeyboardEnabled()) ash::Shell::Get()->EnableKeyboard(); } else {
diff --git a/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc b/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc index bd71625..59cabfb 100644 --- a/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc +++ b/chrome/browser/chromeos/login/bluetooth_host_pairing_browsertest.cc
@@ -237,7 +237,7 @@ } // This is the class to simulate the OOBE process for devices that have -// sufficient input, i.e., the first screen of OOBE is the network screen. +// sufficient input, i.e., the first screen of OOBE is the welcome screen. // The device will not put itself in Bluetooth discoverable mode until the user // manually trigger it using the proper accelerator. class BluetoothHostPairingWithInputTest @@ -257,7 +257,7 @@ // the Bluetooth is disabled by default. IN_PROC_BROWSER_TEST_F(BluetoothHostPairingWithInputTest, BluetoothDisableByDefault) { - OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait(); EXPECT_FALSE(controller()); EXPECT_FALSE(bluetooth_adapter()); }
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.cc b/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.cc index b653d99..c5c45ae 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.cc
@@ -135,7 +135,7 @@ DCHECK(!policy_dir_.empty()); if (!ok) { - SetupFailed(*message); + SetupFailed(*message, false); return; } @@ -155,16 +155,18 @@ void DemoSetupController::OnEnrollmentError(policy::EnrollmentStatus status) { // TODO(mukai): improve the message details. - SetupFailed(base::StringPrintf( - "EnrollmentError: status: %d client_status: %d store_status: %d " - "validation_status: %d lock_status: %d", - status.status(), status.client_status(), status.store_status(), - status.validation_status(), status.lock_status())); + SetupFailed( + base::StringPrintf( + "EnrollmentError: status: %d client_status: %d store_status: %d " + "validation_status: %d lock_status: %d", + status.status(), status.client_status(), status.store_status(), + status.validation_status(), status.lock_status()), + false); } void DemoSetupController::OnOtherError( EnterpriseEnrollmentHelper::OtherError error) { - SetupFailed(base::StringPrintf("Other error: %d", error)); + SetupFailed(base::StringPrintf("Other error: %d", error), false); } void DemoSetupController::OnDeviceEnrolled( @@ -213,13 +215,13 @@ if (!blob.has_value()) { // This is very unlikely to happen since the file existence is already // checked as CheckOfflinePolicyFilesExist. - SetupFailed("Policy file for the device local account not found"); + SetupFailed("Policy file for the device local account not found", true); return; } enterprise_management::PolicyFetchResponse policy; if (!policy.ParseFromString(blob.value())) { - SetupFailed("Error parsing local account policy blob."); + SetupFailed("Error parsing local account policy blob.", true); return; } @@ -227,7 +229,7 @@ enterprise_management::PolicyData policy_data; if (policy.policy_data().empty() || !policy_data.ParseFromString(policy.policy_data())) { - SetupFailed("Error parsing local account policy data."); + SetupFailed("Error parsing local account policy data.", true); return; } @@ -239,16 +241,17 @@ } if (!device_local_account_policy_store_) { - SetupFailed("Can't find the store for the local account policy."); + SetupFailed("Can't find the store for the local account policy.", true); return; } device_local_account_policy_store_->AddObserver(this); device_local_account_policy_store_->Store(policy); } -void DemoSetupController::SetupFailed(const std::string& message) { +void DemoSetupController::SetupFailed(const std::string& message, bool fatal) { Reset(); - delegate_->OnSetupError(message); + LOG(ERROR) << message << " fatal=" << fatal; + delegate_->OnSetupError(fatal); } void DemoSetupController::Reset() { @@ -272,8 +275,7 @@ void DemoSetupController::OnStoreError(policy::CloudPolicyStore* store) { DCHECK_EQ(store, device_local_account_policy_store_); - Reset(); - delegate_->OnSetupError("Failed to store the local account policy"); + SetupFailed("Failed to store the local account policy", true); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.h b/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.h index e9d2ffc..5ff7322b 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.h +++ b/chrome/browser/chromeos/login/demo_mode/demo_setup_controller.h
@@ -26,9 +26,9 @@ public: virtual ~Delegate() = default; - // Called when the setup flow finished with error. |message| contains - // the error message to describe the error details. - virtual void OnSetupError(const std::string& message) = 0; + // Called when the setup flow finished with error. |fatal| is true if the + // error isn't recoverable and needs powerwash. + virtual void OnSetupError(bool fatal) = 0; // Called when the setup flow finished successfully. virtual void OnSetupSuccess() = 0; @@ -68,7 +68,7 @@ void OnDeviceLocalAccountPolicyLoaded(base::Optional<std::string> blob); // Finish the flow with an error message. - void SetupFailed(const std::string& message); + void SetupFailed(const std::string& message, bool fatal); // Clears the internal state. void Reset();
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_setup_controller_unittest.cc b/chrome/browser/chromeos/login/demo_mode/demo_setup_controller_unittest.cc index 7d7751b8..176aa72 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_setup_controller_unittest.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_setup_controller_unittest.cc
@@ -30,9 +30,10 @@ : run_loop_(std::make_unique<base::RunLoop>()) {} ~MockDemoSetupControllerDelegate() override = default; - void OnSetupError(const std::string&) override { + void OnSetupError(bool fatal) override { EXPECT_FALSE(succeeded_.has_value()); succeeded_ = false; + fatal_ = fatal; run_loop_->Quit(); } @@ -50,6 +51,9 @@ return succeeded_.has_value() && succeeded_.value() == expected; } + // Returns true if it receives a fatal error. + bool IsErrorFatal() const { return fatal_; } + void Reset() { succeeded_.reset(); run_loop_ = std::make_unique<base::RunLoop>(); @@ -57,6 +61,7 @@ private: base::Optional<bool> succeeded_; + bool fatal_ = false; std::unique_ptr<base::RunLoop> run_loop_; DISALLOW_COPY_AND_ASSIGN(MockDemoSetupControllerDelegate); @@ -202,6 +207,7 @@ tested_controller_->EnrollOffline( base::FilePath(FILE_PATH_LITERAL("/no/such/path"))); EXPECT_TRUE(delegate_->WaitResult(false)); + EXPECT_FALSE(delegate_->IsErrorFatal()); } TEST_F(DemoSetupControllerTest, OfflineDeviceLocalAccountPolicyStoreFailed) { @@ -218,6 +224,7 @@ tested_controller_->EnrollOffline(temp_dir.GetPath()); EXPECT_TRUE(delegate_->WaitResult(false)); + EXPECT_TRUE(delegate_->IsErrorFatal()); } TEST_F(DemoSetupControllerTest, OfflineInvalidDeviceLocalAccountPolicyBlob) { @@ -229,6 +236,7 @@ tested_controller_->EnrollOffline(temp_dir.GetPath()); EXPECT_TRUE(delegate_->WaitResult(false)); + EXPECT_TRUE(delegate_->IsErrorFatal()); } TEST_F(DemoSetupControllerTest, OfflineError) { @@ -244,6 +252,7 @@ tested_controller_->EnrollOffline(temp_dir.GetPath()); EXPECT_TRUE(delegate_->WaitResult(false)); + EXPECT_FALSE(delegate_->IsErrorFatal()); } TEST_F(DemoSetupControllerTest, OnlineSuccess) { @@ -260,6 +269,7 @@ tested_controller_->EnrollOnline(); EXPECT_TRUE(delegate_->WaitResult(false)); + EXPECT_FALSE(delegate_->IsErrorFatal()); } TEST_F(DemoSetupControllerTest, EnrollTwice) { @@ -268,6 +278,7 @@ tested_controller_->EnrollOnline(); EXPECT_TRUE(delegate_->WaitResult(false)); + EXPECT_FALSE(delegate_->IsErrorFatal()); delegate_->Reset();
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc index ad2fcfc..9cc2673 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
@@ -439,13 +439,15 @@ } void EnrollmentScreen::JoinDomain(const std::string& dm_token, + const std::string& domain_join_config, OnDomainJoinedCallback on_joined_callback) { if (!authpolicy_login_helper_) authpolicy_login_helper_ = std::make_unique<AuthPolicyLoginHelper>(); authpolicy_login_helper_->set_dm_token(dm_token); on_joined_callback_ = std::move(on_joined_callback); - view_->ShowActiveDirectoryScreen(std::string(), std::string(), - authpolicy::ERROR_NONE); + view_->ShowActiveDirectoryScreen( + domain_join_config, std::string() /* machine_name */, + std::string() /* username */, authpolicy::ERROR_NONE); } void EnrollmentScreen::OnActiveDirectoryJoined( @@ -458,7 +460,8 @@ std::move(on_joined_callback_).Run(machine_domain); return; } - view_->ShowActiveDirectoryScreen(machine_name, username, error); + view_->ShowActiveDirectoryScreen(std::string() /* domain_join_config */, + machine_name, username, error); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.h b/chrome/browser/chromeos/login/enrollment/enrollment_screen.h index 2f524e6..799ed28 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.h +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.h
@@ -89,6 +89,7 @@ // ActiveDirectoryJoinDelegate implementation: void JoinDomain(const std::string& dm_token, + const std::string& domain_join_config, OnDomainJoinedCallback on_joined_callback) override; // Used for testing. @@ -117,8 +118,8 @@ TestActiveDirectoryEnrollment_UIErrors); FRIEND_TEST_ALL_PREFIXES(EnterpriseEnrollmentTest, TestActiveDirectoryEnrollment_ErrorCard); - FRIEND_TEST_ALL_PREFIXES(HandsOffNetworkScreenTest, RequiresNoInput); - FRIEND_TEST_ALL_PREFIXES(HandsOffNetworkScreenTest, ContinueClickedOnlyOnce); + FRIEND_TEST_ALL_PREFIXES(HandsOffWelcomeScreenTest, RequiresNoInput); + FRIEND_TEST_ALL_PREFIXES(HandsOffWelcomeScreenTest, ContinueClickedOnlyOnce); FRIEND_TEST_ALL_PREFIXES(ZeroTouchEnrollmentScreenUnitTest, Retry); FRIEND_TEST_ALL_PREFIXES(ZeroTouchEnrollmentScreenUnitTest, TestSuccess); FRIEND_TEST_ALL_PREFIXES(ZeroTouchEnrollmentScreenUnitTest,
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h b/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h index 5e579129..4d41a8b4 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h
@@ -69,7 +69,8 @@ const base::DictionaryValue& license_types) = 0; // Shows the Active Directory domain joining screen. - virtual void ShowActiveDirectoryScreen(const std::string& machine_name, + virtual void ShowActiveDirectoryScreen(const std::string& domain_join_config, + const std::string& machine_name, const std::string& username, authpolicy::ErrorType error) = 0;
diff --git a/chrome/browser/chromeos/login/enrollment/mock_enrollment_screen.h b/chrome/browser/chromeos/login/enrollment/mock_enrollment_screen.h index 8604d6a..437ceaa 100644 --- a/chrome/browser/chromeos/login/enrollment/mock_enrollment_screen.h +++ b/chrome/browser/chromeos/login/enrollment/mock_enrollment_screen.h
@@ -33,8 +33,9 @@ MOCK_METHOD0(ShowSigninScreen, void()); MOCK_METHOD1(ShowLicenseTypeSelectionScreen, void(const base::DictionaryValue&)); - MOCK_METHOD3(ShowActiveDirectoryScreen, - void(const std::string& machine_name, + MOCK_METHOD4(ShowActiveDirectoryScreen, + void(const std::string& domain_join_config, + const std::string& machine_name, const std::string& username, authpolicy::ErrorType error)); MOCK_METHOD2(ShowAttributePromptScreen,
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc index 3af93862..4ad9e33 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -162,8 +162,8 @@ js_checker().ExecuteAsync(set_encryption_types); } js_checker().ExecuteAsync( - "document.querySelector('#oauth-enroll-ad-join-ui /deep/ " - "#button').fire('tap')"); + "document.querySelector('#oauth-enroll-ad-join-ui /deep/ #adCreds" + " /deep/ #button').fire('tap')"); ExecutePendingJavaScript(); } @@ -235,12 +235,13 @@ EnrollUsingAuthCode("test_auth_code", _)) .WillOnce(InvokeWithoutArgs([this, expected_domain]() { this->enrollment_screen()->JoinDomain( - kDMToken, base::BindOnce( - [](const std::string& expected_domain, - const std::string& domain) { - ASSERT_EQ(expected_domain, domain); - }, - expected_domain)); + kDMToken, std::string() /* domain_join_config */, + base::BindOnce( + [](const std::string& expected_domain, + const std::string& domain) { + ASSERT_EQ(expected_domain, domain); + }, + expected_domain)); })); }); } @@ -259,23 +260,25 @@ void SetupActiveDirectoryJSNotifications() { js_checker().ExecuteAsync( - "var testShowStep = login.OAuthEnrollmentScreen.showStep;\n" + "var originalShowStep = login.OAuthEnrollmentScreen.showStep;\n" "login.OAuthEnrollmentScreen.showStep = function(step) {\n" - " testShowStep(step);\n" + " originalShowStep(step);\n" " if (step == 'working') {\n" " window.domAutomationController.send('ShowSpinnerScreen');\n" " }" "}\n" - "var testShowError = login.OAuthEnrollmentScreen.showError;\n" + "var originalShowError = login.OAuthEnrollmentScreen.showError;\n" "login.OAuthEnrollmentScreen.showError = function(message, retry) {\n" - " testShowError(message, retry);\n" + " originalShowError(message, retry);\n" " window.domAutomationController.send('ShowADJoinError');\n" "}\n"); js_checker().ExecuteAsync( - "var testInvalidateAd = login.OAuthEnrollmentScreen.invalidateAd;" - "login.OAuthEnrollmentScreen.invalidateAd = function(machineName, " - "user, errorState) {" - " testInvalidateAd(machineName, user, errorState);" + "var originalSetAdJoinParams =" + " login.OAuthEnrollmentScreen.setAdJoinParams;" + "login.OAuthEnrollmentScreen.setAdJoinParams = function(" + " machineName, user, errorState, showUnlockConfig) {" + " originalSetAdJoinParams(" + " machineName, user, errorState, showUnlockConfig);" " window.domAutomationController.send('ShowJoinDomainError');" "}"); } @@ -432,13 +435,11 @@ content::DOMMessageQueue message_queue; SetupActiveDirectoryJSNotifications(); - authpolicy::KerberosEncryptionTypes enc_types = - authpolicy::KerberosEncryptionTypes::ENC_TYPES_ALL; - SetExpectedJoinRequest("machine_name", "" /* machine_domain */, enc_types, + SetExpectedJoinRequest("machine_name", "" /* machine_domain */, + authpolicy::KerberosEncryptionTypes::ENC_TYPES_ALL, {} /* machine_ou */, kAdTestUser, kDMToken); - SubmitActiveDirectoryCredentials("machine_name", "" /* machine_dn */, - std::to_string(enc_types), kAdTestUser, - "password"); + SubmitActiveDirectoryCredentials("machine_name", "" /* machine_dn */, "all", + kAdTestUser, "password"); WaitForMessage(&message_queue, "\"ShowSpinnerScreen\""); EXPECT_FALSE(IsStepDisplayed("ad-join")); @@ -554,11 +555,8 @@ content::DOMMessageQueue message_queue; SetupActiveDirectoryJSNotifications(); // Legacy type triggers error card. - authpolicy::KerberosEncryptionTypes enc_types = - authpolicy::KerberosEncryptionTypes::ENC_TYPES_LEGACY; SubmitActiveDirectoryCredentials("machine_name", "" /* machine_dn */, - std::to_string(enc_types), "test_user", - "password"); + "legacy", "test_user", "password"); WaitForMessage(&message_queue, "\"ShowADJoinError\""); EXPECT_TRUE(IsStepDisplayed("active-directory-join-error")); ClickRetry();
diff --git a/chrome/browser/chromeos/login/hid_detection_browsertest.cc b/chrome/browser/chromeos/login/hid_detection_browsertest.cc index b3f3f82..c604096 100644 --- a/chrome/browser/chromeos/login/hid_detection_browsertest.cc +++ b/chrome/browser/chromeos/login/hid_detection_browsertest.cc
@@ -110,7 +110,7 @@ } IN_PROC_BROWSER_TEST_F(HidDetectionSkipTest, BothDevicesPreConnected) { - OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait(); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index 80936e0e..d2c9426 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -924,7 +924,7 @@ DISABLED_LaunchAppWithNetworkConfigAccelerator) { ScopedCanConfigureNetwork can_configure_network(true, false); - // Block app loading until the network screen is shown. + // Block app loading until the welcome screen is shown. AppLaunchController::SetBlockAppLaunchForTesting(true); // Start app launch and wait for network connectivity timeout. @@ -1051,7 +1051,7 @@ // Start login screen after configuring auto launch app since the warning // is triggered when switching to login screen. - wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_NETWORK); + wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_WELCOME); ReloadAutolaunchKioskApps(); EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); @@ -1084,7 +1084,7 @@ // Start login screen after configuring auto launch app since the warning // is triggered when switching to login screen. - wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_NETWORK); + wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_WELCOME); ReloadAutolaunchKioskApps(); EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); @@ -1277,7 +1277,7 @@ chromeos::WizardController* wizard_controller = chromeos::WizardController::default_controller(); ASSERT_TRUE(wizard_controller); - wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_NETWORK); + wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_WELCOME); ReloadAutolaunchKioskApps(); wizard_controller->SkipToLoginForTesting(LoginScreenContext()); content::WindowedNotificationObserver( @@ -2474,7 +2474,7 @@ // Start login screen after configuring auto launch app since the warning // is triggered when switching to login screen. - wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_NETWORK); + wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_WELCOME); ReloadAutolaunchKioskApps(); wizard_controller->SkipToLoginForTesting(LoginScreenContext());
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc index 159ebc5..de8dc81 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -40,7 +40,6 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/login_screen_client.h" #include "chrome/browser/ui/ash/session_controller_client.h" #include "chrome/browser/ui/webui/chromeos/login/screenlock_icon_provider.h"
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc index ba72dde..4d1e6532 100644 --- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
@@ -12,7 +12,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h" @@ -22,7 +21,6 @@ #include "chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/lifetime/browser_shutdown.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/session_controller_client.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" @@ -43,6 +41,7 @@ #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/keyboard/keyboard_util.h" @@ -78,7 +77,7 @@ // Bail for mash because IdleDetector/UserActivityDetector does not work // properly there. // TODO(xiyuan): Revisit after http://crbug.com/626899. - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) return false; Profile* profile = ProfileHelper::Get()->GetProfileByUser( @@ -144,7 +143,7 @@ gfx::Rect bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); lock_time_ = base::TimeTicks::Now(); - lock_window_ = new ash::LockWindow(chromeos::GetAshConfig()); + lock_window_ = new ash::LockWindow(); lock_window_->AddObserver(this); Init();
diff --git a/chrome/browser/chromeos/login/login_ui_browsertest.cc b/chrome/browser/chromeos/login/login_ui_browsertest.cc index c16ac29d..e70a505 100644 --- a/chrome/browser/chromeos/login/login_ui_browsertest.cc +++ b/chrome/browser/chromeos/login/login_ui_browsertest.cc
@@ -86,10 +86,10 @@ prefs->SetBoolean(prefs::kDeviceEnrollmentCanExit, false); } -// Tests that the default first screen is the network screen after OOBE +// Tests that the default first screen is the welcome screen after OOBE // when auto enrollment is enabled and device is not yet enrolled. IN_PROC_BROWSER_TEST_F(LoginUITest, InterruptedAutoStartEnrollment) { - OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait(); } IN_PROC_BROWSER_TEST_F(LoginUITest, OobeNoExceptions) {
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc index 612419c..d3272ccf 100644 --- a/chrome/browser/chromeos/login/login_utils_browsertest.cc +++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -4,14 +4,12 @@ #include <string> -#include "ash/public/cpp/config.h" #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/login/screens/gaia_view.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" @@ -31,6 +29,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_response.h" #include "rlz/buildflags/buildflags.h" +#include "ui/base/ui_base_features.h" #if BUILDFLAG(ENABLE_RLZ) #include "base/task_scheduler/post_task.h" @@ -80,7 +79,7 @@ // Exercises login, like the desktopui_MashLogin Chrome OS autotest. IN_PROC_BROWSER_TEST_F(LoginUtilsTest, MashLogin) { - if (GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) return; WaitForSigninScreen();
diff --git a/chrome/browser/chromeos/login/oobe_localization_browsertest.cc b/chrome/browser/chromeos/login/oobe_localization_browsertest.cc index 26c280a1..3338af6 100644 --- a/chrome/browser/chromeos/login/oobe_localization_browsertest.cc +++ b/chrome/browser/chromeos/login/oobe_localization_browsertest.cc
@@ -15,7 +15,7 @@ #include "chrome/browser/chromeos/customization/customization_document.h" #include "chrome/browser/chromeos/login/login_manager_test.h" #include "chrome/browser/chromeos/login/login_wizard.h" -#include "chrome/browser/chromeos/login/screens/network_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/wizard_controller.h" @@ -90,19 +90,19 @@ DISALLOW_COPY_AND_ASSIGN(TimedRunLoop); }; -class LanguageListWaiter : public NetworkScreen::Observer { +class LanguageListWaiter : public WelcomeScreen::Observer { public: LanguageListWaiter() - : network_screen_(NetworkScreen::Get( + : welcome_screen_(WelcomeScreen::Get( WizardController::default_controller()->screen_manager())), loop_(base::TimeDelta::FromSeconds(kTimeoutSeconds), "LanguageList") { - network_screen_->AddObserver(this); + welcome_screen_->AddObserver(this); CheckLanguageList(); } - ~LanguageListWaiter() override { network_screen_->RemoveObserver(this); } + ~LanguageListWaiter() override { welcome_screen_->RemoveObserver(this); } - // NetworkScreen::Observer implementation: + // WelcomeScreen::Observer implementation: void OnLanguageListReloaded() override { CheckLanguageList(); } // Returns true on success, false on timeout. @@ -114,14 +114,14 @@ } private: - bool LanguageListReady() const { return network_screen_->language_list(); } + bool LanguageListReady() const { return welcome_screen_->language_list(); } void CheckLanguageList() { if (LanguageListReady()) loop_.Quit(); } - NetworkScreen* network_screen_; + WelcomeScreen* welcome_screen_; TimedRunLoop loop_; }; @@ -160,7 +160,7 @@ {"de", "xkb:ch::ger", "de", "xkb:ch::ger", "xkb:ch::ger,[xkb:de::ger,xkb:de:neo:ger,xkb:be::ger,xkb:us::eng]"}, - // NetworkScreenMultipleLocales + // WelcomeScreenMultipleLocales {"es,en-US,nl", "xkb:be::nld", "es,en-US,nl", "xkb:be::nld", "xkb:be::nld,[xkb:es::spa,xkb:latam::spa,xkb:us::eng]"},
diff --git a/chrome/browser/chromeos/login/oobe_screen.cc b/chrome/browser/chromeos/login/oobe_screen.cc index 727c7a5..cb32c20 100644 --- a/chrome/browser/chromeos/login/oobe_screen.cc +++ b/chrome/browser/chromeos/login/oobe_screen.cc
@@ -18,7 +18,7 @@ // in the same order as the Screen enum. const char* kScreenNames[] = { "hid-detection", // SCREEN_OOBE_HID_DETECTION - "connect", // SCREEN_OOBE_NETWORK + "connect", // SCREEN_OOBE_WELCOME "eula", // SCREEN_OOBE_EULA "update", // SCREEN_OOBE_UPDATE "debugging", // SCREEN_OOBE_ENABLE_DEBUGGING
diff --git a/chrome/browser/chromeos/login/oobe_screen.h b/chrome/browser/chromeos/login/oobe_screen.h index 62cc8ed..fc74346 100644 --- a/chrome/browser/chromeos/login/oobe_screen.h +++ b/chrome/browser/chromeos/login/oobe_screen.h
@@ -16,7 +16,7 @@ // update kScreenNames in the cc file as well. enum class OobeScreen : unsigned int { SCREEN_OOBE_HID_DETECTION = 0, - SCREEN_OOBE_NETWORK, + SCREEN_OOBE_WELCOME, SCREEN_OOBE_EULA, SCREEN_OOBE_UPDATE, SCREEN_OOBE_ENABLE_DEBUGGING,
diff --git a/chrome/browser/chromeos/login/screens/base_screen.h b/chrome/browser/chromeos/login/screens/base_screen.h index d9f5d56..9761fb1 100644 --- a/chrome/browser/chromeos/login/screens/base_screen.h +++ b/chrome/browser/chromeos/login/screens/base_screen.h
@@ -128,11 +128,11 @@ TestCancel); FRIEND_TEST_ALL_PREFIXES(MultiAuthEnrollmentScreenTest, TestCancel); FRIEND_TEST_ALL_PREFIXES(ProvisionedEnrollmentScreenTest, TestBackButton); - FRIEND_TEST_ALL_PREFIXES(HandsOffNetworkScreenTest, RequiresNoInput); - FRIEND_TEST_ALL_PREFIXES(HandsOffNetworkScreenTest, ContinueClickedOnlyOnce); + FRIEND_TEST_ALL_PREFIXES(HandsOffWelcomeScreenTest, RequiresNoInput); + FRIEND_TEST_ALL_PREFIXES(HandsOffWelcomeScreenTest, ContinueClickedOnlyOnce); friend class BaseWebUIHandler; - friend class NetworkScreenTest; + friend class WelcomeScreenTest; friend class ScreenEditor; friend class ScreenManager; friend class UpdateScreenTest;
diff --git a/chrome/browser/chromeos/login/screens/demo_setup_screen.cc b/chrome/browser/chromeos/login/screens/demo_setup_screen.cc index f5f7eb2..77f51fcc 100644 --- a/chrome/browser/chromeos/login/screens/demo_setup_screen.cc +++ b/chrome/browser/chromeos/login/screens/demo_setup_screen.cc
@@ -61,9 +61,8 @@ } } -void DemoSetupScreen::OnSetupError(const std::string& message) { - LOG(ERROR) << "Failure on setting up demo mode: " << message; - // TODO(mukai): show the error messages on screen. +void DemoSetupScreen::OnSetupError(bool fatal) { + // TODO(mukai): propagate |fatal| information and change the error message. } void DemoSetupScreen::OnSetupSuccess() {
diff --git a/chrome/browser/chromeos/login/screens/demo_setup_screen.h b/chrome/browser/chromeos/login/screens/demo_setup_screen.h index dd3def4..dec3b8a 100644 --- a/chrome/browser/chromeos/login/screens/demo_setup_screen.h +++ b/chrome/browser/chromeos/login/screens/demo_setup_screen.h
@@ -30,7 +30,7 @@ void OnUserAction(const std::string& action_id) override; // DemoSetupManager::Delegate: - void OnSetupError(const std::string& message) override; + void OnSetupError(bool fatal) override; void OnSetupSuccess() override; // Called when view is being destroyed. If Screen is destroyed earlier
diff --git a/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc index 1ae76e6..5344799 100644 --- a/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/hid_detection_screen_browsertest.cc
@@ -156,7 +156,7 @@ // Simulate the user's click on "Continue" button. hid_detection_screen()->OnContinueButtonClicked(); - OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait(); // The adapter should not be powered off at this moment. EXPECT_TRUE(adapter()->IsPowered()); @@ -173,7 +173,7 @@ // Simulate the user's click on "Continue" button. hid_detection_screen()->OnContinueButtonClicked(); - OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait(); + OobeScreenWaiter(OobeScreen::SCREEN_OOBE_WELCOME).Wait(); // The adapter should be powered off at this moment. EXPECT_FALSE(adapter()->IsPowered());
diff --git a/chrome/browser/chromeos/login/screens/mock_network_screen.cc b/chrome/browser/chromeos/login/screens/mock_network_screen.cc deleted file mode 100644 index b6e9f6e..0000000 --- a/chrome/browser/chromeos/login/screens/mock_network_screen.cc +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/login/screens/mock_network_screen.h" - -namespace chromeos { - -using ::testing::AtLeast; -using ::testing::_; - -MockNetworkScreen::MockNetworkScreen(BaseScreenDelegate* base_screen_delegate, - Delegate* delegate, - NetworkView* view) - : NetworkScreen(base_screen_delegate, delegate, view) {} - -MockNetworkScreen::~MockNetworkScreen() {} - -MockNetworkView::MockNetworkView() { - EXPECT_CALL(*this, MockBind(_)).Times(AtLeast(1)); -} - -MockNetworkView::~MockNetworkView() { - if (screen_) - screen_->OnViewDestroyed(this); -} - -void MockNetworkView::Bind(NetworkScreen* screen) { - screen_ = screen; - MockBind(screen); -} - -void MockNetworkView::Unbind() { - screen_ = nullptr; - MockUnbind(); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/mock_network_screen.h b/chrome/browser/chromeos/login/screens/mock_network_screen.h deleted file mode 100644 index 965d6243..0000000 --- a/chrome/browser/chromeos/login/screens/mock_network_screen.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_NETWORK_SCREEN_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_NETWORK_SCREEN_H_ - -#include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" -#include "chrome/browser/chromeos/login/screens/network_screen.h" -#include "chrome/browser/chromeos/login/screens/network_view.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace chromeos { - -class MockNetworkScreen : public NetworkScreen { - public: - MockNetworkScreen(BaseScreenDelegate* base_screen_delegate, - Delegate* delegate, - NetworkView* view); - ~MockNetworkScreen() override; - - MOCK_METHOD0(Show, void()); - MOCK_METHOD0(Hide, void()); -}; - -class MockNetworkView : public NetworkView { - public: - MockNetworkView(); - ~MockNetworkView() override; - - void Bind(NetworkScreen* screen) override; - void Unbind() override; - - MOCK_METHOD1(MockBind, void(NetworkScreen* screen)); - MOCK_METHOD0(MockUnbind, void()); - MOCK_METHOD0(Show, void()); - MOCK_METHOD0(Hide, void()); - MOCK_METHOD1(ShowError, void(const base::string16& message)); - MOCK_METHOD0(ClearErrors, void()); - MOCK_METHOD0(StopDemoModeDetection, void()); - MOCK_METHOD2(ShowConnectingStatus, - void(bool connecting, const base::string16& network_id)); - MOCK_METHOD1(EnableContinue, void(bool enabled)); - MOCK_METHOD0(ReloadLocalizedContent, void()); - - private: - NetworkScreen* screen_ = nullptr; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_NETWORK_SCREEN_H_
diff --git a/chrome/browser/chromeos/login/screens/mock_welcome_screen.cc b/chrome/browser/chromeos/login/screens/mock_welcome_screen.cc new file mode 100644 index 0000000..c6b336e --- /dev/null +++ b/chrome/browser/chromeos/login/screens/mock_welcome_screen.cc
@@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/login/screens/mock_welcome_screen.h" + +namespace chromeos { + +using ::testing::AtLeast; +using ::testing::_; + +MockWelcomeScreen::MockWelcomeScreen(BaseScreenDelegate* base_screen_delegate, + Delegate* delegate, + WelcomeView* view) + : WelcomeScreen(base_screen_delegate, delegate, view) {} + +MockWelcomeScreen::~MockWelcomeScreen() {} + +MockWelcomeView::MockWelcomeView() { + EXPECT_CALL(*this, MockBind(_)).Times(AtLeast(1)); +} + +MockWelcomeView::~MockWelcomeView() { + if (screen_) + screen_->OnViewDestroyed(this); +} + +void MockWelcomeView::Bind(WelcomeScreen* screen) { + screen_ = screen; + MockBind(screen); +} + +void MockWelcomeView::Unbind() { + screen_ = nullptr; + MockUnbind(); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/mock_welcome_screen.h b/chrome/browser/chromeos/login/screens/mock_welcome_screen.h new file mode 100644 index 0000000..722f442 --- /dev/null +++ b/chrome/browser/chromeos/login/screens/mock_welcome_screen.h
@@ -0,0 +1,52 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_WELCOME_SCREEN_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_WELCOME_SCREEN_H_ + +#include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_view.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace chromeos { + +class MockWelcomeScreen : public WelcomeScreen { + public: + MockWelcomeScreen(BaseScreenDelegate* base_screen_delegate, + Delegate* delegate, + WelcomeView* view); + ~MockWelcomeScreen() override; + + MOCK_METHOD0(Show, void()); + MOCK_METHOD0(Hide, void()); +}; + +class MockWelcomeView : public WelcomeView { + public: + MockWelcomeView(); + ~MockWelcomeView() override; + + void Bind(WelcomeScreen* screen) override; + void Unbind() override; + + MOCK_METHOD1(MockBind, void(WelcomeScreen* screen)); + MOCK_METHOD0(MockUnbind, void()); + MOCK_METHOD0(Show, void()); + MOCK_METHOD0(Hide, void()); + MOCK_METHOD1(ShowError, void(const base::string16& message)); + MOCK_METHOD0(ClearErrors, void()); + MOCK_METHOD0(StopDemoModeDetection, void()); + MOCK_METHOD2(ShowConnectingStatus, + void(bool connecting, const base::string16& network_id)); + MOCK_METHOD1(EnableContinue, void(bool enabled)); + MOCK_METHOD0(ReloadLocalizedContent, void()); + + private: + WelcomeScreen* screen_ = nullptr; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_WELCOME_SCREEN_H_
diff --git a/chrome/browser/chromeos/login/screens/screen_exit_code.h b/chrome/browser/chromeos/login/screens/screen_exit_code.h index 1510541..8af7d7c9 100644 --- a/chrome/browser/chromeos/login/screens/screen_exit_code.h +++ b/chrome/browser/chromeos/login/screens/screen_exit_code.h
@@ -19,7 +19,7 @@ // Numeric ids are provided to facilitate interpretation of log files only, // they are subject to change without notice. enum class ScreenExitCode { - // "Continue" was pressed on network screen and network is online. + // "Continue" was pressed on welcome screen and network is online. NETWORK_CONNECTED = 0, HID_DETECTION_COMPLETED = 1, // Connection failed while trying to load a WebPageScreen.
diff --git a/chrome/browser/chromeos/login/screens/update_view.h b/chrome/browser/chromeos/login/screens/update_view.h index 3d273f6..dc9c851 100644 --- a/chrome/browser/chromeos/login/screens/update_view.h +++ b/chrome/browser/chromeos/login/screens/update_view.h
@@ -12,7 +12,7 @@ class UpdateScreen; -// Interface for dependency injection between NetworkScreen and its actual +// Interface for dependency injection between WelcomeScreen and its actual // representation. Owned by UpdateScreen. class UpdateView { public:
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc index adbf64a..2476db8 100644 --- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc +++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -360,6 +360,10 @@ proximity_auth::ScreenlockBridge::Get()->SetLockHandler(this); } +bool UserSelectionScreen::HasAnyUsers() const { + return !users_.empty(); +} + // static void UserSelectionScreen::FillUserDictionary( user_manager::User* user,
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.h b/chrome/browser/chromeos/login/screens/user_selection_screen.h index 8ddccf9..a6b6dc98 100644 --- a/chrome/browser/chromeos/login/screens/user_selection_screen.h +++ b/chrome/browser/chromeos/login/screens/user_selection_screen.h
@@ -65,11 +65,12 @@ void AttemptEasyUnlock(const AccountId& account_id); void RecordClickOnLockIcon(const AccountId& account_id); + void InitEasyUnlock(); + bool HasAnyUsers() const; + // ui::UserActivityDetector implementation: void OnUserActivity(const ui::Event* event) override; - void InitEasyUnlock(); - // proximity_auth::ScreenlockBridge::LockHandler implementation: void ShowBannerMessage(const base::string16& message, bool is_warning) override;
diff --git a/chrome/browser/chromeos/login/screens/network_screen.cc b/chrome/browser/chromeos/login/screens/welcome_screen.cc similarity index 79% rename from chrome/browser/chromeos/login/screens/network_screen.cc rename to chrome/browser/chromeos/login/screens/welcome_screen.cc index 3a2ee916..36f1b02 100644 --- a/chrome/browser/chromeos/login/screens/network_screen.cc +++ b/chrome/browser/chromeos/login/screens/welcome_screen.cc
@@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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/chromeos/login/screens/network_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include <utility> @@ -18,7 +18,7 @@ #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/screen_manager.h" #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" -#include "chrome/browser/chromeos/login/screens/network_view.h" +#include "chrome/browser/chromeos/login/screens/welcome_view.h" #include "chrome/browser/chromeos/login/ui/input_events_blocker.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/system/timezone_util.h" @@ -50,18 +50,18 @@ namespace chromeos { /////////////////////////////////////////////////////////////////////////////// -// NetworkScreen, public: +// WelcomeScreen, public: // static -NetworkScreen* NetworkScreen::Get(ScreenManager* manager) { - return static_cast<NetworkScreen*>( - manager->GetScreen(OobeScreen::SCREEN_OOBE_NETWORK)); +WelcomeScreen* WelcomeScreen::Get(ScreenManager* manager) { + return static_cast<WelcomeScreen*>( + manager->GetScreen(OobeScreen::SCREEN_OOBE_WELCOME)); } -NetworkScreen::NetworkScreen(BaseScreenDelegate* base_screen_delegate, +WelcomeScreen::WelcomeScreen(BaseScreenDelegate* base_screen_delegate, Delegate* delegate, - NetworkView* view) - : BaseScreen(base_screen_delegate, OobeScreen::SCREEN_OOBE_NETWORK), + WelcomeView* view) + : BaseScreen(base_screen_delegate, OobeScreen::SCREEN_OOBE_WELCOME), view_(view), delegate_(delegate), network_state_helper_(new login::NetworkStateHelper), @@ -75,7 +75,7 @@ UpdateLanguageList(); } -NetworkScreen::~NetworkScreen() { +WelcomeScreen::~WelcomeScreen() { if (view_) view_->Unbind(); connection_timer_.Stop(); @@ -85,24 +85,24 @@ } //////////////////////////////////////////////////////////////////////////////// -// NetworkScreen, public API, setters and getters for input method and timezone. +// WelcomeScreen, public API, setters and getters for input method and timezone. -void NetworkScreen::OnViewDestroyed(NetworkView* view) { +void WelcomeScreen::OnViewDestroyed(WelcomeView* view) { if (view_ == view) { view_ = nullptr; timezone_subscription_.reset(); - // Ownership of NetworkScreen is complicated; ensure that we remove + // Ownership of WelcomeScreen is complicated; ensure that we remove // this as a NetworkStateHandler observer when the view is destroyed. UnsubscribeNetworkNotification(); } } -void NetworkScreen::UpdateLanguageList() { +void WelcomeScreen::UpdateLanguageList() { ScheduleResolveLanguageList( std::unique_ptr<locale_util::LanguageSwitchResult>()); } -void NetworkScreen::SetApplicationLocaleAndInputMethod( +void WelcomeScreen::SetApplicationLocaleAndInputMethod( const std::string& locale, const std::string& input_method) { const std::string& app_locale = g_browser_process->GetApplicationLocale(); @@ -115,22 +115,22 @@ // Block UI while resource bundle is being reloaded. // (InputEventsBlocker will live until callback is finished.) locale_util::SwitchLanguageCallback callback(base::Bind( - &NetworkScreen::OnLanguageChangedCallback, weak_factory_.GetWeakPtr(), + &WelcomeScreen::OnLanguageChangedCallback, weak_factory_.GetWeakPtr(), base::Owned(new chromeos::InputEventsBlocker), input_method)); locale_util::SwitchLanguage(locale, true /* enableLocaleKeyboardLayouts */, true /* login_layouts_only */, callback, ProfileManager::GetActiveUserProfile()); } -std::string NetworkScreen::GetApplicationLocale() { +std::string WelcomeScreen::GetApplicationLocale() { return g_browser_process->GetApplicationLocale(); } -std::string NetworkScreen::GetInputMethod() const { +std::string WelcomeScreen::GetInputMethod() const { return input_method_; } -void NetworkScreen::SetTimezone(const std::string& timezone_id) { +void WelcomeScreen::SetTimezone(const std::string& timezone_id) { if (timezone_id.empty()) return; @@ -138,18 +138,18 @@ chromeos::system::SetSystemAndSigninScreenTimezone(timezone_id); } -std::string NetworkScreen::GetTimezone() const { +std::string WelcomeScreen::GetTimezone() const { return timezone_; } -void NetworkScreen::GetConnectedWifiNetwork(std::string* out_onc_spec) { +void WelcomeScreen::GetConnectedWifiNetwork(std::string* out_onc_spec) { // Currently We can only transfer unsecured WiFi configuration from shark to // remora. There is no way to get password for a secured Wifi network in Cros // for security reasons. network_state_helper_->GetConnectedWifiNetwork(out_onc_spec); } -void NetworkScreen::CreateAndConnectNetworkFromOnc( +void WelcomeScreen::CreateAndConnectNetworkFromOnc( const std::string& onc_spec, const base::Closure& success_callback, const network_handler::ErrorCallback& error_callback) { @@ -157,12 +157,12 @@ onc_spec, success_callback, error_callback); } -void NetworkScreen::AddObserver(Observer* observer) { +void WelcomeScreen::AddObserver(Observer* observer) { if (observer) observers_.AddObserver(observer); } -void NetworkScreen::RemoveObserver(Observer* observer) { +void WelcomeScreen::RemoveObserver(Observer* observer) { if (observer) observers_.RemoveObserver(observer); } @@ -170,7 +170,7 @@ //////////////////////////////////////////////////////////////////////////////// // BaseScreen implementation: -void NetworkScreen::Show() { +void WelcomeScreen::Show() { Refresh(); // Here we should handle default locales, for which we do not have UI @@ -189,13 +189,13 @@ view_->Show(); } -void NetworkScreen::Hide() { +void WelcomeScreen::Hide() { timezone_subscription_.reset(); if (view_) view_->Hide(); } -void NetworkScreen::OnUserAction(const std::string& action_id) { +void WelcomeScreen::OnUserAction(const std::string& action_id) { if (action_id == kUserActionContinueButtonClicked) { OnContinueButtonPressed(); } else if (action_id == kUserActionConnectDebuggingFeaturesClicked) { @@ -206,7 +206,7 @@ } } -void NetworkScreen::OnContextKeyUpdated( +void WelcomeScreen::OnContextKeyUpdated( const ::login::ScreenContext::KeyType& key) { if (key == kContextKeyLocale) SetApplicationLocale(context_.GetString(kContextKeyLocale)); @@ -219,20 +219,20 @@ } //////////////////////////////////////////////////////////////////////////////// -// NetworkScreen, NetworkStateHandlerObserver implementation: +// WelcomeScreen, NetworkStateHandlerObserver implementation: -void NetworkScreen::NetworkConnectionStateChanged(const NetworkState* network) { +void WelcomeScreen::NetworkConnectionStateChanged(const NetworkState* network) { UpdateStatus(); } -void NetworkScreen::DefaultNetworkChanged(const NetworkState* network) { +void WelcomeScreen::DefaultNetworkChanged(const NetworkState* network) { UpdateStatus(); } //////////////////////////////////////////////////////////////////////////////// -// NetworkScreen, InputMethodManager::Observer implementation: +// WelcomeScreen, InputMethodManager::Observer implementation: -void NetworkScreen::InputMethodChanged( +void WelcomeScreen::InputMethodChanged( input_method::InputMethodManager* manager, Profile* /* proflie */, bool /* show_message */) { @@ -242,9 +242,9 @@ } //////////////////////////////////////////////////////////////////////////////// -// NetworkScreen, private: +// WelcomeScreen, private: -void NetworkScreen::SetApplicationLocale(const std::string& locale) { +void WelcomeScreen::SetApplicationLocale(const std::string& locale) { const std::string& app_locale = g_browser_process->GetApplicationLocale(); if (app_locale == locale || locale.empty()) return; @@ -252,14 +252,14 @@ // Block UI while resource bundle is being reloaded. // (InputEventsBlocker will live until callback is finished.) locale_util::SwitchLanguageCallback callback(base::Bind( - &NetworkScreen::OnLanguageChangedCallback, weak_factory_.GetWeakPtr(), + &WelcomeScreen::OnLanguageChangedCallback, weak_factory_.GetWeakPtr(), base::Owned(new chromeos::InputEventsBlocker), std::string())); locale_util::SwitchLanguage(locale, true /* enableLocaleKeyboardLayouts */, true /* login_layouts_only */, callback, ProfileManager::GetActiveUserProfile()); } -void NetworkScreen::SetInputMethod(const std::string& input_method) { +void WelcomeScreen::SetInputMethod(const std::string& input_method) { const std::vector<std::string>& input_methods = input_method::InputMethodManager::Get() ->GetActiveIMEState() @@ -275,23 +275,23 @@ ->ChangeInputMethod(input_method_, false /* show_message */); } -void NetworkScreen::InitializeTimezoneObserver() { +void WelcomeScreen::InitializeTimezoneObserver() { timezone_subscription_ = CrosSettings::Get()->AddSettingsObserver( - kSystemTimezone, base::Bind(&NetworkScreen::OnSystemTimezoneChanged, + kSystemTimezone, base::Bind(&WelcomeScreen::OnSystemTimezoneChanged, base::Unretained(this))); } -void NetworkScreen::Refresh() { +void WelcomeScreen::Refresh() { SubscribeNetworkNotification(); UpdateStatus(); } -void NetworkScreen::SetNetworkStateHelperForTest( +void WelcomeScreen::SetNetworkStateHelperForTest( login::NetworkStateHelper* helper) { network_state_helper_.reset(helper); } -void NetworkScreen::SubscribeNetworkNotification() { +void WelcomeScreen::SubscribeNetworkNotification() { if (!is_network_subscribed_) { is_network_subscribed_ = true; NetworkHandler::Get()->network_state_handler()->AddObserver(this, @@ -299,7 +299,7 @@ } } -void NetworkScreen::UnsubscribeNetworkNotification() { +void WelcomeScreen::UnsubscribeNetworkNotification() { if (is_network_subscribed_) { is_network_subscribed_ = false; NetworkHandler::Get()->network_state_handler()->RemoveObserver(this, @@ -307,14 +307,14 @@ } } -void NetworkScreen::NotifyOnConnection() { +void WelcomeScreen::NotifyOnConnection() { // TODO(nkostylev): Check network connectivity. UnsubscribeNetworkNotification(); connection_timer_.Stop(); Finish(ScreenExitCode::NETWORK_CONNECTED); } -void NetworkScreen::OnConnectionTimeout() { +void WelcomeScreen::OnConnectionTimeout() { StopWaitingForConnection(network_id_); if (!network_state_helper_->IsConnected() && view_) { // Show error bubble. @@ -324,7 +324,7 @@ } } -void NetworkScreen::UpdateStatus() { +void WelcomeScreen::UpdateStatus() { if (!view_) return; @@ -341,7 +341,7 @@ StopWaitingForConnection(network_id_); } -void NetworkScreen::StopWaitingForConnection(const base::string16& network_id) { +void WelcomeScreen::StopWaitingForConnection(const base::string16& network_id) { bool is_connected = network_state_helper_->IsConnected(); if (is_connected && continue_pressed_) { NotifyOnConnection(); @@ -362,12 +362,12 @@ } } -void NetworkScreen::WaitForConnection(const base::string16& network_id) { +void WelcomeScreen::WaitForConnection(const base::string16& network_id) { if (network_id_ != network_id || !connection_timer_.IsRunning()) { connection_timer_.Stop(); connection_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kConnectionTimeoutSec), - this, &NetworkScreen::OnConnectionTimeout); + this, &WelcomeScreen::OnConnectionTimeout); } network_id_ = network_id; @@ -375,7 +375,7 @@ view_->ShowConnectingStatus(continue_pressed_, network_id_); } -void NetworkScreen::OnContinueButtonPressed() { +void WelcomeScreen::OnContinueButtonPressed() { ++continue_attempts_; if (view_) { view_->StopDemoModeDetection(); @@ -389,7 +389,7 @@ } } -void NetworkScreen::OnLanguageChangedCallback( +void WelcomeScreen::OnLanguageChangedCallback( const InputEventsBlocker* /* input_events_blocker */, const std::string& input_method, const locale_util::LanguageSwitchResult& result) { @@ -401,21 +401,20 @@ selected_language_code_); } ScheduleResolveLanguageList( - std::unique_ptr<locale_util::LanguageSwitchResult>( - new locale_util::LanguageSwitchResult(result))); + std::make_unique<locale_util::LanguageSwitchResult>(result)); AccessibilityManager::Get()->OnLocaleChanged(); SetInputMethod(input_method); } -void NetworkScreen::ScheduleResolveLanguageList( +void WelcomeScreen::ScheduleResolveLanguageList( std::unique_ptr<locale_util::LanguageSwitchResult> language_switch_result) { UILanguageListResolvedCallback callback = base::Bind( - &NetworkScreen::OnLanguageListResolved, weak_factory_.GetWeakPtr()); + &WelcomeScreen::OnLanguageListResolved, weak_factory_.GetWeakPtr()); ResolveUILanguageList(std::move(language_switch_result), callback); } -void NetworkScreen::OnLanguageListResolved( +void WelcomeScreen::OnLanguageListResolved( std::unique_ptr<base::ListValue> new_language_list, const std::string& new_language_list_locale, const std::string& new_selected_language) { @@ -433,7 +432,7 @@ observer.OnLanguageListReloaded(); } -void NetworkScreen::OnSystemTimezoneChanged() { +void WelcomeScreen::OnSystemTimezoneChanged() { std::string current_timezone_id; CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id); GetContextEditor().SetString(kContextKeyTimezone, current_timezone_id);
diff --git a/chrome/browser/chromeos/login/screens/network_screen.h b/chrome/browser/chromeos/login/screens/welcome_screen.h similarity index 86% rename from chrome/browser/chromeos/login/screens/network_screen.h rename to chrome/browser/chromeos/login/screens/welcome_screen.h index 3f383569..667417e 100644 --- a/chrome/browser/chromeos/login/screens/network_screen.h +++ b/chrome/browser/chromeos/login/screens/welcome_screen.h
@@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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_CHROMEOS_LOGIN_SCREENS_NETWORK_SCREEN_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_NETWORK_SCREEN_H_ +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_WELCOME_SCREEN_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_WELCOME_SCREEN_H_ #include <memory> @@ -25,7 +25,7 @@ namespace chromeos { class InputEventsBlocker; -class NetworkView; +class WelcomeView; class ScreenManager; namespace locale_util { @@ -36,7 +36,7 @@ class NetworkStateHelper; } -class NetworkScreen : public BaseScreen, +class WelcomeScreen : public BaseScreen, public NetworkStateHandlerObserver, public input_method::InputMethodManager::Observer { public: @@ -56,16 +56,16 @@ virtual void OnLanguageListReloaded() = 0; }; - NetworkScreen(BaseScreenDelegate* base_screen_delegate, + WelcomeScreen(BaseScreenDelegate* base_screen_delegate, Delegate* delegate, - NetworkView* view); - ~NetworkScreen() override; + WelcomeView* view); + ~WelcomeScreen() override; - static NetworkScreen* Get(ScreenManager* manager); + static WelcomeScreen* Get(ScreenManager* manager); // Called when |view| has been destroyed. If this instance is destroyed before // the |view| it should call view->Unbind(). - void OnViewDestroyed(NetworkView* view); + void OnViewDestroyed(WelcomeView* view); const std::string& language_list_locale() const { return language_list_locale_; @@ -97,12 +97,12 @@ void RemoveObserver(Observer* observer); private: - friend class NetworkScreenTest; - friend class NetworkScreenUnitTest; - FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, Timeout); - FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, CanConnect); - FRIEND_TEST_ALL_PREFIXES(NetworkScreenUnitTest, ContinuesAutomatically); - FRIEND_TEST_ALL_PREFIXES(NetworkScreenUnitTest, ContinuesOnlyOnce); + friend class WelcomeScreenTest; + friend class WelcomeScreenUnitTest; + FRIEND_TEST_ALL_PREFIXES(WelcomeScreenTest, Timeout); + FRIEND_TEST_ALL_PREFIXES(WelcomeScreenTest, CanConnect); + FRIEND_TEST_ALL_PREFIXES(WelcomeScreenUnitTest, ContinuesAutomatically); + FRIEND_TEST_ALL_PREFIXES(WelcomeScreenUnitTest, ContinuesOnlyOnce); // BaseScreen implementation: void Show() override; @@ -125,7 +125,7 @@ // Subscribe to timezone changes. void InitializeTimezoneObserver(); - // Subscribes NetworkScreen to the network change notification, + // Subscribes WelcomeScreen to the network change notification, // forces refresh of current network state. void Refresh(); @@ -198,7 +198,7 @@ std::unique_ptr<CrosSettings::ObserverSubscription> timezone_subscription_; - NetworkView* view_ = nullptr; + WelcomeView* view_ = nullptr; Delegate* delegate_ = nullptr; std::unique_ptr<login::NetworkStateHelper> network_state_helper_; @@ -215,11 +215,11 @@ base::ObserverList<Observer> observers_; - base::WeakPtrFactory<NetworkScreen> weak_factory_; + base::WeakPtrFactory<WelcomeScreen> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(NetworkScreen); + DISALLOW_COPY_AND_ASSIGN(WelcomeScreen); }; } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_NETWORK_SCREEN_H_ +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_WELCOME_SCREEN_H_
diff --git a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/welcome_screen_browsertest.cc similarity index 82% rename from chrome/browser/chromeos/login/screens/network_screen_browsertest.cc rename to chrome/browser/chromeos/login/screens/welcome_screen_browsertest.cc index 94a6407..382beca 100644 --- a/chrome/browser/chromeos/login/screens/network_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/welcome_screen_browsertest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/login/screens/network_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include <memory> @@ -41,10 +41,10 @@ void ButtonPressed(views::Button* sender, const ui::Event& event) override {} }; -class NetworkScreenTest : public WizardInProcessBrowserTest { +class WelcomeScreenTest : public WizardInProcessBrowserTest { public: - NetworkScreenTest() - : WizardInProcessBrowserTest(OobeScreen::SCREEN_OOBE_NETWORK), + WelcomeScreenTest() + : WizardInProcessBrowserTest(OobeScreen::SCREEN_OOBE_WELCOME), fake_session_manager_client_(nullptr) {} protected: @@ -60,26 +60,26 @@ WizardInProcessBrowserTest::SetUpOnMainThread(); mock_base_screen_delegate_.reset(new MockBaseScreenDelegate()); ASSERT_TRUE(WizardController::default_controller() != nullptr); - network_screen_ = NetworkScreen::Get( + welcome_screen_ = WelcomeScreen::Get( WizardController::default_controller()->screen_manager()); - ASSERT_TRUE(network_screen_ != nullptr); + ASSERT_TRUE(welcome_screen_ != nullptr); ASSERT_EQ(WizardController::default_controller()->current_screen(), - network_screen_); - network_screen_->base_screen_delegate_ = mock_base_screen_delegate_.get(); - ASSERT_TRUE(network_screen_->view_ != nullptr); + welcome_screen_); + welcome_screen_->base_screen_delegate_ = mock_base_screen_delegate_.get(); + ASSERT_TRUE(welcome_screen_->view_ != nullptr); mock_network_state_helper_ = new login::MockNetworkStateHelper; SetDefaultNetworkStateHelperExpectations(); - network_screen_->SetNetworkStateHelperForTest(mock_network_state_helper_); + welcome_screen_->SetNetworkStateHelperForTest(mock_network_state_helper_); } - void EmulateContinueButtonExit(NetworkScreen* network_screen) { + void EmulateContinueButtonExit(WelcomeScreen* welcome_screen) { EXPECT_CALL(*mock_base_screen_delegate_, OnExit(_, ScreenExitCode::NETWORK_CONNECTED, _)) .Times(1); EXPECT_CALL(*mock_network_state_helper_, IsConnected()) .WillOnce(Return(true)); - network_screen->OnContinueButtonPressed(); + welcome_screen->OnContinueButtonPressed(); content::RunAllPendingInMessageLoop(); } @@ -97,18 +97,18 @@ std::unique_ptr<MockBaseScreenDelegate> mock_base_screen_delegate_; login::MockNetworkStateHelper* mock_network_state_helper_; - NetworkScreen* network_screen_; + WelcomeScreen* welcome_screen_; FakeSessionManagerClient* fake_session_manager_client_; private: - DISALLOW_COPY_AND_ASSIGN(NetworkScreenTest); + DISALLOW_COPY_AND_ASSIGN(WelcomeScreenTest); }; -IN_PROC_BROWSER_TEST_F(NetworkScreenTest, CanConnect) { +IN_PROC_BROWSER_TEST_F(WelcomeScreenTest, CanConnect) { EXPECT_CALL(*mock_network_state_helper_, IsConnecting()) .WillOnce((Return(true))); // EXPECT_FALSE(view_->IsContinueEnabled()); - network_screen_->UpdateStatus(); + welcome_screen_->UpdateStatus(); EXPECT_CALL(*mock_network_state_helper_, IsConnected()) .Times(2) @@ -116,17 +116,17 @@ // TODO(nkostylev): Add integration with WebUI view http://crosbug.com/22570 // EXPECT_FALSE(view_->IsContinueEnabled()); // EXPECT_FALSE(view_->IsConnecting()); - network_screen_->UpdateStatus(); + welcome_screen_->UpdateStatus(); // EXPECT_TRUE(view_->IsContinueEnabled()); - EmulateContinueButtonExit(network_screen_); + EmulateContinueButtonExit(welcome_screen_); } -IN_PROC_BROWSER_TEST_F(NetworkScreenTest, Timeout) { +IN_PROC_BROWSER_TEST_F(WelcomeScreenTest, Timeout) { EXPECT_CALL(*mock_network_state_helper_, IsConnecting()) .WillOnce((Return(true))); // EXPECT_FALSE(view_->IsContinueEnabled()); - network_screen_->UpdateStatus(); + welcome_screen_->UpdateStatus(); EXPECT_CALL(*mock_network_state_helper_, IsConnected()) .Times(2) @@ -134,7 +134,7 @@ // TODO(nkostylev): Add integration with WebUI view http://crosbug.com/22570 // EXPECT_FALSE(view_->IsContinueEnabled()); // EXPECT_FALSE(view_->IsConnecting()); - network_screen_->OnConnectionTimeout(); + welcome_screen_->OnConnectionTimeout(); // Close infobubble with error message - it makes the test stable. // EXPECT_FALSE(view_->IsContinueEnabled());
diff --git a/chrome/browser/chromeos/login/screens/network_screen_unittest.cc b/chrome/browser/chromeos/login/screens/welcome_screen_unittest.cc similarity index 75% rename from chrome/browser/chromeos/login/screens/network_screen_unittest.cc rename to chrome/browser/chromeos/login/screens/welcome_screen_unittest.cc index 58c739c..0f5e7e2e0 100644 --- a/chrome/browser/chromeos/login/screens/network_screen_unittest.cc +++ b/chrome/browser/chromeos/login/screens/welcome_screen_unittest.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/chromeos/login/mock_network_state_helper.h" #include "chrome/browser/chromeos/login/screens/mock_base_screen_delegate.h" #include "chrome/browser/chromeos/login/screens/mock_model_view_channel.h" -#include "chrome/browser/chromeos/login/screens/mock_network_screen.h" +#include "chrome/browser/chromeos/login/screens/mock_welcome_screen.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chrome/test/base/testing_browser_process.h" @@ -27,9 +27,9 @@ namespace chromeos { -class NetworkScreenUnitTest : public testing::Test { +class WelcomeScreenUnitTest : public testing::Test { public: - NetworkScreenUnitTest() {} + WelcomeScreenUnitTest() {} // testing::Test: void SetUp() override { @@ -48,26 +48,26 @@ new MockComponentExtensionIMEManager())); input_method::InitializeForTesting(mock_input_manager); - // Create the NetworkScreen we will use for testing. - network_screen_.reset( - new NetworkScreen(&mock_base_screen_delegate_, nullptr, &mock_view_)); - network_screen_->set_model_view_channel(&mock_channel_); + // Create the WelcomeScreen we will use for testing. + welcome_screen_.reset( + new WelcomeScreen(&mock_base_screen_delegate_, nullptr, &mock_view_)); + welcome_screen_->set_model_view_channel(&mock_channel_); mock_network_state_helper_ = new login::MockNetworkStateHelper(); - network_screen_->SetNetworkStateHelperForTest(mock_network_state_helper_); + welcome_screen_->SetNetworkStateHelperForTest(mock_network_state_helper_); } void TearDown() override { TestingBrowserProcess::GetGlobal()->SetShuttingDown(true); - network_screen_.reset(); + welcome_screen_.reset(); input_method::Shutdown(); DBusThreadManager::Shutdown(); } protected: - // A pointer to the NetworkScreen. - std::unique_ptr<NetworkScreen> network_screen_; + // A pointer to the WelcomeScreen. + std::unique_ptr<WelcomeScreen> welcome_screen_; - // Accessory objects needed by NetworkScreen. + // Accessory objects needed by WelcomeScreen. MockBaseScreenDelegate mock_base_screen_delegate_; login::MockNetworkStateHelper* mock_network_state_helper_ = nullptr; @@ -75,8 +75,8 @@ // Test versions of core browser infrastructure. content::TestBrowserThreadBundle threads_; - // More accessory objects needed by NetworkScreen. - MockNetworkView mock_view_; + // More accessory objects needed by WelcomeScreen. + MockWelcomeView mock_view_; MockModelViewChannel mock_channel_; // Scoped test versions of required global objects. @@ -84,11 +84,11 @@ ScopedTestCrosSettings cros_settings_; system::ScopedFakeStatisticsProvider provider_; - DISALLOW_COPY_AND_ASSIGN(NetworkScreenUnitTest); + DISALLOW_COPY_AND_ASSIGN(WelcomeScreenUnitTest); }; -TEST_F(NetworkScreenUnitTest, ContinuesAutomatically) { - // Set expectation that NetworkScreen will finish. +TEST_F(WelcomeScreenUnitTest, ContinuesAutomatically) { + // Set expectation that WelcomeScreen will finish. EXPECT_CALL(mock_base_screen_delegate_, OnExit(_, ScreenExitCode::NETWORK_CONNECTED, _)) .Times(1); @@ -97,14 +97,14 @@ EXPECT_CALL(*mock_network_state_helper_, IsConnected()) .Times(AnyNumber()) .WillRepeatedly((Return(true))); - network_screen_->UpdateStatus(); + welcome_screen_->UpdateStatus(); // Check that we continued once - EXPECT_EQ(1, network_screen_->continue_attempts_); + EXPECT_EQ(1, welcome_screen_->continue_attempts_); } -TEST_F(NetworkScreenUnitTest, ContinuesOnlyOnce) { - // Set expectation that NetworkScreen will finish. +TEST_F(WelcomeScreenUnitTest, ContinuesOnlyOnce) { + // Set expectation that WelcomeScreen will finish. EXPECT_CALL(mock_base_screen_delegate_, OnExit(_, ScreenExitCode::NETWORK_CONNECTED, _)) .Times(1); @@ -118,16 +118,16 @@ .WillRepeatedly(Return(true)); // Stop waiting for net0. - network_screen_->StopWaitingForConnection(base::ASCIIToUTF16("net0")); + welcome_screen_->StopWaitingForConnection(base::ASCIIToUTF16("net0")); // Check that we have continued exactly once. - ASSERT_EQ(1, network_screen_->continue_attempts_); + ASSERT_EQ(1, welcome_screen_->continue_attempts_); // Stop waiting for another network, net1. - network_screen_->StopWaitingForConnection(base::ASCIIToUTF16("net1")); + welcome_screen_->StopWaitingForConnection(base::ASCIIToUTF16("net1")); // Check that we have still continued only once. - EXPECT_EQ(1, network_screen_->continue_attempts_); + EXPECT_EQ(1, welcome_screen_->continue_attempts_); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/network_view.h b/chrome/browser/chromeos/login/screens/welcome_view.h similarity index 68% rename from chrome/browser/chromeos/login/screens/network_view.h rename to chrome/browser/chromeos/login/screens/welcome_view.h index 6742989..7e80233 100644 --- a/chrome/browser/chromeos/login/screens/network_view.h +++ b/chrome/browser/chromeos/login/screens/welcome_view.h
@@ -1,24 +1,24 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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_CHROMEOS_LOGIN_SCREENS_NETWORK_VIEW_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_NETWORK_VIEW_H_ +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_WELCOME_VIEW_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_WELCOME_VIEW_H_ #include "base/strings/string16.h" #include "chrome/browser/chromeos/login/oobe_screen.h" namespace chromeos { -class NetworkScreen; +class WelcomeScreen; -// Interface for dependency injection between NetworkScreen and its actual -// representation, either views based or WebUI. Owned by NetworkScreen. -class NetworkView { +// Interface for dependency injection between WelcomeScreen and its actual +// representation, either views based or WebUI. Owned by WelcomeScreen. +class WelcomeView { public: - constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_NETWORK; + constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_WELCOME; - virtual ~NetworkView() {} + virtual ~WelcomeView() {} // Shows the contents of the screen. virtual void Show() = 0; @@ -27,7 +27,7 @@ virtual void Hide() = 0; // Binds |screen| to the view. - virtual void Bind(NetworkScreen* screen) = 0; + virtual void Bind(WelcomeScreen* screen) = 0; // Unbinds model from the view. virtual void Unbind() = 0; @@ -51,4 +51,4 @@ } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_NETWORK_VIEW_H_ +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_WELCOME_VIEW_H_
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc index 364457c..aa315f8eb 100644 --- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc +++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -31,7 +31,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chromeos/chromeos_switches.h"
diff --git a/chrome/browser/chromeos/login/ui/input_events_blocker.cc b/chrome/browser/chromeos/login/ui/input_events_blocker.cc index aeba656..9f1e46e 100644 --- a/chrome/browser/chromeos/login/ui/input_events_blocker.cc +++ b/chrome/browser/chromeos/login/ui/input_events_blocker.cc
@@ -6,7 +6,7 @@ #include "ash/shell.h" #include "base/logging.h" -#include "chrome/browser/ui/ash/ash_util.h" +#include "ui/base/ui_base_features.h" #include "ui/events/event.h" namespace chromeos { @@ -14,7 +14,7 @@ InputEventsBlocker::InputEventsBlocker() { // TODO(mash): Implement a mash version. This will probably need to talk to // the window server. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { ash::Shell::Get()->AddPreTargetHandler(this, ui::EventTarget::Priority::kSystem); VLOG(1) << "InputEventsBlocker " << this << " created."; @@ -24,7 +24,7 @@ } InputEventsBlocker::~InputEventsBlocker() { - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { ash::Shell::Get()->RemovePreTargetHandler(this); VLOG(1) << "InputEventsBlocker " << this << " destroyed."; } else {
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.cc b/chrome/browser/chromeos/login/ui/login_display_host_common.cc index c57a508..7dc0b94 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_common.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
@@ -15,11 +15,11 @@ #include "chrome/browser/chromeos/mobile_config.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/system/device_disabling_manager.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/wallpaper_controller_client.h" #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h" #include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/scoped_keep_alive.h" +#include "ui/base/ui_base_features.h" #include "ui/wm/public/scoped_drag_drop_disabler.h" namespace chromeos { @@ -49,7 +49,7 @@ // Disable Drag'n'Drop for the login session. // ash::Shell may be null in tests. - if (ash::Shell::HasInstance() && !ash_util::IsRunningInMash()) { + if (ash::Shell::HasInstance() && features::IsAshInBrowserProcess()) { scoped_drag_drop_disabler_.reset( new wm::ScopedDragDropDisabler(ash::Shell::GetPrimaryRootWindow())); } else {
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc index 13fdb6aa..0fea31f 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
@@ -7,6 +7,7 @@ #include <string> #include <utility> +#include "base/optional.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/mojo_version_info_dispatcher.h" @@ -137,13 +138,15 @@ DCHECK(GetOobeUI()); // Dtor of the old WizardController should be called before ctor of the - // new one to ensure only one |ExistingUserController| instance at a time. + // new one to ensure only one |WizardController| instance at a time. wizard_controller_.reset(); wizard_controller_.reset(new WizardController(this, GetOobeUI())); wizard_controller_->Init(first_screen); + bool closable_by_esc = first_screen == OobeScreen::SCREEN_OOBE_RESET; + // Post login screens should not be closable by escape key. - dialog_->Show(false /*closable_by_esc*/); + dialog_->Show(closable_by_esc); } WizardController* LoginDisplayHostMojo::GetWizardController() { @@ -171,6 +174,20 @@ return; } + // If signin_screen_started_, we already have an instance of LockScreen, + // so we can skip login screen initialization and just reset the dialog state. + if (signin_screen_started_) { + if (user_selection_screen_->HasAnyUsers()) { + dialog_->Hide(); + } else { + GetOobeUI()->GetGaiaScreenView()->ShowGaiaAsync(base::nullopt); + dialog_->Show(false /*closable_by_esc*/); + } + return; + } + + signin_screen_started_ = true; + // There can only be one |ExistingUserController| instance at a time. existing_user_controller_.reset(); existing_user_controller_ = std::make_unique<ExistingUserController>(this); @@ -222,13 +239,11 @@ DCHECK(dialog_); if (visible) { - if (prefilled_account) { - // Make sure gaia displays |account| if requested. - GetOobeUI()->GetGaiaScreenView()->ShowGaiaAsync(prefilled_account); + GetOobeUI()->GetGaiaScreenView()->ShowGaiaAsync(prefilled_account); + if (prefilled_account) LoginDisplayHost::default_host()->LoadWallpaper(*prefilled_account); - } else { + else LoginDisplayHost::default_host()->LoadSigninWallpaper(); - } dialog_->Show(can_close /*closable_by_esc*/); return;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h index 066ef658..2f6d0ab 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h +++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
@@ -144,6 +144,8 @@ // Updates UI when version info is changed. std::unique_ptr<MojoVersionInfoDispatcher> version_info_updater_; + bool signin_screen_started_ = false; + base::WeakPtrFactory<LoginDisplayHostMojo> weak_factory_; DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostMojo);
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc index b1fcb2a3..e4ad585 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -55,7 +55,6 @@ #include "chrome/browser/chromeos/system/timezone_util.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/system_tray_client.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/common/chrome_constants.h" @@ -90,6 +89,7 @@ #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_features.h" #include "ui/compositor/compositor_observer.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_observer.h" @@ -397,7 +397,7 @@ // * Ash crash at the login screen on mustash // In the latter case the mash root process will trigger a clean restart // of content_browser. - if (ash_util::IsRunningInMash() && login_display_host_) + if (!features::IsAshInBrowserProcess() && login_display_host_) login_display_host_->ResetLoginWindowAndView(); } void DeleteDelegate() override { delete this; } @@ -420,7 +420,7 @@ LoginDisplayHostWebUI::LoginDisplayHostWebUI() : oobe_startup_sound_played_(StartupUtils::IsOobeCompleted()), weak_factory_(this) { - if (ash_util::IsRunningInMash()) { + if (!features::IsAshInBrowserProcess()) { // Animation, and initializing hidden, are not currently supported for Mash. finalize_animation_type_ = ANIMATION_NONE; initialize_webui_hidden_ = false; @@ -439,19 +439,19 @@ bool zero_delay_enabled = WizardController::IsZeroDelayEnabled(); // Mash always runs login screen with zero delay - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) zero_delay_enabled = true; waiting_for_wallpaper_load_ = !zero_delay_enabled; // Initializing hidden is not supported in Mash - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { initialize_webui_hidden_ = kHiddenWebUIInitializationDefault && !zero_delay_enabled; } // Check if WebUI init type is overriden. Not supported in Mash. - if (!ash_util::IsRunningInMash() && + if (features::IsAshInBrowserProcess() && base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kAshWebUIInit)) { const std::string override_type = @@ -621,7 +621,7 @@ restore_path_ = RESTORE_ADD_USER_INTO_SESSION; // Animation is not supported in Mash - if (!ash_util::IsRunningInMash()) + if (features::IsAshInBrowserProcess()) finalize_animation_type_ = ANIMATION_ADD_USER; // Observe the user switch animation and defer the deletion of itself only // after the animation is finished. @@ -637,7 +637,7 @@ // We should emit this signal only at login screen (after reboot or sign out). login_view_->set_should_emit_login_prompt_visible(false); - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { // Lock container can be transparent after lock screen animation. aura::Window* lock_container = ash::Shell::GetContainer( ash::Shell::GetPrimaryRootWindow(), @@ -679,7 +679,7 @@ restore_path_ = RESTORE_SIGN_IN; is_showing_login_ = true; // Animation is not supported in Mash - if (!ash_util::IsRunningInMash()) + if (features::IsAshInBrowserProcess()) finalize_animation_type_ = ANIMATION_WORKSPACE; if (waiting_for_wallpaper_load_ && !initialize_webui_hidden_) { @@ -730,7 +730,7 @@ void LoginDisplayHostWebUI::OnStartAppLaunch() { // Animation is not supported in Mash. - if (!ash_util::IsRunningInMash()) + if (features::IsAshInBrowserProcess()) finalize_animation_type_ = ANIMATION_FADE_OUT; if (!login_window_) LoadURL(GURL(kAppLaunchSplashURL)); @@ -740,7 +740,7 @@ void LoginDisplayHostWebUI::OnStartArcKiosk() { // Animation is not supported in Mash. - if (!ash_util::IsRunningInMash()) + if (features::IsAshInBrowserProcess()) finalize_animation_type_ = ANIMATION_FADE_OUT; if (!login_window_) { LoadURL(GURL(kAppLaunchSplashURL)); @@ -918,7 +918,7 @@ // LoginDisplayHostWebUI, private void LoginDisplayHostWebUI::ScheduleWorkspaceAnimation() { - if (ash_util::IsRunningInMash()) { + if (!features::IsAshInBrowserProcess()) { NOTIMPLEMENTED(); return; } @@ -1029,7 +1029,7 @@ ? ash::kShellWindowId_AlwaysOnTopContainer : ash::kShellWindowId_LockScreenContainer; // The ash::Shell containers are not available in Mash - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { params.parent = ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), container); } else { @@ -1049,7 +1049,7 @@ // Animations are not available in Mash. // For voice interaction OOBE, we do not want the animation here. - if (!ash_util::IsRunningInMash() && !is_voice_interaction_oobe_) { + if (features::IsAshInBrowserProcess() && !is_voice_interaction_oobe_) { login_window_->SetVisibilityAnimationDuration( base::TimeDelta::FromMilliseconds(kLoginFadeoutTransitionDurationMs)); login_window_->SetVisibilityAnimationTransition( @@ -1082,7 +1082,7 @@ } if (login_window_) { - if (ash_util::IsRunningInMash()) { + if (!features::IsAshInBrowserProcess()) { login_window_->Close(); } else { login_window_->Hide(); @@ -1230,7 +1230,7 @@ // Shows networks screen instead of enrollment screen to resume the // interrupted auto start enrollment flow because enrollment screen does // not handle flaky network. See http://crbug.com/332572 - display_host->StartWizard(OobeScreen::SCREEN_OOBE_NETWORK); + display_host->StartWizard(OobeScreen::SCREEN_OOBE_WELCOME); return; }
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc index eb0a259..1aa5824 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_view.cc +++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -38,7 +38,6 @@ #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/renderer_preferences_util.h" #include "chrome/browser/sessions/session_tab_helper.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/system_tray_client.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h" @@ -61,6 +60,7 @@ #include "content/public/common/renderer_preferences.h" #include "extensions/browser/view_type_utils.h" #include "third_party/blink/public/platform/web_input_event.h" +#include "ui/base/ui_base_features.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/keyboard/keyboard_controller.h" @@ -126,7 +126,7 @@ : settings_(settings) { // TODO(mash): Support virtual keyboard under MASH. There is no // KeyboardController in the browser process under MASH. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { keyboard::KeyboardController::Get()->AddObserver(this); } else { NOTIMPLEMENTED(); @@ -191,7 +191,7 @@ kAccelSendFeedback; for (AccelMap::iterator i(accel_map_.begin()); i != accel_map_.end(); ++i) { - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { // To make reset accelerator work while system tray is open, register it // at accelerator controller. ash::Shell::Get()->accelerator_controller()->Register({i->first}, this); @@ -203,7 +203,7 @@ } } - if (!ash_util::IsRunningInMash()) + if (features::IsAshInBrowserProcess()) ash::Shell::Get()->system_tray_notifier()->AddSystemTrayFocusObserver(this); } @@ -211,7 +211,7 @@ for (auto& observer : observer_list_) observer.OnHostDestroying(); - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { ash::Shell::Get()->system_tray_notifier()->RemoveSystemTrayFocusObserver( this); ash::Shell::Get()->accelerator_controller()->UnregisterAll(this); @@ -353,7 +353,7 @@ web_view()->RequestFocus(); // There is no Shell instance while running in mash. - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) return; } @@ -581,7 +581,7 @@ bool WebUILoginView::MoveFocusToSystemTray(bool reverse) { // Focus is accepted, but the Ash system tray is not available in Mash, so // exit early. - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) return true; // The old system tray is not available when UnifiedSystemTray is enabled.
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index b07a3fd..b23adfb2 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -48,7 +48,6 @@ #include "chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen.h" #include "chrome/browser/chromeos/login/screens/kiosk_enable_screen.h" #include "chrome/browser/chromeos/login/screens/network_error.h" -#include "chrome/browser/chromeos/login/screens/network_view.h" #include "chrome/browser/chromeos/login/screens/recommend_apps_screen.h" #include "chrome/browser/chromeos/login/screens/reset_screen.h" #include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" @@ -58,6 +57,7 @@ #include "chrome/browser/chromeos/login/screens/user_image_screen.h" #include "chrome/browser/chromeos/login/screens/voice_interaction_value_prop_screen.h" #include "chrome/browser/chromeos/login/screens/wait_for_container_ready_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_view.h" #include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/startup_utils.h" @@ -74,7 +74,6 @@ #include "chrome/browser/metrics/metrics_reporting_state.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/tablet_mode_client.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" @@ -111,6 +110,7 @@ #include "services/service_manager/public/cpp/connector.h" #include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/base/accelerators/accelerator.h" +#include "ui/base/ui_base_features.h" using content::BrowserThread; @@ -123,7 +123,7 @@ // Stores the list of all screens that should be shown when resuming OOBE. const chromeos::OobeScreen kResumableScreens[] = { - chromeos::OobeScreen::SCREEN_OOBE_NETWORK, + chromeos::OobeScreen::SCREEN_OOBE_WELCOME, chromeos::OobeScreen::SCREEN_OOBE_UPDATE, chromeos::OobeScreen::SCREEN_OOBE_EULA, chromeos::OobeScreen::SCREEN_OOBE_ENROLLMENT, @@ -159,7 +159,7 @@ constexpr const Entry kLegacyUmaOobeScreenNames[] = { {chromeos::OobeScreen::SCREEN_ARC_TERMS_OF_SERVICE, "arc_tos"}, {chromeos::OobeScreen::SCREEN_OOBE_ENROLLMENT, "enroll"}, - {chromeos::OobeScreen::SCREEN_OOBE_NETWORK, "network"}, + {chromeos::OobeScreen::SCREEN_OOBE_WELCOME, "network"}, {chromeos::OobeScreen::SCREEN_CREATE_SUPERVISED_USER_FLOW, "supervised-user-creation-flow"}, {chromeos::OobeScreen::SCREEN_TERMS_OF_SERVICE, "tos"}, @@ -275,7 +275,7 @@ // In session OOBE was initiated from voice interaction keyboard shortcuts. is_in_session_oobe_ = session_manager::SessionManager::Get()->IsSessionStarted(); - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { AccessibilityManager* accessibility_manager = AccessibilityManager::Get(); if (accessibility_manager) { // accessibility_manager could be null in Tests. @@ -376,8 +376,8 @@ } BaseScreen* WizardController::CreateScreen(OobeScreen screen) { - if (screen == OobeScreen::SCREEN_OOBE_NETWORK) { - return new NetworkScreen(this, this, oobe_ui_->GetNetworkView()); + if (screen == OobeScreen::SCREEN_OOBE_WELCOME) { + return new WelcomeScreen(this, this, oobe_ui_->GetWelcomeView()); } else if (screen == OobeScreen::SCREEN_OOBE_UPDATE) { return new UpdateScreen(this, oobe_ui_->GetUpdateView(), remora_controller_.get()); @@ -466,10 +466,10 @@ current_screen_ = screen; } -void WizardController::ShowNetworkScreen() { - VLOG(1) << "Showing network screen."; - UpdateStatusAreaVisibilityForScreen(OobeScreen::SCREEN_OOBE_NETWORK); - SetCurrentScreen(GetScreen(OobeScreen::SCREEN_OOBE_NETWORK)); +void WizardController::ShowWelcomeScreen() { + VLOG(1) << "Showing welcome screen."; + UpdateStatusAreaVisibilityForScreen(OobeScreen::SCREEN_OOBE_WELCOME); + SetCurrentScreen(GetScreen(OobeScreen::SCREEN_OOBE_WELCOME)); // There are two possible screens where we listen to the incoming Bluetooth // connection request: the first one is the HID detection screen, which will @@ -653,7 +653,7 @@ SetCurrentScreen(GetScreen(OobeScreen::SCREEN_OOBE_HID_DETECTION)); // In HID detection screen, puts the Bluetooth in discoverable mode and waits // for the incoming Bluetooth connection request. See the comments in - // WizardController::ShowNetworkScreen() for more details. + // WizardController::ShowWelcomeScreen() for more details. MaybeStartListeningForSharkConnection(); } @@ -742,7 +742,7 @@ void WizardController::OnHIDDetectionCompleted() { // Check for tests configuration. if (!StartupUtils::IsOobeCompleted()) - ShowNetworkScreen(); + ShowWelcomeScreen(); } void WizardController::OnNetworkConnected() { @@ -819,7 +819,7 @@ // we do not want to block users from being able to proceed to the login // screen. if (is_out_of_box_ && is_critical_update) - ShowNetworkScreen(); + ShowWelcomeScreen(); else OnUpdateCompleted(); } @@ -1143,11 +1143,11 @@ } void WizardController::UpdateStatusAreaVisibilityForScreen(OobeScreen screen) { - if (screen == OobeScreen::SCREEN_OOBE_NETWORK) { + if (screen == OobeScreen::SCREEN_OOBE_WELCOME) { // Hide the status area initially; it only appears after OOBE first animates - // in. Keep it visible if the user goes back to the existing network screen. + // in. Keep it visible if the user goes back to the existing welcome screen. host_->SetStatusAreaVisible( - screen_manager_->HasScreen(OobeScreen::SCREEN_OOBE_NETWORK)); + screen_manager_->HasScreen(OobeScreen::SCREEN_OOBE_WELCOME)); } else if (screen == OobeScreen::SCREEN_OOBE_RESET || screen == OobeScreen::SCREEN_KIOSK_ENABLE || screen == OobeScreen::SCREEN_KIOSK_AUTOLAUNCH || @@ -1169,13 +1169,13 @@ if (screen_needed) { ShowHIDDetectionScreen(); } else { - ShowNetworkScreen(); + ShowWelcomeScreen(); } } void WizardController::AdvanceToScreen(OobeScreen screen) { - if (screen == OobeScreen::SCREEN_OOBE_NETWORK) { - ShowNetworkScreen(); + if (screen == OobeScreen::SCREEN_OOBE_WELCOME) { + ShowWelcomeScreen(); } else if (screen == OobeScreen::SCREEN_SPECIAL_LOGIN) { ShowLoginScreen(LoginScreenContext()); } else if (screen == OobeScreen::SCREEN_OOBE_UPDATE) { @@ -1242,7 +1242,7 @@ weak_factory_.GetWeakPtr()); oobe_ui_->GetHIDDetectionView()->CheckIsScreenRequired(on_check); } else { - ShowNetworkScreen(); + ShowWelcomeScreen(); } } else { ShowLoginScreen(LoginScreenContext()); @@ -1293,7 +1293,7 @@ OnEulaAccepted(); break; case ScreenExitCode::EULA_BACK: - ShowNetworkScreen(); + ShowWelcomeScreen(); break; case ScreenExitCode::ENABLE_DEBUGGING_CANCELED: OnDeviceModificationCanceled(); @@ -1395,9 +1395,9 @@ void WizardController::SetHostNetwork() { if (!shark_controller_) return; - NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); + WelcomeScreen* welcome_screen = WelcomeScreen::Get(screen_manager()); std::string onc_spec; - network_screen->GetConnectedWifiNetwork(&onc_spec); + welcome_screen->GetConnectedWifiNetwork(&onc_spec); if (!onc_spec.empty()) shark_controller_->SetHostNetwork(onc_spec); } @@ -1405,11 +1405,11 @@ void WizardController::SetHostConfiguration() { if (!shark_controller_) return; - NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); + WelcomeScreen* welcome_screen = WelcomeScreen::Get(screen_manager()); shark_controller_->SetHostConfiguration( true, // Eula must be accepted before we get this far. - network_screen->GetApplicationLocale(), network_screen->GetTimezone(), - GetUsageStatisticsReporting(), network_screen->GetInputMethod()); + welcome_screen->GetApplicationLocale(), welcome_screen->GetTimezone(), + GetUsageStatisticsReporting(), welcome_screen->GetInputMethod()); } void WizardController::ConfigureHostRequested( @@ -1424,9 +1424,9 @@ StartupUtils::MarkEulaAccepted(); SetUsageStatisticsReporting(send_reports); - NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); - network_screen->SetApplicationLocaleAndInputMethod(lang, keyboard_layout); - network_screen->SetTimezone(timezone); + WelcomeScreen* welcome_screen = WelcomeScreen::Get(screen_manager()); + welcome_screen->SetApplicationLocaleAndInputMethod(lang, keyboard_layout); + welcome_screen->SetTimezone(timezone); // Don't block the OOBE update and the following enrollment process if there // is available and valid network already. @@ -1441,16 +1441,16 @@ remora_controller_->OnNetworkConnectivityChanged( pairing_chromeos::HostPairingController::CONNECTIVITY_CONNECTING); - NetworkScreen* network_screen = NetworkScreen::Get(screen_manager()); + WelcomeScreen* welcome_screen = WelcomeScreen::Get(screen_manager()); const chromeos::NetworkState* network_state = chromeos::NetworkHandler::Get() ->network_state_handler() ->DefaultNetwork(); if (NetworkAllowUpdate(network_state)) { - network_screen->CreateAndConnectNetworkFromOnc( + welcome_screen->CreateAndConnectNetworkFromOnc( onc_spec, base::DoNothing(), network_handler::ErrorCallback()); } else { - network_screen->CreateAndConnectNetworkFromOnc( + welcome_screen->CreateAndConnectNetworkFromOnc( onc_spec, base::Bind(&WizardController::OnSetHostNetworkSuccessful, weak_factory_.GetWeakPtr()), @@ -1535,7 +1535,7 @@ // static bool WizardController::IsOOBEStepToTrack(OobeScreen screen_id) { return (screen_id == OobeScreen::SCREEN_OOBE_HID_DETECTION || - screen_id == OobeScreen::SCREEN_OOBE_NETWORK || + screen_id == OobeScreen::SCREEN_OOBE_WELCOME || screen_id == OobeScreen::SCREEN_OOBE_UPDATE || screen_id == OobeScreen::SCREEN_USER_IMAGE_PICKER || screen_id == OobeScreen::SCREEN_OOBE_EULA ||
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h index 3cb3db5..00c1a64 100644 --- a/chrome/browser/chromeos/login/wizard_controller.h +++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -25,8 +25,8 @@ #include "chrome/browser/chromeos/login/screens/eula_screen.h" #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h" #include "chrome/browser/chromeos/login/screens/host_pairing_screen.h" -#include "chrome/browser/chromeos/login/screens/network_screen.h" #include "chrome/browser/chromeos/login/screens/reset_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include "chrome/browser/chromeos/policy/enrollment_config.h" class PrefService; @@ -54,7 +54,7 @@ public EulaScreen::Delegate, public ControllerPairingScreen::Delegate, public HostPairingScreen::Delegate, - public NetworkScreen::Delegate, + public WelcomeScreen::Delegate, public HIDDetectionScreen::Delegate { public: WizardController(LoginDisplayHost* host, OobeUI* oobe_ui); @@ -137,7 +137,7 @@ private: // Show specific screen. - void ShowNetworkScreen(); + void ShowWelcomeScreen(); void ShowUserImageScreen(); void ShowEulaScreen(); void ShowEnrollmentScreen(); @@ -241,7 +241,7 @@ void AddNetworkRequested(const std::string& onc_spec) override; void RebootHostRequested() override; - // Override from NetworkScreen::Delegate: + // Override from WelcomeScreen::Delegate: void OnEnableDebuggingScreenRequested() override; // Override from HIDDetectionScreen::Delegate
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index 3682b19..5777f68 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -31,12 +31,12 @@ #include "chrome/browser/chromeos/login/screens/mock_device_disabled_screen_view.h" #include "chrome/browser/chromeos/login/screens/mock_enable_debugging_screen.h" #include "chrome/browser/chromeos/login/screens/mock_eula_screen.h" -#include "chrome/browser/chromeos/login/screens/mock_network_screen.h" #include "chrome/browser/chromeos/login/screens/mock_update_screen.h" +#include "chrome/browser/chromeos/login/screens/mock_welcome_screen.h" #include "chrome/browser/chromeos/login/screens/mock_wrong_hwid_screen.h" -#include "chrome/browser/chromeos/login/screens/network_screen.h" #include "chrome/browser/chromeos/login/screens/reset_screen.h" #include "chrome/browser/chromeos/login/screens/user_image_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/test/wizard_in_process_browser_test.h" @@ -405,7 +405,7 @@ IN_PROC_BROWSER_TEST_F(WizardControllerTest, SwitchLanguage) { ASSERT_TRUE(WizardController::default_controller() != NULL); WizardController::default_controller()->AdvanceToScreen( - OobeScreen::SCREEN_OOBE_NETWORK); + OobeScreen::SCREEN_OOBE_WELCOME); // Checking the default locale. Provided that the profile is cleared in SetUp. EXPECT_EQ("en-US", g_browser_process->GetApplicationLocale()); @@ -517,15 +517,15 @@ NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); // Set up the mocks for all screens. - mock_network_screen_ = new MockNetworkScreen( + mock_welcome_screen_ = new MockWelcomeScreen( WizardController::default_controller(), - WizardController::default_controller(), GetOobeUI()->GetNetworkView()); + WizardController::default_controller(), GetOobeUI()->GetWelcomeView()); WizardController::default_controller() ->screen_manager() - ->screens_[OobeScreen::SCREEN_OOBE_NETWORK] - .reset(mock_network_screen_); - EXPECT_CALL(*mock_network_screen_, Show()).Times(0); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(0); + ->screens_[OobeScreen::SCREEN_OOBE_WELCOME] + .reset(mock_welcome_screen_); + EXPECT_CALL(*mock_welcome_screen_, Show()).Times(0); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(0); MOCK(mock_update_screen_, OobeScreen::SCREEN_OOBE_UPDATE, MockUpdateScreen, MockUpdateView); @@ -552,12 +552,12 @@ // Switch to the initial screen. EXPECT_EQ(NULL, wizard_controller->current_screen()); - EXPECT_CALL(*mock_network_screen_, Show()).Times(1); - wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_NETWORK); + EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1); + wizard_controller->AdvanceToScreen(OobeScreen::SCREEN_OOBE_WELCOME); } void TearDownOnMainThread() override { - mock_network_screen_ = nullptr; + mock_welcome_screen_ = nullptr; device_disabled_screen_view_.reset(); WizardControllerTest::TearDownOnMainThread(); } @@ -619,16 +619,16 @@ } void TestControlFlowMain() { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); WaitUntilJSIsReady(); // Check visibility of the header bar. ASSERT_FALSE(JSExecuteBooleanExpression("$('login-header-bar').hidden")); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); @@ -669,7 +669,7 @@ ->GetCurrentTimezoneID())); } - MockNetworkScreen* mock_network_screen_; // Unowned ptr. + MockWelcomeScreen* mock_welcome_screen_; // Unowned ptr. MockOutShowHide<MockUpdateScreen, MockUpdateView>* mock_update_screen_; MockOutShowHide<MockEulaScreen, MockEulaView>* mock_eula_screen_; MockOutShowHide<MockEnrollmentScreen, MockEnrollmentScreenView>* @@ -706,12 +706,12 @@ // log in. IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorUpdateNonCriticalUpdate) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(0); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -741,12 +741,12 @@ // screen and thus prevents the user from proceeding to log in. IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorUpdateCriticalUpdate) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(0); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -761,20 +761,20 @@ EXPECT_CALL(*mock_update_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(0); EXPECT_CALL(*mock_auto_enrollment_check_screen_, Show()).Times(0); - EXPECT_CALL(*mock_network_screen_, Show()).Times(1); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(0); // last transition + EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(0); // last transition OnExit(*mock_update_screen_, ScreenExitCode::UPDATE_ERROR_UPDATING_CRITICAL_UPDATE); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowSkipUpdateEnroll) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(0); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -805,24 +805,24 @@ } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEulaDeclined) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); - EXPECT_CALL(*mock_network_screen_, Show()).Times(1); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(0); // last transition + EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(0); // last transition OnExit(*mock_eula_screen_, ScreenExitCode::EULA_BACK); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEnrollmentCompleted) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); EXPECT_CALL(*mock_enrollment_screen_->view(), SetParameters( @@ -830,7 +830,7 @@ EnrollmentModeMatches(policy::EnrollmentConfig::MODE_MANUAL))) .Times(1); EXPECT_CALL(*mock_enrollment_screen_, Show()).Times(1); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); WizardController::default_controller()->AdvanceToScreen( OobeScreen::SCREEN_OOBE_ENROLLMENT); @@ -843,7 +843,7 @@ IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowWrongHWIDScreenFromLogin) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); LoginDisplayHost::default_host()->StartSignInScreen(LoginScreenContext()); EXPECT_FALSE(ExistingUserController::current_controller() == NULL); @@ -881,12 +881,12 @@ IN_PROC_BROWSER_TEST_P(WizardControllerErrorUpdateAfterCompletedOobeTest, ControlFlowErrorUpdate) { const ScreenExitCode update_screen_exit_code = GetParam(); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(0); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -978,10 +978,10 @@ EXPECT_NE(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, auto_enrollment_controller()->state()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1005,10 +1005,10 @@ IN_PROC_BROWSER_TEST_F(WizardControllerDeviceStateTest, ControlFlowDeviceDisabled) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1089,10 +1089,10 @@ // the device should be enrolled. IN_PROC_BROWSER_TEST_P(WizardControllerDeviceStateExplicitRequirementTest, ControlFlowForcedReEnrollment) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1172,10 +1172,10 @@ ScopedFakeAutoEnrollmentClientFactory fake_auto_enrollment_client_factory( auto_enrollment_controller()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1324,10 +1324,10 @@ fake_statistics_provider_.SetMachineStatistic( system::kRlzEmbargoEndDateKey, GenerateEmbargoEndDate(-15 /* days_offset */)); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1393,10 +1393,10 @@ fake_statistics_provider_.SetMachineStatistic( system::kRlzEmbargoEndDateKey, GenerateEmbargoEndDate(-15 /* days_offset */)); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1483,10 +1483,10 @@ EXPECT_NE(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, auto_enrollment_controller()->state()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1521,10 +1521,10 @@ EXPECT_NE(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, auto_enrollment_controller()->state()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1571,10 +1571,10 @@ EXPECT_NE(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, auto_enrollment_controller()->state()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1621,10 +1621,10 @@ EXPECT_NE(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, auto_enrollment_controller()->state()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1698,10 +1698,10 @@ EXPECT_NE(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, auto_enrollment_controller()->state()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1800,7 +1800,7 @@ void SetUpOnMainThread() override { WizardControllerTest::SetUpOnMainThread(); WizardController::default_controller()->AdvanceToScreen( - OobeScreen::SCREEN_OOBE_NETWORK); + OobeScreen::SCREEN_OOBE_WELCOME); } void SetUpCommandLine(base::CommandLine* command_line) override { @@ -1823,7 +1823,7 @@ chrome::NOTIFICATION_AUTH_NEEDED, content::NotificationService::AllSources()); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); LoginDisplayHost::default_host()->StartSignInScreen(LoginScreenContext()); auth_needed_waiter.Wait(); @@ -1855,10 +1855,10 @@ EnrollmentModeMatches( policy::EnrollmentConfig::MODE_LOCAL_FORCED))) .Times(1); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1898,10 +1898,10 @@ policy::EnrollmentConfig::MODE_LOCAL_FORCED))) .Times(1); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); - OnExit(*mock_network_screen_, ScreenExitCode::NETWORK_CONNECTED); + OnExit(*mock_welcome_screen_, ScreenExitCode::NETWORK_CONNECTED); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_EULA); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); @@ -1951,14 +1951,14 @@ IN_PROC_BROWSER_TEST_F(WizardControllerEnableDebuggingTest, ShowAndCancelEnableDebugging) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); WaitUntilJSIsReady(); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_enable_debugging_screen_, Show()).Times(1); ASSERT_TRUE( - JSExecute("chrome.send('login.NetworkScreen.userActed', " + JSExecute("chrome.send('login.WelcomeScreen.userActed', " "['connect-debugging-features']);")); // Let update screen smooth time process (time = 0ms). @@ -1966,7 +1966,7 @@ CheckCurrentScreen(OobeScreen::SCREEN_OOBE_ENABLE_DEBUGGING); EXPECT_CALL(*mock_enable_debugging_screen_, Hide()).Times(1); - EXPECT_CALL(*mock_network_screen_, Show()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1); OnExit(*mock_enable_debugging_screen_, ScreenExitCode::ENABLE_DEBUGGING_CANCELED); @@ -1974,7 +1974,7 @@ // Let update screen smooth time process (time = 0ms). content::RunAllPendingInMessageLoop(); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); } class WizardControllerDemoSetupTest : public WizardControllerFlowTest { @@ -1992,10 +1992,10 @@ }; IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoSetupFinished) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); WaitUntilJSIsReady(); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_demo_setup_screen_, Show()).Times(1); WizardController::default_controller()->AdvanceToScreen( @@ -2010,10 +2010,10 @@ } IN_PROC_BROWSER_TEST_F(WizardControllerDemoSetupTest, DemoSetupCanceled) { - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); WaitUntilJSIsReady(); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); EXPECT_CALL(*mock_demo_setup_screen_, Show()).Times(1); WizardController::default_controller()->AdvanceToScreen( @@ -2022,11 +2022,11 @@ CheckCurrentScreen(OobeScreen::SCREEN_OOBE_DEMO_SETUP); EXPECT_CALL(*mock_demo_setup_screen_, Hide()).Times(1); - EXPECT_CALL(*mock_network_screen_, Show()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1); OnExit(*mock_demo_setup_screen_, ScreenExitCode::DEMO_MODE_SETUP_CANCELED); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); } class WizardControllerOobeResumeTest : public WizardControllerTest { @@ -2043,8 +2043,8 @@ NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); // Set up the mocks for all screens. - MOCK_WITH_DELEGATE(mock_network_screen_, OobeScreen::SCREEN_OOBE_NETWORK, - MockNetworkScreen, MockNetworkView); + MOCK_WITH_DELEGATE(mock_welcome_screen_, OobeScreen::SCREEN_OOBE_WELCOME, + MockWelcomeScreen, MockWelcomeView); MOCK(mock_enrollment_screen_, OobeScreen::SCREEN_OOBE_ENROLLMENT, MockEnrollmentScreen, MockEnrollmentScreenView); } @@ -2058,7 +2058,7 @@ return WizardController::default_controller()->first_screen(); } - MockOutShowHide<MockNetworkScreen, MockNetworkView>* mock_network_screen_; + MockOutShowHide<MockWelcomeScreen, MockWelcomeView>* mock_welcome_screen_; MockOutShowHide<MockEnrollmentScreen, MockEnrollmentScreenView>* mock_enrollment_screen_; @@ -2069,17 +2069,17 @@ IN_PROC_BROWSER_TEST_F(WizardControllerOobeResumeTest, PRE_ControlFlowResumeInterruptedOobe) { // Switch to the initial screen. - EXPECT_CALL(*mock_network_screen_, Show()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Show()).Times(1); WizardController::default_controller()->AdvanceToScreen( - OobeScreen::SCREEN_OOBE_NETWORK); - CheckCurrentScreen(OobeScreen::SCREEN_OOBE_NETWORK); + OobeScreen::SCREEN_OOBE_WELCOME); + CheckCurrentScreen(OobeScreen::SCREEN_OOBE_WELCOME); EXPECT_CALL(*mock_enrollment_screen_->view(), SetParameters( mock_enrollment_screen_, EnrollmentModeMatches(policy::EnrollmentConfig::MODE_MANUAL))) .Times(1); EXPECT_CALL(*mock_enrollment_screen_, Show()).Times(1); - EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); + EXPECT_CALL(*mock_welcome_screen_, Hide()).Times(1); WizardController::default_controller()->AdvanceToScreen( OobeScreen::SCREEN_OOBE_ENROLLMENT);
diff --git a/chrome/browser/chromeos/policy/active_directory_join_delegate.h b/chrome/browser/chromeos/policy/active_directory_join_delegate.h index 8c54b7b..286a6fa 100644 --- a/chrome/browser/chromeos/policy/active_directory_join_delegate.h +++ b/chrome/browser/chromeos/policy/active_directory_join_delegate.h
@@ -24,8 +24,10 @@ public: ActiveDirectoryJoinDelegate() = default; // Start the Active Directory domain join flow. |dm_token| will be stored in - // the device policy. + // the device policy. |domain_join_config| could be used to streamline the + // flow. virtual void JoinDomain(const std::string& dm_token, + const std::string& domain_join_config, OnDomainJoinedCallback on_joined_callback) = 0; protected:
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc index 06f5f8a3..fa98e10a 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/base64.h" #include "base/bind.h" #include "base/command_line.h" #include "base/location.h" @@ -124,6 +125,24 @@ return result; } +// Returns binary config which is encrypted by a password that the joining user +// has to enter. +std::string GetActiveDirectoryDomainJoinConfig( + const base::DictionaryValue* config) { + if (!config) + return std::string(); + const base::Value* base64_value = config->FindKeyOfType( + "active_directory_domain_join_config", base::Value::Type::STRING); + if (!base64_value) + return std::string(); + std::string result; + if (!base::Base64Decode(base64_value->GetString(), &result)) { + LOG(ERROR) << "Active Directory config is not base64"; + return std::string(); + } + return result; +} + } // namespace EnrollmentHandlerChromeOS::EnrollmentHandlerChromeOS( @@ -622,6 +641,7 @@ DCHECK(ad_join_delegate_); ad_join_delegate_->JoinDomain( client_->dm_token(), + GetActiveDirectoryDomainJoinConfig(client_->configuration_seed()), base::BindOnce(&EnrollmentHandlerChromeOS::OnAdDomainJoined, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager.cc b/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager.cc index d1a387f..0974293 100644 --- a/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager.cc +++ b/chrome/browser/chromeos/power/ml/adaptive_screen_brightness_manager.cc
@@ -16,7 +16,6 @@ #include "base/timer/timer.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/power/ml/adaptive_screen_brightness_ukm_logger.h" #include "chrome/browser/chromeos/power/ml/adaptive_screen_brightness_ukm_logger_impl.h" #include "chrome/browser/chromeos/power/ml/real_boot_clock.h" @@ -37,6 +36,7 @@ #include "services/metrics/public/cpp/ukm_source_id.h" #include "services/viz/public/interfaces/compositing/video_detector_observer.mojom.h" #include "ui/aura/env.h" +#include "ui/base/ui_base_features.h" #include "ui/base/user_activity/user_activity_detector.h" namespace chromeos { @@ -162,7 +162,7 @@ // TODO(jiameng): video detector below doesn't work with MASH. Temporary // solution is to disable logging if we're under MASH env. if (chromeos::GetDeviceType() != chromeos::DeviceType::kChromebook || - chromeos::GetAshConfig() == ash::Config::MASH) { + !features::IsAshInBrowserProcess()) { return nullptr; }
diff --git a/chrome/browser/chromeos/power/ml/user_activity_controller.cc b/chrome/browser/chromeos/power/ml/user_activity_controller.cc index f99c4df..d564e114 100644 --- a/chrome/browser/chromeos/power/ml/user_activity_controller.cc +++ b/chrome/browser/chromeos/power/ml/user_activity_controller.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/chromeos/power/ml/user_activity_controller.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/system/devicetype.h" @@ -12,6 +11,7 @@ #include "components/viz/host/host_frame_sink_manager.h" #include "services/viz/public/interfaces/compositing/video_detector_observer.mojom.h" #include "ui/aura/env.h" +#include "ui/base/ui_base_features.h" #include "ui/compositor/compositor.h" namespace chromeos { @@ -22,7 +22,7 @@ // TODO(jiameng): video detector below doesn't work with MASH. Temporary // solution is to disable logging if we're under MASH env. if (chromeos::GetDeviceType() != chromeos::DeviceType::kChromebook || - chromeos::GetAshConfig() == ash::Config::MASH) + !features::IsAshInBrowserProcess()) return; chromeos::PowerManagerClient* power_manager_client =
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index b8c4e3e..86447d9 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/input_method/input_method_syncer.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" @@ -32,7 +31,6 @@ #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/prefs/pref_service_syncable_util.h" #include "chrome/browser/ui/ash/ash_shell_init.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/system_tray_client.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/chromeos/system_logs/touch_log_source.cc b/chrome/browser/chromeos/system_logs/touch_log_source.cc index 6bb16805..e47ed38 100644 --- a/chrome/browser/chromeos/system_logs/touch_log_source.cc +++ b/chrome/browser/chromeos/system_logs/touch_log_source.cc
@@ -6,7 +6,6 @@ #include <stddef.h> -#include "ash/public/cpp/config.h" #include "ash/touch/touch_hud_debug.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -20,9 +19,9 @@ #include "base/task_scheduler/post_task.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" -#include "chrome/browser/chromeos/ash_config.h" #include "content/public/browser/browser_thread.h" #include "services/ui/public/cpp/input_devices/input_device_controller_client.h" +#include "ui/base/ui_base_features.h" using content::BrowserThread; @@ -171,7 +170,7 @@ // Collect touch HUD debug logs. This needs to be done on the UI thread. void CollectTouchHudDebugLog(system_logs::SystemLogsResponse* response) { // TODO(mash): Collect this data from window server over mojo. - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { NOTIMPLEMENTED(); return; }
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc index 4f960e34..3d49e24 100644 --- a/chrome/browser/client_hints/client_hints_browsertest.cc +++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -1091,6 +1091,13 @@ // Start incognito browser twice to ensure that client hints prefs are // not carried over. IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, ClientHintsHttpsIncognito) { + // TODO(crbug.com/850945): This test causes a use-after-free when the + // NetworkServices feature is enabled. Disable the test in that configuration + // until the issue is fixed. + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { + return; + } + for (size_t i = 0; i < 2; ++i) { base::HistogramTester histogram_tester;
diff --git a/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc b/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc index bd1dc33..48aa6b9b 100644 --- a/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc +++ b/chrome/browser/component_updater/third_party_module_list_component_installer_win.cc
@@ -4,54 +4,45 @@ #include "chrome/browser/component_updater/third_party_module_list_component_installer_win.h" +#include <iterator> #include <utility> #include "base/bind.h" -#include "base/files/file_enumerator.h" -#include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/json/json_reader.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/path_service.h" -#include "base/strings/string_number_conversions.h" -#include "base/task_scheduler/post_task.h" #include "base/values.h" #include "base/version.h" #include "chrome/browser/conflicts/module_database_win.h" #include "chrome/browser/conflicts/third_party_conflicts_manager_win.h" -#include "components/component_updater/component_updater_paths.h" -#include "content/public/browser/browser_thread.h" - -using component_updater::ComponentUpdateService; namespace { // The relative path of the expected module list file inside of an installation // of this component. -const wchar_t kRelativeModuleListPath[] = L"module_list_proto"; +constexpr base::FilePath::CharType kRelativeModuleListPath[] = + FILE_PATH_LITERAL("module_list_proto"); + +constexpr char kComponentId[] = "ehgidpndbllacpjalkiimkbadgjfnnmc"; } // namespace namespace component_updater { // The SHA256 of the SubjectPublicKeyInfo used to sign the component. -// The component id is: EHGIDPNDBLLACPJALKIIMKBADGJFNNMC -const uint8_t kThirdPartyModuleListPublicKeySHA256[32] = { +constexpr uint8_t kThirdPartyModuleListPublicKeySHA256[32] = { 0x47, 0x68, 0x3f, 0xd3, 0x1b, 0xb0, 0x2f, 0x90, 0xba, 0x88, 0xca, 0x10, 0x36, 0x95, 0xdd, 0xc2, 0x29, 0xd1, 0x4f, 0x38, 0xf2, 0x9d, 0x6c, 0x9c, 0x68, 0x6c, 0xa2, 0xa4, 0xa2, 0x8e, 0xa5, 0x5c}; // The name of the component. This is used in the chrome://components page. -const char kThirdPartyModuleListName[] = "Third Party Module List"; +constexpr char kThirdPartyModuleListName[] = "Third Party Module List"; ThirdPartyModuleListComponentInstallerPolicy:: - ThirdPartyModuleListComponentInstallerPolicy( - ThirdPartyConflictsManager* manager) - : manager_(manager) {} + ThirdPartyModuleListComponentInstallerPolicy() = default; ThirdPartyModuleListComponentInstallerPolicy:: - ~ThirdPartyModuleListComponentInstallerPolicy() {} + ~ThirdPartyModuleListComponentInstallerPolicy() = default; bool ThirdPartyModuleListComponentInstallerPolicy:: SupportsGroupPolicyEnabledComponentUpdates() const { @@ -83,7 +74,12 @@ // Forward the notification to the ThirdPartyConflictsManager on the current // (UI) thread. The manager is responsible for the work of actually loading // the module list, etc, on background threads. - manager_->LoadModuleList(GetModuleListPath(install_dir)); + ThirdPartyConflictsManager* manager = + ModuleDatabase::GetInstance()->third_party_conflicts_manager(); + if (!manager) + return; + + manager->LoadModuleList(GetModuleListPath(install_dir)); } bool ThirdPartyModuleListComponentInstallerPolicy::VerifyInstallation( @@ -97,12 +93,12 @@ base::FilePath ThirdPartyModuleListComponentInstallerPolicy::GetRelativeInstallDir() const { - static constexpr wchar_t kRelativeModuleListInstallDir[] = - L"ThirdPartyModuleList" + static constexpr base::FilePath::CharType kRelativeModuleListInstallDir[] = + FILE_PATH_LITERAL("ThirdPartyModuleList") #ifdef _WIN64 - "64"; + FILE_PATH_LITERAL("64"); #else - "32"; + FILE_PATH_LITERAL("32"); #endif return base::FilePath(kRelativeModuleListInstallDir); @@ -134,21 +130,27 @@ return install_dir.Append(kRelativeModuleListPath); } -void RegisterThirdPartyModuleListComponent(ComponentUpdateService* cus) { +void RegisterThirdPartyModuleListComponent( + ComponentUpdateService* component_update_service) { DVLOG(1) << "Registering Third Party Module List component."; - // Get a handle to the manager. This will only exist if the corresponding - // feature is enabled. - ModuleDatabase* database = ModuleDatabase::GetInstance(); - if (!database) + // Check if component is needed. The ThirdPartyConflictsManager instance only + // exists when the module list is needed. + if (!ModuleDatabase::GetInstance()->third_party_conflicts_manager()) return; - ThirdPartyConflictsManager* manager = - database->third_party_conflicts_manager(); - if (!manager) - return; + auto installer = base::MakeRefCounted<ComponentInstaller>( - std::make_unique<ThirdPartyModuleListComponentInstallerPolicy>(manager)); - installer->Register(cus, base::OnceClosure()); + std::make_unique<ThirdPartyModuleListComponentInstallerPolicy>()); + installer->Register( + component_update_service, base::BindOnce([]() { + // Notify the ThirdPartyConflictsManager. + ThirdPartyConflictsManager* manager = + ModuleDatabase::GetInstance()->third_party_conflicts_manager(); + if (!manager) + return; + + manager->OnModuleListComponentRegistered(kComponentId); + })); } } // namespace component_updater
diff --git a/chrome/browser/component_updater/third_party_module_list_component_installer_win.h b/chrome/browser/component_updater/third_party_module_list_component_installer_win.h index 5ccb855..bd42a3d 100644 --- a/chrome/browser/component_updater/third_party_module_list_component_installer_win.h +++ b/chrome/browser/component_updater/third_party_module_list_component_installer_win.h
@@ -11,15 +11,10 @@ #include <string> #include <vector> +#include "base/files/file_path.h" +#include "base/macros.h" #include "components/component_updater/component_installer.h" -namespace base { -class FilePath; -} // namespace base - -// Will receive notifications about a new module list being available. -class ThirdPartyConflictsManager; - namespace component_updater { class ComponentUpdateService; @@ -29,19 +24,14 @@ // chrome/browser/conflicts/proto/module_list.proto // // Notifications of a new version of the module list are sent to the -// ThirdPartyConflictsManager. +// ThirdPartyConflictsManager instance in the ModuleDatabase, if it exists. class ThirdPartyModuleListComponentInstallerPolicy : public ComponentInstallerPolicy { public: - // The |manager| will be notified each time a new module list is available, - // including once every startup when a component is already installed. - explicit ThirdPartyModuleListComponentInstallerPolicy( - ThirdPartyConflictsManager* manager); + ThirdPartyModuleListComponentInstallerPolicy(); ~ThirdPartyModuleListComponentInstallerPolicy() override; private: - friend class ThirdPartyModuleListComponentInstallerPolicyTest; - // ComponentInstallerPolicy implementation. bool SupportsGroupPolicyEnabledComponentUpdates() const override; bool RequiresNetworkEncryption() const override; @@ -63,15 +53,11 @@ // Returns the path to the proto file for the given |install_dir|. static base::FilePath GetModuleListPath(const base::FilePath& install_dir); - // The manager is not owned by this class, so the code creating it is - // expected to ensure the manager lives as long as this class does. Typically - // the manager provided will be a global singleton. - ThirdPartyConflictsManager* manager_; - DISALLOW_COPY_AND_ASSIGN(ThirdPartyModuleListComponentInstallerPolicy); }; -void RegisterThirdPartyModuleListComponent(ComponentUpdateService* cus); +void RegisterThirdPartyModuleListComponent( + ComponentUpdateService* component_update_service); } // namespace component_updater
diff --git a/chrome/browser/conflicts/incompatible_applications_updater_win.cc b/chrome/browser/conflicts/incompatible_applications_updater_win.cc index dfcb8cf..e36b8ad 100644 --- a/chrome/browser/conflicts/incompatible_applications_updater_win.cc +++ b/chrome/browser/conflicts/incompatible_applications_updater_win.cc
@@ -207,16 +207,21 @@ // IncompatibleApplicationsUpdater IncompatibleApplicationsUpdater::IncompatibleApplicationsUpdater( + ModuleDatabaseEventSource* module_database_event_source, const CertificateInfo& exe_certificate_info, const ModuleListFilter& module_list_filter, const InstalledApplications& installed_applications) - : exe_certificate_info_(exe_certificate_info), + : module_database_event_source_(module_database_event_source), + exe_certificate_info_(exe_certificate_info), module_list_filter_(module_list_filter), installed_applications_(installed_applications) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + module_database_event_source_->AddObserver(this); } -IncompatibleApplicationsUpdater::~IncompatibleApplicationsUpdater() = default; +IncompatibleApplicationsUpdater::~IncompatibleApplicationsUpdater() { + module_database_event_source_->RemoveObserver(this); +} // static void IncompatibleApplicationsUpdater::RegisterLocalStatePrefs(
diff --git a/chrome/browser/conflicts/incompatible_applications_updater_win.h b/chrome/browser/conflicts/incompatible_applications_updater_win.h index 2b3eb425..2a399440 100644 --- a/chrome/browser/conflicts/incompatible_applications_updater_win.h +++ b/chrome/browser/conflicts/incompatible_applications_updater_win.h
@@ -42,6 +42,7 @@ // Creates an instance of the updater. // The parameters must outlive the lifetime of this class. IncompatibleApplicationsUpdater( + ModuleDatabaseEventSource* module_database_event_source, const CertificateInfo& exe_certificate_info, const ModuleListFilter& module_list_filter, const InstalledApplications& installed_applications); @@ -67,10 +68,10 @@ void OnModuleDatabaseIdle() override; private: + ModuleDatabaseEventSource* const module_database_event_source_; + const CertificateInfo& exe_certificate_info_; - const ModuleListFilter& module_list_filter_; - const InstalledApplications& installed_applications_; // Temporarily holds incompatible applications that were recently found.
diff --git a/chrome/browser/conflicts/incompatible_applications_updater_win_unittest.cc b/chrome/browser/conflicts/incompatible_applications_updater_win_unittest.cc index a5ac596..d5f9733 100644 --- a/chrome/browser/conflicts/incompatible_applications_updater_win_unittest.cc +++ b/chrome/browser/conflicts/incompatible_applications_updater_win_unittest.cc
@@ -102,7 +102,8 @@ } // namespace -class IncompatibleApplicationsUpdaterTest : public testing::Test { +class IncompatibleApplicationsUpdaterTest : public testing::Test, + public ModuleDatabaseEventSource { protected: IncompatibleApplicationsUpdaterTest() : dll1_(kDllPath1), @@ -141,12 +142,17 @@ } } - CertificateInfo& exe_certificate_info() { return exe_certificate_info_; } - MockModuleListFilter& module_list_filter() { return module_list_filter_; } - MockInstalledApplications& installed_applications() { - return installed_applications_; + std::unique_ptr<IncompatibleApplicationsUpdater> + CreateIncompatibleApplicationsUpdater() { + return std::make_unique<IncompatibleApplicationsUpdater>( + this, exe_certificate_info_, module_list_filter_, + installed_applications_); } + // ModuleDatabaseEventSource: + void AddObserver(ModuleDatabaseObserver* observer) override {} + void RemoveObserver(ModuleDatabaseObserver* observer) override {} + const base::FilePath dll1_; const base::FilePath dll2_; @@ -173,9 +179,7 @@ // registered installed applications. TEST_F(IncompatibleApplicationsUpdaterTest, NoIncompatibleApplications) { auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Simulate some arbitrary module loading into the process. incompatible_applications_updater->OnNewModuleFound( @@ -190,9 +194,7 @@ AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY); auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Simulate the module loading into the process. incompatible_applications_updater->OnNewModuleFound( @@ -211,9 +213,7 @@ AddIncompatibleApplication(dll1_, L"Bar", Option::ADD_REGISTRY_ENTRY); auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Simulate the module loading into the process. incompatible_applications_updater->OnNewModuleFound( @@ -232,9 +232,7 @@ AddIncompatibleApplication(dll2_, L"Bar", Option::ADD_REGISTRY_ENTRY); auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Simulate the module loading into the process. incompatible_applications_updater->OnNewModuleFound( @@ -262,9 +260,7 @@ AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY); auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Simulate the module loading into the process. incompatible_applications_updater->OnNewModuleFound( @@ -285,9 +281,7 @@ AddIncompatibleApplication(dll2_, L"Bar", Option::NO_REGISTRY_ENTRY); auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Simulate the modules loading into the process. incompatible_applications_updater->OnNewModuleFound( @@ -309,9 +303,7 @@ AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY); auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Simulate the module loading into the process. incompatible_applications_updater->OnNewModuleFound( @@ -332,9 +324,7 @@ Option::ADD_REGISTRY_ENTRY); auto incompatible_applications_updater = - std::make_unique<IncompatibleApplicationsUpdater>( - exe_certificate_info(), module_list_filter(), - installed_applications()); + CreateIncompatibleApplicationsUpdater(); // Set the respective bit for registered modules. auto module_data1 = CreateLoadedModuleInfoData();
diff --git a/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc b/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc index 209f86f..50a2c999 100644 --- a/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc +++ b/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc
@@ -89,10 +89,12 @@ constexpr base::TimeDelta ModuleBlacklistCacheUpdater::kUpdateTimerDuration; ModuleBlacklistCacheUpdater::ModuleBlacklistCacheUpdater( + ModuleDatabaseEventSource* module_database_event_source, const CertificateInfo& exe_certificate_info, const ModuleListFilter& module_list_filter, OnCacheUpdatedCallback on_cache_updated_callback) - : exe_certificate_info_(exe_certificate_info), + : module_database_event_source_(module_database_event_source), + exe_certificate_info_(exe_certificate_info), module_list_filter_(module_list_filter), on_cache_updated_callback_(std::move(on_cache_updated_callback)), background_sequence_(base::CreateSequencedTaskRunnerWithTraits( @@ -108,9 +110,13 @@ base::Bind(&ModuleBlacklistCacheUpdater::OnTimerExpired, base::Unretained(this)), false /* is_repeating */), - weak_ptr_factory_(this) {} + weak_ptr_factory_(this) { + module_database_event_source_->AddObserver(this); +} -ModuleBlacklistCacheUpdater::~ModuleBlacklistCacheUpdater() = default; +ModuleBlacklistCacheUpdater::~ModuleBlacklistCacheUpdater() { + module_database_event_source_->RemoveObserver(this); +} // static bool ModuleBlacklistCacheUpdater::IsThirdPartyModuleBlockingEnabled() {
diff --git a/chrome/browser/conflicts/module_blacklist_cache_updater_win.h b/chrome/browser/conflicts/module_blacklist_cache_updater_win.h index 4a98af3..eaa3433 100644 --- a/chrome/browser/conflicts/module_blacklist_cache_updater_win.h +++ b/chrome/browser/conflicts/module_blacklist_cache_updater_win.h
@@ -56,11 +56,12 @@ // Creates an instance of the updater. The callback will be invoked every time // the cache is updated. - // The |exe_certificate_info| & |module_list_filter| must outlive the lifetime - // of this class. - ModuleBlacklistCacheUpdater(const CertificateInfo& exe_certificate_info, - const ModuleListFilter& module_list_filter, - OnCacheUpdatedCallback on_cache_updated_callback); + // The parameters must outlive the lifetime of this class. + ModuleBlacklistCacheUpdater( + ModuleDatabaseEventSource* module_database_event_source, + const CertificateInfo& exe_certificate_info, + const ModuleListFilter& module_list_filter, + OnCacheUpdatedCallback on_cache_updated_callback); ~ModuleBlacklistCacheUpdater() override; // Returns true if the blocking of third-party modules is enabled. The return @@ -92,6 +93,8 @@ // Invoked on the sequence that owns this instance when the cache is updated. void OnModuleBlacklistCacheUpdated(const CacheUpdateResult& result); + ModuleDatabaseEventSource* const module_database_event_source_; + const CertificateInfo& exe_certificate_info_; const ModuleListFilter& module_list_filter_;
diff --git a/chrome/browser/conflicts/module_blacklist_cache_updater_win_unittest.cc b/chrome/browser/conflicts/module_blacklist_cache_updater_win_unittest.cc index 66393c3..8b59ea6 100644 --- a/chrome/browser/conflicts/module_blacklist_cache_updater_win_unittest.cc +++ b/chrome/browser/conflicts/module_blacklist_cache_updater_win_unittest.cc
@@ -100,7 +100,8 @@ } // namespace -class ModuleBlacklistCacheUpdaterTest : public testing::Test { +class ModuleBlacklistCacheUpdaterTest : public testing::Test, + public ModuleDatabaseEventSource { protected: ModuleBlacklistCacheUpdaterTest() : dll1_(kDllPath1), @@ -124,7 +125,7 @@ std::unique_ptr<ModuleBlacklistCacheUpdater> CreateModuleBlacklistCacheUpdater() { return std::make_unique<ModuleBlacklistCacheUpdater>( - exe_certificate_info_, module_list_filter_, + this, exe_certificate_info_, module_list_filter_, base::BindRepeating( &ModuleBlacklistCacheUpdaterTest::OnModuleBlacklistCacheUpdated, base::Unretained(this))); @@ -146,6 +147,10 @@ return on_cache_updated_callback_invoked_; } + // ModuleDatabaseEventSource: + void AddObserver(ModuleDatabaseObserver* observer) override {} + void RemoveObserver(ModuleDatabaseObserver* observer) override {} + const base::FilePath dll1_; const base::FilePath dll2_;
diff --git a/chrome/browser/conflicts/module_database_observer_win.h b/chrome/browser/conflicts/module_database_observer_win.h index d423b86..a49fdca2 100644 --- a/chrome/browser/conflicts/module_database_observer_win.h +++ b/chrome/browser/conflicts/module_database_observer_win.h
@@ -10,8 +10,6 @@ class ModuleDatabaseObserver { public: - virtual ~ModuleDatabaseObserver() = default; - // Invoked when a new module is loaded into Chrome, but after it has been // inspected on disk. virtual void OnNewModuleFound(const ModuleInfoKey& module_key, @@ -21,6 +19,18 @@ // ModuleDatabase stopped inspecting modules and it received no new module // events in the last 10 seconds. virtual void OnModuleDatabaseIdle() {} + + protected: + virtual ~ModuleDatabaseObserver() = default; +}; + +class ModuleDatabaseEventSource { + public: + virtual void AddObserver(ModuleDatabaseObserver* observer) = 0; + virtual void RemoveObserver(ModuleDatabaseObserver* observer) = 0; + + protected: + virtual ~ModuleDatabaseEventSource() = default; }; #endif // CHROME_BROWSER_CONFLICTS_MODULE_DATABASE_OBSERVER_WIN_H_
diff --git a/chrome/browser/conflicts/module_database_win.cc b/chrome/browser/conflicts/module_database_win.cc index b51e437..57d9b04 100644 --- a/chrome/browser/conflicts/module_database_win.cc +++ b/chrome/browser/conflicts/module_database_win.cc
@@ -295,7 +295,6 @@ base::FeatureList::IsEnabled(features::kThirdPartyModulesBlocking)) { third_party_conflicts_manager_ = std::make_unique<ThirdPartyConflictsManager>(this); - AddObserver(third_party_conflicts_manager_.get()); pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); pref_change_registrar_->Init(g_browser_process->local_state());
diff --git a/chrome/browser/conflicts/module_database_win.h b/chrome/browser/conflicts/module_database_win.h index 19a80fd4..dbd5683 100644 --- a/chrome/browser/conflicts/module_database_win.h +++ b/chrome/browser/conflicts/module_database_win.h
@@ -39,7 +39,7 @@ // This is effectively a singleton, but doesn't use base::Singleton. The intent // is for the object to be created when Chrome is single-threaded, and for it // be set as the process-wide singleton via SetInstance. -class ModuleDatabase { +class ModuleDatabase : public ModuleDatabaseEventSource { public: // Structures for maintaining information about modules. using ModuleMap = std::map<ModuleInfoKey, ModuleInfoData>; @@ -55,7 +55,7 @@ // otherwise noted. For calls from other contexts this task runner is used to // bounce the call when appropriate. explicit ModuleDatabase(scoped_refptr<base::SequencedTaskRunner> task_runner); - ~ModuleDatabase(); + ~ModuleDatabase() override; // Retrieves the singleton global instance of the ModuleDatabase. static ModuleDatabase* GetInstance(); @@ -108,8 +108,10 @@ // OnModuleDatabaseIdle() will also be invoked. // Must be called in the same sequence as |task_runner_|, and all // notifications will be sent on that same task runner. - void AddObserver(ModuleDatabaseObserver* observer); - void RemoveObserver(ModuleDatabaseObserver* observer); + // + // ModuleDatabaseEventSource: + void AddObserver(ModuleDatabaseObserver* observer) override; + void RemoveObserver(ModuleDatabaseObserver* observer) override; // Raises the priority of module inspection tasks to ensure the // ModuleDatabase becomes idle ASAP. @@ -122,10 +124,11 @@ // administrative policy. static bool IsThirdPartyBlockingPolicyEnabled(); - // Accessor for the third party conflicts manager. This is exposed so that the - // manager can be wired up to the ThirdPartyModuleListComponentInstaller. + // Accessor for the third party conflicts manager. // Returns null if both the tracking of incompatible applications and the // blocking of third-party modules are disabled. + // Do not hold a pointer to the manager because it can be destroyed if the + // ThirdPartyBlocking policy is disabled. ThirdPartyConflictsManager* third_party_conflicts_manager() { return third_party_conflicts_manager_.get(); }
diff --git a/chrome/browser/conflicts/third_party_blocking_browsertest.cc b/chrome/browser/conflicts/third_party_blocking_browsertest.cc index 66c64c24..ca1deba 100644 --- a/chrome/browser/conflicts/third_party_blocking_browsertest.cc +++ b/chrome/browser/conflicts/third_party_blocking_browsertest.cc
@@ -13,7 +13,6 @@ #include "base/scoped_native_library.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_reg_util_win.h" -#include "chrome/browser/conflicts/incompatible_applications_updater_win.h" #include "chrome/browser/conflicts/module_blacklist_cache_updater_win.h" #include "chrome/browser/conflicts/module_blacklist_cache_util_win.h" #include "chrome/browser/conflicts/module_database_win.h"
diff --git a/chrome/browser/conflicts/third_party_conflicts_manager_win.cc b/chrome/browser/conflicts/third_party_conflicts_manager_win.cc index 87d80b46..79517c5 100644 --- a/chrome/browser/conflicts/third_party_conflicts_manager_win.cc +++ b/chrome/browser/conflicts/third_party_conflicts_manager_win.cc
@@ -9,6 +9,7 @@ #include "base/base_paths.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/feature_list.h" #include "base/files/file_path.h" #include "base/location.h" @@ -22,7 +23,6 @@ #include "chrome/browser/conflicts/incompatible_applications_updater_win.h" #include "chrome/browser/conflicts/installed_applications_win.h" #include "chrome/browser/conflicts/module_blacklist_cache_updater_win.h" -#include "chrome/browser/conflicts/module_database_win.h" #include "chrome/browser/conflicts/module_info_util_win.h" #include "chrome/browser/conflicts/module_list_filter_win.h" #include "chrome/common/chrome_features.h" @@ -56,15 +56,19 @@ } // namespace ThirdPartyConflictsManager::ThirdPartyConflictsManager( - ModuleDatabase* module_database) - : module_database_(module_database), + ModuleDatabaseEventSource* module_database_event_source) + : module_database_event_source_(module_database_event_source), background_sequence_(base::CreateSequencedTaskRunnerWithTraits( {base::TaskPriority::BACKGROUND, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()})), module_list_received_(false), on_module_database_idle_called_(false), + initialization_forced_(false), + module_list_update_needed_(false), + component_update_service_observer_(this), weak_ptr_factory_(this) { + module_database_event_source_->AddObserver(this); base::PostTaskAndReplyWithResult( background_sequence_.get(), FROM_HERE, base::BindOnce(&CreateExeCertificateInfo), @@ -72,7 +76,10 @@ weak_ptr_factory_.GetWeakPtr())); } -ThirdPartyConflictsManager::~ThirdPartyConflictsManager() = default; +ThirdPartyConflictsManager::~ThirdPartyConflictsManager() { + SetTerminalState(State::kDestroyed); + module_database_event_source_->RemoveObserver(this); +} // static void ThirdPartyConflictsManager::RegisterLocalStatePrefs( @@ -113,6 +120,11 @@ on_module_database_idle_called_ = true; + // The InstalledApplications instance is only needed for the incompatible + // applications warning. + if (!base::FeatureList::IsEnabled(features::kIncompatibleApplicationsWarning)) + return; + base::PostTaskAndReplyWithResult( background_sequence_.get(), FROM_HERE, base::BindOnce([]() { return std::make_unique<InstalledApplications>(); @@ -122,10 +134,39 @@ weak_ptr_factory_.GetWeakPtr())); } +void ThirdPartyConflictsManager::OnModuleListComponentRegistered( + base::StringPiece component_id) { + DCHECK(module_list_component_id_.empty()); + module_list_component_id_ = component_id.as_string(); + + auto components = g_browser_process->component_updater()->GetComponents(); + auto iter = std::find_if(components.begin(), components.end(), + [this](const auto& component) { + return component.id == module_list_component_id_; + }); + DCHECK(iter != components.end()); + + if (iter->version == base::Version("0.0.0.0")) { + // The module list component is currently not installed. An update is + // required to initialize the ModuleListFilter. + module_list_update_needed_ = true; + + // The update is usually done automatically when the component update + // service decides to do it. But if the initialization was forced, the + // component update must also be triggered right now. + if (initialization_forced_) + ForceModuleListComponentUpdate(); + } + + // LoadModuleList() will be called if the version is not "0.0.0.0". +} + void ThirdPartyConflictsManager::LoadModuleList(const base::FilePath& path) { if (module_list_received_) return; + component_update_service_observer_.RemoveAll(); + module_list_received_ = true; base::PostTaskAndReplyWithResult( @@ -135,15 +176,69 @@ weak_ptr_factory_.GetWeakPtr())); } +void ThirdPartyConflictsManager::ForceInitialization( + OnInitializationCompleteCallback on_initialization_complete_callback) { + on_initialization_complete_callback_ = + std::move(on_initialization_complete_callback); + + if (terminal_state_.has_value()) { + std::move(on_initialization_complete_callback_) + .Run(terminal_state_.value()); + return; + } + + // It doesn't make sense to do this twice. + if (initialization_forced_) + return; + initialization_forced_ = true; + + // Nothing to force if we already received a module list. + if (module_list_received_) + return; + + // Only force an update if it is needed, because the ModuleListFilter can be + // initialized with an older version of the Module List component. + if (module_list_update_needed_) + ForceModuleListComponentUpdate(); +} + +void ThirdPartyConflictsManager::OnEvent(Events event, + const std::string& component_id) { + DCHECK(!module_list_component_id_.empty()); + + // LoadModuleList() was already invoked. + if (module_list_received_) + return; + + // Only consider events for the module list component. + if (component_id != module_list_component_id_) + return; + + // There are 2 cases that are important. Either the component is being + // updated, or the component is not updated because there is no update + // available. + // + // For the first case, there is nothing to do because LoadModuleList() will + // eventually be called when the component is installed. + // + // For the second case, it means that the server is not offering any update + // right now, either because it is too busy, or there is an issue with the + // server-side component configuration. + // + // Note: + // The COMPONENT_NOT_UPDATED event can also be broadcasted when the component + // is already up-to-date. This is not the case here because this class only + // registers to the component updater service as an observer when the + // component version is 0.0.0.0 (aka not installed). + if (event == Events::COMPONENT_NOT_UPDATED) + SetTerminalState(State::kNoModuleListAvailableFailure); +} + void ThirdPartyConflictsManager::OnExeCertificateCreated( std::unique_ptr<CertificateInfo> exe_certificate_info) { exe_certificate_info_ = std::move(exe_certificate_info); - if (module_list_filter_ && installed_applications_) - InitializeIncompatibleApplicationsUpdater(); - - if (module_list_filter_) - MaybeInitializeModuleBlacklistCacheUpdater(); + InitializeIfReady(); } void ThirdPartyConflictsManager::OnModuleListFilterCreated( @@ -158,52 +253,53 @@ // Mark the module list as not received so that a new one may trigger the // creation of a valid filter. module_list_received_ = false; + SetTerminalState(State::kModuleListInvalidFailure); return; } - if (exe_certificate_info_ && installed_applications_) - InitializeIncompatibleApplicationsUpdater(); + module_list_update_needed_ = false; - if (exe_certificate_info_) - MaybeInitializeModuleBlacklistCacheUpdater(); + InitializeIfReady(); } void ThirdPartyConflictsManager::OnInstalledApplicationsCreated( std::unique_ptr<InstalledApplications> installed_applications) { installed_applications_ = std::move(installed_applications); - if (exe_certificate_info_ && module_list_filter_) - InitializeIncompatibleApplicationsUpdater(); + InitializeIfReady(); } -void ThirdPartyConflictsManager::InitializeIncompatibleApplicationsUpdater() { - DCHECK(exe_certificate_info_); - DCHECK(module_list_filter_); - DCHECK(installed_applications_); +void ThirdPartyConflictsManager::InitializeIfReady() { + DCHECK(!terminal_state_.has_value()); - incompatible_applications_updater_ = - std::make_unique<IncompatibleApplicationsUpdater>( - *exe_certificate_info_, *module_list_filter_, - *installed_applications_); - module_database_->AddObserver(incompatible_applications_updater_.get()); -} - -void ThirdPartyConflictsManager::MaybeInitializeModuleBlacklistCacheUpdater() { - DCHECK(exe_certificate_info_); - DCHECK(module_list_filter_); - - if (!base::FeatureList::IsEnabled(features::kThirdPartyModulesBlocking)) + // Check if this instance is ready to initialize. + if (!exe_certificate_info_ || !module_list_filter_ || + (!installed_applications_ && + base::FeatureList::IsEnabled( + features::kIncompatibleApplicationsWarning))) { return; + } - // Create the instance. It is safe to use base::Unretained() since the - // callback is not invoked when the updater is freed. - module_blacklist_cache_updater_ = - std::make_unique<ModuleBlacklistCacheUpdater>( - *exe_certificate_info_, *module_list_filter_, - base::BindRepeating( - &ThirdPartyConflictsManager::OnModuleBlacklistCacheUpdated, - base::Unretained(this))); - module_database_->AddObserver(module_blacklist_cache_updater_.get()); + if (installed_applications_) { + incompatible_applications_updater_ = + std::make_unique<IncompatibleApplicationsUpdater>( + module_database_event_source_, *exe_certificate_info_, + *module_list_filter_, *installed_applications_); + } + + if (base::FeatureList::IsEnabled(features::kThirdPartyModulesBlocking)) { + // It is safe to use base::Unretained() since the callback will not be + // invoked if the updater is freed. + module_blacklist_cache_updater_ = + std::make_unique<ModuleBlacklistCacheUpdater>( + module_database_event_source_, *exe_certificate_info_, + *module_list_filter_, + base::BindRepeating( + &ThirdPartyConflictsManager::OnModuleBlacklistCacheUpdated, + base::Unretained(this))); + } + + SetTerminalState(State::kInitialized); } void ThirdPartyConflictsManager::OnModuleBlacklistCacheUpdated( @@ -232,3 +328,23 @@ prefs::kModuleBlacklistCacheMD5Digest, base::Value(base::MD5DigestToBase16(result.new_md5_digest))); } + +void ThirdPartyConflictsManager::ForceModuleListComponentUpdate() { + auto* component_update_service = g_browser_process->component_updater(); + + // Observe the component updater service to know the result of the update. + DCHECK(!component_update_service_observer_.IsObserving( + component_update_service)); + component_update_service_observer_.Add(component_update_service); + + component_update_service->MaybeThrottle(module_list_component_id_, + base::DoNothing()); +} + +void ThirdPartyConflictsManager::SetTerminalState(State terminal_state) { + DCHECK(!terminal_state_.has_value()); + terminal_state_ = terminal_state; + if (on_initialization_complete_callback_) + std::move(on_initialization_complete_callback_) + .Run(terminal_state_.value()); +}
diff --git a/chrome/browser/conflicts/third_party_conflicts_manager_win.h b/chrome/browser/conflicts/third_party_conflicts_manager_win.h index c676e1b5..dfb5c5a 100644 --- a/chrome/browser/conflicts/third_party_conflicts_manager_win.h +++ b/chrome/browser/conflicts/third_party_conflicts_manager_win.h
@@ -6,16 +6,21 @@ #define CHROME_BROWSER_CONFLICTS_THIRD_PARTY_CONFLICTS_MANAGER_WIN_H_ #include <memory> +#include <string> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "base/scoped_observer.h" +#include "base/strings/string_piece_forward.h" #include "chrome/browser/conflicts/module_blacklist_cache_updater_win.h" #include "chrome/browser/conflicts/module_database_observer_win.h" +#include "components/component_updater/component_updater_service.h" class IncompatibleApplicationsUpdater; class InstalledApplications; -class ModuleDatabase; class ModuleListFilter; class PrefRegistrySimple; struct CertificateInfo; @@ -28,9 +33,17 @@ // This class owns all the third-party conflicts-related classes and is // responsible for their initialization. -class ThirdPartyConflictsManager : public ModuleDatabaseObserver { +// +// The Module List component is received from the component update service, +// which invokes OnModuleListComponentRegister() and LoadModuleList() when +// appropriate. +class ThirdPartyConflictsManager + : public ModuleDatabaseObserver, + public component_updater::ComponentUpdateService::Observer { public: - explicit ThirdPartyConflictsManager(ModuleDatabase* module_database); + // |module_database_event_source| must outlive this. + explicit ThirdPartyConflictsManager( + ModuleDatabaseEventSource* module_database_event_source); ~ThirdPartyConflictsManager() override; static void RegisterLocalStatePrefs(PrefRegistrySimple* registry); @@ -53,9 +66,42 @@ // ModuleDatabaseObserver: void OnModuleDatabaseIdle() override; + // Invoked when the Third Party Module List component is registered with the + // component update service. Checks if the component is currently installed or + // if an update is required. + void OnModuleListComponentRegistered(base::StringPiece component_id); + // Loads the |module_list_filter_| using the Module List at |path|. void LoadModuleList(const base::FilePath& path); + // Force the initialization of the IncompatibleApplicationsUpdater and the + // ModuleBlacklistCacheUpdater instances by triggering an update of the module + // list component, if needed. Immediately invokes + // |on_initialization_event_callback| if this instance is already in a final + // state (Failed to initialize or fully initialized). This is only meant to be + // used when the chrome://conflicts page is opened by the user. + enum class State { + // The initialization failed because the Module List component couldn't be + // used to initialize the ModuleListFilter. + kModuleListInvalidFailure, + // The initialization failed because there was no Module List version + // available to install. + kNoModuleListAvailableFailure, + // The instance is initialized. If their respective feature is enabled, the + // |incompatible_applications_updater_| & |module_blacklist_cache_updater_| + // instances are initialized. + kInitialized, + // The instance is about to be deleted. + kDestroyed, + }; + using OnInitializationCompleteCallback = + base::OnceCallback<void(State state)>; + void ForceInitialization( + OnInitializationCompleteCallback on_initialization_complete_callback); + + // ComponentUpdateService::Observer: + void OnEvent(Events event, const std::string& component_id) override; + private: // Called when |exe_certificate_info_| finishes its initialization. void OnExeCertificateCreated( @@ -69,21 +115,25 @@ void OnInstalledApplicationsCreated( std::unique_ptr<InstalledApplications> installed_applications); - // Initializes |incompatible_applications_updater_| when the - // exe_certificate_info_, the module_list_filter_ and the - // installed_applications_ are available. - void InitializeIncompatibleApplicationsUpdater(); - - // Initializes |module_blacklist_cache_updater_| if third-party module - // blocking is enabled. - void MaybeInitializeModuleBlacklistCacheUpdater(); + // Initializes either or both |incompatible_applications_updater_| and + // |module_blacklist_cache_updater_| when the exe_certificate_info_, the + // module_list_filter_ and the installed_applications_ are available. + void InitializeIfReady(); // Checks if the |old_md5_digest| matches the expected one from the Local // State file, and updates it to |new_md5_digest|. void OnModuleBlacklistCacheUpdated( const ModuleBlacklistCacheUpdater::CacheUpdateResult& result); - ModuleDatabase* module_database_; + // Forcibly triggers an update of the Third Party Module List component. Only + // invoked when ForceInitialization() is called. + void ForceModuleListComponentUpdate(); + + // Modifies the current state and invokes + // |on_initialization_complete_callback_|. + void SetTerminalState(State terminal_state); + + ModuleDatabaseEventSource* const module_database_event_source_; scoped_refptr<base::SequencedTaskRunner> background_sequence_; @@ -99,13 +149,30 @@ // The certificate info of the current executable. std::unique_ptr<CertificateInfo> exe_certificate_info_; + // Holds the id of the Third Party Module List component. + std::string module_list_component_id_; + + // Remembers if ForceInitialization() was invoked. + bool initialization_forced_; + + // Indicates if an update to the Module List component is needed to initialize + // the ModuleListFilter. + bool module_list_update_needed_; + + // Observes the component update service when an update to the Module List + // component was forced. + ScopedObserver<component_updater::ComponentUpdateService, + component_updater::ComponentUpdateService::Observer> + component_update_service_observer_; + // Filters third-party modules against a whitelist and a blacklist. std::unique_ptr<ModuleListFilter> module_list_filter_; // Retrieves the list of installed applications. std::unique_ptr<InstalledApplications> installed_applications_; - // Maintains the cache of incompatible applications. + // Maintains the cache of incompatible applications. This member is only + // initialized when the IncompatibleApplicationsWarning feature is enabled. std::unique_ptr<IncompatibleApplicationsUpdater> incompatible_applications_updater_; @@ -113,6 +180,12 @@ // the ThirdPartyModuleBlocking feature is enabled. std::unique_ptr<ModuleBlacklistCacheUpdater> module_blacklist_cache_updater_; + // The final state of this instance. + base::Optional<State> terminal_state_; + + // The callback that is invoked when |state_| changes. + OnInitializationCompleteCallback on_initialization_complete_callback_; + base::WeakPtrFactory<ThirdPartyConflictsManager> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ThirdPartyConflictsManager);
diff --git a/chrome/browser/conflicts/third_party_conflicts_manager_win_unittest.cc b/chrome/browser/conflicts/third_party_conflicts_manager_win_unittest.cc new file mode 100644 index 0000000..c2c6e42 --- /dev/null +++ b/chrome/browser/conflicts/third_party_conflicts_manager_win_unittest.cc
@@ -0,0 +1,146 @@ +// 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/conflicts/third_party_conflicts_manager_win.h" + +#include <utility> + +#include "base/bind_helpers.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "chrome/browser/conflicts/proto/module_list.pb.h" +#include "chrome/common/chrome_features.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" + +class ThirdPartyConflictsManagerTest : public testing::Test, + public ModuleDatabaseEventSource { + public: + ThirdPartyConflictsManagerTest() + : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {} + + void SetUp() override { + ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); + + scoped_feature_list_.InitWithFeatures( + // Enabled features. + {features::kIncompatibleApplicationsWarning, + features::kThirdPartyModulesBlocking}, + // Disabled features. + {}); + } + + // Returns the path to the module list. + base::FilePath GetModuleListPath() const { + return scoped_temp_dir_.GetPath().Append(L"ModuleList.bin"); + } + + // Writes an empty serialized ModuleList proto to |GetModuleListPath()|. + void CreateModuleList() { + chrome::conflicts::ModuleList module_list; + // Include an empty blacklist and whitelist. + module_list.mutable_blacklist(); + module_list.mutable_whitelist(); + + std::string contents; + ASSERT_TRUE(module_list.SerializeToString(&contents)); + ASSERT_EQ(base::WriteFile(GetModuleListPath(), contents.data(), + static_cast<int>(contents.size())), + static_cast<int>(contents.size())); + } + + void OnManagerInitializationComplete( + base::Closure quit_closure, + ThirdPartyConflictsManager::State final_state) { + final_state_ = final_state; + std::move(quit_closure).Run(); + } + + const base::Optional<ThirdPartyConflictsManager::State>& final_state() { + return final_state_; + } + + // ModuleDatabaseEventSource: + void AddObserver(ModuleDatabaseObserver* observer) override {} + void RemoveObserver(ModuleDatabaseObserver* observer) override {} + + private: + content::TestBrowserThreadBundle test_browser_thread_bundle_; + ScopedTestingLocalState scoped_testing_local_state_; + + // Temp directory used to host module list. + base::ScopedTempDir scoped_temp_dir_; + + base::test::ScopedFeatureList scoped_feature_list_; + + base::Optional<ThirdPartyConflictsManager::State> final_state_; + + DISALLOW_COPY_AND_ASSIGN(ThirdPartyConflictsManagerTest); +}; + +TEST_F(ThirdPartyConflictsManagerTest, InitializeBothUpdaters) { + ThirdPartyConflictsManager third_party_conflicts_manager(this); + + third_party_conflicts_manager.OnModuleDatabaseIdle(); + ASSERT_NO_FATAL_FAILURE(CreateModuleList()); + third_party_conflicts_manager.LoadModuleList(GetModuleListPath()); + + base::RunLoop run_loop; + third_party_conflicts_manager.ForceInitialization(base::BindRepeating( + &ThirdPartyConflictsManagerTest::OnManagerInitializationComplete, + base::Unretained(this), run_loop.QuitClosure())); + + run_loop.Run(); + + ASSERT_TRUE(final_state().has_value()); + EXPECT_EQ(final_state().value(), + ThirdPartyConflictsManager::State::kInitialized); +} + +TEST_F(ThirdPartyConflictsManagerTest, InvalidModuleList) { + ThirdPartyConflictsManager third_party_conflicts_manager(this); + + third_party_conflicts_manager.OnModuleDatabaseIdle(); + + // Pass in an empty path which will ensure that the deserialization will fail. + third_party_conflicts_manager.LoadModuleList(GetModuleListPath()); + + base::RunLoop run_loop; + third_party_conflicts_manager.ForceInitialization(base::BindRepeating( + &ThirdPartyConflictsManagerTest::OnManagerInitializationComplete, + base::Unretained(this), run_loop.QuitClosure())); + + run_loop.Run(); + + ASSERT_TRUE(final_state().has_value()); + EXPECT_EQ(final_state().value(), + ThirdPartyConflictsManager::State::kModuleListInvalidFailure); +} + +TEST_F(ThirdPartyConflictsManagerTest, DestroyManager) { + auto third_party_conflicts_manager = + std::make_unique<ThirdPartyConflictsManager>(this); + + third_party_conflicts_manager->OnModuleDatabaseIdle(); + ASSERT_NO_FATAL_FAILURE(CreateModuleList()); + third_party_conflicts_manager->LoadModuleList(GetModuleListPath()); + + base::RunLoop run_loop; + third_party_conflicts_manager->ForceInitialization(base::BindRepeating( + &ThirdPartyConflictsManagerTest::OnManagerInitializationComplete, + base::Unretained(this), run_loop.QuitClosure())); + + // Delete the instance while it is initializing. + third_party_conflicts_manager = nullptr; + run_loop.Run(); + + ASSERT_TRUE(final_state().has_value()); + EXPECT_EQ(final_state().value(), + ThirdPartyConflictsManager::State::kDestroyed); +}
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc index 4fe6a36..9b55a1a 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.cc +++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -759,15 +759,11 @@ const std::string& resource_identifier) { const ContentSettingsDetails details( primary_pattern, secondary_pattern, content_type, resource_identifier); - const NavigationController& controller = web_contents()->GetController(); - NavigationEntry* entry = controller.GetVisibleEntry(); - GURL entry_url; - if (entry) - entry_url = entry->GetURL(); + const GURL& visible_url = web_contents()->GetVisibleURL(); if (details.update_all() || - // The visible NavigationEntry is the URL in the URL field of a tab. + // The visible URL is the URL in the URL field of a tab. // Currently this should be matched by the |primary_pattern|. - details.primary_pattern().Matches(entry_url)) { + details.primary_pattern().Matches(visible_url)) { Profile* profile = Profile::FromBrowserContext(web_contents()->GetBrowserContext()); const HostContentSettingsMap* map =
diff --git a/chrome/browser/data_use_measurement/page_load_capping/page_load_capping_browsertest.cc b/chrome/browser/data_use_measurement/page_load_capping/page_load_capping_browsertest.cc index 43bb174..5d7b181 100644 --- a/chrome/browser/data_use_measurement/page_load_capping/page_load_capping_browsertest.cc +++ b/chrome/browser/data_use_measurement/page_load_capping/page_load_capping_browsertest.cc
@@ -59,14 +59,6 @@ base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); } - { - scoped_refptr<base::FieldTrial> trial = - base::FieldTrialList::CreateFieldTrial("TrialName3", "GroupName3"); - feature_list->RegisterFieldTrialOverride( - features::kResourceLoadScheduler.name, - base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); - } - scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); }
diff --git a/chrome/browser/exo_parts.cc b/chrome/browser/exo_parts.cc index e7edc34..3355eca 100644 --- a/chrome/browser/exo_parts.cc +++ b/chrome/browser/exo_parts.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/common/chrome_switches.h" #include "components/exo/file_helper.h" #include "components/user_manager/user_manager.h" @@ -23,6 +22,7 @@ #include "content/public/common/drop_data.h" #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_url.h" +#include "ui/base/ui_base_features.h" namespace { @@ -106,7 +106,7 @@ // static std::unique_ptr<ExoParts> ExoParts::CreateIfNecessary() { // For mash, exosphere will not run in the browser process. - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) return nullptr; if (!base::CommandLine::ForCurrentProcess()->HasSwitch( ash::switches::kAshEnableWaylandServer)) { @@ -121,7 +121,7 @@ } ExoParts::ExoParts() { - DCHECK(!ash_util::IsRunningInMash()); + DCHECK(features::IsAshInBrowserProcess()); std::unique_ptr<ChromeFileHelper> file_helper = std::make_unique<ChromeFileHelper>(); ash::Shell::Get()->InitWaylandServer(std::move(file_helper));
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 50db393..7c45ac6 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -864,6 +864,7 @@ "//components/sync_sessions", "//components/translate/core/browser", "//components/undo", + "//components/unified_consent", "//components/update_client", "//components/url_matcher", "//components/user_prefs",
diff --git a/chrome/browser/extensions/DEPS b/chrome/browser/extensions/DEPS index 826af389..d47480a 100644 --- a/chrome/browser/extensions/DEPS +++ b/chrome/browser/extensions/DEPS
@@ -4,6 +4,7 @@ "+components/chrome_apps", "+components/crx_file", "+components/strings/grit/components_strings.h", + "+components/unified_consent", "+components/user_manager", "+extensions/strings/grit/extensions_strings.h", "+ui/base",
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc index 0734948..ea4e2fa 100644 --- a/chrome/browser/extensions/active_tab_unittest.cc +++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -333,10 +333,10 @@ TEST_F(ActiveTabTest, CapturingPagesWithActiveTab) { std::vector<GURL> test_urls = { - GURL("https://example.com"), GURL("chrome://version"), + GURL("https://example.com"), + GURL("chrome://version"), GURL("chrome://newtab"), - // IPv6 addresses don't work with activeTab: https://crbug.com/853064. - // {"http://[2607:f8b0:4005:805::200e]"}, + GURL("http://[2607:f8b0:4005:805::200e]"), extension->GetResourceURL("test.html"), another_extension->GetResourceURL("test.html"), };
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc index f63491b6..f609d252 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
@@ -147,6 +147,11 @@ // TODO(drcrash): Use a separate device-wide policy for the API. return Manifest::IsPolicyLocation(extension_->location()); } + if (Manifest::IsComponentLocation(extension_->location())) { + // Note: For this to even be called, the component extension must also be + // whitelisted in chrome/common/extensions/api/_permission_features.json + return true; + } const base::ListValue* list = profile_->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist); base::Value value(extension_->id());
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 0c2cf26..2ff63cb0b 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -29,6 +29,7 @@ #include "components/spellcheck/browser/pref_names.h" #include "components/translate/core/browser/translate_pref_names.h" #include "components/translate/core/browser/translate_prefs.h" +#include "components/unified_consent/pref_names.h" #include "components/url_formatter/url_fixer.h" #include "extensions/browser/extension_pref_value_map.h" #include "extensions/browser/extension_pref_value_map_factory.h" @@ -191,12 +192,16 @@ settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[password_manager::prefs::kCredentialsEnableAutosignin] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + + // Sync and personalization page. (*s_whitelist)[::prefs::kSafeBrowsingEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[::prefs::kSafeBrowsingScoutReportingEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[::prefs::kSearchSuggestEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_whitelist)[::prefs::kUnifiedConsentGiven] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // Languages page (*s_whitelist)[spellcheck::prefs::kSpellCheckEnable] =
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 10354f1..d04a2ce 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -98,17 +98,16 @@ #include "ui/base/ui_base_types.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/config.h" #include "ash/public/cpp/window_pin_type.h" #include "ash/public/cpp/window_properties.h" #include "ash/public/interfaces/window_pin_type.mojom.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" #include "chrome/browser/ui/browser_command_controller.h" #include "content/public/browser/devtools_agent_host.h" #include "ui/aura/window.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard_types.h" +#include "ui/base/ui_base_features.h" #endif using content::BrowserThread; @@ -282,7 +281,7 @@ // Disallow screenshots in locked fullscreen mode. // TODO(isandrk, 816900): ChromeScreenshotGrabber isn't implemented in Mash // yet, remove this conditional when it becomes available. - if (chromeos::GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) ChromeScreenshotGrabber::Get()->set_screenshots_allowed(!locked); // Reset the clipboard and kill dev tools when entering or exiting locked
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc index 5dcfb299..d9be4a86 100644 --- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc +++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -38,9 +38,9 @@ namespace { -aura::Window* GetKeyboardContainer() { +aura::Window* GetKeyboardWindow() { auto* controller = keyboard::KeyboardController::Get(); - return controller->enabled() ? controller->GetContainerWindow() : nullptr; + return controller->enabled() ? controller->GetContentsWindow() : nullptr; } std::string GenerateFeatureFlag(const std::string& feature, bool enabled) { @@ -143,7 +143,7 @@ const std::string& key_name, int modifiers) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - aura::Window* window = GetKeyboardContainer(); + aura::Window* window = GetKeyboardWindow(); return window && keyboard::SendKeyEvent(type, char_value, key_code, key_name, modifiers, window->GetHost()); }
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 7a8377b..83ecbc5 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -42,10 +42,12 @@ #include "content/public/test/background_sync_test_util.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/service_worker_test_helpers.h" +#include "extensions/browser/event_router.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/process_manager.h" #include "extensions/common/extension_features.h" +#include "extensions/common/value_builder.h" #include "extensions/test/background_page_watcher.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" @@ -298,6 +300,83 @@ EXPECT_TRUE(newtab_listener.WaitUntilSatisfied()); } +// Class that dispatches "test.onMessage" event to |extension_id| right after a +// listener to the event is added from the extension's Service Worker. +class EarlyWorkerMessageSender : public EventRouter::Observer { + public: + EarlyWorkerMessageSender(content::BrowserContext* browser_context, + const ExtensionId& extension_id) + : browser_context_(browser_context), + event_router_(EventRouter::EventRouter::Get(browser_context_)), + extension_id_(extension_id), + listener_("PASS", false) { + DCHECK(browser_context_); + listener_.set_failure_message("FAIL"); + event_router_->RegisterObserver(this, kTestOnMessageEventName); + } + + ~EarlyWorkerMessageSender() override { + event_router_->UnregisterObserver(this); + } + + // EventRouter::Observer: + void OnListenerAdded(const EventListenerInfo& details) override { + if (did_dispatch_event_ || extension_id_ != details.extension_id) + return; + const bool is_lazy_listener = details.browser_context == nullptr; + if (is_lazy_listener) { + // Wait for the non-lazy listener as we want to exercise the code to + // dispatch the event right after the Service Worker registration is + // completing. + return; + } + DispatchEvent(); + did_dispatch_event_ = true; + } + + bool SendAndWait() { return listener_.WaitUntilSatisfied(); } + + private: + static constexpr const char* const kTestOnMessageEventName = "test.onMessage"; + + void DispatchEvent() { + std::unique_ptr<base::ListValue> event_args = + ListBuilder() + .Append(DictionaryBuilder() + .Set("data", "hello") + .Set("lastMessage", true) + .Build()) + .Build(); + auto event = std::make_unique<Event>( + events::TEST_ON_MESSAGE, std::string(kTestOnMessageEventName), + std::move(event_args), browser_context_); + EventRouter::Get(browser_context_) + ->DispatchEventToExtension(extension_id_, std::move(event)); + } + + content::BrowserContext* const browser_context_ = nullptr; + EventRouter* const event_router_ = nullptr; + const ExtensionId extension_id_; + ExtensionTestMessageListener listener_; + bool did_dispatch_event_ = false; + + DISALLOW_COPY_AND_ASSIGN(EarlyWorkerMessageSender); +}; + +// Tests that extension event dispatch works correctly right after extension +// installation registers its Service Worker. +// Regression test for: https://crbug.com/850792. +IN_PROC_BROWSER_TEST_P(ServiceWorkerBasedBackgroundTest, EarlyEventDispatch) { + const ExtensionId kId("pkplfbidichfdicaijlchgnapepdginl"); + EarlyWorkerMessageSender sender(profile(), kId); + // pkplfbidichfdicaijlchgnapepdginl + const Extension* extension = LoadExtension(test_data_dir_.AppendASCII( + "service_worker/worker_based_background/early_event_dispatch")); + CHECK(extension); + EXPECT_EQ(kId, extension->id()); + EXPECT_TRUE(sender.SendAndWait()); +} + class ServiceWorkerBackgroundSyncTest : public ServiceWorkerTest { public: ServiceWorkerBackgroundSyncTest() {}
diff --git a/chrome/browser/favicon/large_icon_service_factory.cc b/chrome/browser/favicon/large_icon_service_factory.cc index aa87f9e..c13fd5f4 100644 --- a/chrome/browser/favicon/large_icon_service_factory.cc +++ b/chrome/browser/favicon/large_icon_service_factory.cc
@@ -16,6 +16,7 @@ #include "components/image_fetcher/core/image_fetcher_impl.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" // static favicon::LargeIconService* LargeIconServiceFactory::GetForBrowserContext( @@ -50,9 +51,11 @@ FaviconServiceFactory::GetForProfile(profile, ServiceAccessType::EXPLICIT_ACCESS); return new favicon::LargeIconService( - favicon_service, std::make_unique<image_fetcher::ImageFetcherImpl>( - std::make_unique<suggestions::ImageDecoderImpl>(), - profile->GetRequestContext())); + favicon_service, + std::make_unique<image_fetcher::ImageFetcherImpl>( + std::make_unique<suggestions::ImageDecoderImpl>(), + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess())); } bool LargeIconServiceFactory::ServiceIsNULLWhileTesting() const {
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc index f68368e7..91bd4c2a 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -33,7 +33,6 @@ #include "ash/public/interfaces/constants.mojom.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/metrics/chromeos_metrics_provider.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chromeos/system/statistics_provider.h" #include "chromeos/system/version_loader.h" #include "content/public/common/service_manager_connection.h"
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 2fa6e51..b59ec73 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -491,10 +491,8 @@ const char kEnableHeavyPageCappingName[] = "Heavy Page Capping"; const char kEnableHeavyPageCappingDescription[] = "Enable showing an InfoBar on data heavy pages that allows the user to " - "pause sub-resource request loading on the page. Sub-resource load pausing " - "functionality currently requires 'Experimental Web Platform features' to " - "be enabled. Using the 'Low' option will reduce the triggering threshold " - " 1MB."; + "pause sub-resource request loading on the page. Using the 'Low' option " + "will reduce the triggering threshold 1MB."; const char kEnableHttpFormWarningName[] = "Show in-form warnings for sensitive fields when the top-level page is not " @@ -1029,10 +1027,6 @@ "Have the Media Router connect to Cast devices on all IP addresses, not " "just RFC1918/RFC4913 private addresses."; -const char kMemoryAblationName[] = "Memory ablation experiment"; -const char kMemoryAblationDescription[] = - "Allocates extra memory in the browser process."; - const char kMemoryCoordinatorName[] = "Memory coordinator"; const char kMemoryCoordinatorDescription[] = "Enable memory coordinator instead of memory pressure listeners."; @@ -1790,6 +1784,10 @@ "Improved Translate UI triggering logic. TranslateRanker decides whether " "or not Translate UI should be triggered in a given context."; +const char kTranslateUIName[] = "Enable Translate"; +const char kTranslateUIDescription[] = + "Enable the Translate popup when visiting webpages in other languages."; + const char kTreatInsecureOriginAsSecureName[] = "Insecure origins treated as secure"; const char kTreatInsecureOriginAsSecureDescription[] = @@ -2549,10 +2547,32 @@ "Enabled (Flash lowers volume when interrupted by other sound, " "experimental)"; +const char kInfiniteSessionRestoreName[] = "Infinite Session Restore"; +const char kInfiniteSessionRestoreDescription[] = + "Reduces the number of tabs being loaded simultaneously during session " + "restore, to improve responsiveness of the foreground tab. This requires " + "#enable-page-almost-idle."; + const char kEnableNewAppMenuIconName[] = "Enable the New App Menu Icon"; const char kEnableNewAppMenuIconDescription[] = "Use the new app menu icon with update notification animations."; +const char kEnableWebAuthenticationAPIName[] = "Web Authentication API"; +const char kEnableWebAuthenticationAPIDescription[] = + "Enable Web Authentication API support"; + +const char kEnableWebAuthenticationCtap2SupportName[] = + "Enable Web Authentication API support for CTAP2 security keys"; +const char kEnableWebAuthenticationCtap2SupportDescription[] = + "Enable CTAP2 security keys for the Web Authenication API."; + +const char kEnableWebAuthenticationTestingAPIName[] = + "Web Authentication Testing API"; +const char kEnableWebAuthenticationTestingAPIDescription[] = + "Enable Web Authentication Testing API support, which disconnects the API " + "implementation from the real world, and allows configuring virtual " + "authenticator devices for testing"; + const char kOmniboxRichEntitySuggestionsName[] = "Omnibox rich entity suggestions"; const char kOmniboxRichEntitySuggestionsDescription[] = @@ -2585,6 +2605,23 @@ "Show a OneGoogleBar on the local New Tab page if Google is the default " "search engine."; +const char kPageAlmostIdleName[] = "Page Almost Idle"; +const char kPageAlmostIdleDescription[] = + "Make session restore use a definition of loading that waits for CPU and " + "network quiescence."; + +const char kProactiveTabFreezeAndDiscardName[] = + "Proactive Tab Freeze and Discard"; +const char kProactiveTabFreezeAndDiscardDescription[] = + "Enables proactive tab freezing and discarding. This requires " + "#enable-page-almost-idle."; + +const char kSiteCharacteristicsDatabaseName[] = "Site Characteristics database"; +const char kSiteCharacteristicsDatabaseDescription[] = + "Records usage of some features in a database while a tab is in background " + "(title/favicon update, audio playback or usage of non-persistent " + "notifications)."; + const char kUseGoogleLocalNtpName[] = "Enable using the Google local NTP"; const char kUseGoogleLocalNtpDescription[] = "Use the local New Tab page if Google is the default search engine."; @@ -2595,22 +2632,6 @@ "Show a microphone for voice search on the local New Tab page " "if Google is the default search engine."; -const char kEnableWebAuthenticationAPIName[] = "Web Authentication API"; -const char kEnableWebAuthenticationAPIDescription[] = - "Enable Web Authentication API support"; - -const char kEnableWebAuthenticationCtap2SupportName[] = - "Enable Web Authentication API support for CTAP2 security keys"; -const char kEnableWebAuthenticationCtap2SupportDescription[] = - "Enable CTAP2 security keys for the Web Authenication API."; - -const char kEnableWebAuthenticationTestingAPIName[] = - "Web Authentication Testing API"; -const char kEnableWebAuthenticationTestingAPIDescription[] = - "Enable Web Authentication Testing API support, which disconnects the API " - "implementation from the real world, and allows configuring virtual " - "authenticator devices for testing"; - #if defined(GOOGLE_CHROME_BUILD) const char kGoogleBrandedContextMenuName[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 74ad0f2..17e8ddd2 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -644,9 +644,6 @@ extern const char kMediaRouterCastAllowAllIPsName[]; extern const char kMediaRouterCastAllowAllIPsDescription[]; -extern const char kMemoryAblationName[]; -extern const char kMemoryAblationDescription[]; - extern const char kMemoryCoordinatorName[]; extern const char kMemoryCoordinatorDescription[]; @@ -1089,6 +1086,9 @@ extern const char kTranslateRankerEnforcementName[]; extern const char kTranslateRankerEnforcementDescription[]; +extern const char kTranslateUIName[]; +extern const char kTranslateUIDescription[]; + extern const char kTreatInsecureOriginAsSecureName[]; extern const char kTreatInsecureOriginAsSecureDescription[]; @@ -1549,6 +1549,18 @@ extern const char kEnableNewAppMenuIconName[]; extern const char kEnableNewAppMenuIconDescription[]; +extern const char kEnableWebAuthenticationAPIName[]; +extern const char kEnableWebAuthenticationAPIDescription[]; + +extern const char kEnableWebAuthenticationCtap2SupportName[]; +extern const char kEnableWebAuthenticationCtap2SupportDescription[]; + +extern const char kEnableWebAuthenticationTestingAPIName[]; +extern const char kEnableWebAuthenticationTestingAPIDescription[]; + +extern const char kInfiniteSessionRestoreName[]; +extern const char kInfiniteSessionRestoreDescription[]; + extern const char kOmniboxRichEntitySuggestionsName[]; extern const char kOmniboxRichEntitySuggestionsDescription[]; @@ -1564,21 +1576,21 @@ extern const char kOneGoogleBarOnLocalNtpName[]; extern const char kOneGoogleBarOnLocalNtpDescription[]; +extern const char kPageAlmostIdleName[]; +extern const char kPageAlmostIdleDescription[]; + +extern const char kProactiveTabFreezeAndDiscardName[]; +extern const char kProactiveTabFreezeAndDiscardDescription[]; + +extern const char kSiteCharacteristicsDatabaseName[]; +extern const char kSiteCharacteristicsDatabaseDescription[]; + extern const char kUseGoogleLocalNtpName[]; extern const char kUseGoogleLocalNtpDescription[]; extern const char kVoiceSearchOnLocalNtpName[]; extern const char kVoiceSearchOnLocalNtpDescription[]; -extern const char kEnableWebAuthenticationAPIName[]; -extern const char kEnableWebAuthenticationAPIDescription[]; - -extern const char kEnableWebAuthenticationTestingAPIName[]; -extern const char kEnableWebAuthenticationTestingAPIDescription[]; - -extern const char kEnableWebAuthenticationCtap2SupportName[]; -extern const char kEnableWebAuthenticationCtap2SupportDescription[]; - #if defined(GOOGLE_CHROME_BUILD) extern const char kGoogleBrandedContextMenuName[];
diff --git a/chrome/browser/global_keyboard_shortcuts_mac.h b/chrome/browser/global_keyboard_shortcuts_mac.h index ae966b7..084f41e4 100644 --- a/chrome/browser/global_keyboard_shortcuts_mac.h +++ b/chrome/browser/global_keyboard_shortcuts_mac.h
@@ -29,6 +29,17 @@ int chrome_command; // The chrome command # to execute for this shortcut. }; +struct CommandForKeyEventResult { + bool found() { return chrome_command != -1; } + + // The command to execute. -1 if none was found. + int chrome_command; + + // Whether the command was from a mapping in the main menu. Only relevant if + // command != -1. + bool from_main_menu; +}; + // macOS applications are supposed to put all keyEquivalents [hotkeys] in the // menu bar. For legacy reasons, Chrome does not. There are around 30 hotkeys // that are explicitly coded to virtual keycodes. This has the following @@ -45,7 +56,7 @@ // NSMenu as well. The user can remap these to conflict with Chrome hotkeys. // This function will return the Chrome hotkey, regardless of whether there's a // conflicting symbolic hotkey. -int CommandForKeyEvent(NSEvent* event); +CommandForKeyEventResult CommandForKeyEvent(NSEvent* event); // For legacy reasons and compatibility with Safari, some commands [e.g. cmd + // left arrow] are only allowed to fire if the firstResponder is a WebContents,
diff --git a/chrome/browser/global_keyboard_shortcuts_mac.mm b/chrome/browser/global_keyboard_shortcuts_mac.mm index 40c53ac..c6d5d03 100644 --- a/chrome/browser/global_keyboard_shortcuts_mac.mm +++ b/chrome/browser/global_keyboard_shortcuts_mac.mm
@@ -101,6 +101,18 @@ return *keys; } +CommandForKeyEventResult NoCommand() { + return {-1, /*from_main_menu=*/false}; +} + +CommandForKeyEventResult MainMenuCommand(int cmd) { + return {cmd, /*from_main_menu=*/true}; +} + +CommandForKeyEventResult ShortcutCommand(int cmd) { + return {cmd, /*from_main_menu=*/false}; +} + } // namespace const std::vector<KeyboardShortcutData>& GetShortcutsNotPresentInMainMenu() { @@ -142,14 +154,14 @@ return *keys; } -int CommandForKeyEvent(NSEvent* event) { +CommandForKeyEventResult CommandForKeyEvent(NSEvent* event) { DCHECK(event); if ([event type] != NSKeyDown) - return -1; + return NoCommand(); int cmdNum = MenuCommandForKeyEvent(event); if (cmdNum != -1) - return cmdNum; + return MainMenuCommand(cmdNum); // Look in secondary keyboard shortcuts. NSUInteger modifiers = [event modifierFlags]; @@ -164,11 +176,11 @@ for (const auto& shortcut : GetShortcutsNotPresentInMainMenu()) { if (MatchesEventForKeyboardShortcut(shortcut, cmdKey, shiftKey, cntrlKey, optKey, keyCode)) { - return shortcut.chrome_command; + return ShortcutCommand(shortcut.chrome_command); } } - return -1; + return NoCommand(); } int DelayedWebContentsCommandForKeyEvent(NSEvent* event) {
diff --git a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm index 597402c7..efd5857 100644 --- a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm +++ b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
@@ -45,7 +45,7 @@ isARepeat:NO keyCode:vkey_code]; - return CommandForKeyEvent(event); + return CommandForKeyEvent(event).chrome_command; } } // namespace
diff --git a/chrome/browser/interstitials/enterprise_util.cc b/chrome/browser/interstitials/enterprise_util.cc index 3b101ff..3a65dc90 100644 --- a/chrome/browser/interstitials/enterprise_util.cc +++ b/chrome/browser/interstitials/enterprise_util.cc
@@ -92,9 +92,10 @@ case safe_browsing::SB_THREAT_TYPE_CSD_WHITELIST: case safe_browsing:: DEPRECATED_SB_THREAT_TYPE_URL_PASSWORD_PROTECTION_PHISHING: - case safe_browsing::SB_THREAT_TYPE_PASSWORD_REUSE: + case safe_browsing::SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE: case safe_browsing::SB_THREAT_TYPE_AD_SAMPLE: case safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE: + case safe_browsing::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: NOTREACHED(); break; }
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc index 6dca457..74e8d57 100644 --- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -822,6 +822,7 @@ const net::URLRequest* request, const previews::PreviewsDecider* previews_decider, content::PreviewsState initial_state) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); if (!previews::HasEnabledPreviews(initial_state)) return content::PREVIEWS_OFF;
diff --git a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc index 961c02e6..500f8ca8 100644 --- a/chrome/browser/media/encrypted_media_supported_types_browsertest.cc +++ b/chrome/browser/media/encrypted_media_supported_types_browsertest.cc
@@ -333,6 +333,20 @@ robustness); } + std::string IsVideoMp4RobustnessSupported(const std::string& key_system, + const char* robustness) { + return IsSupportedByKeySystem(key_system, kVideoMP4MimeType, + video_mp4_codecs(), SessionType::kTemporary, + robustness); + } + + std::string IsAudioMp4RobustnessSupported(const std::string& key_system, + const char* robustness) { + return IsSupportedByKeySystem(key_system, kAudioMP4MimeType, + audio_mp4_codecs(), SessionType::kTemporary, + robustness); + } + std::string IsAudioEncryptionSchemeSupported(const std::string& key_system, const char* encryption_scheme) { return IsSupportedByKeySystem(key_system, kAudioWebMMimeType, @@ -417,6 +431,27 @@ } }; +class EncryptedMediaSupportedTypesWidevineHwSecureTest + : public EncryptedMediaSupportedTypesWidevineTest { + protected: + EncryptedMediaSupportedTypesWidevineHwSecureTest() { + scoped_feature_list_.InitAndEnableFeature(media::kHardwareSecureDecryption); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + EncryptedMediaSupportedTypesWidevineTest::SetUpCommandLine(command_line); + // Pretend that we support hardware secure decryption for vp8 and vp9, but + // not for avc1. + command_line->AppendSwitchASCII( + switches::kEnableHardwareSecureCodecsForTesting, "vp8,vp9"); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN(EncryptedMediaSupportedTypesWidevineHwSecureTest); +}; + #if BUILDFLAG(ENABLE_LIBRARY_CDMS) // Registers ClearKey CDM with the wrong path (filename). class EncryptedMediaSupportedTypesClearKeyCdmRegisteredWithWrongPathTest @@ -1081,6 +1116,86 @@ } // +// Widevine with hardware secure decryption support. Note that for the test +// suite EncryptedMediaSupportedTypesWidevineHwSecureTest, feature +// media::kHardwareSecureDecryption is enabled, and command line switch +// kEnableHardwareSecureCodecsForTesting is used to always enable vp8 and vp9, +// and disable avc1. With the switch, real hardware capabilities are not checked +// for the stability of tests. + +IN_PROC_BROWSER_TEST_F(EncryptedMediaSupportedTypesWidevineHwSecureTest, + Robustness) { + // Robustness is recommended but not required. + EXPECT_WV_SUCCESS(IsVideoRobustnessSupported(kWidevine, nullptr)); + EXPECT_WV_SUCCESS(IsVideoRobustnessSupported(kWidevine, "")); + + // Video robustness. + EXPECT_WV_SUCCESS(IsVideoRobustnessSupported(kWidevine, "SW_SECURE_CRYPTO")); + EXPECT_WV_SUCCESS(IsVideoRobustnessSupported(kWidevine, "SW_SECURE_DECODE")); + EXPECT_WV_SUCCESS(IsVideoRobustnessSupported(kWidevine, "HW_SECURE_CRYPTO")); + EXPECT_WV_SUCCESS(IsVideoRobustnessSupported(kWidevine, "HW_SECURE_ALL")); + + // Audio robustness. + EXPECT_WV_SUCCESS(IsAudioRobustnessSupported(kWidevine, "SW_SECURE_CRYPTO")); + EXPECT_WV_SUCCESS(IsAudioRobustnessSupported(kWidevine, "HW_SECURE_CRYPTO")); +#if defined(OS_CHROMEOS) + // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the + // protected media identifier permission is allowed. See + // kUnsafelyAllowProtectedMediaIdentifierForDomain used above. + EXPECT_WV_SUCCESS(IsAudioRobustnessSupported(kWidevine, "SW_SECURE_DECODE")); + EXPECT_WV_SUCCESS(IsAudioRobustnessSupported(kWidevine, "HW_SECURE_ALL")); +#else + EXPECT_UNSUPPORTED(IsAudioRobustnessSupported(kWidevine, "SW_SECURE_DECODE")); + EXPECT_UNSUPPORTED(IsAudioRobustnessSupported(kWidevine, "HW_SECURE_ALL")); +#endif + + // Video proprietary codecs. + EXPECT_WV_PROPRIETARY( + IsVideoMp4RobustnessSupported(kWidevine, "SW_SECURE_CRYPTO")); + EXPECT_WV_PROPRIETARY( + IsVideoMp4RobustnessSupported(kWidevine, "SW_SECURE_DECODE")); +#if defined(OS_CHROMEOS) + // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the + // protected media identifier permission is allowed. See + // kUnsafelyAllowProtectedMediaIdentifierForDomain used above. + EXPECT_WV_PROPRIETARY( + IsVideoMp4RobustnessSupported(kWidevine, "HW_SECURE_CRYPTO")); + EXPECT_WV_PROPRIETARY( + IsVideoMp4RobustnessSupported(kWidevine, "HW_SECURE_ALL")); +#else + // Not supported because hardware secure avc1 is not supported. + EXPECT_UNSUPPORTED( + IsVideoMp4RobustnessSupported(kWidevine, "HW_SECURE_CRYPTO")); + EXPECT_UNSUPPORTED(IsVideoMp4RobustnessSupported(kWidevine, "HW_SECURE_ALL")); +#endif + + // Audio proprietary codecs. + // Note that "hardware secure audio" is still supported since hardware secure + // decryption is supported (because hardware vp8 and vp9 are supported), and + // we only do decrypt-only for audio. + EXPECT_WV_PROPRIETARY( + IsAudioMp4RobustnessSupported(kWidevine, "SW_SECURE_CRYPTO")); + EXPECT_WV_PROPRIETARY( + IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_CRYPTO")); +#if defined(OS_CHROMEOS) + // "SW_SECURE_DECODE" and "HW_SECURE_ALL" supported on ChromeOS when the + // protected media identifier permission is allowed. See + // kUnsafelyAllowProtectedMediaIdentifierForDomain used above. + EXPECT_WV_PROPRIETARY( + IsAudioMp4RobustnessSupported(kWidevine, "SW_SECURE_DECODE")); + EXPECT_WV_PROPRIETARY( + IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_ALL")); +#else + EXPECT_UNSUPPORTED( + IsAudioMp4RobustnessSupported(kWidevine, "SW_SECURE_DECODE")); + EXPECT_UNSUPPORTED(IsAudioMp4RobustnessSupported(kWidevine, "HW_SECURE_ALL")); +#endif +} + +// TODO(crbug.com/853261): Add a test for hardware secure encryption scheme +// support. + +// // Misc failure test cases. //
diff --git a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.cc b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.cc index 3514dc0..36e9344 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.cc
@@ -125,4 +125,23 @@ return registered_apps; } +base::flat_set<MediaSink::Id> CastAppAvailabilityTracker::GetAvailableSinks( + const CastMediaSource& source) const { + base::flat_set<MediaSink::Id> sink_ids; + // For each sink, check if there is at least one available app in |source|. + for (const auto& availabilities : app_availabilities_) { + for (const auto& app_info : source.app_infos()) { + const auto& availabilities_map = availabilities.second; + auto availability_it = availabilities_map.find(app_info.app_id); + if (availability_it != availabilities_map.end() && + availability_it->second.first == + GetAppAvailabilityResult::kAvailable) { + sink_ids.insert(availabilities.first); + break; + } + } + } + return sink_ids; +} + } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.h b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.h index d1eb55e..095a6b8 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.h +++ b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker.h
@@ -95,6 +95,11 @@ // Returns a list of registered app IDs. std::vector<std::string> GetRegisteredApps() const; + // Returns a list of sink IDs compatible with |source|, using the current + // availability info. + base::flat_set<MediaSink::Id> GetAvailableSinks( + const CastMediaSource& source) const; + private: // App ID to availability. using AppAvailabilityMap = base::flat_map<std::string, AppAvailability>;
diff --git a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc index ffc698f..591ef24 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc
@@ -110,21 +110,34 @@ "sinkId1", "AAAAAAAA", {GetAppAvailabilityResult::kAvailable, Now()}), CastMediaSourcesEqual(std::vector<CastMediaSource>())); + base::flat_set<MediaSink::Id> sinks_1 = {"sinkId1"}; + base::flat_set<MediaSink::Id> sinks_1_2 = {"sinkId1", "sinkId2"}; std::vector<CastMediaSource> sources_1 = {*source1}; std::vector<CastMediaSource> sources_1_2 = {*source1, *source2}; + // Tracker returns available sinks even though sources aren't registered. + EXPECT_EQ(sinks_1, tracker_.GetAvailableSinks(*source1)); + EXPECT_EQ(sinks_1, tracker_.GetAvailableSinks(*source2)); + EXPECT_TRUE(tracker_.GetAvailableSinks(*source3).empty()); + tracker_.RegisterSource(*source1); // Only |source1| is registered for this app. EXPECT_THAT( tracker_.UpdateAppAvailability( "sinkId2", "AAAAAAAA", {GetAppAvailabilityResult::kAvailable, Now()}), CastMediaSourcesEqual(sources_1)); + EXPECT_EQ(sinks_1_2, tracker_.GetAvailableSinks(*source1)); + EXPECT_EQ(sinks_1_2, tracker_.GetAvailableSinks(*source2)); + EXPECT_TRUE(tracker_.GetAvailableSinks(*source3).empty()); tracker_.RegisterSource(*source2); EXPECT_THAT(tracker_.UpdateAppAvailability( "sinkId2", "AAAAAAAA", {GetAppAvailabilityResult::kUnavailable, Now()}), CastMediaSourcesEqual(sources_1_2)); + EXPECT_EQ(sinks_1, tracker_.GetAvailableSinks(*source1)); + EXPECT_EQ(sinks_1, tracker_.GetAvailableSinks(*source2)); + EXPECT_TRUE(tracker_.GetAvailableSinks(*source3).empty()); } TEST_F(CastAppAvailabilityTrackerTest, RemoveResultsForSink) { @@ -136,14 +149,20 @@ EXPECT_EQ(GetAppAvailabilityResult::kAvailable, tracker_.GetAvailability("sinkId1", "AAAAAAAA").first); + base::flat_set<MediaSink::Id> expected_sink_ids = {"sinkId1"}; + EXPECT_EQ(expected_sink_ids, tracker_.GetAvailableSinks(*source1)); + // Unrelated sink ID. tracker_.RemoveResultsForSink("sinkId2"); EXPECT_EQ(GetAppAvailabilityResult::kAvailable, tracker_.GetAvailability("sinkId1", "AAAAAAAA").first); + EXPECT_EQ(expected_sink_ids, tracker_.GetAvailableSinks(*source1)); + expected_sink_ids.clear(); tracker_.RemoveResultsForSink("sinkId1"); EXPECT_EQ(GetAppAvailabilityResult::kUnknown, tracker_.GetAvailability("sinkId1", "AAAAAAAA").first); + EXPECT_EQ(expected_sink_ids, tracker_.GetAvailableSinks(*source1)); } } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc index b0bde64..80cbbb1 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc
@@ -35,12 +35,6 @@ return false; } -bool HasAllRequiredCapabilities(int required_capabilities, - const MediaSinkInternal& sink) { - return (required_capabilities & sink.cast_data().capabilities) == - required_capabilities; -} - } // namespace CastAppDiscoveryServiceImpl::CastAppDiscoveryServiceImpl( @@ -74,10 +68,11 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const MediaSource::Id& source_id = source.source_id(); - // Return cached results immediately, if available. - auto cached_sinks = GetAvailableSinks(source); - if (!cached_sinks.empty()) - callback.Run(source_id, cached_sinks); + // Returned cached results immediately, if available. + base::flat_set<MediaSink::Id> cached_sink_ids = + availability_tracker_.GetAvailableSinks(source); + if (!cached_sink_ids.empty()) + callback.Run(source_id, GetSinksByIds(cached_sink_ids)); auto& callback_list = sink_queries_[source_id]; if (!callback_list) { @@ -219,36 +214,21 @@ auto it = sink_queries_.find(source_id); if (it == sink_queries_.end()) continue; - it->second->Notify(source_id, GetAvailableSinks(source)); + base::flat_set<MediaSink::Id> sink_ids = + availability_tracker_.GetAvailableSinks(source); + it->second->Notify(source_id, GetSinksByIds(sink_ids)); } } -bool CastAppDiscoveryServiceImpl::SinkSupportsSource( - const MediaSinkInternal& sink, - const CastMediaSource& source) const { - const auto& app_infos = source.app_infos(); - for (const auto& app_info : app_infos) { - auto required_capabilities = app_info.required_capabilities; - auto availability = - availability_tracker_.GetAvailability(sink.sink().id(), app_info.app_id) - .first; - if (availability == cast_channel::GetAppAvailabilityResult::kAvailable && - HasAllRequiredCapabilities(required_capabilities, sink)) { - return true; - } +std::vector<MediaSinkInternal> CastAppDiscoveryServiceImpl::GetSinksByIds( + const base::flat_set<MediaSink::Id>& sink_ids) const { + std::vector<MediaSinkInternal> sinks; + for (const auto& sink_id : sink_ids) { + const MediaSinkInternal* sink = media_sink_service_->GetSinkById(sink_id); + if (sink) + sinks.push_back(*sink); } - return false; -} - -std::vector<MediaSinkInternal> CastAppDiscoveryServiceImpl::GetAvailableSinks( - const CastMediaSource& source) const { - const auto& sinks = media_sink_service_->GetSinks(); - std::vector<MediaSinkInternal> available_sinks; - for (const auto& sink : sinks) { - if (SinkSupportsSource(sink.second, source)) - available_sinks.push_back(sink.second); - } - return available_sinks; + return sinks; } } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h index cb49655..def76dc 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h
@@ -114,14 +114,9 @@ // associated with |source|. void MaybeRemoveSinkQueryEntry(const CastMediaSource& source); - // Returns true if |sink| supports |source|, based on both app availability - // and required capabilities. - bool SinkSupportsSource(const MediaSinkInternal& sink, - const CastMediaSource& source) const; - - // Returns a list of sinks that supports |source|. - std::vector<MediaSinkInternal> GetAvailableSinks( - const CastMediaSource& source) const; + // Gets a list of sinks corresponding to |sink_ids|. + std::vector<MediaSinkInternal> GetSinksByIds( + const base::flat_set<MediaSink::Id>& sink_ids) const; // Registered sink queries and their associated callbacks. base::flat_map<MediaSource::Id, std::unique_ptr<SinkQueryCallbackList>>
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc index 2f67a4f7..63dc64ea 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc
@@ -18,7 +18,6 @@ using cast_channel::GetAppAvailabilityResult; using testing::_; using testing::Invoke; -using testing::IsEmpty; namespace media_router { @@ -33,13 +32,9 @@ &socket_service_, &media_sink_service_, &clock_)), - source_a_1_(*CastMediaSource::From( - "cast:AAAAAAAA?clientId=1&capabilities=video_out,audio_out")), - source_a_2_(*CastMediaSource::From( - "cast:AAAAAAAA?clientId=2&capabilities=video_out,audio_out")), - source_b_1_(*CastMediaSource::From( - "cast:BBBBBBBB?clientId=1&capabilities=video_out,audio_out")), - sink1_(CreateCastSink(1)) { + source_a_1_(*CastMediaSource::From("cast:AAAAAAAA?clientId=1")), + source_a_2_(*CastMediaSource::From("cast:AAAAAAAA?clientId=2")), + source_b_1_(*CastMediaSource::From("cast:BBBBBBBB?clientId=1")) { ON_CALL(socket_service_, GetSocket(_)) .WillByDefault(testing::Return(&socket_)); task_runner_->RunPendingTasks(); @@ -80,7 +75,6 @@ CastMediaSource source_a_1_; CastMediaSource source_a_2_; CastMediaSource source_b_1_; - MediaSinkInternal sink1_; private: DISALLOW_COPY_AND_ASSIGN(CastAppDiscoveryServiceTest); @@ -91,6 +85,7 @@ // Adding a sink after app registered causes app availability request to be // sent. + MediaSinkInternal sink1 = CreateCastSink(1); cast_channel::GetAppAvailabilityCallback cb; EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) .WillOnce( @@ -99,7 +94,7 @@ cb = std::move(callback); })); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); // Same app ID should not trigger another request. EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, _, _)).Times(0); @@ -108,7 +103,7 @@ base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated, base::Unretained(this))); - std::vector<MediaSinkInternal> sinks_1 = {sink1_}; + std::vector<MediaSinkInternal> sinks_1 = {sink1}; EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1)); EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_2_.source_id(), sinks_1)); std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable); @@ -116,8 +111,9 @@ // No more updates for |source_a_1_|. subscription1.reset(); EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), _)).Times(0); - EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_2_.source_id(), IsEmpty())); - RemoveSink(sink1_); + EXPECT_CALL(*this, + OnSinkQueryUpdated(source_a_2_.source_id(), testing::IsEmpty())); + RemoveSink(sink1); } TEST_F(CastAppDiscoveryServiceTest, SinkQueryUpdatedOnSinkUpdate) { @@ -125,6 +121,7 @@ // Adding a sink after app registered causes app availability request to be // sent. + MediaSinkInternal sink1 = CreateCastSink(1); cast_channel::GetAppAvailabilityCallback cb; EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) .WillOnce( @@ -133,24 +130,25 @@ cb = std::move(callback); })); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); - // Query now includes |sink1_|. - std::vector<MediaSinkInternal> sinks_1 = {sink1_}; + // Query now includes |sink1|. + std::vector<MediaSinkInternal> sinks_1 = {sink1}; EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1)); std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable); // Updating |sink1| causes |source_a_1_| query to be updated. - sink1_.sink().set_name("Updated name"); - sinks_1 = {sink1_}; + sink1.sink().set_name("Updated name"); + sinks_1 = {sink1}; EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1)); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); } TEST_F(CastAppDiscoveryServiceTest, Refresh) { auto subscription1 = StartObservingMediaSinksInitially(source_a_1_); auto subscription2 = StartObservingMediaSinksInitially(source_b_1_); + MediaSinkInternal sink1 = CreateCastSink(1); EXPECT_CALL(*this, OnSinkQueryUpdated(_, _)); EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) .WillOnce(Invoke([](cast_channel::CastSocket*, const std::string& app_id, @@ -162,7 +160,7 @@ cast_channel::GetAppAvailabilityCallback& callback) { std::move(callback).Run(app_id, GetAppAvailabilityResult::kUnknown); })); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); MediaSinkInternal sink2 = CreateCastSink(2); EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) @@ -198,8 +196,9 @@ TEST_F(CastAppDiscoveryServiceTest, StartObservingMediaSinksAfterSinkAdded) { // No registered apps. + MediaSinkInternal sink1 = CreateCastSink(1); EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, _, _)).Times(0); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)); auto subscription1 = app_discovery_service_->StartObservingMediaSinks( @@ -226,6 +225,7 @@ // Adding a sink after app registered causes app availability request to be // sent. + MediaSinkInternal sink1 = CreateCastSink(1); cast_channel::GetAppAvailabilityCallback cb; EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) .WillOnce( @@ -233,9 +233,9 @@ cast_channel::GetAppAvailabilityCallback& callback) { cb = std::move(callback); })); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); - std::vector<MediaSinkInternal> sinks_1 = {sink1_}; + std::vector<MediaSinkInternal> sinks_1 = {sink1}; EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1)); std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable); @@ -249,7 +249,7 @@ base::Unretained(this))); // Same source as |source_a_1_|. The callback will be invoked. - auto source3 = CastMediaSource::From(source_a_1_.source_id()); + auto source3 = CastMediaSource::From("cast:AAAAAAAA?clientId=1"); ASSERT_TRUE(source3); EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, _, _)).Times(0); EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1)); @@ -264,13 +264,14 @@ // Adding a sink after app registered causes app availability request to be // sent. + MediaSinkInternal sink1 = CreateCastSink(1); EXPECT_CALL(*this, OnSinkQueryUpdated(_, _)).Times(0); EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) .WillOnce(Invoke([](cast_channel::CastSocket*, const std::string&, cast_channel::GetAppAvailabilityCallback& callback) { std::move(callback).Run("AAAAAAAA", GetAppAvailabilityResult::kUnknown); })); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); // Sink updated and unknown app availability will cause request to be sent // again. @@ -281,43 +282,20 @@ std::move(callback).Run("AAAAAAAA", GetAppAvailabilityResult::kUnavailable); })); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); // Known availability -- no request sent. EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) .Times(0); - AddOrUpdateSink(sink1_); + AddOrUpdateSink(sink1); // Removing the sink will also remove previous availability information. // Next time sink is added, request will be sent. EXPECT_CALL(*this, OnSinkQueryUpdated(_, _)).Times(0); - RemoveSink(sink1_); + RemoveSink(sink1); EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)); - AddOrUpdateSink(sink1_); -} - -TEST_F(CastAppDiscoveryServiceTest, CapabilitiesFiltering) { - // Make |sink1_| an audio only device. - sink1_.cast_data().capabilities = - cast_channel::CastDeviceCapability::AUDIO_OUT; - AddOrUpdateSink(sink1_); - - cast_channel::GetAppAvailabilityCallback cb; - EXPECT_CALL(message_handler_, DoRequestAppAvailability(_, "AAAAAAAA", _)) - .WillOnce(testing::WithArg<2>( - [&cb](cast_channel::GetAppAvailabilityCallback& callback) { - cb = std::move(callback); - })); - auto subscription1 = app_discovery_service_->StartObservingMediaSinks( - source_a_1_, - base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated, - base::Unretained(this))); - - // Even though the app is available, the sink does not fulfill the required - // capabilities. - EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), IsEmpty())); - std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable); + AddOrUpdateSink(sink1); } } // namespace media_router
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc index e7614c1..899befd 100644 --- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc +++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
@@ -39,7 +39,7 @@ #if defined(OS_CHROMEOS) #include "ash/shell.h" -#include "chrome/browser/chromeos/ash_config.h" +#include "ui/base/ui_base_features.h" #endif // defined(OS_CHROMEOS) using content::BrowserThread; @@ -272,7 +272,7 @@ content::MEDIA_DEVICE_INVALID_STATE; #if defined(OS_CHROMEOS) - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { // TODO(crbug.com/806366): Screen capture support for mash. NOTIMPLEMENTED() << "Screen capture not yet implemented in --mash"; screen_capture_enabled = false;
diff --git a/chrome/browser/memory/oom_memory_details.cc b/chrome/browser/memory/oom_memory_details.cc index 5d7f6bf..4a0f24a 100644 --- a/chrome/browser/memory/oom_memory_details.cc +++ b/chrome/browser/memory/oom_memory_details.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/memory/oom_memory_details.h" #include "base/logging.h" +#include "base/metrics/histogram_macros.h" #include "base/process/process_metrics.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -41,6 +42,7 @@ log_string += base::UTF16ToASCII(ui::FormatBytes(memory.gem_size)); } #endif + UMA_HISTOGRAM_MEDIUM_TIMES("TabManager.Discarding.LogMemoryTime", delta); LOG(WARNING) << title_ << " (" << delta.InMilliseconds() << " ms):\n" << log_string; // Delete ourselves so we don't have to worry about OomPriorityManager
diff --git a/chrome/browser/metrics/oom/OWNERS b/chrome/browser/metrics/oom/OWNERS index cd2293f..64a5b5f 100644 --- a/chrome/browser/metrics/oom/OWNERS +++ b/chrome/browser/metrics/oom/OWNERS
@@ -1,5 +1,4 @@ csharrison@chromium.org -mariakhomenko@chromium.org ssid@chromium.org # TEAM: memory-dev@chromium.org
diff --git a/chrome/browser/net/DEPS b/chrome/browser/net/DEPS index 6582d2d..c3a6dd5a 100644 --- a/chrome/browser/net/DEPS +++ b/chrome/browser/net/DEPS
@@ -2,6 +2,7 @@ "+components/data_use_measurement", # For nss_context_chromeos_browsertest.cc. "+components/user_manager", + "+services/network/session_cleanup_channel_id_store.h", ] specific_include_rules = {
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc index 45a38097..c497972b 100644 --- a/chrome/browser/net/chrome_network_delegate.cc +++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -16,7 +16,6 @@ #include "base/debug/stack_trace.h" #include "base/logging.h" #include "base/macros.h" -#include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" @@ -47,7 +46,6 @@ #include "content/public/common/resource_type.h" #include "extensions/buildflags/buildflags.h" #include "net/base/host_port_pair.h" -#include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_options.h" @@ -94,39 +92,6 @@ std::move(callback).Run(rv); } -void ReportInvalidReferrerSendOnUI() { - base::RecordAction( - base::UserMetricsAction("Net.URLRequest_StartJob_InvalidReferrer")); -} - -void ReportInvalidReferrerSend(const GURL& target_url, - const GURL& referrer_url) { - LOG(ERROR) << "Cancelling request to " << target_url - << " with invalid referrer " << referrer_url; - // Record information to help debug http://crbug.com/422871 - if (!target_url.SchemeIsHTTPOrHTTPS()) - return; - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(&ReportInvalidReferrerSendOnUI)); - base::debug::DumpWithoutCrashing(); - NOTREACHED(); -} - -// Record network errors that HTTP requests complete with, including OK and -// ABORTED. -void RecordNetworkErrorHistograms(const net::URLRequest* request, - int net_error) { - if (request->url().SchemeIs("http")) { - base::UmaHistogramSparse("Net.HttpRequestCompletionErrorCodes", - std::abs(net_error)); - - if (request->load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) { - base::UmaHistogramSparse("Net.HttpRequestCompletionErrorCodes.MainFrame", - std::abs(net_error)); - } - } -} - bool IsAccessAllowedInternal(const base::FilePath& path, const base::FilePath& profile_path) { #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) @@ -367,12 +332,6 @@ void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request, bool started, int net_error) { - DCHECK_NE(net::ERR_IO_PENDING, net_error); - - // TODO(amohammadkhan): Verify that there is no double recording in data use - // of redirected requests. - RecordNetworkErrorHistograms(request, net_error); - extensions_delegate_->NotifyCompleted(request, started, net_error); if (domain_reliability_monitor_) domain_reliability_monitor_->OnCompleted(request, started); @@ -496,7 +455,9 @@ const net::URLRequest& request, const GURL& target_url, const GURL& referrer_url) const { - ReportInvalidReferrerSend(target_url, referrer_url); + // These errors should be handled by the NetworkDelegate wrapper created by + // the owning NetworkContext. + NOTREACHED(); return true; }
diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc index f4fb0b8..9b25c69 100644 --- a/chrome/browser/net/chrome_network_delegate_unittest.cc +++ b/chrome/browser/net/chrome_network_delegate_unittest.cc
@@ -237,56 +237,6 @@ fake_aggregator.off_the_record_rx_bytes()); } -TEST_F(ChromeNetworkDelegateTest, HttpRequestCompletionErrorCodes) { - Initialize(); - - const struct { - const GURL url; - int net_error; - bool is_main_frame; - int expected_sample_bucket; - int expected_request_completion_count; - int expected_request_completion_main_frame_count; - } kTests[] = { - {GURL("http://example.com"), net::OK, true, std::abs(net::OK), 1, 1}, - {GURL("http://example.com"), net::ERR_ABORTED, true, - std::abs(net::ERR_ABORTED), 1, 1}, - {GURL("http://example.com"), net::OK, false, std::abs(net::OK), 1, 0}, - {GURL("https://example.com"), net::OK, true, std::abs(net::OK), 0, 0}, - }; - - const char kHttpRequestCompletionErrorCode[] = - "Net.HttpRequestCompletionErrorCodes"; - const char kHttpRequestCompletionErrorCodeMainFrame[] = - "Net.HttpRequestCompletionErrorCodes.MainFrame"; - - for (const auto& test : kTests) { - base::HistogramTester histograms; - - net::TestDelegate test_delegate; - std::unique_ptr<net::URLRequest> request( - context()->CreateRequest(test.url, net::DEFAULT_PRIORITY, - &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); - if (test.is_main_frame) { - request->SetLoadFlags(request->load_flags() | - net::LOAD_MAIN_FRAME_DEPRECATED); - } - network_delegate()->NotifyCompleted(request.get(), false, test.net_error); - - histograms.ExpectTotalCount(kHttpRequestCompletionErrorCode, - test.expected_request_completion_count); - histograms.ExpectUniqueSample(kHttpRequestCompletionErrorCode, - test.expected_sample_bucket, - test.expected_request_completion_count); - histograms.ExpectTotalCount( - kHttpRequestCompletionErrorCodeMainFrame, - test.expected_request_completion_main_frame_count); - histograms.ExpectUniqueSample( - kHttpRequestCompletionErrorCodeMainFrame, test.expected_sample_bucket, - test.expected_request_completion_main_frame_count); - } -} - class ChromeNetworkDelegatePolicyTest : public testing::Test { public: ChromeNetworkDelegatePolicyTest()
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index 11e3d07..fb7175a 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -56,6 +56,7 @@ #include "net/test/embedded_test_server/http_response.h" #include "net/test/spawned_test_server/spawned_test_server.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "net/url_request/url_request.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/resource_response.h" #include "services/network/public/cpp/resource_response_info.h" @@ -945,6 +946,36 @@ EXPECT_EQ("None", referrer); } +// Make sure that sending referrers that violate the referrer policy results in +// errors. +IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, + PolicyViolatingReferrers) { + std::unique_ptr<network::ResourceRequest> request = + std::make_unique<network::ResourceRequest>(); + request->url = embedded_test_server()->GetURL("/echoheader?Referer"); + request->referrer = GURL("http://referrer/"); + request->referrer_policy = net::URLRequest::NO_REFERRER; + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<network::SimpleURLLoader> simple_loader = + network::SimpleURLLoader::Create(std::move(request), + TRAFFIC_ANNOTATION_FOR_TESTS); + + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory(), simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + if (GetParam().network_context_type == NetworkContextType::kSafeBrowsing && + base::FeatureList::IsEnabled(network::features::kNetworkService)) { + // Safebrowsing ignores referrers, when the network service is enabled, so + // the requests succeed. + EXPECT_EQ(net::OK, simple_loader->NetError()); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ("None", *simple_loader_helper.response_body()); + } else { + // In all other cases, the invalid referrer causes the request to fail. + EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, simple_loader->NetError()); + } +} + class NetworkContextConfigurationFixedPortBrowserTest : public NetworkContextConfigurationBrowserTest { public:
diff --git a/chrome/browser/net/quota_policy_channel_id_store.cc b/chrome/browser/net/quota_policy_channel_id_store.cc index a1d5b1c..d91bc69 100644 --- a/chrome/browser/net/quota_policy_channel_id_store.cc +++ b/chrome/browser/net/quota_policy_channel_id_store.cc
@@ -4,79 +4,24 @@ #include "chrome/browser/net/quota_policy_channel_id_store.h" -#include <list> - #include "base/bind.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_util.h" -#include "base/threading/thread.h" -#include "base/threading/thread_restrictions.h" -#include "net/cookies/cookie_util.h" -#include "net/extras/sqlite/sqlite_channel_id_store.h" #include "storage/browser/quota/special_storage_policy.h" -#include "url/gurl.h" QuotaPolicyChannelIDStore::QuotaPolicyChannelIDStore( const base::FilePath& path, const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy) - : special_storage_policy_(special_storage_policy), - persistent_store_( - new net::SQLiteChannelIDStore(path, background_task_runner)) { - DCHECK(background_task_runner.get()); -} + : SessionCleanupChannelIDStore(path, background_task_runner), + special_storage_policy_(special_storage_policy) {} QuotaPolicyChannelIDStore::~QuotaPolicyChannelIDStore() { if (!special_storage_policy_.get() || !special_storage_policy_->HasSessionOnlyOrigins()) { return; } - std::list<std::string> session_only_server_identifiers; - for (std::set<std::string>::iterator it = server_identifiers_.begin(); - it != server_identifiers_.end(); - ++it) { - GURL url(net::cookie_util::CookieOriginToURL(*it, true)); - if (special_storage_policy_->IsStorageSessionOnly(url)) - session_only_server_identifiers.push_back(*it); - } - persistent_store_->DeleteAllInList(session_only_server_identifiers); -} -void QuotaPolicyChannelIDStore::Load(const LoadedCallback& loaded_callback) { - persistent_store_->Load( - base::Bind(&QuotaPolicyChannelIDStore::OnLoad, this, loaded_callback)); -} - -void QuotaPolicyChannelIDStore::AddChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) { - server_identifiers_.insert(channel_id.server_identifier()); - persistent_store_->AddChannelID(channel_id); -} - -void QuotaPolicyChannelIDStore::DeleteChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) { - server_identifiers_.erase(channel_id.server_identifier()); - persistent_store_->DeleteChannelID(channel_id); -} - -void QuotaPolicyChannelIDStore::Flush() { - persistent_store_->Flush(); -} - -void QuotaPolicyChannelIDStore::SetForceKeepSessionState() { - special_storage_policy_ = NULL; -} - -void QuotaPolicyChannelIDStore::OnLoad( - const LoadedCallback& loaded_callback, - std::unique_ptr<ChannelIDVector> channel_ids) { - for (ChannelIDVector::const_iterator channel_id = channel_ids->begin(); - channel_id != channel_ids->end(); - ++channel_id) { - server_identifiers_.insert((*channel_id)->server_identifier()); - } - loaded_callback.Run(std::move(channel_ids)); + DeleteSessionChannelIDs( + base::BindRepeating(&storage::SpecialStoragePolicy::IsStorageSessionOnly, + special_storage_policy_)); }
diff --git a/chrome/browser/net/quota_policy_channel_id_store.h b/chrome/browser/net/quota_policy_channel_id_store.h index c62d3f6..230da33 100644 --- a/chrome/browser/net/quota_policy_channel_id_store.h +++ b/chrome/browser/net/quota_policy_channel_id_store.h
@@ -5,17 +5,10 @@ #ifndef CHROME_BROWSER_NET_QUOTA_POLICY_CHANNEL_ID_STORE_H_ #define CHROME_BROWSER_NET_QUOTA_POLICY_CHANNEL_ID_STORE_H_ -#include <memory> -#include <set> -#include <string> -#include <vector> - -#include "base/callback_forward.h" -#include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "net/extras/sqlite/sqlite_channel_id_store.h" -#include "net/ssl/default_channel_id_store.h" +#include "services/network/session_cleanup_channel_id_store.h" namespace base { class FilePath; @@ -28,8 +21,7 @@ // Persistent ChannelID Store that takes into account SpecialStoragePolicy and // removes ChannelIDs that are StorageSessionOnly when store is closed. -class QuotaPolicyChannelIDStore - : public net::DefaultChannelIDStore::PersistentStore { +class QuotaPolicyChannelIDStore : public network::SessionCleanupChannelIDStore { public: // Create or open persistent store in file |path|. All I/O tasks are performed // in background using |background_task_runner|. If provided, a @@ -41,28 +33,10 @@ const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy); - // net::DefaultChannelIDStore::PersistentStore: - void Load(const LoadedCallback& loaded_callback) override; - void AddChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) override; - void DeleteChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) override; - void Flush() override; - void SetForceKeepSessionState() override; - private: - typedef std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>> - ChannelIDVector; - ~QuotaPolicyChannelIDStore() override; - void OnLoad(const LoadedCallback& loaded_callback, - std::unique_ptr<ChannelIDVector> channel_ids); - scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; - scoped_refptr<net::SQLiteChannelIDStore> persistent_store_; - // Cache of server identifiers we have channel IDs stored for. - std::set<std::string> server_identifiers_; DISALLOW_COPY_AND_ASSIGN(QuotaPolicyChannelIDStore); };
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index e63f799..8da9902 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -345,7 +345,7 @@ service->category_ranker(), service->remote_suggestions_scheduler(), std::move(suggestions_fetcher), std::make_unique<ImageFetcherImpl>(std::make_unique<ImageDecoderImpl>(), - request_context.get()), + url_loader_factory), std::make_unique<RemoteSuggestionsDatabase>(database_dir), std::make_unique<RemoteSuggestionsStatusServiceImpl>( identity_manager->HasPrimaryAccount(), pref_service,
diff --git a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc index 64ff2e59..336e362 100644 --- a/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/contextual_content_suggestions_service_factory.cc
@@ -26,7 +26,6 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/service_manager_connection.h" -#include "net/url_request/url_request_context_getter.h" #include "services/data_decoder/public/cpp/safe_json_parser.h" #if defined(OS_ANDROID) @@ -93,8 +92,6 @@ } PrefService* pref_service = profile->GetPrefs(); - scoped_refptr<net::URLRequestContextGetter> request_context = - profile->GetRequestContext(); content::StoragePartition* storage_partition = content::BrowserContext::GetDefaultStoragePartition(context); auto contextual_suggestions_fetcher = @@ -110,7 +107,8 @@ std::make_unique<ntp_snippets::CachedImageFetcher>( std::make_unique<image_fetcher::ImageFetcherImpl>( std::make_unique<suggestions::ImageDecoderImpl>(), - request_context.get()), + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess()), pref_service, contextual_suggestions_database.get()); auto reporter_provider = std::make_unique< contextual_suggestions::ContextualSuggestionsReporterProvider>(
diff --git a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc index 0e51e40..70d0070 100644 --- a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc +++ b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
@@ -26,6 +26,7 @@ #include "components/ntp_tiles/icon_cacher_impl.h" #include "components/ntp_tiles/metrics.h" #include "components/ntp_tiles/most_visited_sites.h" +#include "content/public/browser/storage_partition.h" using suggestions::SuggestionsServiceFactory; @@ -127,6 +128,7 @@ LargeIconServiceFactory::GetForBrowserContext(profile), std::make_unique<image_fetcher::ImageFetcherImpl>( std::make_unique<suggestions::ImageDecoderImpl>(), - profile->GetRequestContext())), + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess())), std::make_unique<SupervisorBridge>(profile)); }
diff --git a/chrome/browser/offline_pages/background_loader_offliner.cc b/chrome/browser/offline_pages/background_loader_offliner.cc index 0fa6a08..34123a3 100644 --- a/chrome/browser/offline_pages/background_loader_offliner.cc +++ b/chrome/browser/offline_pages/background_loader_offliner.cc
@@ -89,6 +89,17 @@ is_previews_enabled); } +void RecordResourceCompletionUMA(bool image_complete, + bool css_complete, + bool xhr_complete) { + base::UmaHistogramBoolean("OfflinePages.Background.ResourceCompletion.Image", + image_complete); + base::UmaHistogramBoolean("OfflinePages.Background.ResourceCompletion.Css", + css_complete); + base::UmaHistogramBoolean("OfflinePages.Background.ResourceCompletion.Xhr", + xhr_complete); +} + void HandleLoadTerminationCancel( Offliner::CompletionCallback completion_callback, const SavePageRequest& canceled_request) { @@ -464,18 +475,24 @@ content::WebContents* web_contents( content::WebContentsObserver::web_contents()); + // Capture loading signals to UMA. + RequestStats& image_stats = stats_[ResourceDataType::IMAGE]; + RequestStats& css_stats = stats_[ResourceDataType::TEXT_CSS]; + RequestStats& xhr_stats = stats_[ResourceDataType::XHR]; + bool image_complete = (image_stats.requested == image_stats.completed); + bool css_complete = (css_stats.requested == css_stats.completed); + bool xhr_complete = (xhr_stats.requested == xhr_stats.completed); + RecordResourceCompletionUMA(image_complete, css_complete, xhr_complete); + // Add loading signal into the MHTML that will be generated if the command // line flag is set for it. if (IsOfflinePagesLoadSignalCollectingEnabled()) { // Write resource percentage signal data into extra data before emitting it // to the MHTML. - RequestStats& image_stats = stats_[ResourceDataType::IMAGE]; signal_data_.SetDouble("StartedImages", image_stats.requested); signal_data_.SetDouble("CompletedImages", image_stats.completed); - RequestStats& css_stats = stats_[ResourceDataType::TEXT_CSS]; signal_data_.SetDouble("StartedCSS", css_stats.requested); signal_data_.SetDouble("CompletedCSS", css_stats.completed); - RequestStats& xhr_stats = stats_[ResourceDataType::XHR]; signal_data_.SetDouble("StartedXHR", xhr_stats.requested); signal_data_.SetDouble("CompletedXHR", xhr_stats.completed);
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc index ebc51388a..734d2dba 100644 --- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
@@ -28,6 +28,8 @@ const char kBackgroundHistogramServiceWorkerParseStart[] = "PageLoad.Clients.ServiceWorker.ParseTiming.NavigationToParseStart." "Background"; +const char kHistogramServiceWorkerFirstPaint[] = + "PageLoad.Clients.ServiceWorker.PaintTiming.NavigationToFirstPaint"; const char kHistogramServiceWorkerFirstContentfulPaint[] = "PageLoad.Clients.ServiceWorker.PaintTiming." "NavigationToFirstContentfulPaint"; @@ -153,6 +155,18 @@ return CONTINUE_OBSERVING; } +void ServiceWorkerPageLoadMetricsObserver::OnFirstPaintInPage( + const page_load_metrics::mojom::PageLoadTiming& timing, + const page_load_metrics::PageLoadExtraInfo& extra_info) { + if (!IsServiceWorkerControlled(extra_info) || + !WasStartedInForegroundOptionalEventInForeground( + timing.paint_timing->first_paint, extra_info)) { + return; + } + PAGE_LOAD_HISTOGRAM(internal::kHistogramServiceWorkerFirstPaint, + timing.paint_timing->first_paint.value()); +} + void ServiceWorkerPageLoadMetricsObserver::OnFirstContentfulPaintInPage( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) {
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h index d59f617..3336127 100644 --- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h
@@ -16,6 +16,7 @@ extern const char kBackgroundHistogramServiceWorkerParseStart[]; extern const char kHistogramServiceWorkerParseStartForwardBack[]; extern const char kHistogramServiceWorkerParseStartForwardBackNoStore[]; +extern const char kHistogramServiceWorkerFirstPaint[]; extern const char kHistogramServiceWorkerFirstContentfulPaint[]; extern const char kBackgroundHistogramServiceWorkerFirstContentfulPaint[]; extern const char kHistogramServiceWorkerFirstContentfulPaintForwardBack[]; @@ -68,6 +69,9 @@ void OnParseStart( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& extra_info) override; + void OnFirstPaintInPage( + const page_load_metrics::mojom::PageLoadTiming& timing, + const page_load_metrics::PageLoadExtraInfo& extra_info) override; void OnFirstContentfulPaintInPage( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& extra_info) override;
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc index d1f5d10..6fceddf8 100644 --- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer_unittest.cc
@@ -37,6 +37,8 @@ void AssertNoServiceWorkerHistogramsLogged() { histogram_tester().ExpectTotalCount( + internal::kHistogramServiceWorkerFirstPaint, 0); + histogram_tester().ExpectTotalCount( internal::kHistogramServiceWorkerFirstContentfulPaint, 0); histogram_tester().ExpectTotalCount( internal::kBackgroundHistogramServiceWorkerFirstContentfulPaint, 0); @@ -123,6 +125,7 @@ page_load_metrics::InitPageLoadTimingForTest(timing); timing->navigation_start = base::Time::FromDoubleT(1); timing->parse_timing->parse_start = base::TimeDelta::FromMilliseconds(100); + timing->paint_timing->first_paint = base::TimeDelta::FromMilliseconds(200); timing->paint_timing->first_contentful_paint = base::TimeDelta::FromMilliseconds(300); timing->paint_timing->first_meaningful_paint = @@ -168,6 +171,12 @@ SimulateTimingAndMetadataUpdate(timing, metadata); histogram_tester().ExpectTotalCount( + internal::kHistogramServiceWorkerFirstPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramServiceWorkerFirstPaint, + timing.paint_timing->first_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( internal::kHistogramServiceWorkerFirstContentfulPaint, 1); histogram_tester().ExpectBucketCount( internal::kHistogramServiceWorkerFirstContentfulPaint, @@ -240,6 +249,8 @@ SimulateTimingAndMetadataUpdate(timing, metadata); histogram_tester().ExpectTotalCount( + internal::kHistogramServiceWorkerFirstPaint, 0); + histogram_tester().ExpectTotalCount( internal::kHistogramServiceWorkerFirstContentfulPaint, 0); histogram_tester().ExpectTotalCount( internal::kBackgroundHistogramServiceWorkerFirstContentfulPaint, 1); @@ -294,6 +305,12 @@ timing.parse_timing->parse_start.value().InMilliseconds(), 1); histogram_tester().ExpectTotalCount( + internal::kHistogramServiceWorkerFirstPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramServiceWorkerFirstPaint, + timing.paint_timing->first_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( internal::kHistogramServiceWorkerFirstContentfulPaint, 1); histogram_tester().ExpectBucketCount( internal::kHistogramServiceWorkerFirstContentfulPaint, @@ -410,6 +427,12 @@ timing.parse_timing->parse_start.value().InMilliseconds(), 1); histogram_tester().ExpectTotalCount( + internal::kHistogramServiceWorkerFirstPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramServiceWorkerFirstPaint, + timing.paint_timing->first_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( internal::kHistogramServiceWorkerFirstContentfulPaint, 1); histogram_tester().ExpectBucketCount( internal::kHistogramServiceWorkerFirstContentfulPaint, @@ -582,6 +605,12 @@ SimulateTimingAndMetadataUpdate(timing, metadata); histogram_tester().ExpectTotalCount( + internal::kHistogramServiceWorkerFirstPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramServiceWorkerFirstPaint, + timing.paint_timing->first_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( internal::kHistogramServiceWorkerFirstContentfulPaint, 1); histogram_tester().ExpectBucketCount( internal::kHistogramServiceWorkerFirstContentfulPaint,
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index dc061f7..09c3f29 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -61,9 +61,6 @@ DISALLOW_COPY_AND_ASSIGN(PictureInPictureWindowControllerBrowserTest); }; -// TODO(845747): ChromeOS is hitting this DCHECK. -#if !defined(OS_CHROMEOS) - // Checks the creation of the window controller, as well as basic window // creation and visibility. IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, @@ -615,8 +612,8 @@ } // Same as above for a cross-origin iframe. -// Flaky on windows: crbug/854349 -#if defined(OS_WIN) +// Flaky on windows and Linux: crbug/854349 +#if defined(OS_WIN) || defined(OS_LINUX) #define MAYBE_CrossOriginFrameEnterLeaveCloseWindow \ DISABLED_CrossOriginFrameEnterLeaveCloseWindow #else @@ -660,5 +657,3 @@ EXPECT_EQ(1u, active_web_contents->GetAllFrames().size()); EXPECT_FALSE(window_controller()->GetWindowForTesting()->IsVisible()); } - -#endif // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc index 240a230a..6d3edb3 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc +++ b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc
@@ -126,10 +126,13 @@ device_management_service, request_context); policy_fetcher_ = std::make_unique<MachineLevelUserCloudPolicyFetcher>( policy_manager, local_state, device_management_service, request_context); - policy_register_watcher_ = - std::make_unique<MachineLevelUserCloudPolicyRegisterWatcher>(this); if (dm_token.empty()) { + policy_register_watcher_ = + std::make_unique<MachineLevelUserCloudPolicyRegisterWatcher>(this); + + enrollment_start_time_ = base::Time::Now(); + // Not registered already, so do it now. policy_registrar_->RegisterForPolicyWithEnrollmentToken( enrollment_token, client_id, @@ -186,16 +189,25 @@ void MachineLevelUserCloudPolicyController:: RegisterForPolicyWithEnrollmentTokenCallback(const std::string& dm_token, const std::string& client_id) { + base::TimeDelta enrollment_time = base::Time::Now() - enrollment_start_time_; + if (dm_token.empty()) { VLOG(1) << "No DM token returned from browser registration."; RecordEnrollmentResult( MachineLevelUserCloudPolicyEnrollmentResult::kFailedToFetch); + UMA_HISTOGRAM_TIMES( + "Enterprise.MachineLevelUserCloudPolicyEnrollment.RequestFailureTime", + enrollment_time); NotifyPolicyRegisterFinished(false); return; } VLOG(1) << "DM token retrieved from server."; + UMA_HISTOGRAM_TIMES( + "Enterprise.MachineLevelUserCloudPolicyEnrollment.RequestSuccessTime", + enrollment_time); + // TODO(alito): Log failures to store the DM token. Should we try again later? BrowserDMTokenStorage::Get()->StoreDMToken( dm_token, base::BindOnce([](bool success) {
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_controller.h b/chrome/browser/policy/machine_level_user_cloud_policy_controller.h index cc2bf77..f0293f2 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_controller.h +++ b/chrome/browser/policy/machine_level_user_cloud_policy_controller.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" +#include "base/time/time.h" #include "net/url_request/url_request_context_getter.h" class PrefService; @@ -80,6 +81,9 @@ std::unique_ptr<MachineLevelUserCloudPolicyRegisterWatcher> policy_register_watcher_; + // Time at which the enrollment process was started. Used to log UMA metric. + base::Time enrollment_start_time_; + DISALLOW_COPY_AND_ASSIGN(MachineLevelUserCloudPolicyController); };
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.cc b/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.cc index 7aa5fe0..b638081 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.cc +++ b/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" +#include "base/metrics/histogram_macros.h" #include "base/syslog_logging.h" #include "chrome/browser/policy/browser_dm_token_storage.h" #include "chrome/grit/chromium_strings.h" @@ -18,6 +19,10 @@ using RegisterResult = MachineLevelUserCloudPolicyController::RegisterResult; +const char + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName[] = + "Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialog"; + MachineLevelUserCloudPolicyRegisterWatcher:: MachineLevelUserCloudPolicyRegisterWatcher( MachineLevelUserCloudPolicyController* controller) @@ -49,6 +54,10 @@ dialog_ = std::move(dialog_creation_callback_).Run(std::move(callback)); else dialog_ = EnterpriseStartupDialog::CreateAndShowDialog(std::move(callback)); + + visible_start_time_ = base::Time::Now(); + RecordEnrollmentStartDialog(EnrollmentStartupDialog::kShown); + if (register_result_) { // |register_result_| has been set only if the enrollment has finihsed. // And it must be failed if it's finished without a DM token which is @@ -78,6 +87,12 @@ dialog_creation_callback_ = std::move(callback); } +// static +void MachineLevelUserCloudPolicyRegisterWatcher::RecordEnrollmentStartDialog( + EnrollmentStartupDialog dialog_startup) { + UMA_HISTOGRAM_ENUMERATION(kStartupDialogHistogramName, dialog_startup); +} + void MachineLevelUserCloudPolicyRegisterWatcher::OnPolicyRegisterFinished( bool succeeded) { register_result_ = succeeded; @@ -97,6 +112,25 @@ void MachineLevelUserCloudPolicyRegisterWatcher::OnDialogClosed( bool is_accepted, bool can_show_browser_window) { + if (can_show_browser_window) { + // Chrome startup can continue normally. + RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedSuccess); + } else if (is_accepted) { + // User chose to restart chrome and try re-enrolling. + RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedRelaunch); + } else if (register_result_.has_value()) { + // User closed the dialog after seeing a message that enrollment failed. + RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedFail); + } else { + // User closed the dialog after waiting too long with no result. + RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedAbort); + } + + base::TimeDelta visible_time = base::Time::Now() - visible_start_time_; + UMA_HISTOGRAM_TIMES( + "Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialogTime", + visible_time); + // User confirm the dialog to relaunch Chrome to retry the register. is_restart_needed_ = is_accepted;
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.h b/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.h index 5b2c404..ef77b05 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.h +++ b/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.h
@@ -9,12 +9,16 @@ #include <string> #include "base/callback_forward.h" +#include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/optional.h" #include "base/run_loop.h" +#include "base/time/time.h" #include "chrome/browser/policy/machine_level_user_cloud_policy_controller.h" #include "chrome/browser/ui/enterprise_startup_dialog.h" +class MachineLevelUserCloudPolicyRegisterWatcherTest; + namespace policy { // Watches the status of machine level user cloud policy enrollment. @@ -38,6 +42,46 @@ void SetDialogCreationCallbackForTesting(DialogCreationCallback callback); private: + FRIEND_TEST_ALL_PREFIXES(MachineLevelUserCloudPolicyRegisterWatcherTest, + EnrollmentSucceed); + FRIEND_TEST_ALL_PREFIXES(MachineLevelUserCloudPolicyRegisterWatcherTest, + EnrollmentFailedAndQuit); + FRIEND_TEST_ALL_PREFIXES(MachineLevelUserCloudPolicyRegisterWatcherTest, + EnrollmentFailedAndRestart); + FRIEND_TEST_ALL_PREFIXES(MachineLevelUserCloudPolicyRegisterWatcherTest, + EnrollmentCanceledBeforeFinish); + FRIEND_TEST_ALL_PREFIXES(MachineLevelUserCloudPolicyRegisterWatcherTest, + EnrollmentFailedBeforeDialogDisplay); + + // Enum used with kStartupDialogHistogramName. + enum class EnrollmentStartupDialog { + // The enrollment startup dialog was shown. + kShown = 0, + + // The dialog was closed automatically because enrollment completed + // successfully. Chrome startup can continue normally. + kClosedSuccess = 1, + + // The dialog was closed because enrollment failed. The user chose to + // relaunch chrome and try again. + kClosedRelaunch = 2, + + // The dialog was closed because enrollment failed. The user chose to + // close chrome. + kClosedFail = 3, + + // The dialog was closed because no response from the server was received + // before the user gave up and closed the dialog. + kClosedAbort = 4, + + kMaxValue = kClosedAbort, + }; + + static const char kStartupDialogHistogramName[]; + + static void RecordEnrollmentStartDialog( + EnrollmentStartupDialog dialog_startup); + // MachineLevelUserCloudPolicyController::Observer void OnPolicyRegisterFinished(bool succeeded) override; @@ -56,6 +100,8 @@ DialogCreationCallback dialog_creation_callback_; + base::Time visible_start_time_; + DISALLOW_COPY_AND_ASSIGN(MachineLevelUserCloudPolicyRegisterWatcher); };
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher_unittest.cc b/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher_unittest.cc index 447470257..de3312e 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher_unittest.cc +++ b/chrome/browser/policy/machine_level_user_cloud_policy_register_watcher_unittest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/strings/string16.h" +#include "base/test/metrics/histogram_tester.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/policy/browser_dm_token_storage.h" #include "chrome/browser/ui/enterprise_startup_dialog.h" @@ -163,6 +164,8 @@ } TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest, EnrollmentSucceed) { + base::HistogramTester histogram_tester; + EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_)); EXPECT_CALL(*dialog(), IsShowing()).WillOnce(Return(true)); base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -172,10 +175,22 @@ base::Unretained(controller()), true)); EXPECT_EQ(RegisterResult::kEnrollmentSuccess, watcher()->WaitUntilCloudPolicyEnrollmentFinished()); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kShown, + 1); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kClosedSuccess, + 1); } TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest, EnrollmentFailedAndQuit) { + base::HistogramTester histogram_tester; + EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_)); EXPECT_CALL(*dialog(), DisplayErrorMessage(_, _)) .WillOnce( @@ -188,10 +203,22 @@ base::Unretained(controller()), false)); EXPECT_EQ(RegisterResult::kQuitDueToFailure, watcher()->WaitUntilCloudPolicyEnrollmentFinished()); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kShown, + 1); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kClosedFail, + 1); } TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest, EnrollmentFailedAndRestart) { + base::HistogramTester histogram_tester; + EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_)); EXPECT_CALL(*dialog(), DisplayErrorMessage(_, _)) .WillOnce( @@ -204,10 +231,22 @@ base::Unretained(controller()), false)); EXPECT_EQ(RegisterResult::kRestartDueToFailure, watcher()->WaitUntilCloudPolicyEnrollmentFinished()); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kShown, + 1); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kClosedRelaunch, + 1); } TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest, EnrollmentCanceledBeforeFinish) { + base::HistogramTester histogram_tester; + EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_)); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -215,16 +254,38 @@ base::Unretained(dialog()), false)); EXPECT_EQ(RegisterResult::kQuitDueToFailure, watcher()->WaitUntilCloudPolicyEnrollmentFinished()); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kShown, + 1); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kClosedAbort, + 1); } TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest, EnrollmentFailedBeforeDialogDisplay) { + base::HistogramTester histogram_tester; + EXPECT_CALL(*dialog(), DisplayErrorMessage(_, _)) .WillOnce( InvokeWithoutArgs([this] { dialog()->UserClickedTheButton(false); })); controller()->FireNotification(false); EXPECT_EQ(RegisterResult::kQuitDueToFailure, watcher()->WaitUntilCloudPolicyEnrollmentFinished()); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kShown, + 1); + histogram_tester.ExpectBucketCount( + MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName, + MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog:: + kClosedFail, + 1); } } // namespace policy
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc index 6b0fb9e2..34fb495 100644 --- a/chrome/browser/printing/print_dialog_cloud.cc +++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -9,6 +9,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "components/cloud_devices/common/cloud_devices_urls.h" @@ -71,8 +72,8 @@ bool add_account, const base::Closure& callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (signin::IsAccountConsistencyMirrorEnabled() && - !browser->profile()->IsOffTheRecord()) { + if (AccountConsistencyModeManager::IsMirrorEnabledForProfile( + browser->profile())) { browser->window()->ShowAvatarBubbleFromAvatarButton( add_account ? BrowserWindow::AVATAR_BUBBLE_MODE_ADD_ACCOUNT : BrowserWindow::AVATAR_BUBBLE_MODE_SIGNIN,
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index d05841fc3..16ef2bd 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -58,6 +58,8 @@ #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" #include "extensions/buildflags/buildflags.h" +#include "media/capabilities/in_memory_video_decode_stats_db_impl.h" +#include "media/mojo/services/video_decode_perf_history.h" #include "net/http/transport_security_state.h" #include "ppapi/buildflags/buildflags.h" #include "services/network/public/mojom/network_context.mojom.h" @@ -107,9 +109,12 @@ using content::HostZoomMap; #endif -#if BUILDFLAG(ENABLE_EXTENSIONS) namespace { +// Key names for OTR Profile user data. +constexpr char kVideoDecodePerfHistoryId[] = "video-decode-perf-history"; + +#if BUILDFLAG(ENABLE_EXTENSIONS) void NotifyOTRProfileCreatedOnIOThread(void* original_profile, void* otr_profile) { extensions::ExtensionWebRequestEventRouter::GetInstance() @@ -121,9 +126,9 @@ extensions::ExtensionWebRequestEventRouter::GetInstance() ->OnOTRBrowserContextDestroyed(original_profile, otr_profile); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) } // namespace -#endif OffTheRecordProfileImpl::OffTheRecordProfileImpl(Profile* real_profile) : profile_(real_profile), start_time_(base::Time::Now()) { @@ -455,11 +460,37 @@ media::VideoDecodePerfHistory* OffTheRecordProfileImpl::GetVideoDecodePerfHistory() { - // Defer to the original profile for VideoDecodePerfHistory. The incognito - // profile will have no history of its own (we don't save it for incognito) - // and the two profiles should have the same video performance. The history is - // not exposed directly to the web, so privacy is not compromised. - return GetOriginalProfile()->GetVideoDecodePerfHistory(); + media::VideoDecodePerfHistory* decode_history = + static_cast<media::VideoDecodePerfHistory*>( + GetUserData(kVideoDecodePerfHistoryId)); + + // Lazily created. Note, this does not trigger loading the DB from disk. That + // occurs later upon first VideoDecodePerfHistory API request that requires DB + // access. DB operations will not block the UI thread. + if (!decode_history) { + // Use the original profile's DB to seed the OTR VideoDeocdePerfHisotry. The + // original DB is treated as read-only, while OTR playbacks will write stats + // to the InMemory version (cleared on profile destruction). Guest profiles + // don't have a root profile like incognito, meaning they don't have a seed + // DB to call on and we can just pass null. + media::VideoDecodeStatsDBProvider* seed_db_provider = + IsGuestSession() ? nullptr + // Safely passing raw pointer to VideoDecodePerfHistory + // because original profile will outlive this profile. + : GetOriginalProfile()->GetVideoDecodePerfHistory(); + + auto db_factory = + std::make_unique<media::InMemoryVideoDecodeStatsDBFactory>( + seed_db_provider); + + auto new_decode_history = + std::make_unique<media::VideoDecodePerfHistory>(std::move(db_factory)); + decode_history = new_decode_history.get(); + + SetUserData(kVideoDecodePerfHistoryId, std::move(new_decode_history)); + } + + return decode_history; } bool OffTheRecordProfileImpl::IsSameProfile(Profile* profile) {
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 74ee7f0..41dca0e7 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -1110,9 +1110,6 @@ builder->set_network_delegate(std::move(network_delegate)); } - builder->set_shared_http_auth_handler_factory( - io_thread_globals->system_request_context->http_auth_handler_factory()); - io_thread->SetUpProxyService(builder.get()); if (g_cert_verifier_for_profile_io_data_testing) {
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 359f6f7..7a86b41 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -61,6 +61,7 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" #include "chrome/browser/ui/sync/sync_promo_ui.h" +#include "chrome/browser/unified_consent/unified_consent_service_factory.h" #include "chrome/common/buildflags.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths_internal.h" @@ -1340,6 +1341,10 @@ ->SetupInvalidationsOnProfileLoad(invalidation_service); AccountReconcilorFactory::GetForProfile(profile); + // Initialization needs to happen after the browser context is available + // because ProfileSyncService needs the URL context getter. + UnifiedConsentServiceFactory::GetForProfile(profile); + #if defined(OS_ANDROID) // TODO(b/678590): create services during profile startup. // Service is responsible for fetching content snippets for the NTP.
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc index 3f3df7d..447812d 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc
@@ -104,6 +104,7 @@ } void TearDown() override { + TabLoadTracker::Get()->StopTracking(web_contents()); DeleteContents(); observer_.reset(); ChromeRenderViewHostTestHarness::TearDown();
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc index 03b80d8..ac2b4d61 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
@@ -205,11 +205,14 @@ } case LifecycleUnitState::PENDING_DISCARD: { - // When the state is PENDING_DISCARD, a freeze request is being processed - // by the renderer. Switch the state to PENDING_FREEZE to prevent a - // discard when the browser is notified that the freeze request has been - // processed. There should be a renderer-initiated to ACTIVE soon after - // the freeze request is processed. + // PENDING_DISCARD indicates that a freeze request is being processed by + // the renderer and that the page should be discarded as soon as it is + // frozen. On focus, we transition the state to PENDING_FREEZE and we stop + // the freeze timeout timer to indicate that a freeze request is being + // processed, but that the page should not be discarded once frozen. After + // the renderer has processed the freeze request, it will realize that the + // page is focused, unfreeze it and initiate a transition to ACTIVE. + freeze_timeout_timer_->Stop(); SetState(LifecycleUnitState::PENDING_FREEZE, StateChangeReason::BROWSER_INITIATED); break; @@ -787,10 +790,10 @@ void TabLifecycleUnitSource::TabLifecycleUnit::OnLifecycleUnitStateChanged( LifecycleUnitState last_state, LifecycleUnitStateChangeReason reason) { - if (!IsValidStateChange(last_state, GetState(), reason)) { - IsValidStateChange(last_state, GetState(), reason); - NOTREACHED(); - } + DCHECK(IsValidStateChange(last_state, GetState(), reason)) + << "Cannot transition TabLifecycleUnit state from " << last_state + << " to " << GetState() << " with reason " << reason; + // Invoke OnDiscardedStateChange() if necessary. const bool was_discarded = IsDiscardedOrPendingDiscard(last_state); const bool is_discarded = IsDiscardedOrPendingDiscard(GetState());
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc index 2316da65..080745b 100644 --- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc +++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
@@ -338,14 +338,16 @@ // Otherwise try to kill tabs only. void TabManagerDelegate::LowMemoryKill(DiscardReason reason) { arc::ArcProcessService* arc_process_service = arc::ArcProcessService::Get(); + base::TimeTicks now = base::TimeTicks::Now(); if (arc_process_service && arc_process_service->RequestAppProcessList( base::BindRepeating(&TabManagerDelegate::LowMemoryKillImpl, - weak_ptr_factory_.GetWeakPtr(), reason))) { + weak_ptr_factory_.GetWeakPtr(), + now, reason))) { return; } - LowMemoryKillImpl(reason, std::vector<arc::ArcProcess>()); + LowMemoryKillImpl(now, reason, std::vector<arc::ArcProcess>()); } int TabManagerDelegate::GetCachedOomScore(ProcessHandle process_handle) { @@ -552,6 +554,7 @@ } void TabManagerDelegate::LowMemoryKillImpl( + base::TimeTicks start_time, DiscardReason reason, std::vector<arc::ArcProcess> arc_processes) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -579,6 +582,7 @@ // The list is sorted by descending importance, so we go through the list // backwards. const TimeTicks now = TimeTicks::Now(); + base::TimeTicks first_kill_time; for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) { MEMORY_LOG(ERROR) << "Target memory to free: " << target_memory_to_free_kb << " KB"; @@ -606,6 +610,9 @@ int estimated_memory_freed_kb = mem_stat_->EstimatedMemoryFreedKB(it->app()->pid()); if (KillArcProcess(it->app()->nspid())) { + if (first_kill_time.is_null()) { + first_kill_time = base::TimeTicks::Now(); + } recently_killed_arc_processes_[it->app()->process_name()] = now; target_memory_to_free_kb -= estimated_memory_freed_kb; memory::MemoryKillsMonitor::LogLowMemoryKill("APP", @@ -624,6 +631,9 @@ int estimated_memory_freed_kb = it->lifecycle_unit()->GetEstimatedMemoryFreedOnDiscardKB(); if (KillTab(it->lifecycle_unit(), reason)) { + if (first_kill_time.is_null()) { + first_kill_time = base::TimeTicks::Now(); + } target_memory_to_free_kb -= estimated_memory_freed_kb; memory::MemoryKillsMonitor::LogLowMemoryKill("TAB", estimated_memory_freed_kb); @@ -637,6 +647,11 @@ MEMORY_LOG(ERROR) << "Unable to kill enough candidates to meet target_memory_to_free_kb "; } + if (!first_kill_time.is_null()) { + TimeDelta delta = first_kill_time - start_time; + MEMORY_LOG(ERROR) << "Time to first kill " << delta; + UMA_HISTOGRAM_MEDIUM_TIMES("Arc.LowMemoryKiller.FirstKillLatency", delta); + } } void TabManagerDelegate::AdjustOomPrioritiesImpl(
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h index be0836f..1e20013b 100644 --- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h +++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h
@@ -143,7 +143,8 @@ void OnFocusTabScoreAdjustmentTimeout(); // Kills a process after getting all info of tabs and apps. - void LowMemoryKillImpl(DiscardReason reason, + void LowMemoryKillImpl(base::TimeTicks start_time, + DiscardReason reason, std::vector<arc::ArcProcess> arc_processes); // Sets a newly focused tab the highest priority process if it wasn't.
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc index d233dee..ce51dd1 100644 --- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/process/process_handle.h" +#include "base/time/time.h" #include "chrome/browser/resource_coordinator/test_lifecycle_unit.h" #include "chrome/browser/resource_coordinator/time.h" #include "chromeos/dbus/fake_debug_daemon_client.h" @@ -326,7 +327,8 @@ memory_stat->SetTargetMemoryToFreeKB(250000); memory_stat->SetProcessPss(30, 10000); - tab_manager_delegate.LowMemoryKillImpl(DiscardReason::kUrgent, + tab_manager_delegate.LowMemoryKillImpl(base::TimeTicks::Now(), + DiscardReason::kUrgent, std::move(arc_processes)); auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses(); @@ -397,7 +399,8 @@ memory_stat->SetProcessPss(20, 30000); memory_stat->SetProcessPss(10, 100000); - tab_manager_delegate.LowMemoryKillImpl(DiscardReason::kProactive, + tab_manager_delegate.LowMemoryKillImpl(base::TimeTicks::Now(), + DiscardReason::kProactive, std::move(arc_processes)); auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses();
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js index 82caa53..1f701b1 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -418,6 +418,13 @@ * @param {!AutomationEvent} evt */ onLocationChanged: function(evt) { + if (evt.target.role == RoleType.DESKTOP) { + var msg = evt.target.state[StateType.HORIZONTAL] ? 'device_landscape' : + 'device_portrait'; + new Output().format('@' + msg).go(); + return; + } + var cur = ChromeVoxState.instance.currentRange; if (AutomationUtil.isDescendantOf(cur.start.node, evt.target) || AutomationUtil.isDescendantOf(cur.end.node, evt.target)) {
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd index 1a1f05e..e3a7822 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -2984,6 +2984,12 @@ <message desc="A hint to the user controls that can be double tapped." name="IDS_CHROMEVOX_HINT_DOUBLE_TAP"> Double tap to activate </message> + <message desc="Shown to the user in braille and speech when the device goes into landscape orientation." name="IDS_CHROMEVOX_DEVICE_LANDSCAPE"> + landscape + </message> + <message desc="Shown to the user in braille and speech when the device goes into portrait orientation." name="IDS_CHROMEVOX_DEVICE_PORTRAIT"> + portrait + </message> </messages> </release> </grit>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb index 1ed5dd91..2c473087 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_am.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">ባለ8 ነጥብ የብሬል ሰንጠረዥ ይምረጡ፦</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">ወደ ዝርዝሮች ለመዝለል Search+A፣ J ይጫኑ።</translation> <translation id="9067522039955793016">ገጽ ከፋይ</translation> <translation id="9077213568694924680">ከምርጫ ተወግዷል</translation> <translation id="9082874451376019682">ምንም ቀዳሚ ተንሸራታች የለም።</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb index dc702606..5b1c8ac 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ar.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">تحديد جدول نمط برايل مكوّن من 8 نقاط:</translation> <translation id="9065283790526219006">+قائمة منبثقة</translation> +<translation id="9066023754636984703">اضغط على "Search+A، J" للانتقال سريعًا إلى التفاصيل.</translation> <translation id="9067522039955793016">فاصل صفحة</translation> <translation id="9077213568694924680">تمت الإزالة من التحديد</translation> <translation id="9082874451376019682">ليس هناك شريط تمرير سابق.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb index faa3ba8..66619a4 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bg.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Изберете таблица за 8-точково брайлово писмо:</translation> <translation id="9065283790526219006">+изскачащ прозорец</translation> +<translation id="9066023754636984703">Натиснете клавиша „търсене“ + A, използвайте J, за да видите подробностите.</translation> <translation id="9067522039955793016">Разделител на страници</translation> <translation id="9077213568694924680">премахнати от открояването</translation> <translation id="9082874451376019682">Няма предишен плъзгач.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb index 915bfcd8..1c45bed 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_da.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" /> %</translation> <translation id="9061884144798498064">Vælg en 8-punkts brailletabel:</translation> <translation id="9065283790526219006">+pop op-vindue</translation> +<translation id="9066023754636984703">Tryk på søgetasten+A, J for at gå til oplysningerne.</translation> <translation id="9067522039955793016">Sideskift</translation> <translation id="9077213568694924680">fjernet fra det valgte</translation> <translation id="9082874451376019682">Ingen tidligere skydere.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb index 689ba58..1c74ae9 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_de.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" /> %</translation> <translation id="9061884144798498064">8-Punkt-Braille-Tabelle auswählen:</translation> <translation id="9065283790526219006">+ Pop-up-Fenster</translation> +<translation id="9066023754636984703">Drücken Sie die Suchtaste + A und J, um Details aufzurufen.</translation> <translation id="9067522039955793016">Seitenumbruch</translation> <translation id="9077213568694924680">aus der Auswahl entfernt</translation> <translation id="9082874451376019682">Kein vorheriger Schieberegler</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb index 25eb36f..b94661e8 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb
@@ -923,6 +923,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Επιλογή οκτάστιγμου πίνακα Μπράιγ:</translation> <translation id="9065283790526219006">+αναδυόμενα παράθυρα</translation> +<translation id="9066023754636984703">Πατήστε Αναζήτηση+A, J για να μεταβείτε στις λεπτομέρειες.</translation> <translation id="9067522039955793016">Αλλαγή σελίδας</translation> <translation id="9077213568694924680">καταργήθηκε από την επιλογή</translation> <translation id="9082874451376019682">Δεν υπάρχει προηγούμενο ρυθμιστικό.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb index e4e2dfa..bbf2fe9a 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_es-419.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" /> %</translation> <translation id="9061884144798498064">Seleccionar una tabla de braille de ocho puntos:</translation> <translation id="9065283790526219006">+emergente</translation> +<translation id="9066023754636984703">Presiona Búsqueda+A y, luego, J para ir a los detalles.</translation> <translation id="9067522039955793016">Salto de página</translation> <translation id="9077213568694924680">eliminado de la selección</translation> <translation id="9082874451376019682">No hay ningún control deslizante anterior.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb index fa93bf2..bde717e 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_et.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Valige 8-punktine punktkirja tabel:</translation> <translation id="9065283790526219006">+hüpik</translation> +<translation id="9066023754636984703">Üksikasjade juurde liikumiseks vajutage otsinguklahvi + klahvi A ja seejärel klahvi J.</translation> <translation id="9067522039955793016">Leheküljepiir</translation> <translation id="9077213568694924680">eemaldatakse valikust</translation> <translation id="9082874451376019682">Eelmist liugurit ei ole.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb index 0228c68..65c1b23 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />٪</translation> <translation id="9061884144798498064">انتخاب جدول بریل ۸ نقطهای:</translation> <translation id="9065283790526219006">+پنجره بازشو</translation> +<translation id="9066023754636984703">برای پرش به جزئیات، «جستجو + A، J» را فشار دهید.</translation> <translation id="9067522039955793016">جداساز صفحه</translation> <translation id="9077213568694924680">از قسمت انتخابی حذف شد</translation> <translation id="9082874451376019682">اسلایدر قبلی موجود نیست.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb index 73c5b10..1699b2f51 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fil.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Pumili ng 8-dot braille table:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">Pindutin ang Search+A, J para lumaktaw sa mga detalye.</translation> <translation id="9067522039955793016">Page break</translation> <translation id="9077213568694924680">inalis sa pagpili</translation> <translation id="9082874451376019682">Walang nakaraang slider.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb index 8dec592e..37ac7fd9 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fr.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" /> %</translation> <translation id="9061884144798498064">Sélectionner un tableau braille à huit points :</translation> <translation id="9065283790526219006">+pop-up</translation> +<translation id="9066023754636984703">Appuyez sur la touche de recherche+A, puis sur J pour accéder directement aux détails.</translation> <translation id="9067522039955793016">Saut de page</translation> <translation id="9077213568694924680">supprimé de la sélection</translation> <translation id="9082874451376019682">Aucun curseur précédent</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb index 0a64561..01c2ec9 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_gu.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8-ડૉટ બ્રેઇલ કોષ્ટક પસંદ કરો:</translation> <translation id="9065283790526219006">+પૉપઅપ</translation> +<translation id="9066023754636984703">Search+A દબાવો, વિગતો પર જવા માટે J દબાવો.</translation> <translation id="9067522039955793016">પેજ વિભાજન</translation> <translation id="9077213568694924680">પસંદગીમાંથી દૂર કર્યું</translation> <translation id="9082874451376019682">પહેલાનું સ્લાઇડર નથી.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb index 877592e..cdbfa059 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hi.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8 बिंदु वाली ब्रेल तालिका चुनें:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">विवरण पर जाने के लिए Search+A, J दबाएं.</translation> <translation id="9067522039955793016">नया पेज</translation> <translation id="9077213568694924680">चयन से निकाले गए</translation> <translation id="9082874451376019682">कोई पिछला स्लाइडर नहीं.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb index 9b07cc5..8a8cf43 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_hu.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8 pontos Braille-táblázat kiválasztása:</translation> <translation id="9065283790526219006">+előugr</translation> +<translation id="9066023754636984703">A Keresés+A, J billentyűkombinációkkal a részletekhez ugorhat.</translation> <translation id="9067522039955793016">Oldaltörés</translation> <translation id="9077213568694924680">eltávolítva a kiválasztottak közül</translation> <translation id="9082874451376019682">Nincs előző dia.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb index 922b504..b5b057d 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_it.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Seleziona una tabella braille a otto punti:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">Premi tasto per la ricerca + A, J per passare ai dettagli.</translation> <translation id="9067522039955793016">Interruzione di pagina</translation> <translation id="9077213568694924680">rimossi dalla selezione</translation> <translation id="9082874451376019682">Nessun dispositivo di scorrimento precedente.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb index e650aad..acdbb4a 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692">%<ph name="NUM" /></translation> <translation id="9061884144798498064">בחר טבלת ברייל 8 נקודות:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">כדי לעבור אל הפרטים צריך להקיש על מקש החיפוש, A ו-J.</translation> <translation id="9067522039955793016">מעבר דף</translation> <translation id="9077213568694924680">הוסר מהבחירה</translation> <translation id="9082874451376019682">אין מחוון קודם.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb index b31aa8a..d77da31 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ja.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8 点点字表を選択:</translation> <translation id="9065283790526219006">ポップアップあり</translation> +<translation id="9066023754636984703">詳細に移動するには、検索キーを押しながら A、J キーを押します。</translation> <translation id="9067522039955793016">改ページ</translation> <translation id="9077213568694924680">選択範囲から削除されています</translation> <translation id="9082874451376019682">前のスライダはありません。</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb index 014000a..6b13bfd 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_kn.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8-ಡಾಟ್ ಬ್ರೈಲ್ ಕೋಷ್ಠಕವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ:</translation> <translation id="9065283790526219006">+ಪಾಪ್ಅಪ್</translation> +<translation id="9066023754636984703">ವಿವರಗಳಿಗೆ ಹೋಗಲು ಹುಡುಕಾಟ+A, J ಒತ್ತಿ.</translation> <translation id="9067522039955793016">ಪುಟ ವಿಭಜನೆ</translation> <translation id="9077213568694924680">ಆಯ್ಕೆಯಿಂದ ತೆಗೆದುಹಾಕಲಾಗಿದೆ</translation> <translation id="9082874451376019682">ಹಿಂದಿನ ಸ್ಲೈಡರ್ ಇಲ್ಲ.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb index 2ae4994..0583de82 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ko.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8점 점자표 선택:</translation> <translation id="9065283790526219006">팝업있음</translation> +<translation id="9066023754636984703">Search+A를 누른 다음 J를 눌러 세부정보로 이동하세요.</translation> <translation id="9067522039955793016">페이지 나누기</translation> <translation id="9077213568694924680">선택 항목에서 삭제</translation> <translation id="9082874451376019682">이전 슬라이더가 없습니다.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb index f9b1fa0..16fd2dd 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_lv.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Atlasiet 8 punktu Braila raksta tabulu:</translation> <translation id="9065283790526219006">ietver uznirstošu elementu</translation> +<translation id="9066023754636984703">Lai pārietu pie detalizētās informācijas, nospiediet meklēšanas taustiņu un A, pēc tam — J.</translation> <translation id="9067522039955793016">Lappuses pārtraukums</translation> <translation id="9077213568694924680">noņemti no atlases</translation> <translation id="9082874451376019682">Iepriekš nav neviena slīdņa.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb index 18b51e04..a2ae0d1d 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ml.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8 ഡോട്ട് ബ്രെയ്ലി പട്ടിക തിരഞ്ഞെടുക്കുക:</translation> <translation id="9065283790526219006">+പോപ്പ്അപ്പ്</translation> +<translation id="9066023754636984703">വിശദാംശങ്ങളിലേക്ക് പോകാൻ Search+A, J അമർത്തുക.</translation> <translation id="9067522039955793016">പേജ് ബ്രേക്ക്</translation> <translation id="9077213568694924680">തിരഞ്ഞെടുത്തതിൽ നിന്നും നീക്കംചെയ്തു</translation> <translation id="9082874451376019682">മുൻ സ്ലൈഡർ ഒന്നുമില്ല.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb index e84bdb26..ae89dbf6 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_mr.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8-बिंदू ब्रेल सारणी निवडा:</translation> <translation id="9065283790526219006">+पॉपअप</translation> +<translation id="9066023754636984703">शोध घेण्यासाठी +A दाबा, तपशीलावर जंप करण्यासाठी J दाबा.</translation> <translation id="9067522039955793016">पेज ब्रेक</translation> <translation id="9077213568694924680">निवडीमधून काढले</translation> <translation id="9082874451376019682">मागील स्लायडर नाही.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb index e29019f..239bd8e 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ms.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Pilih jadual braille 8 titik:</translation> <translation id="9065283790526219006">+pop timbul</translation> +<translation id="9066023754636984703">Tekan Carian+A, J untuk melangkau ke butiran.</translation> <translation id="9067522039955793016">Pemisah halaman</translation> <translation id="9077213568694924680">dialih keluar daripada pilihan</translation> <translation id="9082874451376019682">Tiada peluncur terdahulu.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb index 8cb4e46..523bd5e 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_nl.xtb
@@ -920,6 +920,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Een tabel voor achtpuntsbraille selecteren:</translation> <translation id="9065283790526219006">+pop-up</translation> +<translation id="9066023754636984703">Druk op Zoeken+A, J om naar de details te gaan.</translation> <translation id="9067522039955793016">Pagina-einde</translation> <translation id="9077213568694924680">uit selectie verwijderd</translation> <translation id="9082874451376019682">Geen vorige schuifregelaar.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb index c99acdf..322663f 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pl.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Wybierz tabelę ośmiopunktowego pisma Braille'a:</translation> <translation id="9065283790526219006">+wyskakujące okienko</translation> +<translation id="9066023754636984703">Naciśnij klawisz wyszukiwania + A, J, by przejść do szczegółów.</translation> <translation id="9067522039955793016">Podział strony</translation> <translation id="9077213568694924680">usunięto zaznaczenie</translation> <translation id="9082874451376019682">Brak poprzedniego suwaka.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb index c98d0e6..88ba798 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_pt-PT.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Selecionar uma tabela de braille de 8 pontos:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">Prima Pesquisa+A, J para aceder aos detalhes.</translation> <translation id="9067522039955793016">Quebra de página</translation> <translation id="9077213568694924680">removido da seleção</translation> <translation id="9082874451376019682">Não existe nenhum controlo de deslize anterior.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb index a4bb7a0..12686d5 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ro.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Selectează un tabel braille cu 8 puncte:</translation> <translation id="9065283790526219006">+fereastră pop-up</translation> +<translation id="9066023754636984703">Apasă tasta de căutare + A, J pentru a accesa detaliile.</translation> <translation id="9067522039955793016">Sfârșit de pagină</translation> <translation id="9077213568694924680">eliminate din selecție</translation> <translation id="9082874451376019682">Nu există un glisor anterior.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb index 2faad9d..9ca1b02 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sl.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" /> %</translation> <translation id="9061884144798498064">Izbira tabele za 8-točkovno braillovo pisavo:</translation> <translation id="9065283790526219006">+pojavnookno</translation> +<translation id="9066023754636984703">Pritisnite Search + A, J, če želite skočiti na podrobnosti.</translation> <translation id="9067522039955793016">Prelom strani</translation> <translation id="9077213568694924680">odstranjeni iz izbora</translation> <translation id="9082874451376019682">Ni prejšnjega drsnika.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb index dc299e2..2094f7b 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sr.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Изаберите табелу Брајеве азбуке са 8 тачака:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">Притисните тастер за претрагу + A, J да бисте прешли на детаље.</translation> <translation id="9067522039955793016">Прелом странице</translation> <translation id="9077213568694924680">уклоњено из избора</translation> <translation id="9082874451376019682">Нема претходног клизача.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb index deb629e..d96b45dd 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sv.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" /> %</translation> <translation id="9061884144798498064">Välj punktskrift med åtta punkter:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">Du kan hoppa till mer information om detta med söktangenten+A, J.</translation> <translation id="9067522039955793016">Sidbrytning</translation> <translation id="9077213568694924680">togs bort från markeringen</translation> <translation id="9082874451376019682">Det finns inget föregående skjutreglage.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb index 0a78f7e..c7690ab 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_sw.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Chagua jedwali la breli ya vitone 8:</translation> <translation id="9065283790526219006">+dirisha ibukizi</translation> +<translation id="9066023754636984703">Bofya Tafuta+A, J ili uende kwenye maelezo.</translation> <translation id="9067522039955793016">Nafasi ya kugawa kurasa</translation> <translation id="9077213568694924680">imeondolewa kwenye uchaguzi</translation> <translation id="9082874451376019682">Hakuna kitelezi kilichotangulia.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb index 155a182..bee08d54 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_ta.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8 புள்ளி பிரெய்லி அட்டவணையைத் தேர்ந்தெடுக்கவும்:</translation> <translation id="9065283790526219006">+பாப்அப்</translation> +<translation id="9066023754636984703">விவரங்களைப் பார்க்க, Search+A, Jவை அழுத்தவும்.</translation> <translation id="9067522039955793016">பக்க முறிப்பு</translation> <translation id="9077213568694924680">தேர்விலிருந்து அகற்றப்பட்டது</translation> <translation id="9082874451376019682">முந்தைய ஸ்லைடர் இல்லை.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb index 1e2d72e..136c4320 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb
@@ -916,6 +916,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">8 చుక్కలు ఉన్న బ్రెయిలీ పట్టికను ఎంచుకోండి:</translation> <translation id="9065283790526219006">+పాప్అప్</translation> +<translation id="9066023754636984703">వివరాలలోకి వెళ్లడం కోసం Search+A నొక్కండి.</translation> <translation id="9067522039955793016">పేజీ విభజన</translation> <translation id="9077213568694924680">ఎంపిక నుండి తీసివేయబడింది</translation> <translation id="9082874451376019682">మునుపటి స్లయిడర్ లేదు.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb index 9f3d42c..0a47f41 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_th.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">เลือกตารางเบรลล์แบบ 8 จุด:</translation> <translation id="9065283790526219006">+ป๊อปอัป</translation> +<translation id="9066023754636984703">กด Search+A, J เพื่อข้ามไปยังรายละเอียด</translation> <translation id="9067522039955793016">ตัวแบ่งหน้า</translation> <translation id="9077213568694924680">ลบออกจากการเลือกแล้ว</translation> <translation id="9082874451376019682">ไม่มีแถบเลื่อนก่อนหน้า</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb index 43ea3ae92..e09b5d7 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_tr.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692">%<ph name="NUM" /></translation> <translation id="9061884144798498064">8 noktalı bir braille tablosu seçin:</translation> <translation id="9065283790526219006">+popup</translation> +<translation id="9066023754636984703">Ayrıntılara gitmek için Arama+A, J tuşlarına basın.</translation> <translation id="9067522039955793016">Sayfa sonu</translation> <translation id="9077213568694924680">seçimden kaldırıldı</translation> <translation id="9082874451376019682">Önceki kaydırma çubuğu yok.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb index fc58313..17e6a99 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_uk.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Виберіть таблицю з 8-крапковим шрифтом Брайля:</translation> <translation id="9065283790526219006">+ спливаюче вікно</translation> +<translation id="9066023754636984703">Натисніть клавішу пошуку + A, J, щоб перейти до деталей.</translation> <translation id="9067522039955793016">Розрив сторінки</translation> <translation id="9077213568694924680">видалено з виділеного</translation> <translation id="9082874451376019682">Немає попереднього повзунка.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb index a7ee550..706a00e 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_vi.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692"><ph name="NUM" />%</translation> <translation id="9061884144798498064">Chọn bảng chữ nổi 8 chấm:</translation> <translation id="9065283790526219006">+cửa sổ bật lên</translation> +<translation id="9066023754636984703">Nhấn Tìm kiếm+A, J để chuyển tới phần thông tin chi tiết.</translation> <translation id="9067522039955793016">Ngắt trang</translation> <translation id="9077213568694924680">đã xóa khỏi lựa chọn</translation> <translation id="9082874451376019682">Không có thanh trượt trước nào.</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb index a59e515..ef3265d1 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-CN.xtb
@@ -921,6 +921,7 @@ <translation id="9043969572162476692">百分之<ph name="NUM" /></translation> <translation id="9061884144798498064">请选择一个 8 点式盲文表:</translation> <translation id="9065283790526219006">含弹出项</translation> +<translation id="9066023754636984703">先按搜索键 + A 键,再按 J 键,即可跳转到相关详情。</translation> <translation id="9067522039955793016">分页符</translation> <translation id="9077213568694924680">已从所选文字中移除</translation> <translation id="9082874451376019682">不存在上一个滑块。</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb index 809811043..c5a6820b 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb
@@ -922,6 +922,7 @@ <translation id="9043969572162476692">百分之 <ph name="NUM" /></translation> <translation id="9061884144798498064">選取 8 點點字表:</translation> <translation id="9065283790526219006">含彈出式元件</translation> +<translation id="9066023754636984703">按下搜尋鍵 + A 鍵和 J 鍵即可跳至詳細資料。</translation> <translation id="9067522039955793016">分頁符號</translation> <translation id="9077213568694924680">已從所選範圍中移除</translation> <translation id="9082874451376019682">沒有上一個滑桿。</translation>
diff --git a/chrome/browser/resources/chromeos/login/login_non_lock_shared.html b/chrome/browser/resources/chromeos/login/login_non_lock_shared.html index f49ae64f..8d5768b 100644 --- a/chrome/browser/resources/chromeos/login/login_non_lock_shared.html +++ b/chrome/browser/resources/chromeos/login/login_non_lock_shared.html
@@ -7,7 +7,7 @@ <link rel="stylesheet" href="oobe_screen_enable_debugging.css"> <link rel="stylesheet" href="oobe_screen_eula_installation_settings_overlay.css"> -<link rel="stylesheet" href="oobe_screen_network.css"> +<link rel="stylesheet" href="oobe_screen_welcome.css"> <link rel="stylesheet" href="oobe_screen_reset.css"> <link rel="stylesheet" href="oobe_screen_autolaunch.css"> <link rel="stylesheet" href="oobe_screen_enable_kiosk.css">
diff --git a/chrome/browser/resources/chromeos/login/login_shared.js b/chrome/browser/resources/chromeos/login/login_shared.js index 783ba693..12cf7ec 100644 --- a/chrome/browser/resources/chromeos/login/login_shared.js +++ b/chrome/browser/resources/chromeos/login/login_shared.js
@@ -108,7 +108,7 @@ chrome.send('headerBarVisible'); }); }; - // Start asynchronously so the OOBE network screen comes in first. + // Start asynchronously so the OOBE welcome screen comes in first. window.setTimeout(showHeaderBar, HEADER_BAR_DELAY_MS); } else { document.body.classList.remove('oobe-display');
diff --git a/chrome/browser/resources/chromeos/login/md_login.js b/chrome/browser/resources/chromeos/login/md_login.js index b040bdb2..dc8d51c 100644 --- a/chrome/browser/resources/chromeos/login/md_login.js +++ b/chrome/browser/resources/chromeos/login/md_login.js
@@ -68,9 +68,6 @@ login.TopHeaderBar.decorate($('top-header-bar')); chrome.send('screenStateInitialize'); - - if (Oobe.getInstance().showingViewsLogin) - chrome.send('showAddUser'); }, // Dummy Oobe functions not present with stripped login UI.
diff --git a/chrome/browser/resources/chromeos/login/md_login_shared.js b/chrome/browser/resources/chromeos/login/md_login_shared.js index e2785597..1ec2102 100644 --- a/chrome/browser/resources/chromeos/login/md_login_shared.js +++ b/chrome/browser/resources/chromeos/login/md_login_shared.js
@@ -109,7 +109,7 @@ chrome.send('headerBarVisible'); }); }; - // Start asynchronously so the OOBE network screen comes in first. + // Start asynchronously so the OOBE welcome screen comes in first. window.setTimeout(showHeaderBar, HEADER_BAR_DELAY_MS); } else { document.body.classList.remove('oobe-display');
diff --git a/chrome/browser/resources/chromeos/login/network_select_login.js b/chrome/browser/resources/chromeos/login/network_select_login.js index 47ae13fb..b4a10e9 100644 --- a/chrome/browser/resources/chromeos/login/network_select_login.js +++ b/chrome/browser/resources/chromeos/login/network_select_login.js
@@ -135,7 +135,7 @@ */ onSelectedNetworkConnected_: function() { this.networkLastSelectedGuid_ = ''; - chrome.send('login.NetworkScreen.userActed', ['continue']); + chrome.send('login.WelcomeScreen.userActed', ['continue']); }, /**
diff --git a/chrome/browser/resources/chromeos/login/offline_ad_login.html b/chrome/browser/resources/chromeos/login/offline_ad_login.html index 3f9ca72..2bed4df 100644 --- a/chrome/browser/resources/chromeos/login/offline_ad_login.html +++ b/chrome/browser/resources/chromeos/login/offline_ad_login.html
@@ -14,6 +14,7 @@ Attributes: 'isDomainJoin' - Whether the screen is for domain join. For the join it contains some specific elements (e.g. machine name input). + 'unlockPasswordStep' - Whether the unlock password step should be shown. 'realm' - The AD realm the device is managed by. 'userRealm' - Autocomplete realm for the user input. 'userNameLabel' - Label for the user input. @@ -31,11 +32,16 @@ chosen encryption types 'username': <username> (UPN), 'password': <typed password> } + 'unlockPasswordEntered' - Fired when user enters password to unlock + configuration. Argument + {'unlock_password': <password>} Methods: 'focus' - Focuses current input (user input or password input). 'setUserMachine' - Accepts arguments |user| and |machineName|. Both are optional. If user passed, the password input would be invalidated. + +TODO(rsorokin): Switch to the new UI (see https://crbug.com/811556) --> <dom-module id="offline-ad-login"> <link rel="stylesheet" href="offline_gaia.css"> @@ -48,11 +54,35 @@ <h1 id="welcomeMsg" class="welcome-message">[[adWelcomeMessage]] </h1> </div> - <div slot="footer" class="flex vertical layout justified"> - <gaia-input-form on-submit="onSubmit_" + <div slot="footer" class="flex vertical layout"> + <gaia-input-form on-submit="onUnlockPasswordEntered_" disabled="[[disabled]]" - i18n-values="button-text:offlineLoginNextBtn"> - <gaia-input slot="inputs" id="machineNameInput" required + i18n-values="button-text:adUnlockButton" + hidden="[[!unlockPasswordStep]]"> + <gaia-input id="unlockPasswordInput" type="password" slot="inputs" + i18n-values="error:adUnlockIncorrectPassword; + label:adUnlockPassword" + required> + </gaia-input> + <gaia-button id="skipButton" on-tap="onSkipClicked_"> + $i18n{adUnlockPasswordSkip} + </gaia-button> + </gaia-input-form> + <div class="layout horizontal justified" hidden id="joinConfig"> + <div> + $i18n{selectConfiguration} + </div> + <div class="md-select-wrapper"> + <select id="joinConfigSelect" class="md-select"> + </select> + <span class="md-select-underline"></span> + </div> + </div> + <gaia-input-form on-submit="onSubmit_" id="adCreds" + disabled="[[disabled]]" + i18n-values="button-text:offlineLoginNextBtn" + hidden="[[unlockPasswordStep]]"> + <gaia-input id="machineNameInput" required slot="inputs" hidden="[[!isDomainJoin]]" error="[[machineNameError]]" i18n-values="label:oauthEnrollAdMachineNameInput"> </gaia-input> @@ -64,6 +94,10 @@ i18n-values="error:adLoginInvalidPassword; label:adLoginPassword"> </gaia-input> + <gaia-button id="backToUnlockButton" on-tap="onBackToUnlock_" + type="link" hidden> + $i18n{adUnlockPassword} + </gaia-button> <gaia-button id="moreOptionsBtn" type="link" on-tap="onMoreOptionsClicked_" hidden="[[!isDomainJoin]]"> $i18n{adJoinMoreOptions}
diff --git a/chrome/browser/resources/chromeos/login/offline_ad_login.js b/chrome/browser/resources/chromeos/login/offline_ad_login.js index 246d23b..ef718e0c 100644 --- a/chrome/browser/resources/chromeos/login/offline_ad_login.js +++ b/chrome/browser/resources/chromeos/login/offline_ad_login.js
@@ -13,13 +13,22 @@ MACHINE_NAME_INVALID: 1, MACHINE_NAME_TOO_LONG: 2, BAD_USERNAME: 3, - BAD_PASSWORD: 4, + BAD_AUTH_PASSWORD: 4, + BAD_UNLOCK_PASSWORD: 5, }; +var DEFAULT_ENCRYPTION_TYPES = 'strong'; + /** @typedef {Iterable<{value: string, title: string, selected: boolean, * subtitle: string}>} */ var EncryptionSelectListType; +/** @typedef {{name: string, ad_username: ?string, ad_password: ?string, + * computer_ou: ?string, encryption_types: ?string, + * computer_name_validation_regex: ?string}} + */ +var JoinConfigType; + Polymer({ is: 'offline-ad-login', @@ -33,6 +42,10 @@ */ isDomainJoin: {type: Boolean, value: false}, /** + * Whether the unlock option should be shown. + */ + unlockPasswordStep: {type: Boolean, value: false}, + /** * The kerberos realm (AD Domain), the machine is part of. */ realm: {type: String, observer: 'realmChanged_'}, @@ -73,6 +86,12 @@ * */ defaultEncryption: String, + /** + * List of domain join configuration options. + * @private {!Array<JoinConfigType>|undefined} + */ + joinConfigOptions_: undefined, + /** @private */ realmChanged_: function() { this.adWelcomeMessage = @@ -100,6 +119,8 @@ this.$.encryptionList, list, this.onEncryptionSelected_.bind(this)); this.defaultEncryption = /** @type {!string} */ (getSelectedValue(list)); this.onEncryptionSelected_(this.defaultEncryption); + this.machineNameError = + loadTimeData.getString('adJoinErrorMachineNameInvalid'); }, focus: function() { @@ -122,7 +143,6 @@ user = user.replace(this.userRealm, ''); this.$.userInput.value = user || ''; this.$.machineNameInput.value = machineName || ''; - this.$.passwordInput.value = ''; this.focus(); }, @@ -130,9 +150,7 @@ * @param {ACTIVE_DIRECTORY_ERROR_STATE} error_state */ setInvalid: function(error_state) { - this.$.machineNameInput.isInvalid = false; - this.$.userInput.isInvalid = false; - this.$.passwordInput.isInvalid = false; + this.resetValidity_(); switch (error_state) { case ACTIVE_DIRECTORY_ERROR_STATE.NONE: break; @@ -149,12 +167,36 @@ case ACTIVE_DIRECTORY_ERROR_STATE.BAD_USERNAME: this.$.userInput.isInvalid = true; break; - case ACTIVE_DIRECTORY_ERROR_STATE.BAD_PASSWORD: + case ACTIVE_DIRECTORY_ERROR_STATE.BAD_AUTH_PASSWORD: this.$.passwordInput.isInvalid = true; break; + case ACTIVE_DIRECTORY_ERROR_STATE.BAD_UNLOCK_PASSWORD: + this.$.unlockPasswordInput.isInvalid = true; + break; } }, + /** + * @param {Array<JoinConfigType>} options + */ + setJoinConfigurationOptions: function(options) { + this.$.backToUnlockButton.hidden = true; + if (!options || options.length < 1) { + this.$.joinConfig.hidden = true; + return; + } + this.joinConfigOptions_ = options; + var selectList = []; + for (var i = 0; i < options.length; ++i) { + selectList.push({title: options[i].name, value: i}); + } + setupSelect( + this.$.joinConfigSelect, selectList, + this.onJoinConfigSelected_.bind(this)); + this.onJoinConfigSelected_(this.$.joinConfigSelect.value); + this.$.joinConfig.hidden = false; + }, + /** @private */ onSubmit_: function() { if (this.isDomainJoin && !this.$.machineNameInput.checkValidity()) @@ -173,8 +215,7 @@ 'password': this.$.passwordInput.value }; if (this.isDomainJoin) - msg['encryption_types'] = parseInt(this.$.encryptionList.value, 10); - this.$.passwordInput.value = ''; + msg['encryption_types'] = this.$.encryptionList.value; this.fire('authCompleted', msg); }, @@ -211,6 +252,25 @@ this.$$('#gaiaCard').classList.remove('full-disabled'); }, + /** @private */ + onUnlockPasswordEntered_: function() { + var msg = { + 'unlock_password': this.$.unlockPasswordInput.value, + }; + this.fire('unlockPasswordEntered', msg); + }, + + /** @private */ + onSkipClicked_: function() { + this.$.backToUnlockButton.hidden = false; + this.unlockPasswordStep = false; + }, + + /** @private */ + onBackToUnlock_: function() { + this.unlockPasswordStep = true; + }, + /** * @private * @param {!string} value @@ -220,4 +280,43 @@ this.encryptionValueToSubtitleMap[value]; this.$.encryptionWarningIcon.hidden = (value == this.defaultEncryption); }, + + /** @private */ + onJoinConfigSelected_: function(value) { + this.resetValidity_(); + var option = this.joinConfigOptions_[value]; + this.$.userInput.value = option['ad_username'] || ''; + this.$.passwordInput.value = option['ad_password'] || ''; + this.$.orgUnitInput.value = option['computer_ou'] || ''; + + var encryptionTypes = + option['encryption_types'] || DEFAULT_ENCRYPTION_TYPES; + if (!(encryptionTypes in this.encryptionValueToSubtitleMap)) { + encryptionTypes = DEFAULT_ENCRYPTION_TYPES; + } + this.$.encryptionList.value = encryptionTypes; + this.onEncryptionSelected_(encryptionTypes); + + var pattern = option['computer_name_validation_regex']; + this.$.machineNameInput.pattern = pattern; + if (pattern) { + this.$.machineNameInput.label = loadTimeData.getStringF( + 'oauthEnrollAdMachineNameInputRegex', pattern); + this.machineNameError = loadTimeData.getStringF( + 'adJoinErrorMachineNameDoesntMatchRegex', pattern); + } else { + this.$.machineNameInput.label = + loadTimeData.getString('oauthEnrollAdMachineNameInput'); + this.machineNameError = + loadTimeData.getString('adJoinErrorMachineNameInvalid'); + } + }, + + /** @private */ + resetValidity_: function() { + this.$.machineNameInput.isInvalid = false; + this.$.userInput.isInvalid = false; + this.$.passwordInput.isInvalid = false; + this.$.unlockPasswordInput.isInvalid = false; + }, });
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js index fe642b6..848f1e7b 100644 --- a/chrome/browser/resources/chromeos/login/oobe.js +++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -15,7 +15,7 @@ // <include src="oobe_screen_eula.js"> // <include src="oobe_screen_hid_detection.js"> // <include src="oobe_screen_host_pairing.js"> -// <include src="oobe_screen_network.js"> +// <include src="oobe_screen_welcome.js"> // <include src="oobe_screen_update.js"> cr.define('cr.ui.Oobe', function() { @@ -28,7 +28,7 @@ cr.ui.login.DisplayManager.initialize(); login.HIDDetectionScreen.register(); login.WrongHWIDScreen.register(); - login.NetworkScreen.register(); + login.WelcomeScreen.register(); login.EulaScreen.register(); login.UpdateScreen.register(); login.AutoEnrollmentCheckScreen.register();
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js index 7119962..fba9eca 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -32,7 +32,8 @@ 'setAvailableLicenseTypes', 'showAttributePromptStep', 'showAttestationBasedEnrollmentSuccess', - 'invalidateAd', + 'setAdJoinParams', + 'setAdJoinConfiguration', ], /** @@ -139,6 +140,11 @@ e.detail.encryption_types, e.detail.username, e.detail.password ]); }.bind(this)); + this.offlineAdUi_.addEventListener('unlockPasswordEntered', function(e) { + this.offlineAdUi_.disabled = true; + chrome.send( + 'oauthEnrollAdUnlockConfiguration', [e.detail.unlock_password]); + }.bind(this)); this.authenticator_.addEventListener( 'authFlowChange', (function(e) { @@ -427,10 +433,30 @@ this.updateControlsState(); }, - invalidateAd: function(machineName, user, errorState) { + /** + * Sets Active Directory join screen params. + * @param {string} machineName + * @param {string} userName + * @param {ACTIVE_DIRECTORY_ERROR_STATE} errorState + * @param {boolean} showUnlockConfig true if there is an encrypted + * configuration (and not unlocked yet). + */ + setAdJoinParams: function( + machineName, userName, errorState, showUnlockConfig) { this.offlineAdUi_.disabled = false; - this.offlineAdUi_.setUser(user, machineName); + this.offlineAdUi_.setUser(userName, machineName); this.offlineAdUi_.setInvalid(errorState); + this.offlineAdUi_.unlockPasswordStep = showUnlockConfig; + }, + + /** + * Sets Active Directory join screen with the unlocked configuration. + * @param {Array<JoinConfigType>} options + */ + setAdJoinConfiguration: function(options) { + this.offlineAdUi_.disabled = false; + this.offlineAdUi_.unlockPasswordStep = false; + this.offlineAdUi_.setJoinConfigurationOptions(options); }, /**
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_network.css b/chrome/browser/resources/chromeos/login/oobe_screen_welcome.css similarity index 100% rename from chrome/browser/resources/chromeos/login/oobe_screen_network.css rename to chrome/browser/resources/chromeos/login/oobe_screen_welcome.css
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_network.html b/chrome/browser/resources/chromeos/login/oobe_screen_welcome.html similarity index 100% rename from chrome/browser/resources/chromeos/login/oobe_screen_network.html rename to chrome/browser/resources/chromeos/login/oobe_screen_welcome.html
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_network.js b/chrome/browser/resources/chromeos/login/oobe_screen_welcome.js similarity index 96% rename from chrome/browser/resources/chromeos/login/oobe_screen_network.js rename to chrome/browser/resources/chromeos/login/oobe_screen_welcome.js index 8cc2ee7..918b985 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_network.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_welcome.js
@@ -3,10 +3,10 @@ // found in the LICENSE file. /** - * @fileoverview Oobe network screen implementation. + * @fileoverview OOBE welcome screen implementation. */ -login.createScreen('NetworkScreen', 'connect', function() { +login.createScreen('WelcomeScreen', 'connect', function() { var CONTEXT_KEY_LOCALE = 'locale'; var CONTEXT_KEY_INPUT_METHOD = 'input-method'; var CONTEXT_KEY_TIMEZONE = 'timezone';
diff --git a/chrome/browser/resources/chromeos/login/oobe_screens.html b/chrome/browser/resources/chromeos/login/oobe_screens.html index c16911c8..cd6a766 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screens.html +++ b/chrome/browser/resources/chromeos/login/oobe_screens.html
@@ -1,5 +1,5 @@ <include src="oobe_screen_eula.html"> -<include src="oobe_screen_network.html"> +<include src="oobe_screen_welcome.html"> <include src="oobe_screen_enable_debugging.html"> <include src="oobe_screen_reset.html"> <include src="oobe_screen_autolaunch.html">
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.js b/chrome/browser/resources/chromeos/login/oobe_welcome.js index 434bd5d..a08f4b6a 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.js +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.js
@@ -241,7 +241,7 @@ /** @private */ onNetworkNextTap_: function() { - chrome.send('login.NetworkScreen.userActed', ['continue']); + chrome.send('login.WelcomeScreen.userActed', ['continue']); }, /**
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js index bdc0d0f7..d1d5a7a 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js +++ b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js
@@ -128,7 +128,7 @@ onDebuggingLinkClicked_: function() { chrome.send( - 'login.NetworkScreen.userActed', ['connect-debugging-features']); + 'login.WelcomeScreen.userActed', ['connect-debugging-features']); }, /*
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index 098343e..b6082e57 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -912,11 +912,13 @@ * user without a password (neither a manually entered one nor one provided * via Credentials Passing API). * @param {string} email + * @param {string} gaiaId * @param {function(boolean)} callback * @private */ - getIsSamlUserPasswordless_: function(email, callback) { - cr.sendWithPromise('getIsSamlUserPasswordless', email).then(callback); + getIsSamlUserPasswordless_: function(email, gaiaId, callback) { + cr.sendWithPromise('getIsSamlUserPasswordless', email, gaiaId) + .then(callback); }, /**
diff --git a/chrome/browser/resources/feedback/css/feedback.css b/chrome/browser/resources/feedback/css/feedback.css index 7e1e03a..336d30cc 100644 --- a/chrome/browser/resources/feedback/css/feedback.css +++ b/chrome/browser/resources/feedback/css/feedback.css
@@ -139,7 +139,7 @@ .content #privacy-note { color: #969696; font-size: 12px; - line-height: 15px; + line-height: 20px; margin-bottom: 20px; margin-top: 20px; text-align: justify;
diff --git a/chrome/browser/resources/feedback/js/feedback.js b/chrome/browser/resources/feedback/js/feedback.js index 7051855..40cf123 100644 --- a/chrome/browser/resources/feedback/js/feedback.js +++ b/chrome/browser/resources/feedback/js/feedback.js
@@ -135,6 +135,22 @@ } /** + * Sets up the event handlers for the given |anchorElement|. + * @param {HTMLElement} anchorElement The <a> html element. + * @param {string} url The destination URL for the link. + */ +function setupLinkHandlers(anchorElement, url) { + anchorElement.onclick = function(e) { + e.preventDefault(); + window.open(url, '_blank'); + }; + + anchorElement.onauxclick = function(e) { + e.preventDefault(); + }; +} + +/** * Opens a new window with chrome://slow_trace, downloading performance data. */ function openSlowTraceWindow() { @@ -402,10 +418,12 @@ loadTimeData.data = strings; i18nTemplate.process(document, loadTimeData); - if ($('sys-info-url')) { + var sysInfoUrlElement = $('sys-info-url'); + if (sysInfoUrlElement) { // Opens a new window showing the full anonymized system+app // information. - $('sys-info-url').onclick = function() { + sysInfoUrlElement.onclick = function(e) { + e.preventDefault(); var win = chrome.app.window.get(SYSINFO_WINDOW_ID); if (win) { win.show(); @@ -440,29 +458,37 @@ }; }); }; + + sysInfoUrlElement.onauxclick = function(e) { + e.preventDefault(); + }; } - if ($('histograms-url')) { + + var histogramUrlElement = $('histograms-url'); + if (histogramUrlElement) { // Opens a new window showing the histogram metrics. - $('histograms-url').onclick = + histogramUrlElement.onclick = windowOpener(STATS_WINDOW_ID, 'chrome://histograms'); - } - if ($('legal-help-page-url')) { - $('legal-help-page-url').onclick = function() { - window.open(FEEDBACK_LEGAL_HELP_URL, '_blank'); + histogramUrlElement.onauxclick = function(e) { + e.preventDefault(); }; } - if ($('privacy-policy-url')) { - $('privacy-policy-url').onclick = function() { - window.open(FEEDBACK_PRIVACY_POLICY_URL, '_blank'); - }; + var legalHelpPageUrlElement = $('legal-help-page-url'); + if (legalHelpPageUrlElement) + setupLinkHandlers(legalHelpPageUrlElement, FEEDBACK_LEGAL_HELP_URL); + + var privacyPolicyUrlElement = $('privacy-policy-url'); + if (privacyPolicyUrlElement) { + setupLinkHandlers( + privacyPolicyUrlElement, FEEDBACK_PRIVACY_POLICY_URL); } - if ($('terms-of-service-url')) { - $('terms-of-service-url').onclick = function() { - window.open(FEEDBACK_TERM_OF_SERVICE_URL, '_blank'); - }; + var termsOfServiceUrlElement = $('terms-of-service-url'); + if (termsOfServiceUrlElement) { + setupLinkHandlers( + termsOfServiceUrlElement, FEEDBACK_TERM_OF_SERVICE_URL); } // Make sure our focus starts on the description field.
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 7f23832..327b0c9 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -158,7 +158,8 @@ * Callback allowing to request whether the specified user which * authenticates via SAML is a user without a password (neither a manually * entered one nor one provided via Credentials Passing API). - * @type {function(string, function(boolean))} + * @type {function(string, string, function(boolean))} Arguments are the + * e-mail, the GAIA ID, and the response callback. */ this.getIsSamlUserPasswordlessCallback = null; this.needPassword = true; @@ -734,19 +735,20 @@ return; if (this.isSamlUserPasswordless_ === null && - this.authFlow == AuthFlow.SAML && this.email_ && + this.authFlow == AuthFlow.SAML && this.email_ && this.gaiaId_ && this.getIsSamlUserPasswordlessCallback) { // Start a request to obtain the |isSamlUserPasswordless_| value for the // current user. Once the response arrives, maybeCompleteAuth_() will be // called again. this.getIsSamlUserPasswordlessCallback( - this.email_, - this.onGotIsSamlUserPasswordless_.bind(this, this.email_)); + this.email_, this.gaiaId_, + this.onGotIsSamlUserPasswordless_.bind( + this, this.email_, this.gaiaId_)); return; } if (this.isSamlUserPasswordless_ && this.authFlow == AuthFlow.SAML && - this.email_) { + this.email_ && this.gaiaId_) { // No password needed for this user, so complete immediately. this.onAuthCompleted_(); return; @@ -805,14 +807,16 @@ /** * Invoked when the result of |getIsSamlUserPasswordlessCallback| arrives. * @param {string} email + * @param {string} gaiaId * @param {boolean} isSamlUserPasswordless * @private */ Authenticator.prototype.onGotIsSamlUserPasswordless_ = function( - email, isSamlUserPasswordless) { - // Compare the request's e-mail with the currently set one, in order to - // ignore responses to old requests. - if (this.email_ && this.email_ == email) { + email, gaiaId, isSamlUserPasswordless) { + // Compare the request's user identifier with the currently set one, in + // order to ignore responses to old requests. + if (this.email_ && this.email_ == email && this.gaiaId_ && + this.gaiaId_ == gaiaId) { this.isSamlUserPasswordless_ = isSamlUserPasswordless; this.maybeCompleteAuth_(); }
diff --git a/chrome/browser/resources/md_bookmarks/shared_vars.html b/chrome/browser/resources/md_bookmarks/shared_vars.html index c39ba31..6c1e3238 100644 --- a/chrome/browser/resources/md_bookmarks/shared_vars.html +++ b/chrome/browser/resources/md_bookmarks/shared_vars.html
@@ -14,8 +14,8 @@ --iron-icon-height: 20px; --iron-icon-width: 20px; --min-sidebar-width: 256px; - --primary-text-color: var(--paper-grey-900); - --secondary-text-color: var(--paper-grey-600); + --primary-text-color: var(--google-grey-900); + --secondary-text-color: var(--google-grey-700); --splitter-width: 15px; } </style>
diff --git a/chrome/browser/resources/md_downloads/item.html b/chrome/browser/resources/md_downloads/item.html index 52813da..11fcfb0 100644 --- a/chrome/browser/resources/md_downloads/item.html +++ b/chrome/browser/resources/md_downloads/item.html
@@ -34,9 +34,12 @@ #date { color: var(--paper-grey-700); - font-size: 100%; - font-weight: 500; + font-size: 123%; + font-weight: 400; + letter-spacing: .25px; margin: 24px auto 10px; + padding-bottom: 4px; + padding-top: 8px; width: var(--downloads-card-width); }
diff --git a/chrome/browser/resources/md_extensions/item.html b/chrome/browser/resources/md_extensions/item.html index e4fb364..d8c34df 100644 --- a/chrome/browser/resources/md_extensions/item.html +++ b/chrome/browser/resources/md_extensions/item.html
@@ -118,9 +118,7 @@ #extension-id, #inspect-views, #button-strip { - /* TODO(dschuyler): use --cr-secondary-text. */ - color: var(--paper-grey-600); - font-weight: 400; + @apply --cr-secondary-text; } #extension-id {
diff --git a/chrome/browser/resources/md_extensions/item_list.html b/chrome/browser/resources/md_extensions/item_list.html index 9644a45..a5cd827 100644 --- a/chrome/browser/resources/md_extensions/item_list.html +++ b/chrome/browser/resources/md_extensions/item_list.html
@@ -54,8 +54,13 @@ #app-title { @apply --cr-section-text; + font-size: 123%; + font-weight: 400; + letter-spacing: .25px; margin-bottom: 12px; margin-top: 21px; + padding-bottom: 4px; + padding-top: 8px; } </style> <div id="container">
diff --git a/chrome/browser/resources/md_history/history.html b/chrome/browser/resources/md_history/history.html index bdce86e..6742558 100644 --- a/chrome/browser/resources/md_history/history.html +++ b/chrome/browser/resources/md_history/history.html
@@ -56,6 +56,7 @@ background: var(--md-toolbar-color); color: #fff; height: 56px; + letter-spacing: .25px; } #loading-message {
diff --git a/chrome/browser/resources/md_history/history_item.html b/chrome/browser/resources/md_history/history_item.html index 175ef83..64aae9e 100644 --- a/chrome/browser/resources/md_history/history_item.html +++ b/chrome/browser/resources/md_history/history_item.html
@@ -41,6 +41,11 @@ :host([is-card-start]) #date-accessed { display: block; + font-size: 123%; + font-weight: 400; + letter-spacing: .25px; + padding-bottom: 4px; + padding-top: 8px; } #item-container {
diff --git a/chrome/browser/resources/md_history/shared_vars.html b/chrome/browser/resources/md_history/shared_vars.html index 984a07d..8738191 100644 --- a/chrome/browser/resources/md_history/shared_vars.html +++ b/chrome/browser/resources/md_history/shared_vars.html
@@ -26,8 +26,8 @@ --iron-icon-height: var(--cr-icon-size); --iron-icon-width: var(--cr-icon-size); --link-color: var(--google-blue-700); - --primary-text-color: var(--paper-grey-900); - --secondary-text-color: var(--paper-grey-600); + --primary-text-color: var(--google-grey-900); + --secondary-text-color: var(--google-grey-700); --separator-color: rgba(0, 0, 0, 0.08); --side-bar-width: 256px; --sidebar-footer-text-color: #6e6e6e;
diff --git a/chrome/browser/resources/md_user_manager/shared_styles.html b/chrome/browser/resources/md_user_manager/shared_styles.html index f113216..9d301a5 100644 --- a/chrome/browser/resources/md_user_manager/shared_styles.html +++ b/chrome/browser/resources/md_user_manager/shared_styles.html
@@ -7,7 +7,7 @@ :root { --error-color: var(--google-red-700); --page-width: 624px; - --primary-text-color: var(--paper-grey-800); + --primary-text-color: var(--google-grey-900); --title-icon-color: var(--paper-grey-500); --user-manager-separator-line: 1px solid rgba(0, 0, 0, .12); }
diff --git a/chrome/browser/resources/pdf/elements/shared-vars.html b/chrome/browser/resources/pdf/elements/shared-vars.html index 9761bad..da5f14a 100644 --- a/chrome/browser/resources/pdf/elements/shared-vars.html +++ b/chrome/browser/resources/pdf/elements/shared-vars.html
@@ -5,7 +5,7 @@ <custom-style> <style is="custom-style"> html { - --primary-text-color: var(--paper-grey-900); + --primary-text-color: var(--google-grey-900); --iron-icon-height: 20px; --iron-icon-width: 20px; --paper-icon-button: {
diff --git a/chrome/browser/resources/print_preview/new/advanced_options_settings.html b/chrome/browser/resources/print_preview/new/advanced_options_settings.html index 77ac579..dae294cc 100644 --- a/chrome/browser/resources/print_preview/new/advanced_options_settings.html +++ b/chrome/browser/resources/print_preview/new/advanced_options_settings.html
@@ -1,6 +1,5 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="../data/destination.html"> <link rel="import" href="advanced_settings_dialog.html"> <link rel="import" href="button_css.html"> @@ -24,13 +23,12 @@ </button> </div> </print-preview-settings-section> - <cr-lazy-render id="advancedDialog"> - <template> - <print-preview-advanced-dialog - settings="{{settings}}" destination="[[destination]]"> - </print-preview-advanced-dialog> - </template> - </cr-lazy-render> + <template is="dom-if" if="[[showAdvancedDialog_]]" restamp> + <print-preview-advanced-dialog + settings="{{settings}}" destination="[[destination]]" + on-close="onDialogClose_"> + </print-preview-advanced-dialog> + </template> </template> <script src="advanced_options_settings.js"></script> </dom-module>
diff --git a/chrome/browser/resources/print_preview/new/advanced_options_settings.js b/chrome/browser/resources/print_preview/new/advanced_options_settings.js index b47ab00..4a5f622 100644 --- a/chrome/browser/resources/print_preview/new/advanced_options_settings.js +++ b/chrome/browser/resources/print_preview/new/advanced_options_settings.js
@@ -12,15 +12,21 @@ /** @type {!print_preview.Destination} */ destination: Object, + + /** @private {boolean} */ + showAdvancedDialog_: { + type: Boolean, + value: false, + }, }, /** @private */ onButtonClick_: function() { - const dialog = this.$.advancedDialog.get(); - // This async() call is a workaround to prevent a DCHECK - see - // https://crbug.com/804047. - this.async(() => { - dialog.show(); - }, 1); + this.showAdvancedDialog_ = true; + }, + + /** @private */ + onDialogClose_: function() { + this.showAdvancedDialog_ = false; }, });
diff --git a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html index 6ad13d0..1ebebe6 100644 --- a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html +++ b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html
@@ -13,9 +13,9 @@ <link rel="import" href="strings.html"> <dom-module id="print-preview-advanced-dialog"> - <style include="print-preview-shared search-dialog button cr-hidden-style"> - </style> <template> + <style include="print-preview-shared search-dialog button cr-hidden-style"> + </style> <cr-dialog id="dialog" on-close="onCloseOrCancel_" show-close-button> <div slot="title"> <div>[[i18n('advancedSettingsDialogTitle', destination.displayName)]]
diff --git a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js index cfba9df4..a2e0e509 100644 --- a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js +++ b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js
@@ -34,6 +34,18 @@ /** @private {!print_preview.PrintSettingsUiMetricsContext} */ metrics_: new print_preview.PrintSettingsUiMetricsContext(), + /** @override */ + attached: function() { + this.metrics_.record(print_preview.Metrics.PrintSettingsUiBucket + .ADVANCED_SETTINGS_DIALOG_SHOWN); + // This async() call is a workaround to prevent a DCHECK - see + // https://crbug.com/804047. + // TODO (rbpotter): Remove after Polymer2 migration is complete. + this.async(() => { + this.$.dialog.showModal(); + }, 1); + }, + /** * @return {boolean} Whether there is more than one vendor item to display. * @private @@ -47,6 +59,9 @@ * @private */ computeHasMatching_: function() { + if (!this.shadowRoot) + return true; + cr.search_highlight_utils.removeHighlights(this.highlights_); for (let bubble of this.bubbles_) bubble.remove(); @@ -101,12 +116,6 @@ this.$.dialog.close(); }, - show: function() { - this.metrics_.record(print_preview.Metrics.PrintSettingsUiBucket - .ADVANCED_SETTINGS_DIALOG_SHOWN); - this.$.dialog.showModal(); - }, - close: function() { this.$.dialog.close(); },
diff --git a/chrome/browser/resources/print_preview/new/advanced_settings_item.html b/chrome/browser/resources/print_preview/new/advanced_settings_item.html index af531c7..7b1e87f 100644 --- a/chrome/browser/resources/print_preview/new/advanced_settings_item.html +++ b/chrome/browser/resources/print_preview/new/advanced_settings_item.html
@@ -9,40 +9,40 @@ <link rel="import" href="settings_behavior.html"> <dom-module id="print-preview-advanced-settings-item"> - <style include="print-preview-shared select search-highlight-style"> - :host { - display: flex; - position: relative; - } - - :host > * { - overflow: hidden; - padding-bottom: 15px; - padding-top: 10px; - text-overflow: ellipsis; - vertical-align: middle; - white-space: nowrap; - } - - :host .label { - -webkit-padding-end: 20px; - display: flex; - flex-direction: column; - justify-content: center; - width: 250px; - } - - :host .value { - width: 175px; - } - - :host input { - height: 28px; - line-height: 24px; - width: 175px; - } - </style> <template> + <style include="print-preview-shared select search-highlight-style"> + :host { + display: flex; + position: relative; + } + + :host > * { + overflow: hidden; + padding-bottom: 15px; + padding-top: 10px; + text-overflow: ellipsis; + vertical-align: middle; + white-space: nowrap; + } + + :host .label { + -webkit-padding-end: 20px; + display: flex; + flex-direction: column; + justify-content: center; + width: 250px; + } + + :host .value { + width: 175px; + } + + :host input { + height: 28px; + line-height: 24px; + width: 175px; + } + </style> <label class="label searchable">[[getDisplayName_(capability)]]</label> <div class="value"> <template is="dom-if" if="[[isCapabilityTypeSelect_(capability)]]"
diff --git a/chrome/browser/resources/print_preview/new/app.js b/chrome/browser/resources/print_preview/new/app.js index 4cdc588..5eba75d 100644 --- a/chrome/browser/resources/print_preview/new/app.js +++ b/chrome/browser/resources/print_preview/new/app.js
@@ -287,7 +287,12 @@ this.isInKioskAutoPrintMode_ = settings.isInKioskAutoPrintMode; // This is only visible in the task manager. - document.head.querySelector('title').textContent = settings.documentTitle; + let title = document.head.querySelector('title'); + if (!title) { + title = document.createElement('title'); + document.head.appendChild(title); + } + title.textContent = settings.documentTitle; }, /** @@ -337,9 +342,10 @@ /** @private */ onDestinationUpdated_: function() { - this.set( - 'destination_.capabilities', - this.destinationStore_.selectedDestination.capabilities); + // Notify observers, since destination_ == + // destinationStore_.selectedDestination and this event indicates + // destinationStore_.selectedDestination.capabilities has been updated. + this.notifyPath('destination_.capabilities'); if (!this.$.model.initialized()) this.$.model.applyStickySettings();
diff --git a/chrome/browser/resources/print_preview/new/destination_dialog.html b/chrome/browser/resources/print_preview/new/destination_dialog.html index 182e131..fbc595ec 100644 --- a/chrome/browser/resources/print_preview/new/destination_dialog.html +++ b/chrome/browser/resources/print_preview/new/destination_dialog.html
@@ -6,6 +6,7 @@ <link rel="import" href="chrome://resources/html/event_tracker.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="../metrics.html"> +<link rel="import" href="../print_preview_utils.html"> <link rel="import" href="../data/destination.html"> <link rel="import" href="../data/destination_store.html"> <link rel="import" href="../data/invitation.html">
diff --git a/chrome/browser/resources/print_preview/new/destination_dialog.js b/chrome/browser/resources/print_preview/new/destination_dialog.js index 8500c9f..ac080a5 100644 --- a/chrome/browser/resources/print_preview/new/destination_dialog.js +++ b/chrome/browser/resources/print_preview/new/destination_dialog.js
@@ -140,6 +140,9 @@ /** @private */ updateDestinations_: function() { + if (this.destinationStore === undefined) + return; + this.notifyPath('userInfo.users'); this.notifyPath('userInfo.activeUser'); this.notifyPath('userInfo.loggedIn'); @@ -158,6 +161,9 @@ * @private */ computeRecentDestinationList_: function() { + if (!observerDepsDefined(Array.from(arguments))) + return []; + let recentDestinations = []; const filterAccount = this.userInfo.activeUser; this.recentDestinations.forEach((recentDestination) => { @@ -260,9 +266,9 @@ }, show: function() { - this.loadingDestinations_ = - this.destinationStore.isPrintDestinationSearchInProgress; this.$.dialog.showModal(); + this.loadingDestinations_ = this.destinationStore === undefined || + this.destinationStore.isPrintDestinationSearchInProgress; this.metrics_.record( print_preview.Metrics.DestinationSearchBucket.DESTINATION_SHOWN); },
diff --git a/chrome/browser/resources/print_preview/new/destination_settings.js b/chrome/browser/resources/print_preview/new/destination_settings.js index 8095bdb..e0681df 100644 --- a/chrome/browser/resources/print_preview/new/destination_settings.js +++ b/chrome/browser/resources/print_preview/new/destination_settings.js
@@ -74,6 +74,9 @@ * @private */ getStatusText_: function() { + if (this.destination === undefined) + return ''; + return this.destination.shouldShowInvalidCertificateError ? this.i18n('noLongerSupportedFragment') : this.destination.connectionStatusText; @@ -86,6 +89,7 @@ const dialog = this.$.destinationDialog.get(); // This async() call is a workaround to prevent a DCHECK - see // https://crbug.com/804047. + // TODO (rbpotter): Remove after Polymer2 migration is complete. this.async(() => { dialog.show(); }, 1);
diff --git a/chrome/browser/resources/print_preview/new/dpi_settings.js b/chrome/browser/resources/print_preview/new/dpi_settings.js index 31e95f6d..2578382 100644 --- a/chrome/browser/resources/print_preview/new/dpi_settings.js +++ b/chrome/browser/resources/print_preview/new/dpi_settings.js
@@ -45,12 +45,13 @@ /** * Adds default labels for each option. - * @return {{option: Array<!print_preview_new.SelectOption>}} + * @return {?{option: Array<!print_preview_new.SelectOption>}} * @private */ computeCapabilityWithLabels_: function() { - if (!this.capability || !this.capability.option) - return this.capability; + if (this.capability === undefined) + return null; + const result = /** @type {{option: Array<!print_preview_new.SelectOption>}} */ ( JSON.parse(JSON.stringify(this.capability))); @@ -76,6 +77,11 @@ * @private */ onDpiSettingChange_: function(value) { + if (this.capabilityWithLabels_ === null || + this.capabilityWithLabels_ === undefined) { + return; + } + const dpiValue = /** @type {print_preview_new.DpiOption} */ (value); for (const option of assert(this.capabilityWithLabels_.option)) { const dpiOption =
diff --git a/chrome/browser/resources/print_preview/new/margin_control.html b/chrome/browser/resources/print_preview/new/margin_control.html index 3d81482..b8a6daf5 100644 --- a/chrome/browser/resources/print_preview/new/margin_control.html +++ b/chrome/browser/resources/print_preview/new/margin_control.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="../print_preview_utils.html"> <link rel="import" href="../data/coordinate2d.html"> <link rel="import" href="../data/margins.html"> <link rel="import" href="../data/size.html">
diff --git a/chrome/browser/resources/print_preview/new/margin_control.js b/chrome/browser/resources/print_preview/new/margin_control.js index 86ca222..3cd82b0 100644 --- a/chrome/browser/resources/print_preview/new/margin_control.js +++ b/chrome/browser/resources/print_preview/new/margin_control.js
@@ -158,6 +158,9 @@ /** @private */ updatePosition_: function() { + if (!observerDepsDefined(Array.from(arguments))) + return; + const orientationEnum = print_preview.ticket_items.CustomMarginsOrientation; let x = this.translateTransform.x; let y = this.translateTransform.y;
diff --git a/chrome/browser/resources/print_preview/new/media_size_settings.js b/chrome/browser/resources/print_preview/new/media_size_settings.js index 1ff1bfb07..5a40807 100644 --- a/chrome/browser/resources/print_preview/new/media_size_settings.js +++ b/chrome/browser/resources/print_preview/new/media_size_settings.js
@@ -22,8 +22,13 @@ * @private */ onMediaSizeSettingChange_: function(value) { + if (!this.capability) + return; + const valueToSet = JSON.stringify(value); - for (const option of this.capability.option) { + for (const option of + /** @type {!Array<!print_preview_new.SelectOption>} */ ( + this.capability.option)) { if (JSON.stringify(option) == valueToSet) { this.$$('print-preview-settings-select').selectValue(valueToSet); return;
diff --git a/chrome/browser/resources/print_preview/new/model.js b/chrome/browser/resources/print_preview/new/model.js index a7ffc57..ac495e4 100644 --- a/chrome/browser/resources/print_preview/new/model.js +++ b/chrome/browser/resources/print_preview/new/model.js
@@ -391,6 +391,9 @@ /** @private */ updateHeaderFooterAvailable_: function() { + if (this.documentInfo === undefined) + return; + this.set( 'settings.headerFooter.available', this.isHeaderFooterAvailable_()); },
diff --git a/chrome/browser/resources/print_preview/new/pages_settings.js b/chrome/browser/resources/print_preview/new/pages_settings.js index 331116e2..96cc7c44 100644 --- a/chrome/browser/resources/print_preview/new/pages_settings.js +++ b/chrome/browser/resources/print_preview/new/pages_settings.js
@@ -76,7 +76,7 @@ }, observers: [ - 'onRangeChange_(errorState_, rangesToPrint_)', + 'onRangeChange_(errorState_, rangesToPrint_, settings.pages)', 'onRadioChange_(allSelected_, customSelected_)' ], @@ -235,6 +235,9 @@ * @private */ onRangeChange_: function() { + if (this.settings === undefined || this.pagesToPrint_ === undefined) + return; + if (this.errorState_ != PagesInputErrorState.NO_ERROR) { this.setSettingValid('pages', false); this.$.pageSettingsCustomInput.classList.add('invalid'); @@ -291,10 +294,11 @@ return loadTimeData.getStringF( 'pageRangeSyntaxInstruction', loadTimeData.getString('examplePageRangeText')); - } else { - return loadTimeData.getStringF( - 'pageRangeLimitInstructionWithValue', this.documentInfo.pageCount); } + return (this.documentInfo === undefined) ? + '' : + loadTimeData.getStringF( + 'pageRangeLimitInstructionWithValue', this.documentInfo.pageCount); }, /**
diff --git a/chrome/browser/resources/print_preview/new/search_dialog_css.html b/chrome/browser/resources/print_preview/new/search_dialog_css.html index 3868122..c94216f 100644 --- a/chrome/browser/resources/print_preview/new/search_dialog_css.html +++ b/chrome/browser/resources/print_preview/new/search_dialog_css.html
@@ -52,6 +52,8 @@ --cr-dialog-close-ripple: { display: none; }; + --primary-text-color: #333; + --secondary-text-color: #333; } #searchBox {
diff --git a/chrome/browser/resources/print_preview/print_preview_new.html b/chrome/browser/resources/print_preview/print_preview_new.html index b7a82538..cb2d303 100644 --- a/chrome/browser/resources/print_preview/print_preview_new.html +++ b/chrome/browser/resources/print_preview/print_preview_new.html
@@ -2,7 +2,6 @@ <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> - <title></title> <style> html { /* Remove 300ms delay for 'click' event, when using touch interface. */
diff --git a/chrome/browser/resources/print_preview/print_preview_utils.js b/chrome/browser/resources/print_preview/print_preview_utils.js index 0220810..1a14c6d 100644 --- a/chrome/browser/resources/print_preview/print_preview_utils.js +++ b/chrome/browser/resources/print_preview/print_preview_utils.js
@@ -241,3 +241,11 @@ return getStringForLocale(localizedStrings, navigator.language) || getStringForLocale(localizedStrings, navigator.language.split('-')[0]); } + +/** + * @param {!Array<*>} args The arguments for the observer. + * @return {boolean} Whether all arguments are defined. + */ +function observerDepsDefined(args) { + return args.every(arg => arg !== undefined); +}
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html index 2d8ac25..a369023 100644 --- a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
@@ -145,12 +145,7 @@ </paper-icon-button-light> </div> - <template is="dom-if" if="[[!showExperimentalFeatures_]]"> - <h2>$i18n{keyboardHeading}</h2> - </template> - <template is="dom-if" if="[[showExperimentalFeatures_]]"> - <h2>$i18n{keyboardAndTextInputHeading}</h2> - </template> + <h2>$i18n{keyboardAndTextInputHeading}</h2> <settings-toggle-button class="first" pref="{{prefs.settings.a11y.sticky_keys_enabled}}" label="$i18n{stickyKeysLabel}"> @@ -159,12 +154,10 @@ pref="{{prefs.settings.a11y.virtual_keyboard}}" label="$i18n{onScreenKeyboardLabel}"> </settings-toggle-button> - <template is="dom-if" if="[[showExperimentalFeatures_]]"> - <settings-toggle-button class="continuation" - pref="{{prefs.settings.a11y.dictation}}" - label="$i18n{dictationLabel}"> - </settings-toggle-button> - </template> + <settings-toggle-button class="continuation" + pref="{{prefs.settings.a11y.dictation}}" + label="$i18n{dictationLabel}"> + </settings-toggle-button> <settings-toggle-button class="continuation" pref="{{prefs.settings.a11y.focus_highlight}}" label="$i18n{focusHighlightLabel}">
diff --git a/chrome/browser/resources/settings/controls/settings_textarea.js b/chrome/browser/resources/settings/controls/settings_textarea.js index fe28e27..eb6ce0d 100644 --- a/chrome/browser/resources/settings/controls/settings_textarea.js +++ b/chrome/browser/resources/settings/controls/settings_textarea.js
@@ -30,7 +30,6 @@ hostAttributes: { 'aria-disabled': 'false', - role: 'textbox', }, listeners: {
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_browser_proxy.html b/chrome/browser/resources/settings/multidevice_page/multidevice_browser_proxy.html new file mode 100644 index 0000000..18e3b69 --- /dev/null +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_browser_proxy.html
@@ -0,0 +1,2 @@ +<link rel="import" href="chrome://resources/html/cr.html"> +<script src="multidevice_browser_proxy.js"></script>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_browser_proxy.js b/chrome/browser/resources/settings/multidevice_page/multidevice_browser_proxy.js new file mode 100644 index 0000000..05b5ce4 --- /dev/null +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_browser_proxy.js
@@ -0,0 +1,27 @@ +// 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. + +cr.define('settings', function() { + /** @interface */ + class MultiDeviceBrowserProxy { + showMultiDeviceSetupDialog() {} + } + + /** + * @implements {settings.MultiDeviceBrowserProxy} + */ + class MultiDeviceBrowserProxyImpl { + /** @override */ + showMultiDeviceSetupDialog() { + chrome.send('showMultiDeviceSetupDialog'); + } + } + + cr.addSingletonGetter(MultiDeviceBrowserProxyImpl); + + return { + MultiDeviceBrowserProxy: MultiDeviceBrowserProxy, + MultiDeviceBrowserProxyImpl: MultiDeviceBrowserProxyImpl, + }; +});
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html index 5af9a39..d7111c75 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.html +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.html
@@ -6,6 +6,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="multidevice_browser_proxy.html"> <dom-module id="settings-multidevice-page"> <template> @@ -19,7 +20,7 @@ </div> <div class="separator"></div> <template is="dom-if" if="[[showButton_(mode)]]" restamp> - <paper-button class="secondary-button"> + <paper-button class="secondary-button" on-click="handleClick_"> [[getButtonText_(mode)]] </paper-button> </template>
diff --git a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js index 358104e..c03c86b 100644 --- a/chrome/browser/resources/settings/multidevice_page/multidevice_page.js +++ b/chrome/browser/resources/settings/multidevice_page/multidevice_page.js
@@ -48,6 +48,14 @@ hostEnabled: Boolean, }, + /** @private {?settings.MultiDeviceBrowserProxy} */ + browserProxy_: null, + + /** @override */ + created: function() { + this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + }, + /** * @return {string} Translated item label. * @private @@ -90,7 +98,7 @@ case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: return this.i18n('multideviceVerifyButton'); default: - return null; + return ''; } }, @@ -109,4 +117,21 @@ showToggle_: function() { return this.mode == settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED; }, + + /** @private */ + handleClick_: function() { + switch (this.mode) { + case settings.MultiDeviceSettingsMode.NO_HOST_SET: + this.browserProxy_.showMultiDeviceSetupDialog(); + return; + case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER: + // TODO(jordynass): Implement this when API is ready. + console.log('Trying to connect to server again.'); + return; + case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: + // TODO(jordynass): Implement this when API is ready. + console.log('Trying to verify multidevice connection.'); + return; + } + }, });
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html index 352ba8f..8743074 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -90,22 +90,13 @@ </settings-sync-account-control> </template> </if> - <div class="settings-box first two-line" + <!-- A change of the unified consent toggle state is automatically handled + in the C++ code after a change in the pref is observed. --> + <settings-toggle-button class="first" pref="{{prefs.unified_consent_given}}" + label="$i18n{syncUnifiedConsentToggleTitle}" hidden="[[!unifiedConsentEnabled]]"> - <div class="start"> - <div>$i18n{syncUnifiedConsentToggleTitle}</div> - <div class="secondary">$i18n{syncUnifiedConsentToggleSubtitle}</div> - </div> - <!-- For now this toggle only turns on all sync services. - TODO(crbug.com/800974): Add custom function for turning - on all unified consent services.--> - <cr-toggle id="syncAllDataTypesControl" - checked="{{syncPrefs.syncAllDataTypes}}" - on-change="onSyncAllDataTypesChanged_" - aria-labelledby="syncUnifiedConsentToggleTitle"> - </cr-toggle> - </div> - <div class="settings-box first two-line" id="sync-section-toggle" + </settings-toggle-button> + <div class="settings-box two-line" id="sync-section-toggle" actionable$="[[!syncSectionDisabled_]]" on-click="toggleExpandButton_" hidden="[[!unifiedConsentEnabled]]"> @@ -423,7 +414,8 @@ opened="[[personalizeSectionOpened_]]"> <settings-personalization-options class="list-frame" prefs="{{prefs}}" page-visibility="[[pageVisibility]]" - unified-consent-enabled="[[unifiedConsentEnabled]]"> + unified-consent-enabled="[[unifiedConsentEnabled]]" + unified-consent-given="{{prefs.unified_consent_given.value}}"> </settings-personalization-options> </iron-collapse> </template>
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chrome/browser/resources/settings/privacy_page/personalization_options.html index 7f8265a3..a462ab4 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.html +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -24,36 +24,42 @@ </style> <settings-toggle-button pref="{{prefs.alternate_error_pages.enabled}}" label="$i18n{linkDoctorPref}" - sub-label="$i18n{linkDoctorPrefDesc}"> + sub-label="$i18n{linkDoctorPrefDesc}" + disabled="[[unifiedConsentGiven]]"> </settings-toggle-button> <settings-toggle-button hidden="[[!pageVisibility.searchPrediction]]" pref="{{prefs.search.suggest_enabled}}" label="$i18n{searchSuggestPref}" - sub-label="$i18n{searchSuggestPrefDesc}"> + sub-label="$i18n{searchSuggestPrefDesc}" + disabled="[[unifiedConsentGiven]]"> </settings-toggle-button> <settings-toggle-button id="safeBrowsingExtendedReportingControl" pref="[[safeBrowsingExtendedReportingPref_]]" label="$i18n{safeBrowsingEnableExtendedReporting}" sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}" on-settings-boolean-control-change="onSberChange_" - no-set-pref> + no-set-pref + disabled="[[unifiedConsentGiven]]"> </settings-toggle-button> <settings-toggle-button hidden="[[!pageVisibility.networkPrediction]]" pref="{{prefs.net.network_prediction_options}}" label="$i18n{networkPredictionEnabled}" sub-label="$i18n{networkPredictionEnabledDesc}" - numeric-unchecked-value="[[networkPredictionEnum_.NEVER]]"> + numeric-unchecked-value="[[networkPredictionEnum_.NEVER]]" + disabled="[[unifiedConsentGiven]]"> </settings-toggle-button> <settings-toggle-button pref="{{prefs.safebrowsing.enabled}}" label="$i18n{safeBrowsingEnableProtection}" - sub-label="$i18n{safeBrowsingEnableProtectionDesc}"> + sub-label="$i18n{safeBrowsingEnableProtectionDesc}" + disabled="[[unifiedConsentGiven]]"> </settings-toggle-button> <if expr="_google_chrome"> <template is="dom-if" if="[[!unifiedConsentEnabled]]"> <settings-toggle-button id="spellCheckControl" pref="{{prefs.spellcheck.use_spelling_service}}" label="$i18n{spellingPref}" - sub-label="$i18n{spellingDescription}"> + sub-label="$i18n{spellingDescription}" + disabled="[[unifiedConsentGiven]]"> </settings-toggle-button> </template> <template is="dom-if" if="[[unifiedConsentEnabled]]"> @@ -64,21 +70,24 @@ $i18nRaw{spellingDescription} </div> </div> - <cr-toggle checked="[[prefs.spellcheck.use_spelling_service]]" disabled> + <cr-toggle checked="[[prefs.spellcheck.use_spelling_service]]" + disabled="[[unifiedConsentGiven]]"> </cr-toggle> </div> </template> <if expr="chromeos"> <settings-toggle-button pref="{{prefs.cros.metrics.reportingEnabled}}" label="$i18n{enableLogging}" - sub-label="$i18n{enableLoggingDesc}"> + sub-label="$i18n{enableLoggingDesc}" + disabled="[[unifiedConsentGiven]]"> </settings-toggle-button> </if><!-- chromeos --> <if expr="not chromeos"> <settings-toggle-button id="metricsReportingControl" pref="[[metricsReportingPref_]]" label="$i18n{enableLogging}" sub-label="$i18n{enableLoggingDesc}" no-set-pref - on-settings-boolean-control-change="onMetricsReportingChange_"> + on-settings-boolean-control-change="onMetricsReportingChange_" + disabled="[[unifiedConsentGiven]]"> <template is="dom-if" if="[[showRestart_]]" restamp> <paper-button on-click="onRestartTap_" id="restart" slot="more-actions"> @@ -90,4 +99,4 @@ </if><!-- _google_chrome --> </template> <script src="personalization_options.js"></script> -</dom-module> \ No newline at end of file +</dom-module>
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.js b/chrome/browser/resources/settings/privacy_page/personalization_options.js index 3d5887b2..8ba2842 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.js +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.js
@@ -60,6 +60,8 @@ unifiedConsentEnabled: Boolean, + unifiedConsentGiven: Boolean, + // <if expr="_google_chrome and not chromeos"> // TODO(dbeam): make a virtual.* pref namespace and set/get this normally // (but handled differently in C++).
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.html b/chrome/browser/resources/settings/settings_page/settings_section.html index b171a2d..cd8e9a9c 100644 --- a/chrome/browser/resources/settings/settings_page/settings_section.html +++ b/chrome/browser/resources/settings/settings_page/settings_section.html
@@ -21,8 +21,13 @@ #header .title { @apply --cr-section-text; + font-size: 123%; + font-weight: 400; + letter-spacing: .25px; margin-bottom: 0; margin-top: var(--settings-page-vertical-margin); + padding-bottom: 4px; + padding-top: 8px; } #card {
diff --git a/chrome/browser/resources/settings/settings_page/settings_subpage.html b/chrome/browser/resources/settings/settings_page/settings_subpage.html index 928ab87..fa88313 100644 --- a/chrome/browser/resources/settings/settings_page/settings_subpage.html +++ b/chrome/browser/resources/settings/settings_page/settings_subpage.html
@@ -47,6 +47,7 @@ } h1 { + color: var(--google-grey-700); flex: 1; /* Push other items to the end. */ @apply --cr-title-text; }
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 8c66f49..29192ba 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -1293,6 +1293,12 @@ <structure name="IDR_SETTINGS_INTERNET_SUBPAGE_JS" file="internet_page/internet_subpage.js" type="chrome_html" /> + <structure name="IDR_SETTINGS_MULTIDEVICE_BROWSER_PROXY_HTML" + file="multidevice_page/multidevice_browser_proxy.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_MULTIDEVICE_BROWSER_PROXY_JS" + file="multidevice_page/multidevice_browser_proxy.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_MULTIDEVICE_PAGE_HTML" file="multidevice_page/multidevice_page.html" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index 2747d31..ff7c42c 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -20,7 +20,7 @@ h2 { align-items: center; align-self: flex-start; - color: var(--paper-grey-600); + color: var(--google-grey-900); display: flex; font-size: inherit; font-weight: 500; @@ -322,7 +322,7 @@ } .column-header { - color: var(--paper-grey-600); + color: var(--google-grey-600); font-weight: 500; }
diff --git a/chrome/browser/resources/settings/site_settings/BUILD.gn b/chrome/browser/resources/settings/site_settings/BUILD.gn index b7d2dca..c9332a9 100644 --- a/chrome/browser/resources/settings/site_settings/BUILD.gn +++ b/chrome/browser/resources/settings/site_settings/BUILD.gn
@@ -19,7 +19,6 @@ ":site_data_details_subpage", ":site_details", ":site_details_permission", - ":site_entry", ":site_list", ":site_settings_behavior", ":site_settings_prefs_browser_proxy", @@ -171,20 +170,6 @@ ] } -js_library("site_entry") { - deps = [ - ":constants", - ":site_settings_behavior", - "..:route", - "//third_party/polymer/v1_0/components-chromium/iron-collapse:iron-collapse-extracted", - "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", - "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render", - "//ui/webui/resources/js:assert", - "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:load_time_data", - ] -} - js_library("site_list") { deps = [ ":constants",
diff --git a/chrome/browser/resources/settings/site_settings/all_sites.js b/chrome/browser/resources/settings/site_settings/all_sites.js index f3b611f..2a395bc 100644 --- a/chrome/browser/resources/settings/site_settings/all_sites.js +++ b/chrome/browser/resources/settings/site_settings/all_sites.js
@@ -40,11 +40,42 @@ */ populateList_: function() { /** @type {!Array<settings.ContentSettingsTypes>} */ - const contentTypes = this.getCategoryList(); - // Make sure to include cookies, because All Sites handles data storage + - // cookies as well as regular settings.ContentSettingsTypes. - if (!contentTypes.includes(settings.ContentSettingsTypes.COOKIES)) - contentTypes.push(settings.ContentSettingsTypes.COOKIES); + let contentTypes = []; + const types = Object.values(settings.ContentSettingsTypes); + for (let i = 0; i < types.length; ++i) { + const type = types[i]; + // <if expr="not chromeos"> + if (type == settings.ContentSettingsTypes.PROTECTED_CONTENT) + continue; + // </if> + // Some categories store their data in a custom way. + if (type == settings.ContentSettingsTypes.PROTOCOL_HANDLERS || + type == settings.ContentSettingsTypes.ZOOM_LEVELS) { + continue; + } + // These categories are gated behind flags. + if (type == settings.ContentSettingsTypes.SENSORS && + !loadTimeData.getBoolean('enableSensorsContentSetting')) { + continue; + } + if (type == settings.ContentSettingsTypes.ADS && + !loadTimeData.getBoolean('enableSafeBrowsingSubresourceFilter')) { + continue; + } + if (type == settings.ContentSettingsTypes.SOUND && + !loadTimeData.getBoolean('enableSoundContentSetting')) { + continue; + } + if (type == settings.ContentSettingsTypes.CLIPBOARD && + !loadTimeData.getBoolean('enableClipboardContentSetting')) { + continue; + } + if (type == settings.ContentSettingsTypes.PAYMENT_HANDLER && + !loadTimeData.getBoolean('enablePaymentHandlerContentSetting')) { + continue; + } + contentTypes.push(type); + } this.browserProxy_.getAllSites(contentTypes).then((response) => { this.siteGroupList = response;
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html index ab798c7..dfbb6fff 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.html +++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -116,7 +116,8 @@ <site-details-permission category="{{ContentSettingsTypes.SENSORS}}" icon="settings:sensors" id="sensors" - label="$i18n{siteSettingsSensors}"> + label="$i18n{siteSettingsSensors}" + hidden$="[[!enableSensorsContentSetting_]]"> </site-details-permission> <site-details-permission category="{{ContentSettingsTypes.NOTIFICATIONS}}" icon="settings:notifications" id="notifications" @@ -138,7 +139,8 @@ <site-details-permission category="{{ContentSettingsTypes.ADS}}" icon="settings:ads" id="ads" - label="$i18n{siteSettingsAds}"> + label="$i18n{siteSettingsAds}" + hidden$="[[!enableSafeBrowsingSubresourceFilter_]]"> </site-details-permission> <site-details-permission category="{{ContentSettingsTypes.BACKGROUND_SYNC}}" @@ -147,7 +149,8 @@ </site-details-permission> <site-details-permission category="{{ContentSettingsTypes.SOUND}}" icon="settings:volume-up" id="sound" - label="$i18n{siteSettingsSound}"> + label="$i18n{siteSettingsSound}" + hidden$="[[!enableSoundContentSetting_]]"> </site-details-permission> <site-details-permission category="{{ContentSettingsTypes.AUTOMATIC_DOWNLOADS}}" @@ -177,12 +180,14 @@ <site-details-permission category="{{ContentSettingsTypes.CLIPBOARD}}" icon="settings:clipboard" id="clipboard" - label="$i18n{siteSettingsClipboard}"> + label="$i18n{siteSettingsClipboard}" + hidden$="[[!enableClipboardContentSetting_]]"> </site-details-permission> <site-details-permission category="{{ContentSettingsTypes.PAYMENT_HANDLER}}" icon="settings:payment-handler" id="paymentHandler" - label="$i18n{siteSettingsPaymentHandler}"> + label="$i18n{siteSettingsPaymentHandler}" + hidden$="[[!enablePaymentHandlerContentSetting_]]"> </site-details-permission> </div>
diff --git a/chrome/browser/resources/settings/site_settings/site_details.js b/chrome/browser/resources/settings/site_settings/site_details.js index 155cc28..a264b52 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.js +++ b/chrome/browser/resources/settings/site_settings/site_details.js
@@ -51,6 +51,47 @@ }, }, + /** @private */ + enableSafeBrowsingSubresourceFilter_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('enableSafeBrowsingSubresourceFilter'); + }, + }, + + /** @private */ + enableSoundContentSetting_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('enableSoundContentSetting'); + }, + }, + + /** @private */ + enableClipboardContentSetting_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('enableClipboardContentSetting'); + }, + }, + + /** @private */ + enableSensorsContentSetting_: { + type: Boolean, + readOnly: true, + value: function() { + return loadTimeData.getBoolean('enableSensorsContentSetting'); + }, + }, + + /** @private */ + enablePaymentHandlerContentSetting_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('enablePaymentHandlerContentSetting'); + }, + }, + /** * The type of storage for the origin. * @private @@ -103,7 +144,7 @@ if (this.enableSiteSettings_) this.$.usageApi.fetchUsageTotal(this.toUrl(this.origin).hostname); - this.updatePermissions_(this.getCategoryList()); + this.updatePermissions_(this.getCategoryList_()); } }); }, @@ -121,7 +162,7 @@ origin === undefined || origin == '') { return; } - if (!this.getCategoryList().includes(category)) + if (!this.getCategoryList_().includes(category)) return; // Site details currently doesn't support embedded origins, so ignore it and @@ -198,20 +239,20 @@ * Resets all permissions for the current origin. * @private */ - onResetSettings_: function(e) { + onResetSettings_: function() { this.browserProxy.setOriginPermissions( - this.origin, this.getCategoryList(), settings.ContentSetting.DEFAULT); - if (this.getCategoryList().includes(settings.ContentSettingsTypes.PLUGINS)) + this.origin, this.getCategoryList_(), settings.ContentSetting.DEFAULT); + if (this.getCategoryList_().includes(settings.ContentSettingsTypes.PLUGINS)) this.browserProxy.clearFlashPref(this.origin); - this.onCloseDialog_(e); + this.$.confirmResetSettings.close(); }, /** * Clears all data stored, except cookies, for the current origin. * @private */ - onClearStorage_: function(e) { + onClearStorage_: function() { // Since usage is only shown when "Site Settings" is enabled, don't clear it // when it's not shown. if (this.enableSiteSettings_ && this.storedData_ != '') { @@ -219,7 +260,7 @@ this.toUrl(this.origin).href, this.storageType_); } - this.onCloseDialog_(e); + this.$.confirmClearStorage.close(); }, /** @@ -234,6 +275,20 @@ }, /** + * Returns list of categories for each permission displayed in <site-details>. + * @return {!Array<!settings.ContentSettingsTypes>} + * @private + */ + getCategoryList_: function() { + const categoryList = []; + this.root.querySelectorAll('site-details-permission').forEach((element) => { + if (!element.hidden) + categoryList.push(element.category); + }); + return categoryList; + }, + + /** * Checks whether the permission list is standalone or has a heading. * @return {string} CSS class applied when the permission list has no heading. * @private
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.html b/chrome/browser/resources/settings/site_settings/site_details_permission.html index 76881dc..e2a3019 100644 --- a/chrome/browser/resources/settings/site_settings/site_details_permission.html +++ b/chrome/browser/resources/settings/site_settings/site_details_permission.html
@@ -12,7 +12,7 @@ <dom-module id="site-details-permission"> <template> <style include="settings-shared md-select"></style> - <div id="details" hidden$="[[shouldHideCategory_(category)]]"> + <div id="details"> <div id="permissionItem" class$="list-item [[permissionInfoStringClass_(site.source, category, site.setting)]]">
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.js b/chrome/browser/resources/settings/site_settings/site_details_permission.js index b40bd94..ce339395 100644 --- a/chrome/browser/resources/settings/site_settings/site_details_permission.js +++ b/chrome/browser/resources/settings/site_settings/site_details_permission.js
@@ -36,10 +36,6 @@ this.onDefaultSettingChanged_.bind(this)); }, - shouldHideCategory_: function(category) { - return !this.getCategoryList().includes(category); - }, - /** * Updates the drop-down value after |site| has changed. * @param {!RawSiteException} site The site to display.
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.html b/chrome/browser/resources/settings/site_settings/site_entry.html index f271018..3f9eb5d 100644 --- a/chrome/browser/resources/settings/site_settings/site_entry.html +++ b/chrome/browser/resources/settings/site_settings/site_entry.html
@@ -7,43 +7,20 @@ <dom-module id="site-entry"> <template> - <style include="settings-shared"> - .row-aligned { - display: flex; - flex-direction: row; - } - </style> + <style include="settings-shared"></style> <div id="collapseParent"> - <div class="settings-box list-item"> - <div id="toggleButton" class="start row-aligned" - on-click="toggleCollapsible_" actionable aria-expanded="false"> - <div class="favicon-image" - style$="[[getSiteGroupIcon_(siteGroup)]]"> - </div> - <div class="middle text-elide" id="displayName"> - [[displayName_]] - </div> - <div hidden$="[[!grouped_(siteGroup)]]"> - <paper-icon-button-light id="expandIcon" class="icon-expand-more"> - <button aria-label$="[[displayName_]]" - aria-describedby="displayName"></button> - </paper-icon-button-light> - </div> - <div hidden$="[[grouped_(siteGroup)]]"> - <paper-icon-button-light class="subpage-arrow"> - <button aria-label$="[[displayName_]]" - aria-describedby="displayName"></button> - </paper-icon-button-light> - </div> + <div id="toggleButton" class="settings-box list-item" + on-click="toggleCollapsible_" actionable aria-expanded="false"> + <div class="favicon-image" + style$="[[getSiteGroupIcon_(siteGroup)]]"> </div> - <div class="row-aligned" hidden$="[[!grouped_(siteGroup)]]"> - <div class="separator"></div> - <paper-icon-button-light class="icon-more-vert"> - <button id="overflowMenuButton" title="$i18n{moreActions}" - on-click="showOverflowMenu_"> - </button> - </paper-icon-button-light> + <div class="middle text-elide" id="displayName"> + [[displayName_(siteGroup)]] </div> + <paper-icon-button-light class="subpage-arrow"> + <button aria-label$="[[displayName_(siteGroup)]]" + aria-describedby="displayName"></button> + </paper-icon-button-light> </div> <iron-collapse id="collapseChild" no-animation> @@ -54,7 +31,7 @@ <div class="favicon-image" style$="[[computeSiteIcon(item)]]"> </div> - <div class="middle text-elide"> + <div class="middle text-elide" data-index="[[index]]"> [[item]] </div> </div> @@ -62,38 +39,6 @@ </div> </iron-collapse> </div> - - <!-- Overflow menu. --> - <cr-lazy-render id="menu"> - <template> - <cr-action-menu> - <button slot="item" class="dropdown-item" role="menuitem" - on-click="onConfirmResetSettings_"> - Reset permissions - </button> - </cr-action-menu> - </template> - </cr-lazy-render> - - <!-- Confirm reset settings dialog. --> - <cr-dialog id="confirmResetSettings" close-text="$i18n{close}"> - <div slot="title"> - $i18n{siteSettingsSiteGroupResetDialogTitle} - </div> - <div slot="body"> - [[getFormatString_( - '$i18nPolymer{siteSettingsSiteGroupResetConfirmation}', - displayName_)]] - </div> - <div slot="button-container"> - <paper-button class="cancel-button" on-click="onCloseDialog_"> - $i18n{cancel} - </paper-button> - <paper-button class="action-button" on-click="onResetSettings_"> - $i18n{siteSettingsSiteResetAll} - </paper-button> - </div> - </cr-dialog> </template> <script src="site_entry.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.js b/chrome/browser/resources/settings/site_settings/site_entry.js index 8b2a1db7..9ba76a6 100644 --- a/chrome/browser/resources/settings/site_settings/site_entry.js +++ b/chrome/browser/resources/settings/site_settings/site_entry.js
@@ -17,23 +17,13 @@ * An object representing a group of sites with the same eTLD+1. * @typedef {!SiteGroup} */ - siteGroup: { - type: Object, - observer: 'onSiteGroupChanged_', - }, - - /** - * The name to display beside the icon. If grouped_() is true, it will be - * the eTLD+1 for all the origins, otherwise, it will match the origin more - * closely in an appropriate site representation. - */ - displayName_: String, + siteGroup: Object, }, /** * Whether the list of origins displayed in this site-entry is a group of * eTLD+1 origins or not. - * @param {SiteGroup} siteGroup The eTLD+1 group of origins. + * @param {Array<Object>} siteGroup The eTLD+1 group of origins. * @return {boolean} * @private */ @@ -42,20 +32,25 @@ }, /** - * @param {SiteGroup} siteGroup The eTLD+1 group of origins. + * The name to display beside the icon. If grouped_() is true, it will return + * the eTLD+1 for all the origins, otherwise, it will return the origin in an + * appropriate site representation. + * @param {Array<Object>} siteGroup The eTLD+1 group of origins. + * @return {string} The name to display. * @private */ - onSiteGroupChanged_: function(siteGroup) { - // TODO(https://crbug.com/835712): Present the origin in a user-friendly - // site representation when ungrouped. - this.displayName_ = - this.grouped_(siteGroup) ? siteGroup.etldPlus1 : siteGroup.origins[0]; + displayName_: function(siteGroup) { + if (this.grouped_(siteGroup)) + return siteGroup.etldPlus1; + // TODO(https://crbug.com/835712): Return the origin in a user-friendly site + // representation. + return siteGroup.origins[0]; }, /** * Get an appropriate favicon that represents this group of eTLD+1 sites as a * whole. - * @param {SiteGroup} siteGroup The eTLD+1 group of origins. + * @param {Array<Object>} siteGroup The eTLD+1 group of origins. * @return {string} CSS to apply to show the appropriate favicon. * @private */ @@ -79,95 +74,28 @@ /** * A handler for selecting a site (by clicking on the origin). - * @param {!{model: !{index: !number}}} e + * @param {!{model: !{index: !number}}} event * @private */ - onOriginTap_: function(e) { - this.navigateToSiteDetails_(this.siteGroup.origins[e.model.index]); + onOriginTap_: function(event) { + this.navigateToSiteDetails_(this.siteGroup.origins[event.model.index]); }, /** * Toggles open and closed the list of origins if there is more than one, and * directly navigates to Site Details if there is only one site. - * @param {!Object} e + * @param {!Object} event * @private */ - toggleCollapsible_: function(e) { + toggleCollapsible_: function(event) { // Individual origins don't expand - just go straight to Site Details. if (!this.grouped_(this.siteGroup)) { this.navigateToSiteDetails_(this.siteGroup.origins[0]); return; } - let collapseChild = - /** @type {IronCollapseElement} */ (this.$.collapseChild); + let collapseChild = this.$.collapseChild; collapseChild.toggle(); this.$.toggleButton.setAttribute('aria-expanded', collapseChild.opened); - this.$.expandIcon.toggleClass('icon-expand-more'); - this.$.expandIcon.toggleClass('icon-expand-less'); - }, - - /** - * Retrieves the overflow menu. - * @private - */ - getOverflowMenu_: function() { - let menu = /** @type {?CrActionMenuElement} */ (this.$.menu.getIfExists()); - if (!menu) - menu = /** @type {!CrActionMenuElement} */ (this.$.menu.get()); - return menu; - }, - - /** - * Opens the overflow menu at event target. - * @param {!{target: Element}} e - * @private - */ - showOverflowMenu_: function(e) { - this.getOverflowMenu_().showAt(e.target); - }, - - /** @private */ - onCloseDialog_: function(e) { - e.target.closest('cr-dialog').close(); - this.getOverflowMenu_().close(); - }, - - /** - * Confirms the resetting of all content settings for an origin. - * @param {!{target: !Element}} e - * @private - */ - onConfirmResetSettings_: function(e) { - e.preventDefault(); - this.$.confirmResetSettings.showModal(); - }, - - /** - * Resets all permissions for all origins listed in |siteGroup.origins|. - * @param {!Event} e - * @private - */ - onResetSettings_: function(e) { - const contentSettingsTypes = this.getCategoryList(); - for (let i = 0; i < this.siteGroup.origins.length; ++i) { - const origin = this.siteGroup.origins[i]; - this.browserProxy.setOriginPermissions( - origin, contentSettingsTypes, settings.ContentSetting.DEFAULT); - if (contentSettingsTypes.includes(settings.ContentSettingsTypes.PLUGINS)) - this.browserProxy.clearFlashPref(origin); - } - this.onCloseDialog_(e); - }, - - /** - * Formats the |label| string with |name|, using $<num> as markers. - * @param {string} label - * @param {string} name - * @return {string} - * @private - */ - getFormatString_: function(label, name) { - return loadTimeData.substituteString(label, name); }, });
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js index 99315be..1c244c0b 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -32,18 +32,6 @@ category: String, /** - * A cached list of ContentSettingsTypes with a standard allow-block-ask - * pattern that are currently enabled for use. This property is the same - * across all elements with SiteSettingsBehavior ('static'). - * @type {Array<settings.ContentSettingsTypes>} - * @private - */ - contentTypes_: { - type: Array, - value: [], - }, - - /** * The browser proxy used to retrieve and change information about site * settings categories and the sites within. * @type {settings.SiteSettingsPrefsBrowserProxy} @@ -110,6 +98,7 @@ * Returns the icon to use for a given site. * @param {string} site The url of the site to fetch the icon for. * @return {string} The background-image style with the favicon. + * @private */ computeSiteIcon: function(site) { site = this.removePatternWildcard(site); @@ -181,56 +170,6 @@ }; }, - /** - * Returns list of categories for each setting.ContentSettingsTypes that are - * currently enabled. - * @return {!Array<!settings.ContentSettingsTypes>} - */ - getCategoryList: function() { - if (this.contentTypes_.length == 0) { - /** @type {!Array<settings.ContentSettingsTypes>} */ - for (let typeName in settings.ContentSettingsTypes) { - const contentType = settings.ContentSettingsTypes[typeName]; - // <if expr="not chromeos"> - if (contentType == settings.ContentSettingsTypes.PROTECTED_CONTENT) - continue; - // </if> - // Some categories store their data in a custom way. - if (contentType == settings.ContentSettingsTypes.COOKIES || - contentType == settings.ContentSettingsTypes.PROTOCOL_HANDLERS || - contentType == settings.ContentSettingsTypes.ZOOM_LEVELS) { - continue; - } - this.contentTypes_.push(contentType); - } - } - - const addOrRemoveSettingWithFlag = (type, flag) => { - if (loadTimeData.getBoolean(flag)) { - if (!this.contentTypes_.includes(type)) - this.contentTypes_.push(type); - } else { - if (this.contentTypes_.includes(type)) - this.contentTypes_.splice(this.contentTypes_.indexOf(type), 1); - } - }; - // These categories are gated behind flags. - addOrRemoveSettingWithFlag( - settings.ContentSettingsTypes.SENSORS, 'enableSensorsContentSetting'); - addOrRemoveSettingWithFlag( - settings.ContentSettingsTypes.ADS, - 'enableSafeBrowsingSubresourceFilter'); - addOrRemoveSettingWithFlag( - settings.ContentSettingsTypes.SOUND, 'enableSoundContentSetting'); - addOrRemoveSettingWithFlag( - settings.ContentSettingsTypes.CLIPBOARD, - 'enableClipboardContentSetting'); - addOrRemoveSettingWithFlag( - settings.ContentSettingsTypes.PAYMENT_HANDLER, - 'enablePaymentHandlerContentSetting'); - return this.contentTypes_.slice(0); - }, - }; /** @polymerBehavior */
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index eb522b51..fd8ebb751 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h" #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h" #include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/policy/chrome_browser_policy_connector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" @@ -32,6 +33,7 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/google/core/browser/google_util.h" #include "components/password_manager/core/browser/hash_password_manager.h" +#include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" @@ -183,6 +185,11 @@ password_manager::prefs::kPasswordHashDataList, base::Bind(&ChromePasswordProtectionService::CheckGaiaPasswordChange, base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kPasswordProtectionWarningTrigger, + base::BindRepeating( + &ChromePasswordProtectionService::OnWarningTriggerChanged, + base::Unretained(this))); password_manager::HashPasswordManager hash_password_manager; hash_password_manager.set_prefs(profile->GetPrefs()); base::Optional<password_manager::PasswordHashData> sync_hash_data = @@ -239,7 +246,8 @@ // static bool ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - content::WebContents* web_contents) { + content::WebContents* web_contents, + ReusedPasswordType password_type) { Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); ChromePasswordProtectionService* service = @@ -249,10 +257,10 @@ if (!service) return false; - // If there is unhandled enterprise password reuses, returns true. - if (service->HasUnhandledEnterprisePasswordReuse(web_contents)) - return true; + if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD) + return service->HasUnhandledEnterprisePasswordReuse(web_contents); + DCHECK_EQ(PasswordReuseEvent::SIGN_IN_PASSWORD, password_type); // Otherwise, checks if there's any unhandled sync password reuses matches // this origin. auto* unhandled_sync_password_reuses = profile->GetPrefs()->GetDictionary( @@ -309,6 +317,8 @@ const std::string& verdict_token, ReusedPasswordType password_type) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(password_type == PasswordReuseEvent::SIGN_IN_PASSWORD || + password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD); // Don't show warning again if there is already a modal warning showing. if (IsModalWarningShowingInWebContents(web_contents)) return; @@ -318,46 +328,62 @@ web_contents->ExitFullscreen(true); ShowPasswordReuseModalWarningDialog( - web_contents, this, + web_contents, this, password_type, base::BindOnce(&ChromePasswordProtectionService::OnUserAction, - base::Unretained(this), web_contents, + base::Unretained(this), web_contents, password_type, PasswordProtectionService::MODAL_DIALOG)); - OnModalWarningShown(web_contents, verdict_token, password_type); + if (password_type == PasswordReuseEvent::SIGN_IN_PASSWORD) + OnModalWarningShownForSignInPassword(web_contents, verdict_token); + else + OnModalWarningShownForEnterprisePassword(web_contents, verdict_token); } -void ChromePasswordProtectionService::OnModalWarningShown( +void ChromePasswordProtectionService::OnModalWarningShownForSignInPassword( content::WebContents* web_contents, - const std::string& verdict_token, - ReusedPasswordType password_type) { + const std::string& verdict_token) { RecordWarningAction(PasswordProtectionService::MODAL_DIALOG, - PasswordProtectionService::SHOWN); + PasswordProtectionService::SHOWN, + PasswordReuseEvent::SIGN_IN_PASSWORD); - GURL trigger_url = web_contents->GetLastCommittedURL(); - DCHECK(trigger_url.is_valid()); - OnPolicySpecifiedPasswordReuseDetected(trigger_url, - /*is_phishing_url=*/true); - if (password_type == PasswordReuseEvent::SIGN_IN_PASSWORD) { - DictionaryPrefUpdate update( - profile_->GetPrefs(), prefs::kSafeBrowsingUnhandledSyncPasswordReuses); - // Since base::Value doesn't support int64_t type, we convert the navigation - // ID to string format and store it in the preference dictionary. - update->SetKey( - Origin::Create(web_contents->GetLastCommittedURL()).Serialize(), - base::Value( - base::Int64ToString(GetLastCommittedNavigationID(web_contents)))); - } else if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD) { - web_contents_with_unhandled_enterprise_reuses_.insert(web_contents); + if (GetSyncAccountType() == PasswordReuseEvent::GSUITE) { + OnPolicySpecifiedPasswordReuseDetected(web_contents->GetLastCommittedURL(), + /*is_phishing_url=*/true); } + DictionaryPrefUpdate update(profile_->GetPrefs(), + prefs::kSafeBrowsingUnhandledSyncPasswordReuses); + // Since base::Value doesn't support int64_t type, we convert the navigation + // ID to string format and store it in the preference dictionary. + update->SetKey( + Origin::Create(web_contents->GetLastCommittedURL()).Serialize(), + base::Value( + base::Int64ToString(GetLastCommittedNavigationID(web_contents)))); - UpdateSecurityState(SB_THREAT_TYPE_PASSWORD_REUSE, web_contents); + UpdateSecurityState(SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE, web_contents); // Starts preparing post-warning report. - MaybeStartThreatDetailsCollection(web_contents, verdict_token); + MaybeStartThreatDetailsCollection(web_contents, verdict_token, + PasswordReuseEvent::SIGN_IN_PASSWORD); +} + +void ChromePasswordProtectionService::OnModalWarningShownForEnterprisePassword( + content::WebContents* web_contents, + const std::string& verdict_token) { + RecordWarningAction(PasswordProtectionService::MODAL_DIALOG, + PasswordProtectionService::SHOWN, + PasswordReuseEvent::ENTERPRISE_PASSWORD); + web_contents_with_unhandled_enterprise_reuses_.insert(web_contents); + UpdateSecurityState(SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE, web_contents); + // Starts preparing post-warning report. + MaybeStartThreatDetailsCollection(web_contents, verdict_token, + PasswordReuseEvent::ENTERPRISE_PASSWORD); } void ChromePasswordProtectionService::ShowInterstitial( - content::WebContents* web_contents) { + content::WebContents* web_contents, + ReusedPasswordType password_type) { + DCHECK(password_type == PasswordReuseEvent::SIGN_IN_PASSWORD || + password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD); DCHECK(base::FeatureList::IsEnabled(kEnterprisePasswordProtectionV1)); // Exit fullscreen if this |web_contents| is showing in fullscreen mode. if (web_contents->IsFullscreenForCurrentTab()) @@ -369,23 +395,42 @@ /*in_new_tab=*/true); RecordWarningAction(PasswordProtectionService::INTERSTITIAL, - PasswordProtectionService::SHOWN); + PasswordProtectionService::SHOWN, password_type); - OnPolicySpecifiedPasswordReuseDetected(trigger_url, - /*is_phishing_url=*/false); + if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD || + GetSyncAccountType() == PasswordReuseEvent::GSUITE) { + OnPolicySpecifiedPasswordReuseDetected(trigger_url, + /*is_phishing_url=*/false); + } } void ChromePasswordProtectionService::OnUserAction( content::WebContents* web_contents, + ReusedPasswordType password_type, PasswordProtectionService::WarningUIType ui_type, PasswordProtectionService::WarningAction action) { - RecordWarningAction(ui_type, action); + // TODO(jialiul): Find a way to pass |password_type| info to the + // chrome://reset-password page. For now, takes an educated guess. + // This info only impacts UMA tracking. + if (password_type == PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN) { + DCHECK_EQ(PasswordProtectionService::INTERSTITIAL, ui_type); + DCHECK_EQ(PasswordProtectionService::CHANGE_PASSWORD, action); + password_type = GetSyncAccountType() == PasswordReuseEvent::GSUITE + ? PasswordReuseEvent::SIGN_IN_PASSWORD + : PasswordReuseEvent::ENTERPRISE_PASSWORD; + } + + DCHECK(password_type == PasswordReuseEvent::SIGN_IN_PASSWORD || + password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD); + + RecordWarningAction(ui_type, action, password_type); + switch (ui_type) { case PasswordProtectionService::PAGE_INFO: - HandleUserActionOnPageInfo(web_contents, action); + HandleUserActionOnPageInfo(web_contents, password_type, action); break; case PasswordProtectionService::MODAL_DIALOG: - HandleUserActionOnModalWarning(web_contents, action); + HandleUserActionOnModalWarning(web_contents, password_type, action); break; case PasswordProtectionService::CHROME_SETTINGS: HandleUserActionOnSettings(web_contents, action); @@ -410,13 +455,16 @@ void ChromePasswordProtectionService::MaybeStartThreatDetailsCollection( content::WebContents* web_contents, - const std::string& token) { + const std::string& token, + ReusedPasswordType password_type) { // |trigger_manager_| can be null in test. if (!trigger_manager_) return; security_interstitials::UnsafeResource resource; - resource.threat_type = SB_THREAT_TYPE_PASSWORD_REUSE; + resource.threat_type = password_type == PasswordReuseEvent::SIGN_IN_PASSWORD + ? SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE + : SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE; resource.url = web_contents->GetLastCommittedURL(); resource.web_contents_getter = resource.GetWebContentsGetter( web_contents->GetMainFrame()->GetProcess()->GetID(), @@ -798,7 +846,8 @@ unhandled_sync_password_reuses->Clear(); for (auto& observer : observer_list_) observer.OnGaiaPasswordChanged(); - OnPolicySpecifiedPasswordChanged(); + if (GetSyncAccountType() == PasswordReuseEvent::GSUITE) + OnPolicySpecifiedPasswordChanged(); } bool ChromePasswordProtectionService::UserClickedThroughSBInterstitial( @@ -868,6 +917,7 @@ void ChromePasswordProtectionService::HandleUserActionOnModalWarning( content::WebContents* web_contents, + ReusedPasswordType password_type, PasswordProtectionService::WarningAction action) { const Origin origin = Origin::Create(web_contents->GetLastCommittedURL()); int64_t navigation_id = @@ -877,21 +927,20 @@ navigation_id, PasswordReuseDialogInteraction::WARNING_ACTION_TAKEN); // Directly open enterprise change password page for enterprise password // reuses. - if (HasUnhandledEnterprisePasswordReuse(web_contents)) { + if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD) { OpenUrl(web_contents, GetEnterpriseChangePasswordURL(), content::Referrer(), /*in_new_tab=*/true); web_contents_with_unhandled_enterprise_reuses_.erase(web_contents); // TODO(jialiul): Remove web_contents pointer when it is closed. - // TODO(jialiul): Add UMA tracking to record user action for enterprise - // password reuse. } else { // Opens chrome://settings page in a new tab. OpenUrl(web_contents, GURL(chrome::kChromeUISettingsURL), content::Referrer(), /*in_new_tab=*/true); RecordWarningAction(PasswordProtectionService::CHROME_SETTINGS, - PasswordProtectionService::SHOWN); + PasswordProtectionService::SHOWN, + PasswordReuseEvent::SIGN_IN_PASSWORD); } } else if (action == PasswordProtectionService::IGNORE_WARNING) { // No need to change state. @@ -913,6 +962,7 @@ void ChromePasswordProtectionService::HandleUserActionOnPageInfo( content::WebContents* web_contents, + ReusedPasswordType password_type, PasswordProtectionService::WarningAction action) { GURL url = web_contents->GetLastCommittedURL(); const Origin origin = Origin::Create(url); @@ -923,13 +973,11 @@ PasswordReuseDialogInteraction::WARNING_ACTION_TAKEN); // Directly open enterprise change password page in a new tab for enterprise // reuses. - if (HasUnhandledEnterprisePasswordReuse(web_contents)) { + if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD) { OpenUrl(web_contents, GetEnterpriseChangePasswordURL(), content::Referrer(), /*in_new_tab=*/true); web_contents_with_unhandled_enterprise_reuses_.erase(web_contents); - // TODO(jialiul): Add UMA tracking to record user action for enterprise - // password reuse. return; } @@ -937,7 +985,8 @@ OpenUrl(web_contents, GURL(chrome::kChromeUISettingsURL), content::Referrer(), /*in_new_tab=*/true); RecordWarningAction(PasswordProtectionService::CHROME_SETTINGS, - PasswordProtectionService::SHOWN); + PasswordProtectionService::SHOWN, + PasswordReuseEvent::SIGN_IN_PASSWORD); return; } @@ -945,7 +994,7 @@ // TODO(vakh): There's no good enum to report this dialog interaction. // This needs to be investigated. UpdateSecurityState(SB_THREAT_TYPE_SAFE, web_contents); - if (HasUnhandledEnterprisePasswordReuse(web_contents)) { + if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD) { web_contents_with_unhandled_enterprise_reuses_.erase(web_contents); } else { DictionaryPrefUpdate update( @@ -989,7 +1038,6 @@ content::Referrer(web_contents->GetLastCommittedURL(), blink::kWebReferrerPolicyDefault), /*in_new_tab=*/false); - web_contents_with_unhandled_enterprise_reuses_.erase(web_contents); } ChromePasswordProtectionService::ChromePasswordProtectionService( @@ -1066,11 +1114,21 @@ return false; } -base::string16 ChromePasswordProtectionService::GetWarningDetailText() { - if (!base::FeatureList::IsEnabled( - safe_browsing::kEnterprisePasswordProtectionV1) || - GetSyncAccountType() != safe_browsing::LoginReputationClientRequest:: - PasswordReuseEvent::GSUITE) { +base::string16 ChromePasswordProtectionService::GetWarningDetailText( + ReusedPasswordType password_type) const { + DCHECK(password_type == PasswordReuseEvent::SIGN_IN_PASSWORD || + password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD); + if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD) { + return base::FeatureList::IsEnabled( + safe_browsing::kEnterprisePasswordProtectionV1) + ? l10n_util::GetStringUTF16( + IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE) + : l10n_util::GetStringUTF16( + IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS); + } + + if (GetSyncAccountType() != + safe_browsing::LoginReputationClientRequest::PasswordReuseEvent::GSUITE) { return l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS); } @@ -1084,7 +1142,10 @@ IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE); } -std::string ChromePasswordProtectionService::GetOrganizationName() { +std::string ChromePasswordProtectionService::GetOrganizationName() const { + if (GetSyncAccountType() != PasswordReuseEvent::GSUITE) + return std::string(); + std::string email = GetAccountInfo().email; return email.empty() ? std::string() : gaia::ExtractDomainName(email); } @@ -1112,4 +1173,21 @@ web_contents_with_unhandled_enterprise_reuses_.end(); } +void ChromePasswordProtectionService::OnWarningTriggerChanged() { + if (GetPasswordProtectionWarningTriggerPref() != PASSWORD_PROTECTION_OFF) + return; + + // Clears captured enterprise password hashes or GSuite sync password hashes. + password_manager::HashPasswordManager hash_password_manager; + hash_password_manager.set_prefs(profile_->GetPrefs()); + if (GetSyncAccountType() == PasswordReuseEvent::GSUITE) { + hash_password_manager.ClearSavedPasswordHash(GetAccountInfo().email, + /*is_gaia_password=*/true); + } + hash_password_manager.ClearAllPasswordHash(/*is_gaia_password=*/false); + PasswordStoreFactory::GetForProfile(profile_, + ServiceAccessType::EXPLICIT_ACCESS) + ->SchedulePasswordHashUpdate(/*should_log_metrics*/ false); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.h b/chrome/browser/safe_browsing/chrome_password_protection_service.h index 59457517..aff705b 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.h +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.h
@@ -45,6 +45,7 @@ void ShowPasswordReuseModalWarningDialog( content::WebContents* web_contents, ChromePasswordProtectionService* service, + ReusedPasswordType password_type, OnWarningDone done_callback); // Called by ChromeContentBrowserClient to create a @@ -92,7 +93,8 @@ // Called by SecurityStateTabHelper to determine if page info bubble should // show password reuse warning. static bool ShouldShowPasswordReusePageInfoBubble( - content::WebContents* web_contents); + content::WebContents* web_contents, + ReusedPasswordType password_type); // Called by ChromeWebUIControllerFactory class to determine if Chrome should // show chrome://reset-password page. @@ -102,12 +104,14 @@ const std::string& verdict_token, ReusedPasswordType password_type) override; - void ShowInterstitial(content::WebContents* web_contens) override; + void ShowInterstitial(content::WebContents* web_contens, + ReusedPasswordType password_type) override; // Called when user interacts with password protection UIs. void OnUserAction(content::WebContents* web_contents, + ReusedPasswordType password_type, PasswordProtectionService::WarningUIType ui_type, - PasswordProtectionService::WarningAction action) override; + PasswordProtectionService::WarningAction action); // Called during the construction of Observer subclass. virtual void AddObserver(Observer* observer); @@ -118,7 +122,8 @@ // Starts collecting threat details if user has extended reporting enabled and // is not in incognito mode. void MaybeStartThreatDetailsCollection(content::WebContents* web_contents, - const std::string& token); + const std::string& token, + ReusedPasswordType password_type); // Sends threat details if user has extended reporting enabled and is not in // incognito mode. @@ -162,12 +167,12 @@ // Gets the detailed warning text that should show in the modal warning dialog // and page info bubble. - base::string16 GetWarningDetailText(); + base::string16 GetWarningDetailText(ReusedPasswordType password_type) const; // If password protection trigger is configured via enterprise policy, gets // the name of the organization that owns the enterprise policy. Otherwise, // returns an empty string. - std::string GetOrganizationName(); + std::string GetOrganizationName() const; // Triggers "safeBrowsingPrivate.OnPolicySpecifiedPasswordReuseDetected" // extension API for enterprise reporting. @@ -231,10 +236,12 @@ void HandleUserActionOnModalWarning( content::WebContents* web_contents, + ReusedPasswordType password_type, PasswordProtectionService::WarningAction action); void HandleUserActionOnPageInfo( content::WebContents* web_contents, + ReusedPasswordType password_type, PasswordProtectionService::WarningAction action); void HandleUserActionOnSettings( @@ -273,6 +280,10 @@ VerifyUnhandledSyncPasswordReuseUponClearHistoryDeletion); FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceBrowserTest, VerifyCheckGaiaPasswordChange); + FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceBrowserTest, + OnEnterpriseTriggerOff); + FRIEND_TEST_ALL_PREFIXES(ChromePasswordProtectionServiceBrowserTest, + OnEnterpriseTriggerOffGSuite); private: friend class MockChromePasswordProtectionService; @@ -311,9 +322,12 @@ sync_pb::UserEventSpecifics::GaiaPasswordReuse:: PasswordReuseDialogInteraction::InteractionResult interaction_result); - void OnModalWarningShown(content::WebContents* web_contents, - const std::string& verdict_token, - ReusedPasswordType password_type); + void OnModalWarningShownForSignInPassword(content::WebContents* web_contents, + const std::string& verdict_token); + + void OnModalWarningShownForEnterprisePassword( + content::WebContents* web_contents, + const std::string& verdict_token); // Constructor used for tests only. ChromePasswordProtectionService( @@ -321,6 +335,10 @@ scoped_refptr<HostContentSettingsMap> content_setting_map, scoped_refptr<SafeBrowsingUIManager> ui_manager); + // If enterprise admin turns off password protection, removes all captured + // enterprise password hashes. + void OnWarningTriggerChanged(); + scoped_refptr<SafeBrowsingUIManager> ui_manager_; TriggerManager* trigger_manager_; // Profile associated with this instance.
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc index 0693ddb0..6c1547fd 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
@@ -72,13 +72,6 @@ base::UTF8ToUTF16(new_password)); } - void SimulateAction(ChromePasswordProtectionService* service, - ChromePasswordProtectionService::WarningUIType ui_type, - ChromePasswordProtectionService::WarningAction action) { - service->OnUserAction(browser()->tab_strip_model()->GetActiveWebContents(), - ui_type, action); - } - void SimulateGaiaPasswordChanged(ChromePasswordProtectionService* service) { service->OnGaiaPasswordChanged(); } @@ -135,9 +128,11 @@ } void ConfigureEnterprisePasswordProtection( + bool is_gsuite, PasswordProtectionTrigger trigger_type) { scoped_features_.InitAndEnableFeature(kEnterprisePasswordProtectionV1); - PrepareSyncAccount("example.com", "stub-user@example.com"); + if (is_gsuite) + PrepareSyncAccount("example.com", "stub-user@example.com"); browser()->profile()->GetPrefs()->SetInteger( prefs::kPasswordProtectionWarningTrigger, trigger_type); browser()->profile()->GetPrefs()->SetString( @@ -153,7 +148,7 @@ }; IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTest, - SuccessfullyChangePassword) { + SuccessfullyChangeSignInPassword) { ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false); Profile* profile = browser()->profile(); content::WebContents* web_contents = @@ -166,7 +161,7 @@ ASSERT_EQ(1, browser()->tab_strip_model()->count()); ASSERT_FALSE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD)); GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::NONE, security_info.security_level); ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_NONE, @@ -181,12 +176,13 @@ profile)); GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::DANGEROUS, security_info.security_level); - ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE, security_info.malicious_content_status); // Simulates clicking "Change Password" button on the modal dialog. - SimulateAction(service, ChromePasswordProtectionService::MODAL_DIALOG, - ChromePasswordProtectionService::CHANGE_PASSWORD); + service->OnUserAction(web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD, + ChromePasswordProtectionService::MODAL_DIALOG, + ChromePasswordProtectionService::CHANGE_PASSWORD); content::WebContents* new_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::TestNavigationObserver observer(new_web_contents, @@ -198,8 +194,9 @@ new_web_contents->GetVisibleURL()); // Simulates clicking "Change password" button on the chrome://settings card. - SimulateAction(service, ChromePasswordProtectionService::CHROME_SETTINGS, - ChromePasswordProtectionService::CHANGE_PASSWORD); + service->OnUserAction(new_web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD, + ChromePasswordProtectionService::CHROME_SETTINGS, + ChromePasswordProtectionService::CHANGE_PASSWORD); base::RunLoop().RunUntilIdle(); // Verify myaccount.google.com or Google signin page should be opened in a // new foreground tab. @@ -235,7 +232,7 @@ ASSERT_EQ(1, browser()->tab_strip_model()->count()); ASSERT_FALSE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD)); GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::NONE, security_info.security_level); ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_NONE, @@ -247,34 +244,35 @@ base::RunLoop().RunUntilIdle(); ASSERT_TRUE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD)); GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::DANGEROUS, security_info.security_level); - ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE, security_info.malicious_content_status); // Simulates clicking "Ignore" button on the modal dialog. - SimulateAction(service, ChromePasswordProtectionService::MODAL_DIALOG, - ChromePasswordProtectionService::IGNORE_WARNING); + service->OnUserAction(web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD, + ChromePasswordProtectionService::MODAL_DIALOG, + ChromePasswordProtectionService::IGNORE_WARNING); base::RunLoop().RunUntilIdle(); // No new tab opens. SecurityInfo doesn't change. ASSERT_EQ(1, browser()->tab_strip_model()->count()); ASSERT_TRUE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD)); GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::DANGEROUS, security_info.security_level); - ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE, security_info.malicious_content_status); // Simulates clicking on "Mark site legitimate". Site is no longer dangerous. - service->OnUserAction(web_contents, + service->OnUserAction(web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD, ChromePasswordProtectionService::PAGE_INFO, ChromePasswordProtectionService::MARK_AS_LEGITIMATE); base::RunLoop().RunUntilIdle(); EXPECT_FALSE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD)); GetSecurityInfo(web_contents, &security_info); EXPECT_EQ(security_state::NONE, security_info.security_level); EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_NONE, @@ -295,22 +293,23 @@ PasswordReuseEvent::SIGN_IN_PASSWORD); base::RunLoop().RunUntilIdle(); // Simulates clicking "Ignore" to close dialog. - SimulateAction(service, ChromePasswordProtectionService::MODAL_DIALOG, - ChromePasswordProtectionService::IGNORE_WARNING); + service->OnUserAction(web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD, + ChromePasswordProtectionService::MODAL_DIALOG, + ChromePasswordProtectionService::IGNORE_WARNING); base::RunLoop().RunUntilIdle(); ASSERT_TRUE( ChromePasswordProtectionService::ShouldShowChangePasswordSettingUI( browser()->profile())); ASSERT_TRUE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD)); GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::DANGEROUS, security_info.security_level); - ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE, security_info.malicious_content_status); // Simulates clicking on "Change Password" in the page info bubble. - service->OnUserAction(web_contents, + service->OnUserAction(web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD, ChromePasswordProtectionService::PAGE_INFO, ChromePasswordProtectionService::CHANGE_PASSWORD); content::WebContents* new_web_contents = @@ -490,9 +489,9 @@ } IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTest, - PasswordAlertMode) { + GSuitePasswordAlertMode) { ConfigureEnterprisePasswordProtection( - PasswordProtectionTrigger::PASSWORD_REUSE); + /*is_gsuite=*/true, PasswordProtectionTrigger::PASSWORD_REUSE); ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false); ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL(kLoginPageUrl)); @@ -501,7 +500,7 @@ // Shows interstitial on current web_contents. content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - service->ShowInterstitial(web_contents); + service->ShowInterstitial(web_contents, PasswordReuseEvent::SIGN_IN_PASSWORD); content::WebContents* new_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::TestNavigationObserver observer(new_web_contents, @@ -528,15 +527,16 @@ ->GetActiveWebContents() ->GetLastCommittedURL(), embedded_test_server()->GetURL(kChangePasswordUrl)); - EXPECT_THAT(histograms.GetAllSamples( - "PasswordProtection.InterstitialAction.SyncPasswordEntry"), - testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 1))); + EXPECT_THAT( + histograms.GetAllSamples( + "PasswordProtection.InterstitialAction.GSuiteSyncPasswordEntry"), + testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 1))); } IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTest, EnterprisePhishingReuseMode) { ConfigureEnterprisePasswordProtection( - PasswordProtectionTrigger::PHISHING_REUSE); + /*is_gsuite=*/false, PasswordProtectionTrigger::PHISHING_REUSE); ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false); Profile* profile = browser()->profile(); content::WebContents* web_contents = @@ -552,19 +552,20 @@ // Enterprise password reuse should not trigger warning in Chrome settings UI. ASSERT_TRUE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::ENTERPRISE_PASSWORD)); ASSERT_FALSE( ChromePasswordProtectionService::ShouldShowChangePasswordSettingUI( profile)); // Security info should be properly updated. GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::DANGEROUS, security_info.security_level); - ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE, security_info.malicious_content_status); // Simulates clicking "Change Password" button on the modal dialog. - SimulateAction(service, ChromePasswordProtectionService::MODAL_DIALOG, - ChromePasswordProtectionService::CHANGE_PASSWORD); + service->OnUserAction(web_contents, PasswordReuseEvent::ENTERPRISE_PASSWORD, + ChromePasswordProtectionService::MODAL_DIALOG, + ChromePasswordProtectionService::CHANGE_PASSWORD); base::RunLoop().RunUntilIdle(); content::WebContents* new_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -577,7 +578,7 @@ IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTest, EnterprisePhishingReuseMarkSiteAsLegitimate) { ConfigureEnterprisePasswordProtection( - PasswordProtectionTrigger::PHISHING_REUSE); + /*is_gsuite=*/false, PasswordProtectionTrigger::PHISHING_REUSE); ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -591,17 +592,17 @@ base::RunLoop().RunUntilIdle(); GetSecurityInfo(web_contents, &security_info); ASSERT_EQ(security_state::DANGEROUS, security_info.security_level); - ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE, security_info.malicious_content_status); // Simulates clicking on "Mark site legitimate". Site is no longer dangerous. - service->OnUserAction(web_contents, + service->OnUserAction(web_contents, PasswordReuseEvent::ENTERPRISE_PASSWORD, ChromePasswordProtectionService::PAGE_INFO, ChromePasswordProtectionService::MARK_AS_LEGITIMATE); base::RunLoop().RunUntilIdle(); EXPECT_FALSE( ChromePasswordProtectionService::ShouldShowPasswordReusePageInfoBubble( - web_contents)); + web_contents, PasswordReuseEvent::ENTERPRISE_PASSWORD)); GetSecurityInfo(web_contents, &security_info); EXPECT_EQ(security_state::NONE, security_info.security_level); EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_NONE, @@ -611,7 +612,7 @@ IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTest, EnterprisePhishingReuseOpenChromeSettingsViaPageInfo) { ConfigureEnterprisePasswordProtection( - PasswordProtectionTrigger::PHISHING_REUSE); + /*is_gsuite=*/false, PasswordProtectionTrigger::PHISHING_REUSE); ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -625,7 +626,7 @@ base::RunLoop().RunUntilIdle(); // Simulates clicking on "Change Password" in the page info bubble. - service->OnUserAction(web_contents, + service->OnUserAction(web_contents, PasswordReuseEvent::ENTERPRISE_PASSWORD, ChromePasswordProtectionService::PAGE_INFO, ChromePasswordProtectionService::CHANGE_PASSWORD); base::RunLoop().RunUntilIdle(); @@ -642,4 +643,65 @@ security_info.malicious_content_status); } +IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTest, + OnEnterpriseTriggerOffGSuite) { + ConfigureEnterprisePasswordProtection( + /*is_gsuite=*/true, PasswordProtectionTrigger::PHISHING_REUSE); + Profile* profile = browser()->profile(); + ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false); + password_manager::HashPasswordManager hash_password_manager; + hash_password_manager.set_prefs(profile->GetPrefs()); + hash_password_manager.SavePasswordHash(service->GetAccountInfo().email, + base::UTF8ToUTF16("password"), + /*is_gaia_password=*/true); + ASSERT_EQ(1u, profile->GetPrefs() + ->GetList(password_manager::prefs::kPasswordHashDataList) + ->GetList() + .size()); + + // Turn off trigger + profile->GetPrefs()->SetInteger( + prefs::kPasswordProtectionWarningTrigger, + PasswordProtectionTrigger::PASSWORD_PROTECTION_OFF); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(hash_password_manager.HasPasswordHash( + service->GetAccountInfo().email, /*is_gaia_password=*/true)); + EXPECT_EQ(0u, profile->GetPrefs() + ->GetList(password_manager::prefs::kPasswordHashDataList) + ->GetList() + .size()); +} + +IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTest, + OnEnterpriseTriggerOff) { + ConfigureEnterprisePasswordProtection( + /*is_gsuite=*/false, PasswordProtectionTrigger::PHISHING_REUSE); + Profile* profile = browser()->profile(); + password_manager::HashPasswordManager hash_password_manager; + hash_password_manager.set_prefs(profile->GetPrefs()); + hash_password_manager.SavePasswordHash( + "username", base::UTF8ToUTF16("password"), /*is_gaia_password=*/false); + hash_password_manager.SavePasswordHash("foo@gmail.com", + base::UTF8ToUTF16("password"), + /*is_gaia_password=*/true); + ASSERT_EQ(2u, profile->GetPrefs() + ->GetList(password_manager::prefs::kPasswordHashDataList) + ->GetList() + .size()); + + // Turn off trigger + profile->GetPrefs()->SetInteger( + prefs::kPasswordProtectionWarningTrigger, + PasswordProtectionTrigger::PASSWORD_PROTECTION_OFF); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(hash_password_manager.HasPasswordHash( + "username", /*is_gaia_password=*/false)); + EXPECT_TRUE(hash_password_manager.HasPasswordHash("foo@gmail.com", + /*is_gaia_password=*/true)); + EXPECT_EQ(1u, profile->GetPrefs() + ->GetList(password_manager::prefs::kPasswordHashDataList) + ->GetList() + .size()); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index 3d3cb49..a8a7dc5 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h" #include "chrome/browser/safe_browsing/test_extension_event_observer.h" @@ -37,6 +38,7 @@ #include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_manager_base.h" +#include "components/strings/grit/components_strings.h" #include "components/sync/user_events/fake_user_event_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/variations/variations_params_manager.h" @@ -47,6 +49,7 @@ #include "net/http/http_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" using sync_pb::UserEventSpecifics; using GaiaPasswordReuse = UserEventSpecifics::GaiaPasswordReuse; @@ -67,8 +70,9 @@ const char kPhishingURL[] = "http://phishing.com/"; const char kPasswordReuseURL[] = "http://login.example.com/"; -const char kTestAccountID[] = "account_id"; +const char kTestGaiaID[] = "gaia_id"; const char kTestEmail[] = "foo@example.com"; +const char kTestGmail[] = "foo@gmail.com"; const char kBasicResponseHeaders[] = "HTTP/1.1 200 OK"; const char kRedirectURL[] = "http://redirect.com"; @@ -225,7 +229,7 @@ } void SetUpSyncAccount(const std::string& hosted_domain, - const std::string& account_id, + const std::string& gaia_id, const std::string& email) { FakeAccountFetcherService* account_fetcher_service = static_cast<FakeAccountFetcherService*>( @@ -233,8 +237,8 @@ AccountTrackerService* account_tracker_service = AccountTrackerServiceFactory::GetForProfile(profile()); account_fetcher_service->FakeUserInfoFetchSuccess( - account_tracker_service->PickAccountIdForAccount(account_id, email), - email, account_id, hosted_domain, "full_name", "given_name", "locale", + account_tracker_service->PickAccountIdForAccount(gaia_id, email), email, + gaia_id, hosted_domain, "full_name", "given_name", "locale", "http://picture.example.com/picture.jpg"); } @@ -305,9 +309,9 @@ TEST_F(ChromePasswordProtectionServiceTest, VerifyUserPopulationForProtectedPasswordEntryPing) { SigninManagerFactory::GetForProfile(profile())->SetAuthenticatedAccountInfo( - kTestAccountID, kTestEmail); + kTestGaiaID, kTestEmail); SetUpSyncAccount(std::string(AccountTrackerService::kNoHostedDomainFound), - std::string(kTestAccountID), std::string(kTestEmail)); + std::string(kTestGaiaID), std::string(kTestEmail)); // Protected password entry pinging is enabled by default. PasswordProtectionService::RequestOutcome reason; @@ -401,19 +405,27 @@ EXPECT_EQ(PasswordProtectionService::MATCHED_ENTERPRISE_LOGIN_URL, reason); } -TEST_F(ChromePasswordProtectionServiceTest, VerifyGetSyncAccountType) { +TEST_F(ChromePasswordProtectionServiceTest, VerifyGetSyncAccountTypeGmail) { EXPECT_EQ(PasswordReuseEvent::NOT_SIGNED_IN, service_->GetSyncAccountType()); EXPECT_TRUE(service_->GetOrganizationName().empty()); SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestGmail); SetUpSyncAccount(std::string(AccountTrackerService::kNoHostedDomainFound), - std::string(kTestAccountID), - std::string(kTestEmail /*foo@example.com*/)); + std::string(kTestGaiaID), + std::string(kTestGmail /*foo@gmail.com*/)); EXPECT_EQ(PasswordReuseEvent::GMAIL, service_->GetSyncAccountType()); - EXPECT_EQ("example.com", service_->GetOrganizationName()); + EXPECT_EQ("", service_->GetOrganizationName()); +} - SetUpSyncAccount("example.edu", std::string(kTestAccountID), +TEST_F(ChromePasswordProtectionServiceTest, VerifyGetSyncAccountTypeGSuite) { + EXPECT_EQ(PasswordReuseEvent::NOT_SIGNED_IN, service_->GetSyncAccountType()); + EXPECT_TRUE(service_->GetOrganizationName().empty()); + SigninManagerBase* signin_manager = + SigninManagerFactory::GetForProfile(profile()); + + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); + SetUpSyncAccount("example.com", std::string(kTestGaiaID), std::string(kTestEmail /*foo@example.com*/)); EXPECT_EQ(PasswordReuseEvent::GSUITE, service_->GetSyncAccountType()); EXPECT_EQ("example.com", service_->GetOrganizationName()); @@ -437,11 +449,12 @@ LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &verdict_proto, base::Time::Now()); - service_->UpdateSecurityState(SB_THREAT_TYPE_PASSWORD_REUSE, web_contents()); + service_->UpdateSecurityState(SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE, + web_contents()); ASSERT_TRUE(service_->ui_manager()->IsUrlWhitelistedOrPendingForWebContents( url, false, web_contents()->GetController().GetLastCommittedEntry(), web_contents(), false, ¤t_threat_type)); - EXPECT_EQ(SB_THREAT_TYPE_PASSWORD_REUSE, current_threat_type); + EXPECT_EQ(SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE, current_threat_type); service_->UpdateSecurityState(safe_browsing::SB_THREAT_TYPE_SAFE, web_contents()); @@ -490,9 +503,9 @@ // Configure sync account type to GMAIL. SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); SetUpSyncAccount(std::string(AccountTrackerService::kNoHostedDomainFound), - std::string(kTestAccountID), std::string(kTestEmail)); + std::string(kTestGaiaID), std::string(kTestEmail)); EXPECT_EQ(PasswordReuseEvent::GMAIL, service_->GetSyncAccountType()); NavigateAndCommit(GURL("https://www.example.com/")); @@ -524,9 +537,9 @@ // Configure sync account type to GMAIL. SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); SetUpSyncAccount(std::string(AccountTrackerService::kNoHostedDomainFound), - std::string(kTestAccountID), std::string(kTestEmail)); + std::string(kTestGaiaID), std::string(kTestEmail)); EXPECT_EQ(PasswordReuseEvent::GMAIL, service_->GetSyncAccountType()); NavigateAndCommit(GURL("https://www.example.com/")); @@ -589,8 +602,8 @@ TEST_F(ChromePasswordProtectionServiceTest, VerifyGetDefaultChangePasswordURL) { SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); - SetUpSyncAccount("example.com", std::string(kTestAccountID), + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); + SetUpSyncAccount("example.com", std::string(kTestGaiaID), std::string(kTestEmail)); EXPECT_EQ(GURL("https://accounts.google.com/" "AccountChooser?Email=foo%40example.com&continue=https%3A%2F%" @@ -764,8 +777,8 @@ // Preparing sync account. SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); - SetUpSyncAccount("example.com", std::string(kTestAccountID), + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); + SetUpSyncAccount("example.com", std::string(kTestGaiaID), std::string(kTestEmail)); // Simulates change password. @@ -794,8 +807,8 @@ scoped_features.InitAndEnableFeature(kEnterprisePasswordProtectionV1); SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); - SetUpSyncAccount("example.com", std::string(kTestAccountID), + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); + SetUpSyncAccount("example.com", std::string(kTestGaiaID), std::string(kTestEmail)); profile()->GetPrefs()->SetInteger(prefs::kPasswordProtectionWarningTrigger, PASSWORD_REUSE); @@ -832,14 +845,14 @@ scoped_features.InitAndEnableFeature(kEnterprisePasswordProtectionV1); SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(profile()); - signin_manager->SetAuthenticatedAccountInfo(kTestAccountID, kTestEmail); - SetUpSyncAccount("example.com", std::string(kTestAccountID), + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); + SetUpSyncAccount("example.com", std::string(kTestGaiaID), std::string(kTestEmail)); profile()->GetPrefs()->SetInteger(prefs::kPasswordProtectionWarningTrigger, PASSWORD_REUSE); NavigateAndCommit(GURL(kPhishingURL)); - service_->OnModalWarningShown(web_contents(), "verdict_token", - PasswordReuseEvent::SIGN_IN_PASSWORD); + service_->OnModalWarningShownForSignInPassword(web_contents(), + "verdict_token"); base::RunLoop().RunUntilIdle(); ASSERT_EQ(1, test_event_router_->GetEventCount( @@ -851,11 +864,85 @@ // If user is in incognito mode, no event should be sent. service_->ConfigService(true /*incognito*/, false /*SBER*/); - service_->OnModalWarningShown(web_contents(), "verdict_token", - PasswordReuseEvent::SIGN_IN_PASSWORD); + service_->OnModalWarningShownForSignInPassword(web_contents(), + "verdict_token"); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, test_event_router_->GetEventCount( OnPolicySpecifiedPasswordReuseDetected::kEventName)); } +TEST_F(ChromePasswordProtectionServiceTest, + VerifyGetWarningDetailTextEnterprise) { + base::string16 default_warning_text = + l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS); + base::string16 generic_enterprise_warning_text = l10n_util::GetStringUTF16( + IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE); + base::string16 warning_text_with_org_name = l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE_WITH_ORG_NAME, + base::UTF8ToUTF16("example.com")); + EXPECT_EQ(PasswordReuseEvent::NOT_SIGNED_IN, service_->GetSyncAccountType()); + EXPECT_TRUE(service_->GetOrganizationName().empty()); + EXPECT_EQ(default_warning_text, service_->GetWarningDetailText( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_EQ(default_warning_text, service_->GetWarningDetailText( + PasswordReuseEvent::ENTERPRISE_PASSWORD)); + + // Enables kEnterprisePasswordProtectionV1 feature. + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndEnableFeature(kEnterprisePasswordProtectionV1); + EXPECT_EQ(default_warning_text, service_->GetWarningDetailText( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_EQ( + generic_enterprise_warning_text, + service_->GetWarningDetailText(PasswordReuseEvent::ENTERPRISE_PASSWORD)); + + // Signs in as a GSuite user. + SigninManagerBase* signin_manager = + SigninManagerFactory::GetForProfile(profile()); + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestEmail); + SetUpSyncAccount(std::string("example.com"), std::string(kTestGaiaID), + std::string(kTestEmail /*foo@example.com*/)); + EXPECT_EQ(PasswordReuseEvent::GSUITE, service_->GetSyncAccountType()); + EXPECT_EQ( + warning_text_with_org_name, + service_->GetWarningDetailText(PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_EQ( + generic_enterprise_warning_text, + service_->GetWarningDetailText(PasswordReuseEvent::ENTERPRISE_PASSWORD)); +} + +TEST_F(ChromePasswordProtectionServiceTest, VerifyGetWarningDetailTextGmail) { + base::string16 default_warning_text = + l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS); + base::string16 generic_enterprise_warning_text = l10n_util::GetStringUTF16( + IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE); + EXPECT_EQ(default_warning_text, service_->GetWarningDetailText( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_EQ(default_warning_text, service_->GetWarningDetailText( + PasswordReuseEvent::ENTERPRISE_PASSWORD)); + + // Enables kEnterprisePasswordProtectionV1 feature. + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndEnableFeature(kEnterprisePasswordProtectionV1); + EXPECT_EQ(default_warning_text, service_->GetWarningDetailText( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_EQ( + generic_enterprise_warning_text, + service_->GetWarningDetailText(PasswordReuseEvent::ENTERPRISE_PASSWORD)); + + // Signs in as a Gmail user. + SigninManagerBase* signin_manager = + SigninManagerFactory::GetForProfile(profile()); + signin_manager->SetAuthenticatedAccountInfo(kTestGaiaID, kTestGmail); + SetUpSyncAccount(std::string(AccountTrackerService::kNoHostedDomainFound), + std::string(kTestGaiaID), + std::string(kTestGmail /*foo@gmail.com*/)); + EXPECT_EQ(PasswordReuseEvent::GMAIL, service_->GetSyncAccountType()); + EXPECT_EQ(default_warning_text, service_->GetWarningDetailText( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_EQ( + generic_enterprise_warning_text, + service_->GetWarningDetailText(PasswordReuseEvent::ENTERPRISE_PASSWORD)); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc index b83d181..e13eb10 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
@@ -696,6 +696,8 @@ std::make_unique<std::vector<uint8_t>>(results.signature_blob); } + detached_code_signatures_.CopyFrom(results.detached_code_signatures); + // Even if !results.success, some of the DMG may have been parsed. archive_is_valid_ = (results.success ? ArchiveValid::VALID : ArchiveValid::INVALID); @@ -974,11 +976,17 @@ "SBClientDownload." "DownloadFileHasDmgSignature", disk_image_signature_ != nullptr); + UMA_HISTOGRAM_BOOLEAN("SBClientDownload.DownloadFileHasDetachedSignatures", + !detached_code_signatures_.empty()); if (disk_image_signature_) { request->set_udif_code_signature(disk_image_signature_->data(), disk_image_signature_->size()); } + if (!detached_code_signatures_.empty()) { + request->mutable_detached_code_signature()->Swap( + &detached_code_signatures_); + } #endif if (archive_is_valid_ != ArchiveValid::UNSET)
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h index 8c6b2c91..8dfc128 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h
@@ -133,6 +133,9 @@ #if defined(OS_MACOSX) std::unique_ptr<std::vector<uint8_t>> disk_image_signature_; + google::protobuf::RepeatedPtrField< + ClientDownloadRequest_DetachedCodeSignature> + detached_code_signatures_; #endif ClientDownloadRequest_SignatureInfo signature_info_;
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc index 9a901881..9003b3b3 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -1641,6 +1641,66 @@ Mock::VerifyAndClearExpectations(binary_feature_extractor_.get()); } +// Verifies the results of DMG analysis end-to-end. +TEST_F(DownloadProtectionServiceTest, DMGAnalysisEndToEnd) { + PrepareResponse(ClientDownloadResponse::SAFE, net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + + base::FilePath dmg; + EXPECT_TRUE(base::PathService::Get(chrome::DIR_GEN_TEST_DATA, &dmg)); + dmg = dmg.AppendASCII("chrome") + .AppendASCII("safe_browsing_dmg") + .AppendASCII("mach_o_in_dmg.dmg"); + + NiceMockDownloadItem item; + PrepareBasicDownloadItemWithFullPaths( + &item, {"http://www.evil.com/a.dmg"}, // url_chain + "http://www.google.com/", // referrer + dmg, // tmp_path + temp_dir_.GetPath().Append(FILE_PATH_LITERAL("a.dmg"))); // final_path + + RunLoop run_loop; + download_service_->CheckClientDownload( + &item, + base::BindRepeating(&DownloadProtectionServiceTest::CheckDoneCallback, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + + ASSERT_TRUE(HasClientDownloadRequest()); + + auto* request = GetClientDownloadRequest(); + + EXPECT_TRUE(request->archive_valid()); + EXPECT_FALSE(request->has_udif_code_signature()); + EXPECT_EQ(ClientDownloadRequest_DownloadType_MAC_EXECUTABLE, + request->download_type()); + + ASSERT_EQ(2, request->archived_binary().size()); + for (const auto& binary : request->archived_binary()) { + EXPECT_FALSE(binary.file_basename().empty()); + EXPECT_EQ(ClientDownloadRequest_DownloadType_MAC_EXECUTABLE, + binary.download_type()); + ASSERT_TRUE(binary.has_digests()); + EXPECT_TRUE(binary.digests().has_sha256()); + EXPECT_TRUE(binary.has_length()); + ASSERT_TRUE(binary.has_image_headers()); + ASSERT_FALSE(binary.image_headers().mach_o_headers().empty()); + EXPECT_FALSE( + binary.image_headers().mach_o_headers().Get(0).mach_header().empty()); + EXPECT_FALSE( + binary.image_headers().mach_o_headers().Get(0).load_commands().empty()); + } + + ASSERT_EQ(1, request->detached_code_signature().size()); + EXPECT_FALSE(request->detached_code_signature().Get(0).file_name().empty()); + EXPECT_FALSE(request->detached_code_signature().Get(0).contents().empty()); + + ClearClientDownloadRequest(); + + Mock::VerifyAndClearExpectations(sb_service_.get()); + Mock::VerifyAndClearExpectations(binary_feature_extractor_.get()); +} + #endif // OS_MACOSX TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) {
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc index d9d2292..78a53c4 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -4,7 +4,6 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/download/download_prefs.h" @@ -2327,7 +2326,6 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, AppendRecentNavigationsToEmptyReferrerChain) { - base::test::ScopedFeatureList scoped_feature_list; ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL(kSingleFrameTestURL)); GURL initial_url = embedded_test_server()->GetURL(kSingleFrameTestURL);
diff --git a/chrome/browser/safe_json_parser_browsertest.cc b/chrome/browser/safe_json_parser_browsertest.cc index 851a456..94475fd4 100644 --- a/chrome/browser/safe_json_parser_browsertest.cc +++ b/chrome/browser/safe_json_parser_browsertest.cc
@@ -7,7 +7,9 @@ #include "base/bind.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" +#include "base/macros.h" #include "base/run_loop.h" +#include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/test_service_manager_listener.h" @@ -24,6 +26,8 @@ using data_decoder::SafeJsonParser; +constexpr char kTestJson[] = "[\"awesome\", \"possum\"]"; + std::string MaybeToJson(const base::Value* value) { if (!value) return "(null)"; @@ -35,32 +39,22 @@ return json; } -class ParseCallback { - public: - explicit ParseCallback(base::Closure callback) : callback_(callback) {} - - void OnSuccess(std::unique_ptr<base::Value> value) { - success_ = true; - callback_.Run(); - } - - void OnError(const std::string& error) { - success_ = false; - callback_.Run(); - } - - bool success() const { return success_; } - - private: - bool success_ = false; - base::Closure callback_; - - DISALLOW_COPY_AND_ASSIGN(ParseCallback); -}; - class SafeJsonParserTest : public InProcessBrowserTest { + public: + SafeJsonParserTest() = default; + protected: - void TestParse(const std::string& json) { + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + + listener_.Init(); + } + + // Tests SafeJsonParser::Parse/ParseBatch. Parses |json| using SafeJsonParser + // and verifies that the correct callbacks are called. If |batch_id| is not + // empty, uses SafeJsonParser::ParseBatch to batch multiple parse requests. + void Parse(const std::string& json, + const base::Optional<std::string>& batch_id = base::nullopt) { SCOPED_TRACE(json); DCHECK(!message_loop_runner_); message_loop_runner_ = new content::MessageLoopRunner; @@ -83,14 +77,25 @@ error_callback = base::Bind(&SafeJsonParserTest::ExpectError, base::Unretained(this), error); } - SafeJsonParser::Parse( - content::ServiceManagerConnection::GetForProcess()->GetConnector(), - json, success_callback, error_callback); + + if (batch_id) { + SafeJsonParser::ParseBatch( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), + json, success_callback, error_callback, *batch_id); + } else { + SafeJsonParser::Parse( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), + json, success_callback, error_callback); + } message_loop_runner_->Run(); message_loop_runner_ = nullptr; } + uint32_t GetServiceStartCount(const std::string& service_name) const { + return listener_.GetServiceStartCount(service_name); + } + private: void ExpectValue(std::unique_ptr<base::Value> expected_value, std::unique_ptr<base::Value> actual_value) { @@ -117,81 +122,49 @@ } scoped_refptr<content::MessageLoopRunner> message_loop_runner_; -}; - -class SafeJsonParserImplTest : public InProcessBrowserTest { - public: - SafeJsonParserImplTest() = default; - - protected: - // InProcessBrowserTest implementation: - void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - - // Initialize the TestServiceManagerListener so it starts listening for - // service activity. - listener_.Init(); - - // The data_decoder service will stop if no connection is bound to it after - // 5 seconds. We bind a connection to it for the duration of the test so it - // is guaranteed the service is always running. - connector()->BindInterface(data_decoder::mojom::kServiceName, - &json_parser_ptr_); - listener_.WaitUntilServiceStarted(data_decoder::mojom::kServiceName); - EXPECT_EQ( - 1U, listener_.GetServiceStartCount(data_decoder::mojom::kServiceName)); - } - - service_manager::Connector* connector() const { - return content::ServiceManagerConnection::GetForProcess()->GetConnector(); - } - - uint32_t GetServiceStartCount(const std::string& service_name) const { - return listener_.GetServiceStartCount(service_name); - } - - private: - data_decoder::mojom::JsonParserPtr json_parser_ptr_; TestServiceManagerListener listener_; - DISALLOW_COPY_AND_ASSIGN(SafeJsonParserImplTest); + DISALLOW_COPY_AND_ASSIGN(SafeJsonParserTest); }; } // namespace IN_PROC_BROWSER_TEST_F(SafeJsonParserTest, Parse) { - TestParse("{}"); - TestParse("choke"); - TestParse("{\"awesome\": true}"); - TestParse("\"laser\""); - TestParse("false"); - TestParse("null"); - TestParse("3.14"); - TestParse("["); - TestParse("\""); - TestParse(std::string()); - TestParse("☃"); - TestParse("\"☃\""); - TestParse("\"\\ufdd0\""); - TestParse("\"\\ufffe\""); - TestParse("\"\\ud83f\\udffe\""); + Parse("{}"); + Parse("choke"); + Parse("{\"awesome\": true}"); + Parse("\"laser\""); + Parse("false"); + Parse("null"); + Parse("3.14"); + Parse("["); + Parse("\""); + Parse(std::string()); + Parse("☃"); + Parse("\"☃\""); + Parse("\"\\ufdd0\""); + Parse("\"\\ufffe\""); + Parse("\"\\ud83f\\udffe\""); } // Tests that when calling SafeJsonParser::Parse() a new service is started // every time. -IN_PROC_BROWSER_TEST_F(SafeJsonParserImplTest, Isolation) { +IN_PROC_BROWSER_TEST_F(SafeJsonParserTest, Isolation) { for (int i = 0; i < 5; i++) { - base::RunLoop run_loop; - ParseCallback parse_callback(run_loop.QuitClosure()); - SafeJsonParser::Parse( - connector(), "[\"awesome\", \"possum\"]", - base::Bind(&ParseCallback::OnSuccess, - base::Unretained(&parse_callback)), - base::Bind(&ParseCallback::OnError, base::Unretained(&parse_callback))); - run_loop.Run(); - EXPECT_TRUE(parse_callback.success()); - // 2 + i below because the data_decoder is already running and the index - // starts at 0. - EXPECT_EQ(2U + i, GetServiceStartCount(data_decoder::mojom::kServiceName)); + SCOPED_TRACE(base::StringPrintf("Testing iteration %d", i)); + Parse(kTestJson); + EXPECT_EQ(1U + i, GetServiceStartCount(data_decoder::mojom::kServiceName)); } } + +// Tests that using a batch ID allows service reuse. +IN_PROC_BROWSER_TEST_F(SafeJsonParserTest, IsolationWithGroups) { + constexpr char kBatchId1[] = "batch1"; + constexpr char kBatchId2[] = "batch2"; + for (int i = 0; i < 5; i++) { + SCOPED_TRACE(base::StringPrintf("Testing iteration %d", i)); + Parse(kTestJson, kBatchId1); + Parse(kTestJson, kBatchId2); + } + EXPECT_EQ(2U, GetServiceStartCount(data_decoder::mojom::kServiceName)); +}
diff --git a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc index 6394797..763856b2 100644 --- a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc +++ b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/search/suggestions/image_decoder_impl.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" +#include "content/public/browser/storage_partition.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -50,9 +51,11 @@ } ImageFetcherImpl* CreateImageFetcher() { - ImageFetcherImpl* fetcher = - new ImageFetcherImpl(std::make_unique<suggestions::ImageDecoderImpl>(), - browser()->profile()->GetRequestContext()); + ImageFetcherImpl* fetcher = new ImageFetcherImpl( + std::make_unique<suggestions::ImageDecoderImpl>(), + content::BrowserContext::GetDefaultStoragePartition( + browser()->profile()) + ->GetURLLoaderFactoryForBrowserProcess()); return fetcher; }
diff --git a/chrome/browser/search/suggestions/suggestions_service_factory.cc b/chrome/browser/search/suggestions/suggestions_service_factory.cc index 72b3c80b..2101b20 100644 --- a/chrome/browser/search/suggestions/suggestions_service_factory.cc +++ b/chrome/browser/search/suggestions/suggestions_service_factory.cc
@@ -30,6 +30,7 @@ #include "components/suggestions/suggestions_store.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" #include "services/identity/public/cpp/identity_manager.h" using content::BrowserThread; @@ -82,9 +83,10 @@ base::FilePath database_dir( profile->GetPath().Append(FILE_PATH_LITERAL("Thumbnails"))); - std::unique_ptr<ImageFetcherImpl> image_fetcher( - new ImageFetcherImpl(std::make_unique<suggestions::ImageDecoderImpl>(), - profile->GetRequestContext())); + std::unique_ptr<ImageFetcherImpl> image_fetcher(new ImageFetcherImpl( + std::make_unique<suggestions::ImageDecoderImpl>(), + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess())); std::unique_ptr<ImageManager> thumbnail_manager( new ImageManager(std::move(image_fetcher), std::move(db), database_dir)); return new SuggestionsServiceImpl(
diff --git a/chrome/browser/search/thumbnail_source.cc b/chrome/browser/search/thumbnail_source.cc index d4b7a07..e1562b4 100644 --- a/chrome/browser/search/thumbnail_source.cc +++ b/chrome/browser/search/thumbnail_source.cc
@@ -11,20 +11,21 @@ #include "chrome/browser/thumbnails/thumbnail_service.h" #include "chrome/browser/thumbnails/thumbnail_service_factory.h" #include "chrome/common/url_constants.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_request.h" #include "url/gurl.h" // The delimiter between the first url and the fallback url passed to // StartDataRequest. const char kUrlDelimiter[] = "?fb="; -// Set ThumbnailService now as Profile isn't thread safe. ThumbnailSource::ThumbnailSource(Profile* profile, bool capture_thumbnails) : thumbnail_service_(ThumbnailServiceFactory::GetForProfile(profile)), capture_thumbnails_(capture_thumbnails), - image_data_fetcher_(profile->GetRequestContext()), - weak_ptr_factory_(this) {} + image_data_fetcher_( + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess()) {} ThumbnailSource::~ThumbnailSource() = default; @@ -37,6 +38,7 @@ const std::string& path, const content::ResourceRequestInfo::WebContentsGetter& wc_getter, const content::URLDataSource::GotDataCallback& callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); GURL page_url; GURL fallback_thumbnail_url; ExtractPageAndThumbnailUrls(path, &page_url, &fallback_thumbnail_url); @@ -97,22 +99,11 @@ std::string ThumbnailSource::GetMimeType(const std::string&) const { // We need to explicitly return a mime type, otherwise if the user tries to // drag the image they get no extension. - // TODO(treib): This isn't correct for remote thumbnails (in - // SendFetchedUrlImage), which are usually jpeg. + // NOTE: This isn't correct for remote thumbnails (in SendFetchedUrlImage), + // which are usually jpeg. However it seems to work fine. return "image/png"; } -scoped_refptr<base::SingleThreadTaskRunner> -ThumbnailSource::TaskRunnerForRequestPath(const std::string& path) const { - // TopSites can be accessed from the IO thread. Otherwise, the URLs should be - // accessed on the UI thread. - // TODO(treib): |thumbnail_service_| is assumed to be non-null in other - // places, so probably this check isn't necessary? - return thumbnail_service_.get() - ? nullptr - : content::URLDataSource::TaskRunnerForRequestPath(path); -} - bool ThumbnailSource::AllowCaching() const { return false; }
diff --git a/chrome/browser/search/thumbnail_source.h b/chrome/browser/search/thumbnail_source.h index 0cf25bfb..59f16cb 100644 --- a/chrome/browser/search/thumbnail_source.h +++ b/chrome/browser/search/thumbnail_source.h
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "base/single_thread_task_runner.h" #include "components/image_fetcher/core/image_data_fetcher.h" #include "content/public/browser/url_data_source.h" @@ -39,8 +38,6 @@ const content::ResourceRequestInfo::WebContentsGetter& wc_getter, const content::URLDataSource::GotDataCallback& callback) override; std::string GetMimeType(const std::string& path) const override; - scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerForRequestPath( - const std::string& path) const override; bool AllowCaching() const override; bool ShouldServiceRequest(const GURL& url, content::ResourceContext* resource_context, @@ -73,7 +70,7 @@ image_fetcher::ImageDataFetcher image_data_fetcher_; - base::WeakPtrFactory<ThumbnailSource> weak_ptr_factory_; + base::WeakPtrFactory<ThumbnailSource> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ThumbnailSource); };
diff --git a/chrome/browser/search_engines/OWNERS b/chrome/browser/search_engines/OWNERS index ba5be80..8bc2e75 100644 --- a/chrome/browser/search_engines/OWNERS +++ b/chrome/browser/search_engines/OWNERS
@@ -3,8 +3,6 @@ bauerb@chromium.org treib@chromium.org -per-file *_android.*=mariakhomenko@chromium.org - per-file default_search_policy_handler*=atwilson@chromium.org # COMPONENT: UI>Browser>Search
diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc index 0bffd557..844b726a 100644 --- a/chrome/browser/signin/account_consistency_mode_manager.cc +++ b/chrome/browser/signin/account_consistency_mode_manager.cc
@@ -84,7 +84,8 @@ } // namespace -bool AccountConsistencyModeManager::ignore_missing_key_for_testing_ = false; +bool AccountConsistencyModeManager::ignore_missing_oauth_client_for_testing_ = + false; // static AccountConsistencyModeManager* AccountConsistencyModeManager::GetForProfile( @@ -173,8 +174,8 @@ } // static -void AccountConsistencyModeManager::SetIgnoreMissingApiKeysForTesting() { - ignore_missing_key_for_testing_ = true; +void AccountConsistencyModeManager::SetIgnoreMissingOAuthClientForTesting() { + ignore_missing_oauth_client_for_testing_ = true; } signin::AccountConsistencyMethod @@ -213,11 +214,11 @@ if (profile_->IsLegacySupervised()) return signin::AccountConsistencyMethod::kDiceFixAuthErrors; - bool can_enable_dice_for_build = - ignore_missing_key_for_testing_ || google_apis::HasKeysConfigured(); + bool can_enable_dice_for_build = ignore_missing_oauth_client_for_testing_ || + google_apis::HasOAuthClientConfigured(); if (!can_enable_dice_for_build) { LOG(WARNING) << "Desktop Identity Consistency cannot be enabled as no " - "API keys have been configured."; + "OAuth client ID and client secret have been configured."; return signin::AccountConsistencyMethod::kDiceFixAuthErrors; }
diff --git a/chrome/browser/signin/account_consistency_mode_manager.h b/chrome/browser/signin/account_consistency_mode_manager.h index 43348982..2efff70 100644 --- a/chrome/browser/signin/account_consistency_mode_manager.h +++ b/chrome/browser/signin/account_consistency_mode_manager.h
@@ -52,9 +52,9 @@ // behaviour enabled. static bool IsMirrorEnabledForProfile(Profile* profile); - // By default, Deskotp Identity Consistency (aka Dice) is not enabled in + // By default, Desktop Identity Consistency (aka Dice) is not enabled in // builds lacking an API key. For testing, set to have Dice enabled in tests. - static void SetIgnoreMissingApiKeysForTesting(); + static void SetIgnoreMissingOAuthClientForTesting(); private: FRIEND_TEST_ALL_PREFIXES(AccountConsistencyModeManagerTest, @@ -76,7 +76,7 @@ // By default, DICE is not enabled in builds lacking an API key. Set to true // for tests. - static bool ignore_missing_key_for_testing_; + static bool ignore_missing_oauth_client_for_testing_; DISALLOW_COPY_AND_ASSIGN(AccountConsistencyModeManager); };
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index 322ecec..1e55772b 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -45,6 +45,7 @@ #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/signin/core/browser/signin_switches.h" +#include "content/public/browser/storage_partition.h" #include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_urls.h" #include "net/url_request/url_request_context_getter.h" @@ -203,8 +204,10 @@ return profile_->GetRequestContext(); } -bool ChromeSigninClient::ShouldMergeSigninCredentialsIntoCookieJar() { - return !signin::IsAccountConsistencyMirrorEnabled(); +scoped_refptr<network::SharedURLLoaderFactory> +ChromeSigninClient::GetURLLoaderFactory() { + return content::BrowserContext::GetDefaultStoragePartition(profile_) + ->GetURLLoaderFactoryForBrowserProcess(); } std::string ChromeSigninClient::GetProductVersion() {
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h index bc94228..d2ea062 100644 --- a/chrome/browser/signin/chrome_signin_client.h +++ b/chrome/browser/signin/chrome_signin_client.h
@@ -51,7 +51,7 @@ std::string GetSigninScopedDeviceId() override; void OnSignedOut() override; net::URLRequestContextGetter* GetURLRequestContext() override; - bool ShouldMergeSigninCredentialsIntoCookieJar() override; + scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; bool IsFirstRun() const override; base::Time GetInstallDate() override; bool AreSigninCookiesAllowed() override;
diff --git a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc index 98ef11c..a7a0d0d 100644 --- a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc +++ b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/chrome_signin_helper.h" #include "chrome/browser/supervised_user/supervised_user_constants.h" #include "chrome/browser/supervised_user/supervised_user_settings_service.h" @@ -113,8 +114,6 @@ // Mirror is enabled for child accounts. IN_PROC_BROWSER_TEST_F(ChromeOsMirrorAccountConsistencyTest, TestMirrorRequestChromeOsChildAccount) { - // On Chrome OS this is false. - ASSERT_FALSE(signin::IsAccountConsistencyMirrorEnabled()); // Child user. LoginUser(account_id_); @@ -123,6 +122,10 @@ ASSERT_EQ(user, user_manager::UserManager::Get()->FindUser(account_id_)); Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); + // On Chrome OS this is false. + ASSERT_FALSE( + AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)); + // Require account consistency. SupervisedUserSettingsService* supervised_user_settings_service = SupervisedUserSettingsServiceFactory::GetForProfile(profile); @@ -152,8 +155,6 @@ // Mirror is not enabled for non-child accounts. IN_PROC_BROWSER_TEST_F(ChromeOsMirrorAccountConsistencyTest, TestMirrorRequestChromeOsNotChildAccount) { - // On Chrome OS this is false. - ASSERT_FALSE(signin::IsAccountConsistencyMirrorEnabled()); // Not a child user. LoginUser(account_id_); @@ -162,6 +163,10 @@ ASSERT_EQ(user, user_manager::UserManager::Get()->FindUser(account_id_)); Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user); + // On Chrome OS this is false. + ASSERT_FALSE( + AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)); + PrefService* prefs = profile->GetPrefs(); ASSERT_FALSE(prefs->GetBoolean(prefs::kAccountConsistencyMirrorRequired));
diff --git a/chrome/browser/signin/signin_error_controller_factory.cc b/chrome/browser/signin/signin_error_controller_factory.cc index 5d7f0eb4..03bd834d 100644 --- a/chrome/browser/signin/signin_error_controller_factory.cc +++ b/chrome/browser/signin/signin_error_controller_factory.cc
@@ -6,6 +6,7 @@ #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/account_consistency_mode_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/signin/core/browser/profile_management_switches.h" @@ -34,7 +35,8 @@ #if defined(OS_CHROMEOS) SigninErrorController::AccountMode::ANY_ACCOUNT; #else - signin::IsAccountConsistencyMirrorEnabled() + AccountConsistencyModeManager::IsMirrorEnabledForProfile( + Profile::FromBrowserContext(context)) ? SigninErrorController::AccountMode::ANY_ACCOUNT : SigninErrorController::AccountMode::PRIMARY_ACCOUNT; #endif
diff --git a/chrome/browser/signin/signin_promo.cc b/chrome/browser/signin/signin_promo.cc index b4cb6e7f..4418135 100644 --- a/chrome/browser/signin/signin_promo.cc +++ b/chrome/browser/signin/signin_promo.cc
@@ -129,6 +129,15 @@ namespace signin { +const char kSignInPromoQueryKeyAccessPoint[] = "access_point"; +const char kSignInPromoQueryKeyAutoClose[] = "auto_close"; +const char kSignInPromoQueryKeyContinue[] = "continue"; +const char kSignInPromoQueryKeyForceKeepData[] = "force_keep_data"; +const char kSignInPromoQueryKeyReason[] = "reason"; +const char kSignInPromoQueryKeySource[] = "source"; +const char kSignInPromoQueryKeyConstrained[] = "constrained"; +const char kSigninPromoLandingURLSuccessPage[] = "success.html"; + bool ShouldShowPromoAtStartup(Profile* profile, bool is_new_profile) { DCHECK(profile); @@ -368,17 +377,6 @@ return false; } -bool ShouldShowAccountManagement(const GURL& url) { - std::string value; - if (net::GetValueForKeyInQuery( - url, kSignInPromoQueryKeyShowAccountManagement, &value)) { - int enabled = 0; - if (base::StringToInt(value, &enabled) && enabled == 1) - return IsAccountConsistencyMirrorEnabled(); - } - return false; -} - void ForceWebBasedSigninFlowForTesting(bool force) { g_force_web_based_signin_flow = force; }
diff --git a/chrome/browser/signin/signin_promo.h b/chrome/browser/signin/signin_promo.h index 6b83a753..06a342a 100644 --- a/chrome/browser/signin/signin_promo.h +++ b/chrome/browser/signin/signin_promo.h
@@ -20,16 +20,14 @@ // Utility functions for sign in promos. namespace signin { -const char kSignInPromoQueryKeyAccessPoint[] = "access_point"; -const char kSignInPromoQueryKeyAutoClose[] = "auto_close"; -const char kSignInPromoQueryKeyContinue[] = "continue"; -const char kSignInPromoQueryKeyForceKeepData[] = "force_keep_data"; -const char kSignInPromoQueryKeyReason[] = "reason"; -const char kSignInPromoQueryKeySource[] = "source"; -const char kSignInPromoQueryKeyConstrained[] = "constrained"; -const char kSignInPromoQueryKeyShowAccountManagement[] = - "showAccountManagement"; -const char kSigninPromoLandingURLSuccessPage[] = "success.html"; +extern const char kSignInPromoQueryKeyAccessPoint[]; +extern const char kSignInPromoQueryKeyAutoClose[]; +extern const char kSignInPromoQueryKeyContinue[]; +extern const char kSignInPromoQueryKeyForceKeepData[]; +extern const char kSignInPromoQueryKeyReason[]; +extern const char kSignInPromoQueryKeySource[]; +extern const char kSignInPromoQueryKeyConstrained[]; +extern const char kSigninPromoLandingURLSuccessPage[]; // Returns true if we should show the sign in promo at startup. bool ShouldShowPromoAtStartup(Profile* profile, bool is_new_profile); @@ -105,10 +103,6 @@ // Returns true if the auto_close parameter in the given URL is set to true. bool IsAutoCloseEnabledInURL(const GURL& url); -// Returns true if the showAccountManagement parameter in the given url is set -// to true. -bool ShouldShowAccountManagement(const GURL& url); - // Forces UseWebBasedSigninFlow() to return true when set; used in tests only. void ForceWebBasedSigninFlowForTesting(bool force);
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc index 34150fc..418a72b 100644 --- a/chrome/browser/ssl/security_state_tab_helper.cc +++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -271,11 +271,29 @@ return security_state::MALICIOUS_CONTENT_STATUS_MALWARE; case safe_browsing::SB_THREAT_TYPE_URL_UNWANTED: return security_state::MALICIOUS_CONTENT_STATUS_UNWANTED_SOFTWARE; - case safe_browsing::SB_THREAT_TYPE_PASSWORD_REUSE: + case safe_browsing::SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE: #if defined(SAFE_BROWSING_DB_LOCAL) if (safe_browsing::ChromePasswordProtectionService:: - ShouldShowPasswordReusePageInfoBubble(web_contents())) { - return security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE; + ShouldShowPasswordReusePageInfoBubble( + web_contents(), + safe_browsing::LoginReputationClientRequest:: + PasswordReuseEvent::SIGN_IN_PASSWORD)) { + return security_state:: + MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE; + } + // If user has already changed Gaia password, returns the regular + // social engineering content status. + return security_state::MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING; +#endif + case safe_browsing::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: +#if defined(SAFE_BROWSING_DB_LOCAL) + if (safe_browsing::ChromePasswordProtectionService:: + ShouldShowPasswordReusePageInfoBubble( + web_contents(), + safe_browsing::LoginReputationClientRequest:: + PasswordReuseEvent::ENTERPRISE_PASSWORD)) { + return security_state:: + MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE; } // If user has already changed Gaia password, returns the regular // social engineering content status.
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc index 0ec3016..3526601 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -1052,10 +1052,11 @@ EXPECT_EQ(content::SSLStatus::NORMAL_CONTENT, entry->GetSSL().content_status); } -// Tests the security level and malicious content status for password reuse -// threat type. -IN_PROC_BROWSER_TEST_P(SecurityStateTabHelperTest, - VerifyPasswordReuseMaliciousContentAndSecurityLevel) { +// Tests the security level and malicious content status for sign-in password +// reuse threat type. +IN_PROC_BROWSER_TEST_P( + SecurityStateTabHelperTest, + VerifySignInPasswordReuseMaliciousContentAndSecurityLevel) { // Setup https server. This makes sure that the DANGEROUS security level is // not caused by any certificate error rather than the password reuse SB // threat type. @@ -1073,7 +1074,7 @@ ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/ssl/google.html")); // Update security state of the current page to match - // SB_THREAT_TYPE_PASSWORD_REUSE. + // SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE. safe_browsing::ChromePasswordProtectionService* service = safe_browsing::ChromePasswordProtectionService:: GetPasswordProtectionService(browser()->profile()); @@ -1085,7 +1086,7 @@ security_state::SecurityInfo security_info; helper->GetSecurityInfo(&security_info); EXPECT_EQ(security_state::DANGEROUS, security_info.security_level); - EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE, security_info.malicious_content_status); // Simulates a Gaia password change, then malicious content status will @@ -1098,6 +1099,45 @@ security_info.malicious_content_status); } +// Tests the security level and malicious content status for enterprise password +// reuse threat type. +IN_PROC_BROWSER_TEST_P( + SecurityStateTabHelperTest, + VerifyEnterprisePasswordReuseMaliciousContentAndSecurityLevel) { + // Setup https server. This makes sure that the DANGEROUS security level is + // not caused by any certificate error rather than the password reuse SB + // threat type. + SetUpMockCertVerifierForHttpsServer(0, net::OK); + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + SecurityStyleTestObserver observer(contents); + + SecurityStateTabHelper* helper = + SecurityStateTabHelper::FromWebContents(contents); + + ui_test_utils::NavigateToURL(browser(), + https_server_.GetURL("/ssl/google.html")); + // Update security state of the current page to match + // SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE. + safe_browsing::ChromePasswordProtectionService* service = + safe_browsing::ChromePasswordProtectionService:: + GetPasswordProtectionService(browser()->profile()); + service->ShowModalWarning(contents, "unused-token", + safe_browsing::LoginReputationClientRequest:: + PasswordReuseEvent::ENTERPRISE_PASSWORD); + observer.WaitForDidChangeVisibleSecurityState(); + + security_state::SecurityInfo security_info; + helper->GetSecurityInfo(&security_info); + EXPECT_EQ(security_state::DANGEROUS, security_info.security_level); + EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE, + security_info.malicious_content_status); + + // Since these are non-Gaia enterprise passwords, Gaia password change won't + // have any impact here. +} + // Tests that the security level of ftp: URLs is always downgraded to // HTTP_SHOW_WARNING. IN_PROC_BROWSER_TEST_P(SecurityStateTabHelperTest,
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 47a8863..89d8a4a 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -320,13 +320,91 @@ component_factory_->CreateCommonDataTypeControllers( disabled_types, local_device_info_provider); -// TODO(mastiz): Merge the two functions below into one or inline bodies here, -// since there is common code. -#if defined(OS_ANDROID) - RegisterAndroidDataTypes(&controllers); -#else - RegisterDesktopDataTypes(disabled_types, &controllers); -#endif // defined(OS_ANDROID) + base::RepeatingClosure error_callback = base::BindRepeating( + &syncer::ReportUnrecoverableError, chrome::GetChannel()); + +#if BUILDFLAG(ENABLE_SUPERVISED_USERS) + controllers.push_back(std::make_unique<SupervisedUserSyncDataTypeController>( + syncer::SUPERVISED_USER_SETTINGS, error_callback, this, profile_)); + controllers.push_back(std::make_unique<SupervisedUserSyncDataTypeController>( + syncer::SUPERVISED_USER_WHITELISTS, error_callback, this, profile_)); +#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // App sync is enabled by default. Register unless explicitly + // disabled. + if (!disabled_types.Has(syncer::APPS)) { + controllers.push_back(std::make_unique<ExtensionDataTypeController>( + syncer::APPS, error_callback, this, profile_)); + } + + // Extension sync is enabled by default. Register unless explicitly + // disabled. + if (!disabled_types.Has(syncer::EXTENSIONS)) { + controllers.push_back(std::make_unique<ExtensionDataTypeController>( + syncer::EXTENSIONS, error_callback, this, profile_)); + } + + // Extension setting sync is enabled by default. Register unless explicitly + // disabled. + if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) { + controllers.push_back(std::make_unique<ExtensionSettingDataTypeController>( + syncer::EXTENSION_SETTINGS, error_callback, this, profile_)); + } + + // App setting sync is enabled by default. Register unless explicitly + // disabled. + if (!disabled_types.Has(syncer::APP_SETTINGS)) { + controllers.push_back(std::make_unique<ExtensionSettingDataTypeController>( + syncer::APP_SETTINGS, error_callback, this, profile_)); + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +#if !defined(OS_ANDROID) + // Theme sync is enabled by default. Register unless explicitly disabled. + if (!disabled_types.Has(syncer::THEMES)) { + controllers.push_back(std::make_unique<ThemeDataTypeController>( + error_callback, this, profile_)); + } + + // Search Engine sync is enabled by default. Register unless explicitly + // disabled. + if (!disabled_types.Has(syncer::SEARCH_ENGINES)) { + controllers.push_back(std::make_unique<SearchEngineDataTypeController>( + error_callback, this, + TemplateURLServiceFactory::GetForProfile(profile_))); + } +#endif // !defined(OS_ANDROID) + +#if BUILDFLAG(ENABLE_APP_LIST) + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::APP_LIST, error_callback, this, syncer::GROUP_UI, + BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); +#endif // BUILDFLAG(ENABLE_APP_LIST) + +#if defined(OS_LINUX) || defined(OS_WIN) + // Dictionary sync is enabled by default. + if (!disabled_types.Has(syncer::DICTIONARY)) { + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::DICTIONARY, error_callback, this, syncer::GROUP_UI, + BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); + } +#endif // defined(OS_LINUX) || defined(OS_WIN) + +#if defined(OS_CHROMEOS) + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableWifiCredentialSync) && + !disabled_types.Has(syncer::WIFI_CREDENTIALS)) { + controllers.push_back(std::make_unique<AsyncDirectoryTypeController>( + syncer::WIFI_CREDENTIALS, error_callback, this, syncer::GROUP_UI, + BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); + } + if (arc::IsArcAllowedForProfile(profile_)) { + controllers.push_back(std::make_unique<ArcPackageSyncDataTypeController>( + syncer::ARC_PACKAGE, error_callback, this, profile_)); + } +#endif // defined(OS_CHROMEOS) + return controllers; } @@ -595,107 +673,4 @@ } } -void ChromeSyncClient::RegisterDesktopDataTypes( - syncer::ModelTypeSet disabled_types, - syncer::DataTypeController::TypeVector* controllers) { - base::Closure error_callback = - base::Bind(&syncer::ReportUnrecoverableError, chrome::GetChannel()); - -#if BUILDFLAG(ENABLE_EXTENSIONS) - // App sync is enabled by default. Register unless explicitly - // disabled. - if (!disabled_types.Has(syncer::APPS)) { - controllers->push_back(std::make_unique<ExtensionDataTypeController>( - syncer::APPS, error_callback, this, profile_)); - } - - // Extension sync is enabled by default. Register unless explicitly - // disabled. - if (!disabled_types.Has(syncer::EXTENSIONS)) { - controllers->push_back(std::make_unique<ExtensionDataTypeController>( - syncer::EXTENSIONS, error_callback, this, profile_)); - } -#endif // BUILDFLAG(ENABLE_EXTENSIONS) - -#if !defined(OS_ANDROID) - // Theme sync is enabled by default. Register unless explicitly disabled. - if (!disabled_types.Has(syncer::THEMES)) { - controllers->push_back(std::make_unique<ThemeDataTypeController>( - error_callback, this, profile_)); - } -#endif // !defined(OS_ANDROID) - - // Search Engine sync is enabled by default. Register unless explicitly - // disabled. - if (!disabled_types.Has(syncer::SEARCH_ENGINES)) { - controllers->push_back(std::make_unique<SearchEngineDataTypeController>( - error_callback, this, - TemplateURLServiceFactory::GetForProfile(profile_))); - } - -#if BUILDFLAG(ENABLE_EXTENSIONS) - // Extension setting sync is enabled by default. Register unless explicitly - // disabled. - if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) { - controllers->push_back(std::make_unique<ExtensionSettingDataTypeController>( - syncer::EXTENSION_SETTINGS, error_callback, this, profile_)); - } - - // App setting sync is enabled by default. Register unless explicitly - // disabled. - if (!disabled_types.Has(syncer::APP_SETTINGS)) { - controllers->push_back(std::make_unique<ExtensionSettingDataTypeController>( - syncer::APP_SETTINGS, error_callback, this, profile_)); - } -#endif // BUILDFLAG(ENABLE_EXTENSIONS) - -#if BUILDFLAG(ENABLE_APP_LIST) - controllers->push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::APP_LIST, error_callback, this, syncer::GROUP_UI, - BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); -#endif // BUILDFLAG(ENABLE_APP_LIST) - -#if defined(OS_LINUX) || defined(OS_WIN) - // Dictionary sync is enabled by default. - if (!disabled_types.Has(syncer::DICTIONARY)) { - controllers->push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::DICTIONARY, error_callback, this, syncer::GROUP_UI, - BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); - } -#endif // defined(OS_LINUX) || defined(OS_WIN) - -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>( - syncer::SUPERVISED_USER_SETTINGS, error_callback, this, profile_)); - controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>( - syncer::SUPERVISED_USER_WHITELISTS, error_callback, this, profile_)); -#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) - -#if defined(OS_CHROMEOS) - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableWifiCredentialSync) && - !disabled_types.Has(syncer::WIFI_CREDENTIALS)) { - controllers->push_back(std::make_unique<AsyncDirectoryTypeController>( - syncer::WIFI_CREDENTIALS, error_callback, this, syncer::GROUP_UI, - BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); - } - if (arc::IsArcAllowedForProfile(profile_)) { - controllers->push_back(std::make_unique<ArcPackageSyncDataTypeController>( - syncer::ARC_PACKAGE, error_callback, this, profile_)); - } -#endif // defined(OS_CHROMEOS) -} - -void ChromeSyncClient::RegisterAndroidDataTypes( - syncer::DataTypeController::TypeVector* controllers) { - base::Closure error_callback = - base::Bind(&syncer::ReportUnrecoverableError, chrome::GetChannel()); -#if BUILDFLAG(ENABLE_SUPERVISED_USERS) - controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>( - syncer::SUPERVISED_USER_SETTINGS, error_callback, this, profile_)); - controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>( - syncer::SUPERVISED_USER_WHITELISTS, error_callback, this, profile_)); -#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) -} - } // namespace browser_sync
diff --git a/chrome/browser/sync/chrome_sync_client.h b/chrome/browser/sync/chrome_sync_client.h index 6aedd85..0762df2 100644 --- a/chrome/browser/sync/chrome_sync_client.h +++ b/chrome/browser/sync/chrome_sync_client.h
@@ -72,15 +72,6 @@ std::vector<const syncer::DeviceInfoTracker*>* trackers); private: - // Register data types which are enabled on desktop platforms only. - void RegisterDesktopDataTypes( - syncer::ModelTypeSet disabled_types, - syncer::DataTypeController::TypeVector* controllers); - - // Register data types which are enabled on Android platforms only. - void RegisterAndroidDataTypes( - syncer::DataTypeController::TypeVector* controllers); - Profile* const profile_; // The sync api component factory in use by this client.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 4eb35df0..95d80ab 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1789,7 +1789,6 @@ "ash/chrome_screenshot_grabber_test_observer.h", "ash/chrome_shell_content_state.cc", "ash/chrome_shell_content_state.h", - "ash/chrome_shell_content_state_chromeos.cc", "ash/chrome_shell_delegate.cc", "ash/chrome_shell_delegate.h", "ash/ime_controller_client.cc", @@ -2017,8 +2016,6 @@ "webui/chromeos/login/native_window_delegate.h", "webui/chromeos/login/network_dropdown_handler.cc", "webui/chromeos/login/network_dropdown_handler.h", - "webui/chromeos/login/network_screen_handler.cc", - "webui/chromeos/login/network_screen_handler.h", "webui/chromeos/login/network_state_informer.cc", "webui/chromeos/login/network_state_informer.h", "webui/chromeos/login/oobe_display_chooser.cc", @@ -2053,6 +2050,8 @@ "webui/chromeos/login/voice_interaction_value_prop_screen_handler.h", "webui/chromeos/login/wait_for_container_ready_screen_handler.cc", "webui/chromeos/login/wait_for_container_ready_screen_handler.h", + "webui/chromeos/login/welcome_screen_handler.cc", + "webui/chromeos/login/welcome_screen_handler.h", "webui/chromeos/login/wrong_hwid_screen_handler.cc", "webui/chromeos/login/wrong_hwid_screen_handler.h", "webui/chromeos/mobile_setup_dialog.cc", @@ -2119,6 +2118,8 @@ "webui/settings/chromeos/google_assistant_handler.h", "webui/settings/chromeos/internet_handler.cc", "webui/settings/chromeos/internet_handler.h", + "webui/settings/chromeos/multidevice_handler.cc", + "webui/settings/chromeos/multidevice_handler.h", "webui/settings/chromeos/smb_handler.cc", "webui/settings/chromeos/smb_handler.h", "webui/settings/tts_handler.cc", @@ -2419,6 +2420,8 @@ "cocoa/md_hover_button.mm", "cocoa/md_util.h", "cocoa/md_util.mm", + "cocoa/media_picker/create_desktop_media_picker_cocoa.h", + "cocoa/media_picker/create_desktop_media_picker_cocoa.mm", "cocoa/media_picker/desktop_media_picker_bridge.h", "cocoa/media_picker/desktop_media_picker_bridge.mm", "cocoa/media_picker/desktop_media_picker_cocoa.h", @@ -2837,6 +2840,12 @@ "views/content_setting_domain_list_view.h", "views/cookie_info_view.cc", "views/cookie_info_view.h", + "views/desktop_capture/desktop_media_list_view.cc", + "views/desktop_capture/desktop_media_list_view.h", + "views/desktop_capture/desktop_media_picker_views.cc", + "views/desktop_capture/desktop_media_picker_views.h", + "views/desktop_capture/desktop_media_source_view.cc", + "views/desktop_capture/desktop_media_source_view.h", "views/device_chooser_content_view.cc", "views/device_chooser_content_view.h", "views/download/download_danger_prompt_views.cc", @@ -3473,12 +3482,6 @@ "views/color_chooser_aura.h", "views/crypto_module_password_dialog_view.cc", "views/crypto_module_password_dialog_view.h", - "views/desktop_capture/desktop_media_list_view.cc", - "views/desktop_capture/desktop_media_list_view.h", - "views/desktop_capture/desktop_media_picker_views.cc", - "views/desktop_capture/desktop_media_picker_views.h", - "views/desktop_capture/desktop_media_source_view.cc", - "views/desktop_capture/desktop_media_source_view.h", "views/dropdown_bar_host_aura.cc", "views/frame/browser_non_client_frame_view_factory_chromeos.cc", "views/ime/ime_window_frame_view.cc", @@ -3738,16 +3741,12 @@ sources += [ "ash/assistant/assistant_client.cc", "ash/assistant/assistant_client.h", - "ash/assistant/assistant_context.cc", - "ash/assistant/assistant_context.h", "ash/assistant/assistant_context_util.cc", "ash/assistant/assistant_context_util.h", "ash/assistant/assistant_image_downloader.cc", "ash/assistant/assistant_image_downloader.h", "ash/assistant/assistant_setup.cc", "ash/assistant/assistant_setup.h", - "ash/assistant/platform_audio_input_host.cc", - "ash/assistant/platform_audio_input_host.h", "ash/assistant/web_contents_manager.cc", "ash/assistant/web_contents_manager.h", ]
diff --git a/chrome/browser/ui/app_list/app_context_menu_unittest.cc b/chrome/browser/ui/app_list/app_context_menu_unittest.cc index 58ad2fb..7de2c43 100644 --- a/chrome/browser/ui/app_list/app_context_menu_unittest.cc +++ b/chrome/browser/ui/app_list/app_context_menu_unittest.cc
@@ -34,7 +34,6 @@ #include "components/keyed_service/core/keyed_service.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_base_features.h" -#include "ui/views/layout/layout_provider.h" namespace { @@ -355,11 +354,6 @@ std::unique_ptr<FakeAppListModelUpdater> model_updater_; base::test::ScopedFeatureList scoped_feature_list_; - // The layout provider is meant to be a singleton, but it is not initialized - // for unit tests. Constructing one here makes it globally available, which - // is later used by the menu item during initialization. - views::LayoutProvider layout_provider_; - DISALLOW_COPY_AND_ASSIGN(AppContextMenuTest); };
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index a517e08..c2cb98d 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "extensions/common/constants.h" #include "ui/base/models/menu_model.h"
diff --git a/chrome/browser/ui/ash/ash_shell_init.h b/chrome/browser/ui/ash/ash_shell_init.h index 08187a3..ef4936e 100644 --- a/chrome/browser/ui/ash/ash_shell_init.h +++ b/chrome/browser/ui/ash/ash_shell_init.h
@@ -9,7 +9,7 @@ class PrefRegistrySimple; -// Initializes and destroys the ash::Shell for ash::Config::CLASSIC. +// Initializes and destroys the ash::Shell when Ash is running in process. class AshShellInit { public: AshShellInit();
diff --git a/chrome/browser/ui/ash/ash_util.cc b/chrome/browser/ui/ash/ash_util.cc index 5b6bf89..b1ad20d 100644 --- a/chrome/browser/ui/ash/ash_util.cc +++ b/chrome/browser/ui/ash/ash_util.cc
@@ -10,27 +10,23 @@ #include "ash/public/interfaces/event_properties.mojom.h" #include "ash/shell.h" #include "base/macros.h" -#include "chrome/browser/chromeos/ash_config.h" #include "mojo/public/cpp/bindings/type_converter.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" #include "ui/aura/window_event_dispatcher.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" namespace ash_util { bool ShouldOpenAshOnStartup() { - return !IsRunningInMash(); -} - -bool IsRunningInMash() { - return chromeos::GetAshConfig() == ash::Config::MASH; + return features::IsAshInBrowserProcess(); } bool IsAcceleratorDeprecated(const ui::Accelerator& accelerator) { // When running in mash the browser doesn't handle ash accelerators. - if (IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) return false; return ash::Shell::Get()->accelerator_controller()->IsDeprecated(accelerator); @@ -47,7 +43,7 @@ DCHECK_GE(container_id, ash::kShellWindowId_MinContainer); DCHECK_LE(container_id, ash::kShellWindowId_MaxContainer); - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { using ui::mojom::WindowManager; params->mus_properties[WindowManager::kContainerId_InitProperty] = mojo::ConvertTo<std::vector<uint8_t>>(container_id);
diff --git a/chrome/browser/ui/ash/ash_util.h b/chrome/browser/ui/ash/ash_util.h index c6eeed5..7ca78c8 100644 --- a/chrome/browser/ui/ash/ash_util.h +++ b/chrome/browser/ui/ash/ash_util.h
@@ -7,7 +7,6 @@ #include <memory> -#include "ash/public/cpp/config.h" #include "ui/views/widget/widget.h" namespace ui { @@ -20,10 +19,6 @@ // Returns true if Ash should be run at startup. bool ShouldOpenAshOnStartup(); -// Returns true if Chrome is running in the mash shell. -// TODO(sky): convert to chromeos::GetAshConfig() and remove. -bool IsRunningInMash(); - // Returns true if the given |accelerator| has been deprecated and hence can // be consumed by web contents if needed. bool IsAcceleratorDeprecated(const ui::Accelerator& accelerator);
diff --git a/chrome/browser/ui/ash/assistant/assistant_client.cc b/chrome/browser/ui/ash/assistant/assistant_client.cc index f5ee870..1e49c84 100644 --- a/chrome/browser/ui/ash/assistant/assistant_client.cc +++ b/chrome/browser/ui/ash/assistant/assistant_client.cc
@@ -8,6 +8,7 @@ #include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" +#include "chrome/browser/ui/ash/assistant/assistant_context_util.h" #include "chrome/browser/ui/ash/assistant/assistant_image_downloader.h" #include "chrome/browser/ui/ash/assistant/assistant_setup.h" #include "chrome/browser/ui/ash/assistant/web_contents_manager.h" @@ -25,10 +26,7 @@ return g_instance; } -AssistantClient::AssistantClient() - : client_binding_(this), - audio_input_binding_(&audio_input_), - context_binding_(&context_) { +AssistantClient::AssistantClient() : client_binding_(this) { DCHECK_EQ(nullptr, g_instance); g_instance = this; } @@ -36,7 +34,6 @@ AssistantClient::~AssistantClient() { DCHECK(g_instance); g_instance = nullptr; - context_binding_.Close(); } void AssistantClient::MaybeInit(service_manager::Connector* connector) { @@ -46,17 +43,10 @@ initialized_ = true; connector->BindInterface(chromeos::assistant::mojom::kServiceName, &assistant_connection_); - chromeos::assistant::mojom::AudioInputPtr audio_input_ptr; - audio_input_binding_.Bind(mojo::MakeRequest(&audio_input_ptr)); chromeos::assistant::mojom::ClientPtr client_ptr; client_binding_.Bind(mojo::MakeRequest(&client_ptr)); - - chromeos::assistant::mojom::ContextPtr context_ptr; - context_binding_.Bind(mojo::MakeRequest(&context_ptr)); - - assistant_connection_->Init(std::move(client_ptr), std::move(context_ptr), - std::move(audio_input_ptr)); + assistant_connection_->Init(std::move(client_ptr)); assistant_image_downloader_ = std::make_unique<AssistantImageDownloader>(connector); @@ -69,3 +59,8 @@ running ? ash::mojom::VoiceInteractionState::RUNNING : ash::mojom::VoiceInteractionState::STOPPED); } + +void AssistantClient::RequestAssistantStructure( + RequestAssistantStructureCallback callback) { + RequestAssistantStructureForActiveBrowserWindow(std::move(callback)); +}
diff --git a/chrome/browser/ui/ash/assistant/assistant_client.h b/chrome/browser/ui/ash/assistant/assistant_client.h index 193fbdd..ec18971 100644 --- a/chrome/browser/ui/ash/assistant/assistant_client.h +++ b/chrome/browser/ui/ash/assistant/assistant_client.h
@@ -8,8 +8,6 @@ #include <memory> #include "base/macros.h" -#include "chrome/browser/ui/ash/assistant/assistant_context.h" -#include "chrome/browser/ui/ash/assistant/platform_audio_input_host.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "mojo/public/cpp/bindings/binding.h" @@ -33,18 +31,12 @@ // assistant::mojom::Client overrides: void OnAssistantStatusChanged(bool running) override; + void RequestAssistantStructure( + RequestAssistantStructureCallback callback) override; private: mojo::Binding<chromeos::assistant::mojom::Client> client_binding_; - chromeos::assistant::mojom::AssistantPlatformPtr assistant_connection_; - mojo::Binding<chromeos::assistant::mojom::AudioInput> audio_input_binding_; - - mojo::Binding<chromeos::assistant::mojom::Context> context_binding_; - - PlatformAudioInputHost audio_input_; - - AssistantContext context_; std::unique_ptr<AssistantImageDownloader> assistant_image_downloader_; std::unique_ptr<AssistantSetup> assistant_setup_;
diff --git a/chrome/browser/ui/ash/assistant/assistant_context.cc b/chrome/browser/ui/ash/assistant/assistant_context.cc deleted file mode 100644 index 3ebca6c..0000000 --- a/chrome/browser/ui/ash/assistant/assistant_context.cc +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/ash/assistant/assistant_context.h" - -#include "chrome/browser/ui/ash/assistant/assistant_context_util.h" - -AssistantContext::AssistantContext() = default; -AssistantContext::~AssistantContext() = default; - -void AssistantContext::RequestAssistantStructure( - RequestAssistantStructureCallback callback) { - RequestAssistantStructureForActiveBrowserWindow(std::move(callback)); -}
diff --git a/chrome/browser/ui/ash/assistant/assistant_context.h b/chrome/browser/ui/ash/assistant/assistant_context.h deleted file mode 100644 index 0e873e9..0000000 --- a/chrome/browser/ui/ash/assistant/assistant_context.h +++ /dev/null
@@ -1,26 +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. - -#ifndef CHROME_BROWSER_UI_ASH_ASSISTANT_ASSISTANT_CONTEXT_H_ -#define CHROME_BROWSER_UI_ASH_ASSISTANT_ASSISTANT_CONTEXT_H_ - -#include "base/macros.h" -#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" - -// Class for Assistant to retrieve view hierarchy information from browser -// windows. -class AssistantContext : public chromeos::assistant::mojom::Context { - public: - AssistantContext(); - ~AssistantContext() override; - - // mojom::Context overrides - void RequestAssistantStructure( - RequestAssistantStructureCallback callback) override; - - private: - DISALLOW_COPY_AND_ASSIGN(AssistantContext); -}; - -#endif // CHROME_BROWSER_UI_ASH_ASSISTANT_ASSISTANT_CONTEXT_H_
diff --git a/chrome/browser/ui/ash/assistant/assistant_context_browsertest.cc b/chrome/browser/ui/ash/assistant/assistant_context_browsertest.cc index 8a0f93e..b60ef92e1 100644 --- a/chrome/browser/ui/ash/assistant/assistant_context_browsertest.cc +++ b/chrome/browser/ui/ash/assistant/assistant_context_browsertest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/ash/assistant/assistant_context.h" +#include "chrome/browser/ui/ash/assistant/assistant_client.h" #include <string> #include <vector>
diff --git a/chrome/browser/ui/ash/assistant/platform_audio_input_host.cc b/chrome/browser/ui/ash/assistant/platform_audio_input_host.cc deleted file mode 100644 index a5af4e3..0000000 --- a/chrome/browser/ui/ash/assistant/platform_audio_input_host.cc +++ /dev/null
@@ -1,140 +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. - -#include "chrome/browser/ui/ash/assistant/platform_audio_input_host.h" - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/logging.h" -#include "base/single_thread_task_runner.h" -#include "media/audio/audio_input_controller.h" -#include "media/audio/audio_manager.h" -#include "media/base/audio_bus.h" -#include "media/base/audio_parameters.h" -#include "media/base/audio_sample_types.h" -#include "media/base/channel_layout.h" - -namespace { - -void NotifyDataAvailable(const base::WeakPtr<PlatformAudioInputHost>& host, - const std::vector<int32_t>& data, - int32_t frames, - base::TimeTicks capture_time) { - if (host) - host->NotifyDataAvailable(std::move(data), frames, capture_time); -} - -void NotifyAudioClosed(const base::WeakPtr<PlatformAudioInputHost>& host) { - if (host) - host->NotifyAudioClosed(); -} - -} // namespace - -class PlatformAudioInputHost::Writer - : public media::AudioInputController::SyncWriter { - public: - Writer(base::WeakPtr<PlatformAudioInputHost> host, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : host_(std::move(host)), task_runner_(task_runner) {} - ~Writer() override = default; - - // media::AudioInputController::SyncWriter overrides: - void Write(const media::AudioBus* data, - double volume, - bool key_pressed, - base::TimeTicks capture_time) override { - // 2 channels * # of frames. - std::vector<int32_t> buffer(2 * data->frames()); - data->ToInterleaved<media::SignedInt32SampleTypeTraits>(data->frames(), - buffer.data()); - - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&::NotifyDataAvailable, host_, std::move(buffer), - data->frames(), capture_time)); - } - - void Close() override { - task_runner_->PostTask(FROM_HERE, - base::BindOnce(&::NotifyAudioClosed, host_)); - } - - private: - base::WeakPtr<PlatformAudioInputHost> host_; - - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - - DISALLOW_COPY_AND_ASSIGN(Writer); -}; - -class PlatformAudioInputHost::EventHandler - : public media::AudioInputController::EventHandler { - public: - EventHandler() = default; - ~EventHandler() override = default; - - // media::AudioInputController::EventHandler overrides: - void OnCreated(bool initially_muted) override {} - void OnError(media::AudioInputController::ErrorCode error_code) override {} - void OnLog(base::StringPiece log) override {} - void OnMuted(bool is_muted) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(EventHandler); -}; - -PlatformAudioInputHost::PlatformAudioInputHost() : weak_factory_(this) { - sync_writer_ = std::make_unique<Writer>(weak_factory_.GetWeakPtr(), - base::ThreadTaskRunnerHandle::Get()); - event_handler_ = std::make_unique<EventHandler>(); - audio_input_controller_ = media::AudioInputController::Create( - media::AudioManager::Get(), event_handler_.get(), sync_writer_.get(), - nullptr, - media::AudioParameters(media::AudioParameters::AUDIO_PCM_LINEAR, - media::CHANNEL_LAYOUT_STEREO, - 16000 /* 16000 frames per second */, - 1600 /* 1600 (16000 / 10) frames per buffer */), - "default" /* device_id */, false /* agc_is_enabled */); -} - -PlatformAudioInputHost::~PlatformAudioInputHost() { - // Bind |sync_writer_| and |event_handler_| to the callback closure to ensure - // they live longer than the |Close| call, which is async. - audio_input_controller_->Close( - base::BindOnce([](std::unique_ptr<EventHandler> event_handler, - std::unique_ptr<Writer> writer) {}, - std::move(event_handler_), std::move(sync_writer_))); -} - -void PlatformAudioInputHost::AddObserver( - chromeos::assistant::mojom::AudioInputObserverPtr observer) { - observers_.AddPtr(std::move(observer)); - if (!recording_) { - audio_input_controller_->Record(); - recording_ = true; - } -} - -void PlatformAudioInputHost::NotifyDataAvailable( - const std::vector<int32_t>& data, - int32_t frames, - base::TimeTicks capture_time) { - observers_.ForAllPtrs([&data, frames, capture_time](auto* observer) { - observer->OnAudioInputFramesAvailable(data, frames, capture_time); - }); - - if (observers_.empty() && recording_) { - recording_ = false; - audio_input_controller_->Close(base::DoNothing()); - } -} - -void PlatformAudioInputHost::NotifyAudioClosed() { - recording_ = false; - observers_.ForAllPtrs([](auto* observer) { observer->OnAudioInputClosed(); }); - observers_.CloseAll(); -}
diff --git a/chrome/browser/ui/ash/assistant/platform_audio_input_host.h b/chrome/browser/ui/ash/assistant/platform_audio_input_host.h deleted file mode 100644 index cb5044b4..0000000 --- a/chrome/browser/ui/ash/assistant/platform_audio_input_host.h +++ /dev/null
@@ -1,54 +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. - -#ifndef CHROME_BROWSER_UI_ASH_ASSISTANT_PLATFORM_AUDIO_INPUT_HOST_H_ -#define CHROME_BROWSER_UI_ASH_ASSISTANT_PLATFORM_AUDIO_INPUT_HOST_H_ - -#include <memory> -#include <vector> - -#include "base/memory/scoped_refptr.h" -#include "base/memory/weak_ptr.h" -#include "base/strings/string_piece_forward.h" -#include "base/time/time.h" -#include "chromeos/services/assistant/public/mojom/assistant.mojom.h" -#include "mojo/public/cpp/bindings/interface_ptr_set.h" - -namespace media { -class AudioInputController; -} // namespace media - -// Interacts with AudioController and forwards audio input stream to assistant. -class PlatformAudioInputHost : public chromeos::assistant::mojom::AudioInput { - public: - PlatformAudioInputHost(); - ~PlatformAudioInputHost() override; - - // mojom::AudioInput overrides: - void AddObserver( - chromeos::assistant::mojom::AudioInputObserverPtr observer) override; - - void NotifyDataAvailable(const std::vector<int32_t>& data, - int32_t frames, - base::TimeTicks capture_time); - void NotifyAudioClosed(); - - private: - class Writer; - class EventHandler; - - std::unique_ptr<Writer> sync_writer_; - std::unique_ptr<EventHandler> event_handler_; - scoped_refptr<media::AudioInputController> audio_input_controller_; - mojo::InterfacePtrSet<chromeos::assistant::mojom::AudioInputObserver> - observers_; - - bool recording_ = false; - - base::WeakPtrFactory<PlatformAudioInputHost> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(PlatformAudioInputHost); -}; - -#endif // CHROME_BROWSER_UI_ASH_ASSISTANT_PLATFORM_AUDIO_INPUT_HOST_H_
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc index 517f3eb..c2af305c 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -16,7 +16,6 @@ #include "base/command_line.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/night_light/night_light_client.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" @@ -64,6 +63,7 @@ #include "ui/aura/mus/property_converter.h" #include "ui/aura/mus/user_activity_forwarder.h" #include "ui/base/ime/chromeos/input_method_manager.h" +#include "ui/base/ui_base_features.h" #include "ui/base/user_activity/user_activity_detector.h" #include "ui/views/mus/mus_client.h" @@ -137,11 +137,16 @@ ChromeBrowserMainExtraPartsAsh::ChromeBrowserMainExtraPartsAsh() : notification_observer_(std::make_unique<NotificationObserver>()) {} -ChromeBrowserMainExtraPartsAsh::~ChromeBrowserMainExtraPartsAsh() {} +ChromeBrowserMainExtraPartsAsh::~ChromeBrowserMainExtraPartsAsh() { + // Views code observes TabletModeClient and may not be destroyed until + // ash::Shell is, so destroy |tablet_mode_client_| after ash::Shell. + // Also extensions need to remove observers after PostMainMessageLoopRun(). + tablet_mode_client_.reset(); +} void ChromeBrowserMainExtraPartsAsh::ServiceManagerConnectionStarted( content::ServiceManagerConnection* connection) { - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { // ash::Shell will not be created because ash is running out-of-process. ash::Shell::SetIsBrowserProcessWithMash(); DCHECK(views::MusClient::Exists()); @@ -164,7 +169,7 @@ std::make_unique<NetworkConnectDelegateChromeOS>(); chromeos::NetworkConnect::Initialize(network_connect_delegate_.get()); - if (chromeos::GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { ash_shell_init_ = std::make_unique<AshShellInit>(); } else { immersive_context_ = std::make_unique<ImmersiveContextMus>(); @@ -232,7 +237,7 @@ } void ChromeBrowserMainExtraPartsAsh::PostProfileInit() { - if (chromeos::GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) chrome_shell_content_state_ = std::make_unique<ChromeShellContentState>(); cast_config_client_media_router_ = @@ -253,7 +258,7 @@ } // TODO(mash): Port TabScrubber. - if (chromeos::GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { // Initialize TabScrubber after the Ash Shell has been initialized. TabScrubber::GetInstance(); } @@ -306,10 +311,6 @@ chromeos::NetworkConnect::Shutdown(); network_connect_delegate_.reset(); - - // Views code observes TabletModeClient and may not be destroyed until - // ash::Shell is so destroy |tablet_mode_client_| after ash::Shell. - tablet_mode_client_.reset(); } class ChromeBrowserMainExtraPartsAsh::NotificationObserver
diff --git a/chrome/browser/ui/ash/chrome_keyboard_ui.cc b/chrome/browser/ui/ash/chrome_keyboard_ui.cc index 25cbede..9277db0 100644 --- a/chrome/browser/ui/ash/chrome_keyboard_ui.cc +++ b/chrome/browser/ui/ash/chrome_keyboard_ui.cc
@@ -283,9 +283,7 @@ } void ChromeKeyboardUI::UpdateInsetsForWindow(aura::Window* window) { - aura::Window* keyboard_container = - keyboard_controller()->GetContainerWindow(); - if (!ShouldWindowOverscroll(window)) + if (!ShouldWindowOverscroll(window) || !HasContentsWindow()) return; std::unique_ptr<content::RenderWidgetHostIterator> widgets( @@ -295,7 +293,7 @@ if (view && window->Contains(view->GetNativeView())) { gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen(); gfx::Rect intersect = gfx::IntersectRects( - window_bounds, keyboard_container->GetBoundsInScreen()); + window_bounds, GetContentsWindow()->GetBoundsInScreen()); int overlap = ShouldEnableInsets(window) ? intersect.height() : 0; if (overlap > 0 && overlap < window_bounds.height()) view->SetInsets(gfx::Insets(0, 0, overlap, 0)); @@ -313,10 +311,16 @@ SetupWebContents(keyboard_contents_.get()); LoadContents(GetVirtualKeyboardUrl()); keyboard_contents_->GetNativeView()->AddObserver(this); + keyboard_contents_->GetNativeView()->set_owned_by_parent(false); content::RenderWidgetHostView* view = keyboard_contents_->GetMainFrame()->GetView(); view->SetBackgroundColor(SK_ColorTRANSPARENT); view->GetNativeView()->SetTransparent(true); + + // By default, layers in WebContents are clipped at the window bounds, + // but this causes the shadows to be clipped too, so clipping needs to + // be disabled. + keyboard_contents_->GetNativeView()->layer()->SetMasksToBounds(false); } return keyboard_contents_->GetNativeView(); @@ -478,17 +482,14 @@ void ChromeKeyboardUI::SetShadowAroundKeyboard() { aura::Window* contents_window = keyboard_contents_->GetNativeView(); - if (!contents_window->parent()) - return; - if (!shadow_) { shadow_ = std::make_unique<ui::Shadow>(); shadow_->Init(wm::kShadowElevationActiveWindow); shadow_->layer()->SetVisible(true); - contents_window->parent()->layer()->Add(shadow_->layer()); + contents_window->layer()->Add(shadow_->layer()); } - shadow_->SetContentBounds(contents_window->bounds()); + shadow_->SetContentBounds(gfx::Rect(contents_window->bounds().size())); } void ChromeKeyboardUI::SetupWebContents(content::WebContents* contents) {
diff --git a/chrome/browser/ui/ash/chrome_shell_content_state.cc b/chrome/browser/ui/ash/chrome_shell_content_state.cc index 86920b7..82633ad 100644 --- a/chrome/browser/ui/ash/chrome_shell_content_state.cc +++ b/chrome/browser/ui/ash/chrome_shell_content_state.cc
@@ -4,9 +4,7 @@ #include "chrome/browser/ui/ash/chrome_shell_content_state.h" -#include "build/build_config.h" #include "chrome/browser/profiles/profile_manager.h" -#include "components/user_manager/user_manager.h" #include "content/public/browser/browser_context.h" namespace { @@ -32,6 +30,5 @@ } content::BrowserContext* ChromeShellContentState::GetActiveBrowserContext() { - DCHECK(user_manager::UserManager::Get()->GetLoggedInUsers().size()); return ProfileManager::GetActiveUserProfile(); }
diff --git a/chrome/browser/ui/ash/chrome_shell_content_state.h b/chrome/browser/ui/ash/chrome_shell_content_state.h index 8bb026b..528c179 100644 --- a/chrome/browser/ui/ash/chrome_shell_content_state.h +++ b/chrome/browser/ui/ash/chrome_shell_content_state.h
@@ -17,12 +17,6 @@ // Overridden from ash::ShellContentState: content::BrowserContext* GetActiveBrowserContext() override; - content::BrowserContext* GetBrowserContextByIndex( - ash::UserIndex index) override; - content::BrowserContext* GetBrowserContextForWindow( - aura::Window* window) override; - content::BrowserContext* GetUserPresentingBrowserContextForWindow( - aura::Window* window) override; private: DISALLOW_COPY_AND_ASSIGN(ChromeShellContentState);
diff --git a/chrome/browser/ui/ash/chrome_shell_content_state_chromeos.cc b/chrome/browser/ui/ash/chrome_shell_content_state_chromeos.cc deleted file mode 100644 index 5ee6abb..0000000 --- a/chrome/browser/ui/ash/chrome_shell_content_state_chromeos.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/ash/chrome_shell_content_state.h" - -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" -#include "components/account_id/account_id.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/browser_context.h" - -content::BrowserContext* ChromeShellContentState::GetBrowserContextByIndex( - ash::UserIndex index) { - DCHECK_LT(static_cast<size_t>(index), - user_manager::UserManager::Get()->GetLoggedInUsers().size()); - user_manager::User* user = - user_manager::UserManager::Get()->GetLRULoggedInUsers()[index]; - CHECK(user); - return chromeos::ProfileHelper::Get()->GetProfileByUser(user); -} - -content::BrowserContext* ChromeShellContentState::GetBrowserContextForWindow( - aura::Window* window) { - DCHECK(window); - // Speculative fix for multi-profile crash. crbug.com/661821 - if (!MultiUserWindowManager::GetInstance()) - return nullptr; - - const AccountId& account_id = - MultiUserWindowManager::GetInstance()->GetWindowOwner(window); - return account_id.is_valid() - ? multi_user_util::GetProfileFromAccountId(account_id) - : nullptr; -} - -content::BrowserContext* -ChromeShellContentState::GetUserPresentingBrowserContextForWindow( - aura::Window* window) { - DCHECK(window); - // Speculative fix for multi-profile crash. crbug.com/661821 - if (!MultiUserWindowManager::GetInstance()) - return nullptr; - - const AccountId& account_id = - MultiUserWindowManager::GetInstance()->GetUserPresentingWindow(window); - return account_id.is_valid() - ? multi_user_util::GetProfileFromAccountId(account_id) - : nullptr; -}
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 0243dca..94f958a 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/browser_process_platform_part_chromeos.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/policy/display_rotation_default_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -39,6 +38,7 @@ #include "content/public/common/url_constants.h" #include "services/ui/public/cpp/input_devices/input_device_controller_client.h" #include "ui/aura/window.h" +#include "ui/base/ui_base_features.h" #include "url/url_constants.h" using chromeos::AccessibilityManager; @@ -104,7 +104,7 @@ void ChromeShellDelegate::PreInit() { // TODO: port to mash. http://crbug.com/678949. - if (chromeos::GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return; // Object owns itself and deletes itself in OnWindowTreeHostManagerShutdown().
diff --git a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc index 6824529..cbfeb5578 100644 --- a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc +++ b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
@@ -181,7 +181,8 @@ controller->ShowKeyboard(true); controller->ui()->GetContentsWindow()->SetBounds(test_bounds); controller->NotifyContentsLoaded(); - gfx::Rect keyboard_bounds = controller->GetContainerWindow()->bounds(); + + gfx::Rect keyboard_bounds = controller->GetContentsWindow()->bounds(); // Starts overscroll. controller->NotifyContentsBoundsChanging(keyboard_bounds);
diff --git a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc index 1033a1d8..545fd12 100644 --- a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc +++ b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
@@ -8,7 +8,6 @@ #include "ash/public/cpp/shelf_types.h" #include "base/macros.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h"
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc index 959e7dc..efa648da 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -21,7 +21,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/extensions/chrome_app_icon_loader.h" #include "chrome/browser/extensions/extension_util.h" @@ -35,7 +34,6 @@ #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/app_list/crostini/crostini_app_icon_loader.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_icon_loader.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" @@ -79,6 +77,7 @@ #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_features.h" #include "ui/display/types/display_constants.h" #include "ui/keyboard/keyboard_util.h" #include "ui/resources/grit/ui_resources.h" @@ -554,7 +553,7 @@ // user. RestoreUnpinnedRunningApplicationOrder(user_email); // TODO(crbug.com/557406): Fix this interaction pattern in Mash. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { // Force on-screen keyboard to reset. if (keyboard::IsKeyboardEnabled()) ash::Shell::Get()->EnableKeyboard(); @@ -1005,7 +1004,7 @@ : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED); } // TODO(crbug.com/557406): Fix this interaction pattern in Mash. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { const bool is_enabled = keyboard::IsKeyboardEnabled(); if (was_enabled && !is_enabled) ash::Shell::Get()->DisableKeyboard();
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index ecb98c6..3adfc3b3 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -39,7 +39,6 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/test_extension_system.h"
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc index a54b298a..8285cd1 100644 --- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc +++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "components/exo/shell_surface.h" #include "components/user_manager/user_manager.h" @@ -39,11 +39,9 @@ aura::Env* env = aura::Env::GetInstanceDontCreate(); if (env) env->AddObserver(this); - BrowserList::AddObserver(this); } CrostiniAppWindowShelfController::~CrostiniAppWindowShelfController() { - BrowserList::RemoveObserver(this); for (auto window : observed_window_to_startup_id_) window.first->RemoveObserver(this); aura::Env* env = aura::Env::GetInstanceDontCreate(); @@ -142,15 +140,31 @@ crostini_app_display_.GetDisplayIdForStartupId(*startup_id); if (display_id == display::kInvalidDisplayId) return; - display::Display display; + + display::Display new_display; if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(display_id, - &display)) + &new_display)) return; - gfx::Rect bounds = window->bounds(); - gfx::Point origin = display.bounds().origin(); - origin.Offset(bounds.x(), bounds.y()); - bounds.set_origin(origin); - window->SetBoundsInScreen(bounds, display); + display::Display old_display = + display::Screen::GetScreen()->GetDisplayNearestWindow(window); + + // Adjust the window size and origin in proportion to the relative size of the + // display. + int old_width = old_display.bounds().width(); + int new_width = new_display.bounds().width(); + int old_height = old_display.bounds().height(); + int new_height = new_display.bounds().height(); + gfx::Rect old_bounds = window->bounds(); + gfx::Rect new_bounds(old_bounds.x() * new_width / old_width, + old_bounds.y() * new_height / old_height, + old_bounds.width() * new_width / old_width, + old_bounds.height() * new_height / old_height); + + // Transform the bounds in display to that in screen. + gfx::Point new_origin = new_display.bounds().origin(); + new_origin.Offset(new_bounds.x(), new_bounds.y()); + new_bounds.set_origin(new_origin); + window->SetBoundsInScreen(new_bounds, new_display); } void CrostiniAppWindowShelfController::OnWindowVisibilityChanged( @@ -165,6 +179,18 @@ if (app_window_it != aura_window_to_app_window_.end()) return; + // Handle browser windows, such as the Crostini terminal. + Browser* browser = chrome::FindBrowserWithWindow(window); + if (browser) { + base::Optional<std::string> app_id = + CrostiniAppIdFromAppName(browser->app_name()); + if (!app_id) + return; + RegisterAppWindow(window, app_id.value()); + return; + } + + // Handle genuine Crostini app windows. const std::string* window_app_id = exo::ShellSurface::GetApplicationId(window); if (window_app_id == nullptr) @@ -186,18 +212,6 @@ RegisterAppWindow(window, shelf_app_id); } -void CrostiniAppWindowShelfController::OnBrowserAdded(Browser* browser) { - // The Crostini Terminal opens in Crosh (a v1 App), but we override the - // Browser's app name so we can properly detect it. - if (!browser->is_type_popup() || !browser->is_app()) - return; - base::Optional<std::string> app_id = - CrostiniAppIdFromAppName(browser->app_name()); - if (!app_id) - return; - RegisterAppWindow(browser->window()->GetNativeWindow(), app_id.value()); -} - void CrostiniAppWindowShelfController::RegisterAppWindow( aura::Window* window, const std::string& shelf_app_id) {
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h index 9f91cc72..4a4b779 100644 --- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h +++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.h
@@ -15,7 +15,6 @@ #include "chrome/browser/chromeos/crostini/crostini_app_launch_observer.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/crostini_app_display.h" -#include "chrome/browser/ui/browser_list_observer.h" #include "mojo/public/cpp/bindings/binding.h" #include "ui/aura/env_observer.h" #include "ui/aura/window_observer.h" @@ -34,7 +33,6 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController, public aura::EnvObserver, public aura::WindowObserver, - public BrowserListObserver, public CrostiniAppLaunchObserver { public: explicit CrostiniAppWindowShelfController(ChromeLauncherController* owner); @@ -53,9 +51,6 @@ void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; void OnWindowDestroying(aura::Window* window) override; - // BrowserListObserver: - void OnBrowserAdded(Browser* browser) override; - // A Crostini app with |startup_id| is requested to launch on display with // |display_id|. void OnAppLaunchRequested(const std::string& startup_id,
diff --git a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc index 853b60f7..0c840429 100644 --- a/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/extension_app_window_launcher_controller.cc
@@ -11,7 +11,6 @@ #include "ash/public/cpp/window_properties.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_item_controller.h"
diff --git a/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc index b9fd53ee..36bfc12 100644 --- a/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc +++ b/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc
@@ -7,7 +7,6 @@ #include <utility> #include "base/bind.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/extensions/context_menu_matcher.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/launch_util.h"
diff --git a/chrome/browser/ui/ash/login_screen_client.cc b/chrome/browser/ui/ash/login_screen_client.cc index 2e5f225..f0c2d57 100644 --- a/chrome/browser/ui/ash/login_screen_client.cc +++ b/chrome/browser/ui/ash/login_screen_client.cc
@@ -118,6 +118,13 @@ } } +void LoginScreenClient::ShowResetScreen() { + if (chromeos::LoginDisplayHost::default_host()) { + chromeos::LoginDisplayHost::default_host()->StartWizard( + chromeos::OobeScreen::SCREEN_OOBE_RESET); + } +} + void LoginScreenClient::OnRemoveUserWarningShown() { ProfileMetrics::LogProfileDeleteUser( ProfileMetrics::DELETE_PROFILE_USER_MANAGER_SHOW_WARNING);
diff --git a/chrome/browser/ui/ash/login_screen_client.h b/chrome/browser/ui/ash/login_screen_client.h index 8460724c..894ad93 100644 --- a/chrome/browser/ui/ash/login_screen_client.h +++ b/chrome/browser/ui/ash/login_screen_client.h
@@ -75,6 +75,7 @@ void ShowGaiaSignin( bool can_close, const base::Optional<AccountId>& prefilled_account) override; + void ShowResetScreen() override; void OnRemoveUserWarningShown() override; void RemoveUser(const AccountId& account_id) override; void LaunchPublicSession(const AccountId& account_id,
diff --git a/chrome/browser/ui/ash/media_client.cc b/chrome/browser/ui/ash/media_client.cc index 88bf9ca7..722e4ed 100644 --- a/chrome/browser/ui/ash/media_client.cc +++ b/chrome/browser/ui/ash/media_client.cc
@@ -12,9 +12,9 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/extensions/media_player_api.h" #include "chrome/browser/chromeos/extensions/media_player_event_router.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/chrome_shell_content_state.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" @@ -198,10 +198,10 @@ // asynchronous (see OnRequestUpdate's PostTask()), we're not worrying about // this right now. std::vector<MediaCaptureState> state; - for (uint32_t i = 0; - i < user_manager::UserManager::Get()->GetLoggedInUsers().size(); ++i) { - state.push_back( - GetMediaCaptureStateByIndex(static_cast<ash::UserIndex>(i))); + for (user_manager::User* user : + user_manager::UserManager::Get()->GetLoggedInUsers()) { + state.push_back(GetMediaCaptureStateOfAllWebContents( + chromeos::ProfileHelper::Get()->GetProfileByUser(user))); } media_controller_->NotifyCaptureState(std::move(state)); @@ -225,10 +225,3 @@ FROM_HERE, base::BindOnce(&MediaClient::RequestCaptureState, weak_ptr_factory_.GetWeakPtr())); } - -MediaCaptureState MediaClient::GetMediaCaptureStateByIndex(int user_index) { - content::BrowserContext* context = - ChromeShellContentState::GetInstance()->GetBrowserContextByIndex( - user_index); - return GetMediaCaptureStateOfAllWebContents(context); -}
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc index 3813a026..0818662 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager.cc
@@ -5,13 +5,13 @@ #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" #include "base/logging.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h" #include "chrome/browser/ui/ash/session_controller_client.h" #include "components/account_id/account_id.h" #include "components/user_manager/user_info.h" #include "components/user_manager/user_manager.h" +#include "ui/base/ui_base_features.h" namespace { MultiUserWindowManager* g_multi_user_window_manager_instance = nullptr; @@ -26,7 +26,7 @@ DCHECK(!g_multi_user_window_manager_instance); // TODO(crbug.com/557406): Enable this component in Mash. The object itself // has direct ash dependencies. - if (!ash_util::IsRunningInMash() && + if (features::IsAshInBrowserProcess() && SessionControllerClient::IsMultiProfileAvailable()) { MultiUserWindowManagerChromeOS* manager = new MultiUserWindowManagerChromeOS(
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc index 609af07..6a5a1d7e 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc
@@ -17,7 +17,6 @@ #include "base/strings/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/media_client.h" @@ -37,6 +36,7 @@ #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_tree_host.h" +#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_types.h" #include "ui/events/event.h" #include "ui/wm/core/transient_window_manager.h" @@ -719,7 +719,7 @@ if (visible) { // TODO(erg): When we get rid of the classic ash, get rid of the direct // linkage on tablet_mode_controller() here. - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { aura::WindowTreeHostMus::ForWindow(window)->PerformWmAction( ash::mojom::kAddWindowToTabletMode); } else {
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc index 1ddce9e..0429a80 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos_unittest.cc
@@ -88,29 +88,6 @@ : NULL; } - content::BrowserContext* GetBrowserContextByIndex( - ash::UserIndex index) override { - return nullptr; - } - - content::BrowserContext* GetBrowserContextForWindow( - aura::Window* window) override { - const AccountId& account_id = - MultiUserWindowManager::GetInstance()->GetWindowOwner(window); - return account_id.is_valid() - ? multi_user_util::GetProfileFromAccountId(account_id) - : nullptr; - } - - content::BrowserContext* GetUserPresentingBrowserContextForWindow( - aura::Window* window) override { - const AccountId& account_id = - MultiUserWindowManager::GetInstance()->GetUserPresentingWindow(window); - return account_id.is_valid() - ? multi_user_util::GetProfileFromAccountId(account_id) - : nullptr; - } - DISALLOW_COPY_AND_ASSIGN(TestShellContentState); };
diff --git a/chrome/browser/ui/ash/session_util.cc b/chrome/browser/ui/ash/session_util.cc index 92aaccd..47e0dcd 100644 --- a/chrome/browser/ui/ash/session_util.cc +++ b/chrome/browser/ui/ash/session_util.cc
@@ -4,11 +4,12 @@ #include "chrome/browser/ui/ash/session_util.h" -#include "ash/content/shell_content_state.h" #include "build/build_config.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" #include "chrome/grit/theme_resources.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_context.h" @@ -16,6 +17,31 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image_skia_operations.h" +namespace { + +// Gets the browser context (profile) associated with |window|. Either the +// profile of the user who owns the window or the profile of the desktop on +// which the window is positioned (for teleported windows) is returned, based on +// |presenting|. +content::BrowserContext* GetBrowserContextForWindow(aura::Window* window, + bool presenting) { + DCHECK(window); + // Speculative fix for multi-profile crash. crbug.com/661821 + if (!MultiUserWindowManager::GetInstance()) + return nullptr; + + const AccountId& account_id = + presenting + ? MultiUserWindowManager::GetInstance()->GetUserPresentingWindow( + window) + : MultiUserWindowManager::GetInstance()->GetWindowOwner(window); + return account_id.is_valid() + ? multi_user_util::GetProfileFromAccountId(account_id) + : nullptr; +} + +} // namespace + content::BrowserContext* GetActiveBrowserContext() { DCHECK(user_manager::UserManager::Get()->GetLoggedInUsers().size()); return ProfileManager::GetActiveUserProfile(); @@ -28,11 +54,10 @@ if (user_manager::UserManager::Get()->GetLoggedInUsers().size() > 1u) { content::BrowserContext* active_browser_context = get_context_callback.Run(); - ash::ShellContentState* state = ash::ShellContentState::GetInstance(); content::BrowserContext* owner_browser_context = - state->GetBrowserContextForWindow(window); + GetBrowserContextForWindow(window, false); content::BrowserContext* shown_browser_context = - state->GetUserPresentingBrowserContextForWindow(window); + GetBrowserContextForWindow(window, true); if (owner_browser_context && active_browser_context && owner_browser_context != active_browser_context &&
diff --git a/chrome/browser/ui/ash/system_tray_client.cc b/chrome/browser/ui/ash/system_tray_client.cc index cd8b458..4ac868e 100644 --- a/chrome/browser/ui/ash/system_tray_client.cc +++ b/chrome/browser/ui/ash/system_tray_client.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/lifetime/termination_notification.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/browser/ui/singleton_tabs.h" @@ -57,6 +56,7 @@ #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" #include "third_party/cros_system_api/dbus/shill/dbus-constants.h" +#include "ui/base/ui_base_features.h" #include "ui/events/event_constants.h" #include "ui/views/widget/widget.h" #include "ui/views/window/dialog_delegate.h" @@ -177,7 +177,7 @@ // Place the dialog in the appropriate modal dialog container, either above // or below the lock screen, based on the login state. int container_id = GetDialogParentContainerId(); - if (ash_util::IsRunningInMash()) { + if (!features::IsAshInBrowserProcess()) { using ui::mojom::WindowManager; params.mus_properties[WindowManager::kContainerId_InitProperty] = mojo::ConvertTo<std::vector<uint8_t>>(container_id);
diff --git a/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc b/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc index a68dd584..c91dbc4a 100644 --- a/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc +++ b/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc
@@ -6,11 +6,9 @@ #include <stddef.h> -#include "ash/public/cpp/config.h" #include "base/memory/singleton.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/extensions/api/automation_internal/automation_event_router.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profiles_state.h" @@ -34,6 +32,7 @@ #include "ash/shell.h" // nogncheck #include "ash/wm/window_util.h" // nogncheck #include "components/session_manager/core/session_manager.h" +#include "ui/base/ui_base_features.h" #endif using content::BrowserContext; @@ -89,7 +88,7 @@ views::AXAuraObjCache::GetInstance()->SetDelegate(this); #if defined(OS_CHROMEOS) - if (chromeos::GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { aura::Window* active_window = ash::wm::GetActiveWindow(); if (active_window) { views::AXAuraObjWrapper* focus =
diff --git a/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.cc b/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.cc index 7e668151..16a85fe4 100644 --- a/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.cc +++ b/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.cc
@@ -6,17 +6,27 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" #include "chrome/common/channel_info.h" +#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/aura/window.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/views/accessibility/ax_aura_obj_cache.h" #include "ui/views/accessibility/ax_window_obj_wrapper.h" AXRootObjWrapper::AXRootObjWrapper() : alert_window_(new aura::Window(NULL)) { alert_window_->Init(ui::LAYER_NOT_DRAWN); + + if (display::Screen::GetScreen()) + display::Screen::GetScreen()->AddObserver(this); } AXRootObjWrapper::~AXRootObjWrapper() { + if (display::Screen::GetScreen()) + display::Screen::GetScreen()->RemoveObserver(this); + if (alert_window_) { delete alert_window_; alert_window_ = NULL; @@ -55,8 +65,29 @@ out_node_data->role = ax::mojom::Role::kDesktop; out_node_data->AddStringAttribute(ax::mojom::StringAttribute::kChromeChannel, chrome::GetChannelName()); + + display::Screen* screen = display::Screen::GetScreen(); + if (!screen) + return; + + const display::Display& display = screen->GetPrimaryDisplay(); + + // Utilize the display bounds to figure out if this screen is in landscape or + // portrait. We use this rather than |rotation| because some devices default + // to landscape, some in portrait. Encode landscape as horizontal state, + // portrait as vertical state. + if (display.bounds().width() > display.bounds().height()) + out_node_data->AddState(ax::mojom::State::kHorizontal); + else + out_node_data->AddState(ax::mojom::State::kVertical); } const ui::AXUniqueId& AXRootObjWrapper::GetUniqueId() const { return unique_id_; } + +void AXRootObjWrapper::OnDisplayMetricsChanged(const display::Display& display, + uint32_t changed_metrics) { + AutomationManagerAura::GetInstance()->OnEvent( + this, ax::mojom::Event::kLocationChanged); +}
diff --git a/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.h b/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.h index 189c6c5..dc7f548a 100644 --- a/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.h +++ b/chrome/browser/ui/aura/accessibility/ax_root_obj_wrapper.h
@@ -11,13 +11,19 @@ #include "base/macros.h" #include "ui/accessibility/platform/ax_unique_id.h" +#include "ui/display/display_observer.h" #include "ui/views/accessibility/ax_aura_obj_wrapper.h" namespace aura { class Window; } // namespace aura -class AXRootObjWrapper : public views::AXAuraObjWrapper { +namespace display { +class Display; +}; + +class AXRootObjWrapper : public views::AXAuraObjWrapper, + display::DisplayObserver { public: AXRootObjWrapper(); ~AXRootObjWrapper() override; @@ -36,6 +42,10 @@ const ui::AXUniqueId& GetUniqueId() const override; private: + // display::DisplayObserver: + void OnDisplayMetricsChanged(const display::Display& display, + uint32_t changed_metrics) override; + ui::AXUniqueId unique_id_; aura::Window* alert_window_;
diff --git a/chrome/browser/ui/aura/accessibility/ax_tree_source_aura.cc b/chrome/browser/ui/aura/accessibility/ax_tree_source_aura.cc index f9729d4f..0bf9f122 100644 --- a/chrome/browser/ui/aura/accessibility/ax_tree_source_aura.cc +++ b/chrome/browser/ui/aura/accessibility/ax_tree_source_aura.cc
@@ -8,10 +8,10 @@ #include <vector> -#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" +#include "ui/accessibility/ax_action_data.h" #include "ui/views/accessibility/ax_aura_obj_cache.h" #include "ui/views/accessibility/ax_aura_obj_wrapper.h" #include "ui/views/accessibility/ax_view_obj_wrapper.h"
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index f3ffe9f..618cc203 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_promo_util.h" #include "chrome/browser/ssl/insecure_sensitive_input_driver_factory.h" +#include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" #include "chrome/browser/ui/autofill/create_card_unmask_prompt_view.h" @@ -149,6 +150,22 @@ return nullptr; } +security_state::SecurityLevel +ChromeAutofillClient::GetSecurityLevelForUmaHistograms() { + SecurityStateTabHelper* helper = + ::SecurityStateTabHelper::FromWebContents(web_contents()); + + // If there is no helper, it means we are not in a "web" state (for example + // the file picker on CrOS). Return SECURITY_LEVEL_COUNT which will not be + // logged. + if (!helper) + return security_state::SecurityLevel::SECURITY_LEVEL_COUNT; + + security_state::SecurityInfo security_info; + helper->GetSecurityInfo(&security_info); + return security_info.security_level; +} + void ChromeAutofillClient::ShowAutofillSettings() { #if defined(OS_ANDROID) chrome::android::PreferencesLauncher::ShowAutofillSettings(web_contents());
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 899c479..accfc9ef 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -55,6 +55,7 @@ ukm::UkmRecorder* GetUkmRecorder() override; ukm::SourceId GetUkmSourceId() override; AddressNormalizer* GetAddressNormalizer() override; + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, UnmaskCardReason reason,
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc index ec5e42f..bf6cc9e 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/ui/autofill/save_card_bubble_view.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -44,7 +45,12 @@ web_contents_(web_contents), save_card_bubble_view_(nullptr), pref_service_( - user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())) {} + user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())) { + security_state::SecurityInfo security_info; + SecurityStateTabHelper::FromWebContents(web_contents) + ->GetSecurityInfo(&security_info); + security_level_ = security_info.security_level; +} SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() { if (save_card_bubble_view_) @@ -67,7 +73,8 @@ AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); card_ = card; local_save_card_callback_ = save_card_callback; @@ -94,7 +101,8 @@ AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); if (!LegalMessageLine::Parse(*legal_message, &legal_message_lines_, /*escape_apostrophes=*/true)) { @@ -102,7 +110,8 @@ AutofillMetrics::SAVE_CARD_PROMPT_END_INVALID_LEGAL_MESSAGE, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); return; } @@ -128,7 +137,8 @@ AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); ShowBubble(); } @@ -194,7 +204,8 @@ AutofillMetrics::LogSaveCardPromptMetric( AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); pref_service_->SetInteger( prefs::kAutofillAcceptSaveCreditCardPromptState, prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_ACCEPTED); @@ -206,7 +217,8 @@ AutofillMetrics::LogSaveCardPromptMetric( AutofillMetrics::SAVE_CARD_PROMPT_END_DENIED, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); pref_service_->SetInteger( prefs::kAutofillAcceptSaveCreditCardPromptState, prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_DENIED); @@ -218,7 +230,8 @@ AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEGAL_MESSAGE, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); } void SaveCardBubbleControllerImpl::OnBubbleClosed() { @@ -271,7 +284,8 @@ : AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_HIDDEN, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); } void SaveCardBubbleControllerImpl::OnVisibilityChanged( @@ -322,7 +336,8 @@ AutofillMetrics::LogSaveCardPromptMetric( AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, is_uploading_, is_reshow_, pref_service_->GetInteger( - prefs::kAutofillAcceptSaveCreditCardPromptState)); + prefs::kAutofillAcceptSaveCreditCardPromptState), + GetSecurityLevel()); } void SaveCardBubbleControllerImpl::UpdateIcon() { @@ -339,4 +354,9 @@ ui::PAGE_TRANSITION_LINK, false)); } +security_state::SecurityLevel SaveCardBubbleControllerImpl::GetSecurityLevel() + const { + return security_level_; +} + } // namespace autofill
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h index f5d362e..880261e 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h
@@ -11,6 +11,7 @@ #include "base/timer/elapsed_timer.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/ui/save_card_bubble_controller.h" +#include "components/security_state/core/security_state.h" #include "components/signin/core/browser/account_info.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -81,6 +82,9 @@ void OnVisibilityChanged(content::Visibility visibility) override; void WebContentsDestroyed() override; + // Gets the security level of the page. + virtual security_state::SecurityLevel GetSecurityLevel() const; + private: friend class content::WebContentsUserData<SaveCardBubbleControllerImpl>; @@ -136,6 +140,9 @@ // reasonable limit, then don't close the bubble upon navigation. std::unique_ptr<base::ElapsedTimer> timer_; + // The security level for the current context. + security_state::SecurityLevel security_level_; + DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleControllerImpl); };
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc index fe127dc..a6363dc 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
@@ -43,6 +43,10 @@ void set_elapsed(base::TimeDelta elapsed) { elapsed_ = elapsed; } + void set_security_level(security_state::SecurityLevel security_level) { + security_level_ = security_level; + } + void SimulateNavigation() { content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); std::unique_ptr<content::NavigationHandle> navigation_handle = @@ -54,8 +58,13 @@ protected: base::TimeDelta Elapsed() const override { return elapsed_; } + security_state::SecurityLevel GetSecurityLevel() const override { + return security_level_; + } + private: base::TimeDelta elapsed_; + security_state::SecurityLevel security_level_; }; class SaveCardBubbleControllerImplTest : public BrowserWithTestWindowTest { @@ -674,4 +683,35 @@ .empty()); } +TEST_F(SaveCardBubbleControllerImplTest, + LogSaveCardPromptMetricBySecurityLevel_Local) { + base::HistogramTester histogram_tester; + controller()->set_security_level(security_state::SecurityLevel::SECURE); + ShowLocalBubble(); + EXPECT_THAT( + histogram_tester.GetAllSamples( + "Security.SaveCardPromptMetric.Local.SECURE"), + ElementsAre(Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, 1), + Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1))); + EXPECT_TRUE(histogram_tester + .GetAllSamples("Security.SaveCardPromptMetric.Upload.SECURE") + .empty()); +} + +TEST_F(SaveCardBubbleControllerImplTest, + LogSaveCardPromptMetricBySecurityLevel_Upload) { + base::HistogramTester histogram_tester; + controller()->set_security_level(security_state::SecurityLevel::EV_SECURE); + ShowUploadBubble(); + EXPECT_THAT( + histogram_tester.GetAllSamples( + "Security.SaveCardPromptMetric.Upload.EV_SECURE"), + ElementsAre(Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, 1), + Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1))); + EXPECT_TRUE( + histogram_tester + .GetAllSamples("Security.SaveCardPromptMetric.Local.EV_SECURE") + .empty()); +} + } // namespace autofill
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 9dcfbd6..9ebef3f 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1698,7 +1698,8 @@ void Browser::RendererUnresponsive( WebContents* source, - content::RenderWidgetHost* render_widget_host) { + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { // Ignore hangs if a tab is blocked. int index = tab_strip_model_->GetIndexOfWebContents(source); DCHECK_NE(TabStripModel::kNoTab, index); @@ -1706,7 +1707,7 @@ return; TabDialogs::FromWebContents(source)->ShowHungRendererDialog( - render_widget_host); + render_widget_host, std::move(hang_monitor_restarter)); } void Browser::RendererResponsive(
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 39d8c201..bc82cff 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -626,7 +626,8 @@ content::WebContents* new_contents) override; void RendererUnresponsive( content::WebContents* source, - content::RenderWidgetHost* render_widget_host) override; + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override; void RendererResponsive( content::WebContents* source, content::RenderWidgetHost* render_widget_host) override;
diff --git a/chrome/browser/ui/cocoa/accelerator_utils_cocoa.mm b/chrome/browser/ui/cocoa/accelerator_utils_cocoa.mm index 1261ded..d51af844 100644 --- a/chrome/browser/ui/cocoa/accelerator_utils_cocoa.mm +++ b/chrome/browser/ui/cocoa/accelerator_utils_cocoa.mm
@@ -46,7 +46,7 @@ isARepeat:NO keyCode:accelerator.key_code()]; - return CommandForKeyEvent(event) != -1; + return CommandForKeyEvent(event).found(); } ui::Accelerator GetPrimaryChromeAcceleratorForBookmarkPage() {
diff --git a/chrome/browser/ui/cocoa/browser_dialogs_views_mac.cc b/chrome/browser/ui/cocoa/browser_dialogs_views_mac.cc index fade77ee..57dec6f3 100644 --- a/chrome/browser/ui/cocoa/browser_dialogs_views_mac.cc +++ b/chrome/browser/ui/cocoa/browser_dialogs_views_mac.cc
@@ -156,10 +156,11 @@ void ShowPasswordReuseWarningDialog( content::WebContents* web_contents, safe_browsing::ChromePasswordProtectionService* service, + safe_browsing::ReusedPasswordType password_type, safe_browsing::OnWarningDone done_callback) { safe_browsing::PasswordReuseModalWarningDialog* dialog = new safe_browsing::PasswordReuseModalWarningDialog( - web_contents, service, std::move(done_callback)); + web_contents, service, password_type, std::move(done_callback)); constrained_window::CreateBrowserModalDialogViews( dialog, web_contents->GetTopLevelNativeWindow()) ->Show();
diff --git a/chrome/browser/ui/cocoa/browser_dialogs_views_mac.h b/chrome/browser/ui/cocoa/browser_dialogs_views_mac.h index f7af950..27cbde7b 100644 --- a/chrome/browser/ui/cocoa/browser_dialogs_views_mac.h +++ b/chrome/browser/ui/cocoa/browser_dialogs_views_mac.h
@@ -104,6 +104,7 @@ void ShowPasswordReuseWarningDialog( content::WebContents* web_contents, safe_browsing::ChromePasswordProtectionService* service, + safe_browsing::ReusedPasswordType password_type, safe_browsing::OnWarningDone done_callback); } // namespace chrome
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index d1cfc8d..febe842 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -583,7 +583,7 @@ if (![BrowserWindowUtils shouldHandleKeyboardEvent:event]) return Result::NOT_HANDLED; - int command = CommandForKeyEvent(event.os_event); + int command = CommandForKeyEvent(event.os_event).chrome_command; if (command == -1) command = DelayedWebContentsCommandForKeyEvent(event.os_event); return command == -1 ? Result::NOT_HANDLED : Result::NOT_HANDLED_IS_SHORTCUT;
diff --git a/chrome/browser/ui/cocoa/browser_window_utils.mm b/chrome/browser/ui/cocoa/browser_window_utils.mm index b473db91..fb6e19b 100644 --- a/chrome/browser/ui/cocoa/browser_window_utils.mm +++ b/chrome/browser/ui/cocoa/browser_window_utils.mm
@@ -44,7 +44,7 @@ } + (int)getCommandId:(const NativeWebKeyboardEvent&)event { - return CommandForKeyEvent(event.os_event); + return CommandForKeyEvent(event.os_event).chrome_command; } + (BOOL)handleKeyboardEvent:(NSEvent*)event
diff --git a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm index dfbdded6..8fd5aaf 100644 --- a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm +++ b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm
@@ -5,6 +5,7 @@ #import "chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.h" #include "base/logging.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/extensions/global_shortcut_listener.h" #include "chrome/browser/global_keyboard_shortcuts_mac.h" #include "chrome/browser/ui/browser_command_controller.h" @@ -34,7 +35,8 @@ return NO; } -- (BOOL)prePerformKeyEquivalent:(NSEvent*)event window:(NSWindow*)window { +- (ui::PerformKeyEquivalentResult)prePerformKeyEquivalent:(NSEvent*)event + window:(NSWindow*)window { // TODO(erikchen): Detect symbolic hot keys, and force control to be passed // back to AppKit so that it can handle it correctly. // https://crbug.com/846893. @@ -44,13 +46,13 @@ NSObject<CommandDispatcherTarget>* target = static_cast<NSObject<CommandDispatcherTarget>*>(responder); if ([target isKeyLocked:event]) - return NO; + return ui::PerformKeyEquivalentResult::kUnhandled; } if ([self eventHandledByExtensionCommand:event priority:ui::AcceleratorManager:: kHighPriority]) { - return YES; + return ui::PerformKeyEquivalentResult::kHandled; } // The specification for this private extensions API is incredibly vague. For @@ -58,7 +60,7 @@ // a chance to handle the event. if (extensions::GlobalShortcutListener::GetInstance() ->IsShortcutHandlingSuspended()) { - return NO; + return ui::PerformKeyEquivalentResult::kUnhandled; } // If this keyEquivalent corresponds to a Chrome command, trigger it directly @@ -78,42 +80,53 @@ // TODO(erikchen): Add a throttle. Otherwise, it's possible for a user holding // down a hotkey [e.g. cmd + w] to accidentally close too many tabs! // https://crbug.com/846893. - int cmd = CommandForKeyEvent(event); - if (cmd != -1) { + CommandForKeyEventResult result = CommandForKeyEvent(event); + if (result.found()) { Browser* browser = chrome::FindBrowserWithWindow(window); - if (browser && browser->command_controller()->IsReservedCommandOrKey( - cmd, content::NativeWebKeyboardEvent(event))) { - chrome::ExecuteCommand(browser, cmd); - return YES; + if (browser && + browser->command_controller()->IsReservedCommandOrKey( + result.chrome_command, content::NativeWebKeyboardEvent(event))) { + if (result.from_main_menu) { + return ui::PerformKeyEquivalentResult::kPassToMainMenu; + } + + chrome::ExecuteCommand(browser, result.chrome_command); + return ui::PerformKeyEquivalentResult::kHandled; } } - return NO; + return ui::PerformKeyEquivalentResult::kUnhandled; } -- (BOOL)postPerformKeyEquivalent:(NSEvent*)event - window:(NSWindow*)window - isRedispatch:(BOOL)isRedispatch { +- (ui::PerformKeyEquivalentResult)postPerformKeyEquivalent:(NSEvent*)event + window:(NSWindow*)window + isRedispatch:(BOOL)isRedispatch { if ([self eventHandledByExtensionCommand:event priority:ui::AcceleratorManager:: kNormalPriority]) { - return true; + return ui::PerformKeyEquivalentResult::kHandled; } - int cmd = CommandForKeyEvent(event); + CommandForKeyEventResult result = CommandForKeyEvent(event); - if (cmd == -1 && isRedispatch) - cmd = DelayedWebContentsCommandForKeyEvent(event); + if (!result.found() && isRedispatch) { + result.chrome_command = DelayedWebContentsCommandForKeyEvent(event); + result.from_main_menu = false; + } - if (cmd != -1) { + if (result.found()) { Browser* browser = chrome::FindBrowserWithWindow(window); if (browser) { - chrome::ExecuteCommand(browser, cmd); - return true; + if (result.from_main_menu) { + return ui::PerformKeyEquivalentResult::kPassToMainMenu; + } + + chrome::ExecuteCommand(browser, result.chrome_command); + return ui::PerformKeyEquivalentResult::kHandled; } } - return false; + return ui::PerformKeyEquivalentResult::kUnhandled; } @end // ChromeCommandDispatchDelegate
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.h b/chrome/browser/ui/cocoa/hung_renderer_controller.h index c9f62830..9e72d53 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller.h +++ b/chrome/browser/ui/cocoa/hung_renderer_controller.h
@@ -21,6 +21,7 @@ #include <memory> +#include "base/callback.h" #import "base/mac/scoped_nsobject.h" @class MultiKeyEquivalentButton; @@ -44,6 +45,10 @@ content::WebContents* hungContents_; content::RenderWidgetHost* hungWidget_; + // Callback that restarts the hang timeout (e.g. if the user wants to wait + // some more until the renderer process responds). + base::RepeatingClosure hangMonitorRestarter_; + // Observes |hungContents_| in case it closes while the panel is up. std::unique_ptr<HungRendererObserverBridge> hungContentsObserver_; @@ -58,7 +63,8 @@ // Shows or hides the hung renderer dialog for the given WebContents. + (void)showForWebContents:(content::WebContents*)contents - renderWidgetHost:(content::RenderWidgetHost*)renderWidget; + renderWidgetHost:(content::RenderWidgetHost*)renderWidget + timeoutRestarter:(base::RepeatingClosure)timeoutRestarter; + (void)endForWebContents:(content::WebContents*)contents renderWidgetHost:(content::RenderWidgetHost*)renderWidget; + (bool)isShowing;
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.mm b/chrome/browser/ui/cocoa/hung_renderer_controller.mm index 8f295a6..ac70e4b 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller.mm +++ b/chrome/browser/ui/cocoa/hung_renderer_controller.mm
@@ -45,7 +45,8 @@ // process with |contents|. The caller must not delete any tab // contents without first calling endForWebContents. - (void)showForWebContents:(content::WebContents*)contents - renderWidgetHost:(content::RenderWidgetHost*)renderWidget; + renderWidgetHost:(content::RenderWidgetHost*)renderWidget + timeoutRestarter:(base::RepeatingClosure)timeoutRestarter; // Notifies the dialog that |contents| is either responsive or closed. // If |contents| shares the same render process as the tab contents @@ -187,13 +188,15 @@ } + (void)showForWebContents:(content::WebContents*)contents - renderWidgetHost:(content::RenderWidgetHost*)renderWidget { + renderWidgetHost:(content::RenderWidgetHost*)renderWidget + timeoutRestarter:(base::RepeatingClosure)timeoutRestarter { if (!logging::DialogsAreSuppressed()) { if (!g_hung_renderer_controller_instance) g_hung_renderer_controller_instance = [[HungRendererController alloc] initWithWindowNibName:@"HungRendererDialog"]; [g_hung_renderer_controller_instance showForWebContents:contents - renderWidgetHost:renderWidget]; + renderWidgetHost:renderWidget + timeoutRestarter:timeoutRestarter]; } } @@ -220,8 +223,8 @@ } - (IBAction)wait:(id)sender { - if (hungWidget_) - hungWidget_->RestartHangMonitorTimeoutIfNecessary(); + if (!hangMonitorRestarter_.is_null()) + hangMonitorRestarter_.Run(); // Cannot call performClose:, because the close button is disabled. [self close]; @@ -264,6 +267,7 @@ // button depressed just when new activity was detected. hungContents_ = nullptr; hungWidget_ = nullptr; + hangMonitorRestarter_ = base::RepeatingClosure(); // Reset the observer now. It is not necessarily the case that this class // actually holds a reference to the containing BrowserWindow, and if it does @@ -281,10 +285,13 @@ // activity!), so it would not add much value. Also, the views // implementation only monitors the initiating tab. - (void)showForWebContents:(WebContents*)contents - renderWidgetHost:(content::RenderWidgetHost*)renderWidget { + renderWidgetHost:(content::RenderWidgetHost*)renderWidget + timeoutRestarter:(base::RepeatingClosure)timeoutRestarter { DCHECK(contents); + DCHECK(!timeoutRestarter.is_null()); hungContents_ = contents; hungWidget_ = renderWidget; + hangMonitorRestarter_ = timeoutRestarter; hungContentsObserver_.reset( new HungRendererObserverBridge(contents, renderWidget, self)); @@ -313,6 +320,7 @@ DCHECK(hungContents_); DCHECK(renderWidget); DCHECK(hungWidget_); + DCHECK(!hangMonitorRestarter_.is_null()); if (hungContents_ && hungWidget_ == renderWidget) { // Cannot call performClose:, because the close button is disabled. [self close]; @@ -327,8 +335,8 @@ - (void)tabUpdated { // Tab was updated so restart the hang monitor if necessary and dismiss the // current dialog. - if (hungWidget_) - hungWidget_->RestartHangMonitorTimeoutIfNecessary(); + if (!hangMonitorRestarter_.is_null()) + hangMonitorRestarter_.Run(); [self close]; }
diff --git a/chrome/browser/ui/cocoa/media_picker/create_desktop_media_picker_cocoa.h b/chrome/browser/ui/cocoa/media_picker/create_desktop_media_picker_cocoa.h new file mode 100644 index 0000000..4ca31b9 --- /dev/null +++ b/chrome/browser/ui/cocoa/media_picker/create_desktop_media_picker_cocoa.h
@@ -0,0 +1,16 @@ +// 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_COCOA_MEDIA_PICKER_CREATE_DESKTOP_MEDIA_PICKER_COCOA_H_ +#define CHROME_BROWSER_UI_COCOA_MEDIA_PICKER_CREATE_DESKTOP_MEDIA_PICKER_COCOA_H_ + +#include <memory> + +#include "chrome/browser/media/webrtc/desktop_media_picker.h" + +// Returns a Cocoa DesktopMediaPicker or nullptr if the Views version should be +// used instead. +std::unique_ptr<DesktopMediaPicker> CreateDesktopMediaPickerCocoa(); + +#endif // CHROME_BROWSER_UI_COCOA_MEDIA_PICKER_CREATE_DESKTOP_MEDIA_PICKER_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/media_picker/create_desktop_media_picker_cocoa.mm b/chrome/browser/ui/cocoa/media_picker/create_desktop_media_picker_cocoa.mm new file mode 100644 index 0000000..5d45349 --- /dev/null +++ b/chrome/browser/ui/cocoa/media_picker/create_desktop_media_picker_cocoa.mm
@@ -0,0 +1,12 @@ +// 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/cocoa/media_picker/create_desktop_media_picker_cocoa.h" + +#import "chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.h" + +// static +std::unique_ptr<DesktopMediaPicker> CreateDesktopMediaPickerCocoa() { + return std::make_unique<DesktopMediaPickerCocoa>(); +}
diff --git a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm index 1036938..832c23c 100644 --- a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm +++ b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_cocoa.mm
@@ -27,8 +27,3 @@ requestAudio:params.request_audio]); [controller_ showWindow:nil]; } - -// static -std::unique_ptr<DesktopMediaPicker> DesktopMediaPicker::Create() { - return std::unique_ptr<DesktopMediaPicker>(new DesktopMediaPickerCocoa()); -}
diff --git a/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.h b/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.h index 60f8021a..bb6eb405 100644 --- a/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.h +++ b/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.h
@@ -22,6 +22,7 @@ PasswordReuseWarningDialogCocoa( content::WebContents* web_contents, safe_browsing::ChromePasswordProtectionService* service, + ReusedPasswordType password_type, safe_browsing::OnWarningDone callback); ~PasswordReuseWarningDialogCocoa() override; @@ -68,6 +69,9 @@ // Controller for the dialog view. base::scoped_nsobject<PasswordReuseWarningViewController> controller_; + // Type of password reuse that triggered this warning dialog. + ReusedPasswordType password_type_; + DISALLOW_COPY_AND_ASSIGN(PasswordReuseWarningDialogCocoa); };
diff --git a/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.mm b/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.mm index 0dc1be5..b22c62bd2 100644 --- a/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/password_reuse_warning_dialog_cocoa.mm
@@ -13,17 +13,18 @@ void ShowPasswordReuseModalWarningDialog( content::WebContents* web_contents, ChromePasswordProtectionService* service, + ReusedPasswordType password_type, OnWarningDone done_callback) { DCHECK(web_contents); if (chrome::ShowAllDialogsWithViewsToolkit()) { - chrome::ShowPasswordReuseWarningDialog(web_contents, service, + chrome::ShowPasswordReuseWarningDialog(web_contents, service, password_type, std::move(done_callback)); return; } // Dialog owns itself. - new PasswordReuseWarningDialogCocoa(web_contents, service, + new PasswordReuseWarningDialogCocoa(web_contents, service, password_type, std::move(done_callback)); } @@ -32,11 +33,13 @@ PasswordReuseWarningDialogCocoa::PasswordReuseWarningDialogCocoa( content::WebContents* web_contents, safe_browsing::ChromePasswordProtectionService* service, + ReusedPasswordType password_type, safe_browsing::OnWarningDone callback) : content::WebContentsObserver(web_contents), service_(service), url_(web_contents->GetLastCommittedURL()), - callback_(std::move(callback)) { + callback_(std::move(callback)), + password_type_(password_type) { controller_.reset( [[PasswordReuseWarningViewController alloc] initWithOwner:this]); @@ -119,5 +122,5 @@ } base::string16 PasswordReuseWarningDialogCocoa::GetWarningDetailText() { - return service_->GetWarningDetailText(); + return service_->GetWarningDetailText(password_type_); }
diff --git a/chrome/browser/ui/cocoa/tab_dialogs_cocoa.h b/chrome/browser/ui/cocoa/tab_dialogs_cocoa.h index 86564160..bb944f7 100644 --- a/chrome/browser/ui/cocoa/tab_dialogs_cocoa.h +++ b/chrome/browser/ui/cocoa/tab_dialogs_cocoa.h
@@ -18,7 +18,8 @@ gfx::NativeView GetDialogParentView() const override; void ShowCollectedCookies() override; void ShowHungRendererDialog( - content::RenderWidgetHost* render_widget_host) override; + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override; void HideHungRendererDialog( content::RenderWidgetHost* render_widget_host) override; bool IsShowingHungRendererDialog() override;
diff --git a/chrome/browser/ui/cocoa/tab_dialogs_cocoa.mm b/chrome/browser/ui/cocoa/tab_dialogs_cocoa.mm index eb8ae5d..5ac94bd1 100644 --- a/chrome/browser/ui/cocoa/tab_dialogs_cocoa.mm +++ b/chrome/browser/ui/cocoa/tab_dialogs_cocoa.mm
@@ -62,9 +62,11 @@ } void TabDialogsCocoa::ShowHungRendererDialog( - content::RenderWidgetHost* render_widget_host) { + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { [HungRendererController showForWebContents:web_contents_ - renderWidgetHost:render_widget_host]; + renderWidgetHost:render_widget_host + timeoutRestarter:hang_monitor_restarter]; } void TabDialogsCocoa::HideHungRendererDialog(
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc index 02eebaa5..969fb98 100644 --- a/chrome/browser/ui/extensions/application_launch.cc +++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -335,8 +335,8 @@ return OpenEnabledApplication(params); } -WebContents* OpenApplicationWindow(const AppLaunchParams& params, - const GURL& url) { +Browser* CreateApplicationWindow(const AppLaunchParams& params, + const GURL& url) { Profile* const profile = params.profile; const Extension* const extension = GetExtension(params); @@ -366,7 +366,13 @@ browser_params.initial_show_state = DetermineWindowShowState(profile, params.container, extension); - Browser* browser = new Browser(browser_params); + return new Browser(browser_params); +} + +WebContents* ShowApplicationWindow(const AppLaunchParams& params, + const GURL& url, + Browser* browser) { + const Extension* const extension = GetExtension(params); ui::PageTransition transition = (extension ? ui::PAGE_TRANSITION_AUTO_BOOKMARK : ui::PAGE_TRANSITION_AUTO_TOPLEVEL); @@ -379,7 +385,6 @@ WebContents* web_contents = nav_params.navigated_or_inserted_contents; extensions::HostedAppBrowserController::SetAppPrefsForWebContents( browser->hosted_app_controller(), web_contents); - browser->window()->Show(); // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial @@ -388,6 +393,12 @@ return web_contents; } +WebContents* OpenApplicationWindow(const AppLaunchParams& params, + const GURL& url) { + Browser* browser = CreateApplicationWindow(params, url); + return ShowApplicationWindow(params, url, browser); +} + void OpenApplicationWithReenablePrompt(const AppLaunchParams& params) { const Extension* extension = GetExtension(params); if (!extension)
diff --git a/chrome/browser/ui/extensions/application_launch.h b/chrome/browser/ui/extensions/application_launch.h index 3d6fd67..80c90bf 100644 --- a/chrome/browser/ui/extensions/application_launch.h +++ b/chrome/browser/ui/extensions/application_launch.h
@@ -25,6 +25,16 @@ // Open the application in a way specified by |params|. content::WebContents* OpenApplication(const AppLaunchParams& params); +// Create the application in a way specified by |params| in a new window but +// delaying activating and showing it. +Browser* CreateApplicationWindow(const AppLaunchParams& params, + const GURL& url); + +// Show the application window that's already created. +content::WebContents* ShowApplicationWindow(const AppLaunchParams& params, + const GURL& url, + Browser* browser); + // Open the application in a way specified by |params| in a new window. content::WebContents* OpenApplicationWindow(const AppLaunchParams& params, const GURL& url);
diff --git a/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc b/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc index 7712a47..87ea546 100644 --- a/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc +++ b/chrome/browser/ui/hung_renderer/hung_renderer_interactive_uitest.cc
@@ -4,6 +4,7 @@ #include <string> +#include "base/bind_helpers.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tab_dialogs.h" @@ -44,7 +45,8 @@ browser()->tab_strip_model()->GetActiveWebContents(); TabDialogs::FromWebContents(active_web_contents) ->ShowHungRendererDialog( - active_web_contents->GetRenderViewHost()->GetWidget()); + active_web_contents->GetRenderViewHost()->GetWidget(), + base::DoNothing::Repeatedly()); ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("b.com", "/title2.html")); // Expect that the dialog has been dismissed.
diff --git a/chrome/browser/ui/media_router/cast_dialog_controller.h b/chrome/browser/ui/media_router/cast_dialog_controller.h index d572005..e3aa857 100644 --- a/chrome/browser/ui/media_router/cast_dialog_controller.h +++ b/chrome/browser/ui/media_router/cast_dialog_controller.h
@@ -11,7 +11,7 @@ namespace media_router { -struct CastDialogModel; +class CastDialogModel; // Controller component of the Cast dialog. Responsible for handling user input, // updating the CastDialogModel, and notifying CastDialogView of updates.
diff --git a/chrome/browser/ui/media_router/cast_dialog_model.cc b/chrome/browser/ui/media_router/cast_dialog_model.cc index 2156466..5d606b8 100644 --- a/chrome/browser/ui/media_router/cast_dialog_model.cc +++ b/chrome/browser/ui/media_router/cast_dialog_model.cc
@@ -12,4 +12,12 @@ CastDialogModel::~CastDialogModel() = default; +base::Optional<size_t> CastDialogModel::GetFirstActiveSinkIndex() const { + for (size_t i = 0; i < media_sinks_.size(); i++) { + if (!media_sinks_.at(i).route_id.empty()) + return i; + } + return base::nullopt; +} + } // namespace media_router
diff --git a/chrome/browser/ui/media_router/cast_dialog_model.h b/chrome/browser/ui/media_router/cast_dialog_model.h index 98f7696..9b7ad59 100644 --- a/chrome/browser/ui/media_router/cast_dialog_model.h +++ b/chrome/browser/ui/media_router/cast_dialog_model.h
@@ -5,28 +5,40 @@ #ifndef CHROME_BROWSER_UI_MEDIA_ROUTER_CAST_DIALOG_MODEL_H_ #define CHROME_BROWSER_UI_MEDIA_ROUTER_CAST_DIALOG_MODEL_H_ +#include "base/optional.h" #include "base/strings/string16.h" #include "chrome/browser/ui/media_router/ui_media_sink.h" namespace media_router { // Holds data needed to populate a Cast dialog. -struct CastDialogModel { +class CastDialogModel { public: CastDialogModel(); CastDialogModel(const CastDialogModel& other); ~CastDialogModel(); - // The tab ID that the dialog is associated with. - // TODO(takumif): Set |tab_id| in the ctor. - int tab_id = -1; + // Returns the index of the first sink with an active route, or nullopt if + // there is no such sink. + base::Optional<size_t> GetFirstActiveSinkIndex() const; + void set_dialog_header(const base::string16& dialog_header) { + dialog_header_ = dialog_header; + } + const base::string16& dialog_header() const { return dialog_header_; } + + void set_media_sinks(const std::vector<UIMediaSink>& media_sinks) { + media_sinks_ = media_sinks; + } + const std::vector<UIMediaSink>& media_sinks() const { return media_sinks_; } + + private: // The header to use at the top of the dialog. // This reflects the current activity associated with the tab. - base::string16 dialog_header; + base::string16 dialog_header_; // Sink data in the order they should be shown in the dialog. - std::vector<UIMediaSink> media_sinks; + std::vector<UIMediaSink> media_sinks_; }; } // namespace media_router
diff --git a/chrome/browser/ui/media_router/media_router_ui_base.cc b/chrome/browser/ui/media_router/media_router_ui_base.cc index cb7efa2..17ff0d2 100644 --- a/chrome/browser/ui/media_router/media_router_ui_base.cc +++ b/chrome/browser/ui/media_router/media_router_ui_base.cc
@@ -23,14 +23,20 @@ #include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_tab_helper.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/common/media_router/media_route.h" #include "chrome/common/media_router/media_sink.h" #include "chrome/common/media_router/media_source.h" #include "chrome/common/media_router/media_source_helper.h" #include "chrome/common/media_router/route_request_result.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/common/fullscreen_video_element.mojom.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/constants.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/icu/source/i18n/unicode/coll.h" #include "ui/base/l10n/l10n_util.h" #include "url/origin.h" @@ -64,6 +70,113 @@ } // namespace +// Observes a WebContents and requests fullscreening of its first +// video element. The request is sent after the WebContents is loaded and tab +// capture has begun. Marked final to prevent inheritance so delete calls are +// contained to scenarios documented below. +class MediaRouterUIBase::WebContentsFullscreenOnLoadedObserver final + : public content::WebContentsObserver { + public: + WebContentsFullscreenOnLoadedObserver(const GURL& file_url, + content::WebContents* web_contents) + : file_url_(file_url), capture_poll_timer_(false, false) { + DCHECK(file_url_.SchemeIsFile()); + DCHECK(fullscreen_request_time_.is_null()); + + // If the WebContents is loading, start listening, otherwise just call the + // fullscreen function. + + // This class destroys itself in the following situations (at least one of + // which will occur): + // * after loading is complete and, + // ** capture has begun and fullscreen requested, + // ** kMaxSecondsToWaitForCapture seconds have passed without capture, + // * another navigation is started, + // * the WebContents is destroyed. + if (web_contents->IsLoading()) { + Observe(web_contents); + } else { + FullScreenFirstVideoElement(web_contents); + } + } + ~WebContentsFullscreenOnLoadedObserver() override {} + + // content::WebContentsObserver implementation. + void DidStopLoading() override { + FullScreenFirstVideoElement(web_contents()); + } + + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override { + // If the user takes over and navigates away from the file, stop listening. + // (It is possible however for this listener to be created before the + // navigation to the requested file triggers, so provided we're still on the + // same URL, go ahead and keep listening). + if (file_url_ != navigation_handle->GetURL()) { + delete this; + } + } + + void WebContentsDestroyed() override { + // If the WebContents is destroyed we will never trigger and need to clean + // up. + delete this; + } + + private: + const GURL file_url_; + + // Time intervals used by the logic that detects if capture has started. + const int kMaxSecondsToWaitForCapture = 10; + const int kPollIntervalInSeconds = 1; + + // The time at which fullscreen was requested. + base::TimeTicks fullscreen_request_time_; + + // Poll timer to monitor the capturer count when fullscreening local files. + // + // TODO(crbug.com/540965): Add a method to WebContentsObserver to report + // capturer count changes and get rid of this polling-based approach. + base::Timer capture_poll_timer_; + + // Sends a request for full screen to the WebContents targeted at the first + // video element. The request is only sent after capture has begun. + void FullScreenFirstVideoElement(content::WebContents* web_contents) { + if (file_url_ != web_contents->GetLastCommittedURL()) { + // The user has navigated before the casting started. Do not attempt to + // fullscreen and cleanup. + return; + } + + fullscreen_request_time_ = base::TimeTicks::Now(); + FullscreenIfContentCaptured(web_contents); + } + + void FullscreenIfContentCaptured(content::WebContents* web_contents) { + if (web_contents->IsBeingCaptured()) { + content::mojom::FullscreenVideoElementHandlerAssociatedPtr client; + web_contents->GetMainFrame() + ->GetRemoteAssociatedInterfaces() + ->GetInterface(&client); + client->RequestFullscreenVideoElement(); + delete this; + return; + } else if (base::TimeTicks::Now() - fullscreen_request_time_ > + base::TimeDelta::FromSeconds(kMaxSecondsToWaitForCapture)) { + // If content capture hasn't started within the timeout skip fullscreen. + DLOG(WARNING) << "Capture of local content did not start within timeout"; + delete this; + return; + } + + capture_poll_timer_.Start( + FROM_HERE, base::TimeDelta::FromSeconds(kPollIntervalInSeconds), + base::BindRepeating( + &WebContentsFullscreenOnLoadedObserver::FullscreenIfContentCaptured, + base::Unretained(this), web_contents)); + } +}; + MediaRouterUIBase::MediaRouterUIBase() : initiator_(nullptr), weak_factory_(this) {} @@ -139,8 +252,18 @@ bool MediaRouterUIBase::CreateRoute(const MediaSink::Id& sink_id, MediaCastMode cast_mode) { - base::Optional<RouteParameters> params = - GetRouteParameters(sink_id, cast_mode); + // Default the tab casting the content to the initiator, and change if + // necessary. + content::WebContents* tab_contents = initiator_; + + base::Optional<RouteParameters> params; + if (cast_mode == MediaCastMode::LOCAL_FILE) { + GURL url = media_router_file_dialog_->GetLastSelectedFileUrl(); + tab_contents = OpenTabWithUrl(url); + params = GetLocalFileRouteParameters(sink_id, url, tab_contents); + } else { + params = GetRouteParameters(sink_id, cast_mode); + } if (!params) { SendIssueForUnableToCast(cast_mode); return false; @@ -148,7 +271,7 @@ GetIssueManager()->ClearNonBlockingIssues(); GetMediaRouter()->CreateRoute(params->source_id, sink_id, params->origin, - initiator_, + tab_contents, std::move(params->route_response_callbacks), params->timeout, params->incognito); return true; @@ -192,10 +315,10 @@ std::string MediaRouterUIBase::GetTruncatedPresentationRequestSourceName() const { GURL gurl = GetFrameURL(); - CHECK(initiator()); + CHECK(initiator_); return gurl.SchemeIs(extensions::kExtensionScheme) ? GetExtensionName(gurl, extensions::ExtensionRegistry::Get( - initiator()->GetBrowserContext())) + initiator_->GetBrowserContext())) : TruncateHost(GetHostFromURL(gurl)); } @@ -207,6 +330,14 @@ GetIssueManager()->ClearIssue(issue_id); } +void MediaRouterUIBase::OpenFileDialog() { + if (!media_router_file_dialog_) { + media_router_file_dialog_ = std::make_unique<MediaRouterFileDialog>(this); + } + + media_router_file_dialog_->OpenFileDialog(GetBrowser()); +} + MediaRouterUIBase::RouteRequest::RouteRequest(const MediaSink::Id& sink_id) : sink_id(sink_id) { static base::AtomicSequenceNumber g_next_request_id; @@ -435,8 +566,8 @@ weak_factory_.GetWeakPtr(), cast_mode)); params.timeout = GetRouteRequestTimeout(cast_mode); - CHECK(initiator()); - params.incognito = initiator()->GetBrowserContext()->IsOffTheRecord(); + CHECK(initiator_); + params.incognito = initiator_->GetBrowserContext()->IsOffTheRecord(); return base::make_optional(std::move(params)); } @@ -499,6 +630,10 @@ issues_observer_->Init(); } +void MediaRouterUIBase::FileDialogSelectionFailed(const IssueInfo& issue) { + AddIssue(issue); +} + MediaRouterUIBase::UiIssuesObserver::UiIssuesObserver( IssueManager* issue_manager, MediaRouterUIBase* ui) @@ -532,10 +667,84 @@ callback_.Run(routes, joinable_route_ids); } +base::Optional<RouteParameters> MediaRouterUIBase::GetLocalFileRouteParameters( + const MediaSink::Id& sink_id, + const GURL& file_url, + content::WebContents* tab_contents) { + RouteParameters params; + SessionID::id_type tab_id = SessionTabHelper::IdForTab(tab_contents).id(); + params.source_id = MediaSourceForTab(tab_id).id(); + + // Use a placeholder URL as origin for local file casting, which is + // essentially mirroring. + params.origin = url::Origin::Create(GURL(chrome::kChromeUIMediaRouterURL)); + + int request_id = current_route_request() ? current_route_request()->id : -1; + params.route_response_callbacks.push_back(base::BindOnce( + &MediaRouterUIBase::OnRouteResponseReceived, weak_factory_.GetWeakPtr(), + request_id, sink_id, MediaCastMode::LOCAL_FILE, + base::UTF8ToUTF16(GetTruncatedPresentationRequestSourceName()))); + + params.route_response_callbacks.push_back( + base::BindOnce(&MediaRouterUIBase::MaybeReportCastingSource, + weak_factory_.GetWeakPtr(), MediaCastMode::LOCAL_FILE)); + + params.route_response_callbacks.push_back( + base::BindOnce(&MediaRouterUIBase::MaybeReportFileInformation, + weak_factory_.GetWeakPtr())); + + params.route_response_callbacks.push_back( + base::BindOnce(&MediaRouterUIBase::FullScreenFirstVideoElement, + weak_factory_.GetWeakPtr(), file_url, tab_contents)); + + params.timeout = GetRouteRequestTimeout(MediaCastMode::LOCAL_FILE); + CHECK(initiator_); + params.incognito = initiator_->GetBrowserContext()->IsOffTheRecord(); + + return base::make_optional(std::move(params)); +} + +// TODO(crbug.com/792547): Refactor FullScreenFirstVideoElement() and +// MaybeReportFileInformation() into a local media casting specific location +// instead of here in the main ui. +void MediaRouterUIBase::FullScreenFirstVideoElement( + const GURL& file_url, + content::WebContents* web_contents, + const RouteRequestResult& result) { + if (result.result_code() == RouteRequestResult::OK) { + new WebContentsFullscreenOnLoadedObserver(file_url, web_contents); + } +} + +void MediaRouterUIBase::MaybeReportFileInformation( + const RouteRequestResult& result) { + if (result.result_code() == RouteRequestResult::OK) + media_router_file_dialog_->MaybeReportLastSelectedFileInformation(); +} + +content::WebContents* MediaRouterUIBase::OpenTabWithUrl(const GURL& url) { + // Check if the current page is a new tab. If so open file in current page. + // If not then open a new page. + if (initiator_->GetVisibleURL() == chrome::kChromeUINewTabURL) { + content::NavigationController::LoadURLParams load_params(url); + load_params.transition_type = ui::PAGE_TRANSITION_GENERATED; + initiator_->GetController().LoadURLWithParams(load_params); + return initiator_; + } else { + return chrome::AddSelectedTabWithURL(GetBrowser(), url, + ui::PAGE_TRANSITION_LINK); + } +} + MediaRouter* MediaRouterUIBase::GetMediaRouter() const { - CHECK(initiator()); + CHECK(initiator_); return MediaRouterFactory::GetApiForBrowserContext( - initiator()->GetBrowserContext()); + initiator_->GetBrowserContext()); +} + +Browser* MediaRouterUIBase::GetBrowser() { + CHECK(initiator_); + return chrome::FindBrowserWithWebContents(initiator_); } } // namespace media_router
diff --git a/chrome/browser/ui/media_router/media_router_ui_base.h b/chrome/browser/ui/media_router/media_router_ui_base.h index 9fe37ad4..137579d 100644 --- a/chrome/browser/ui/media_router/media_router_ui_base.h +++ b/chrome/browser/ui/media_router/media_router_ui_base.h
@@ -19,6 +19,7 @@ #include "chrome/browser/media/router/media_router_dialog_controller.h" #include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h" #include "chrome/browser/ui/media_router/media_cast_mode.h" +#include "chrome/browser/ui/media_router/media_router_file_dialog.h" #include "chrome/browser/ui/media_router/media_router_ui_helper.h" #include "chrome/browser/ui/media_router/media_sink_with_cast_modes.h" #include "chrome/browser/ui/media_router/query_result_manager.h" @@ -52,9 +53,11 @@ // observing and organizing route, sink, and presentation request information, // and executing and keeping track of route requests from the dialog to Media // Router. -class MediaRouterUIBase : public QueryResultManager::Observer, - public PresentationServiceDelegateImpl:: - DefaultPresentationRequestObserver { +class MediaRouterUIBase + : public QueryResultManager::Observer, + public PresentationServiceDelegateImpl:: + DefaultPresentationRequestObserver, + public MediaRouterFileDialog::MediaRouterFileDialogDelegate { public: MediaRouterUIBase(); ~MediaRouterUIBase() override; @@ -120,6 +123,9 @@ // Calls MediaRouter to remove the given issue. void RemoveIssue(const Issue::Id& issue_id); + // Opens a file picker for when the user selected local file casting. + void OpenFileDialog(); + const std::vector<MediaRoute>& routes() const { return routes_; } content::WebContents* initiator() const { return initiator_; } @@ -201,6 +207,9 @@ // Instantiates and initializes the issues observer. void StartObservingIssues(); + // MediaRouterFileDialogDelegate: + void FileDialogSelectionFailed(const IssueInfo& issue) override; + const base::Optional<RouteRequest> current_route_request() const { return current_route_request_; } @@ -214,6 +223,11 @@ start_presentation_context_ = std::move(start_presentation_context); } + void set_media_router_file_dialog_for_test( + std::unique_ptr<MediaRouterFileDialog> file_dialog) { + media_router_file_dialog_ = std::move(file_dialog); + } + QueryResultManager* query_result_manager() const { return query_result_manager_.get(); } @@ -224,6 +238,8 @@ FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest, UIMediaRoutesObserverSkipsUnavailableCastModes); + class WebContentsFullscreenOnLoadedObserver; + // This class calls to refresh the UI when the highest priority issue is // updated. class UiIssuesObserver : public IssuesObserver { @@ -268,9 +284,32 @@ virtual void OnIssue(const Issue& issue) = 0; virtual void OnIssueCleared() = 0; + // Populates route-related parameters for CreateRoute() when doing file + // casting. + base::Optional<RouteParameters> GetLocalFileRouteParameters( + const MediaSink::Id& sink_id, + const GURL& file_url, + content::WebContents* tab_contents); + + // If the current URL for |web_contents| is |file_url|, requests the first + // video in it to be shown fullscreen. + void FullScreenFirstVideoElement(const GURL& file_url, + content::WebContents* web_contents, + const RouteRequestResult& result); + + // Sends a request to the file dialog to log UMA stats for the file that was + // cast if the result is successful. + void MaybeReportFileInformation(const RouteRequestResult& result); + + // Opens the URL in a tab, returns the tab it was opened in. + content::WebContents* OpenTabWithUrl(const GURL& url); + // Returns the MediaRouter for this instance's BrowserContext. virtual MediaRouter* GetMediaRouter() const; + // Retrieves the browser associated with this UI. + Browser* GetBrowser(); + // This is non-null while this instance is registered to receive // updates from them. std::unique_ptr<MediaRoutesObserver> routes_observer_; @@ -308,6 +347,10 @@ // WebContents for the tab for which the Cast dialog is shown. content::WebContents* initiator_; + // The dialog that handles opening the file dialog and validating and + // returning the results. + std::unique_ptr<MediaRouterFileDialog> media_router_file_dialog_; + std::unique_ptr<IssuesObserver> issues_observer_; #if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER)
diff --git a/chrome/browser/ui/omnibox/omnibox_theme.cc b/chrome/browser/ui/omnibox/omnibox_theme.cc index 8795c5d..9d527940 100644 --- a/chrome/browser/ui/omnibox/omnibox_theme.cc +++ b/chrome/browser/ui/omnibox/omnibox_theme.cc
@@ -225,8 +225,12 @@ const bool dark = tint == OmniboxTint::DARK; switch (part) { - case OmniboxPart::LOCATION_BAR_BACKGROUND: - return dark ? SkColorSetRGB(0x28, 0x2C, 0x2F) : gfx::kGoogleGrey100; + case OmniboxPart::LOCATION_BAR_BACKGROUND: { + const bool hovered = state == OmniboxPartState::HOVERED; + return dark ? (hovered ? SkColorSetRGB(0x2F, 0x33, 0x36) + : SkColorSetRGB(0x28, 0x2C, 0x2F)) + : (hovered ? gfx::kGoogleGrey200 : gfx::kGoogleGrey100); + } case OmniboxPart::LOCATION_BAR_SECURITY_CHIP: return GetSecurityChipColor(tint, state); case OmniboxPart::LOCATION_BAR_SELECTED_KEYWORD:
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc index 483ed86..3b06fc4 100644 --- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc +++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -445,14 +445,7 @@ #endif } -// Fails on Linux. http://crbug.com/408634 -#if defined(OS_LINUX) -#define MAYBE_PopupAccelerators DISABLED_PopupAccelerators -#else -#define MAYBE_PopupAccelerators PopupAccelerators -#endif - -IN_PROC_BROWSER_TEST_F(OmniboxViewTest, MAYBE_PopupAccelerators) { +IN_PROC_BROWSER_TEST_F(OmniboxViewTest, PopupAccelerators) { // Create a popup. Browser* popup = CreateBrowserForPopup(browser()->profile()); ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(popup)); @@ -478,19 +471,19 @@ GetOmniboxViewForBrowser(popup, &omnibox_view)); #endif - // Set the edit text to "Hello world". - omnibox_view->SetUserText(ASCIIToUTF16("Hello world")); + // Navigate to https://helloworld.com + ui_test_utils::NavigateToURL(popup, GURL("https://helloworld.com")); chrome::FocusLocationBar(popup); EXPECT_TRUE(omnibox_view->IsSelectAll()); // Try editing the location bar text -- should be disallowed. ASSERT_NO_FATAL_FAILURE(SendKeyForBrowser(popup, ui::VKEY_S, 0)); - EXPECT_EQ(ASCIIToUTF16("Hello world"), omnibox_view->GetText()); + EXPECT_EQ(ASCIIToUTF16("https://helloworld.com"), omnibox_view->GetText()); EXPECT_TRUE(omnibox_view->IsSelectAll()); ASSERT_NO_FATAL_FAILURE( SendKeyForBrowser(popup, ui::VKEY_X, kCtrlOrCmdMask)); - EXPECT_EQ(ASCIIToUTF16("Hello world"), omnibox_view->GetText()); + EXPECT_EQ(ASCIIToUTF16("https://helloworld.com"), omnibox_view->GetText()); EXPECT_TRUE(omnibox_view->IsSelectAll()); #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX) @@ -878,13 +871,13 @@ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_B, 0)); ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_C, 0)); - // Check if RevertAll() resets the text and preserves the cursor position. + // Check if RevertAll() resets the text and resets cursor position omnibox_view->RevertAll(); EXPECT_FALSE(omnibox_view->IsSelectAll()); EXPECT_EQ(old_text, omnibox_view->GetText()); omnibox_view->GetSelectionBounds(&start, &end); - EXPECT_EQ(3U, start); - EXPECT_EQ(3U, end); + EXPECT_EQ(11U, start); + EXPECT_EQ(11U, end); // Check that reverting clamps the cursor to the bounds of the new text. // Move the cursor to the end.
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index cfec84c3..66dd2f9 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -93,6 +93,10 @@ using base::UTF8ToUTF16; using base::UTF16ToUTF8; using content::BrowserThread; +#if defined(SAFE_BROWSING_DB_LOCAL) +using PasswordReuseEvent = + safe_browsing::LoginReputationClientRequest::PasswordReuseEvent; +#endif // SAFE_BROWSING_DB_LOCAL namespace { @@ -501,8 +505,15 @@ content::WebContents* web_contents) { #if defined(SAFE_BROWSING_DB_LOCAL) DCHECK(password_protection_service_); + DCHECK(site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE || + site_identity_status_ == + SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE); password_protection_service_->OnUserAction( - web_contents, safe_browsing::PasswordProtectionService::PAGE_INFO, + web_contents, + site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE + ? PasswordReuseEvent::SIGN_IN_PASSWORD + : PasswordReuseEvent::ENTERPRISE_PASSWORD, + safe_browsing::PasswordProtectionService::PAGE_INFO, safe_browsing::PasswordProtectionService::CHANGE_PASSWORD); #endif } @@ -511,8 +522,15 @@ content::WebContents* web_contents) { #if defined(SAFE_BROWSING_DB_LOCAL) DCHECK(password_protection_service_); + DCHECK(site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE || + site_identity_status_ == + SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE); password_protection_service_->OnUserAction( - web_contents, safe_browsing::PasswordProtectionService::PAGE_INFO, + web_contents, + site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE + ? PasswordReuseEvent::SIGN_IN_PASSWORD + : PasswordReuseEvent::ENTERPRISE_PASSWORD, + safe_browsing::PasswordProtectionService::PAGE_INFO, safe_browsing::PasswordProtectionService::MARK_AS_LEGITIMATE); #endif } @@ -566,8 +584,11 @@ security_info.malicious_content_status, &site_identity_status_, &site_identity_details_); show_change_password_buttons_ = - security_info.malicious_content_status == - security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE; + (security_info.malicious_content_status == + security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE || + security_info.malicious_content_status == + security_state:: + MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE); } else if (certificate_ && (!net::IsCertStatusError(security_info.cert_status) || net::IsCertStatusMinorError(security_info.cert_status))) { @@ -898,9 +919,19 @@ ui_->SetIdentityInfo(info); #if defined(SAFE_BROWSING_DB_LOCAL) if (password_protection_service_ && show_change_password_buttons_) { - password_protection_service_->RecordWarningAction( - safe_browsing::PasswordProtectionService::PAGE_INFO, - safe_browsing::PasswordProtectionService::SHOWN); + if (site_identity_status_ == SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE) { + password_protection_service_->RecordWarningAction( + safe_browsing::PasswordProtectionService::PAGE_INFO, + safe_browsing::PasswordProtectionService::SHOWN, + safe_browsing::LoginReputationClientRequest::PasswordReuseEvent:: + SIGN_IN_PASSWORD); + } else { + password_protection_service_->RecordWarningAction( + safe_browsing::PasswordProtectionService::PAGE_INFO, + safe_browsing::PasswordProtectionService::SHOWN, + safe_browsing::LoginReputationClientRequest::PasswordReuseEvent:: + ENTERPRISE_PASSWORD); + } } #endif } @@ -939,12 +970,24 @@ *details = l10n_util::GetStringUTF16(IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS); break; - case security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE: + case security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE: #if defined(SAFE_BROWSING_DB_LOCAL) - *status = PageInfo::SITE_IDENTITY_STATUS_PASSWORD_REUSE; - *details = safe_browsing::ChromePasswordProtectionService:: - GetPasswordProtectionService(profile_) - ->GetWarningDetailText(); + *status = PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE; + // |password_protection_service_| may be null in test. + *details = password_protection_service_ + ? password_protection_service_->GetWarningDetailText( + PasswordReuseEvent::SIGN_IN_PASSWORD) + : base::string16(); +#endif + break; + case security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE: +#if defined(SAFE_BROWSING_DB_LOCAL) + *status = PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE; + // |password_protection_service_| maybe null in test. + *details = password_protection_service_ + ? password_protection_service_->GetWarningDetailText( + PasswordReuseEvent::ENTERPRISE_PASSWORD) + : base::string16(); #endif break; }
diff --git a/chrome/browser/ui/page_info/page_info.h b/chrome/browser/ui/page_info/page_info.h index cde9ce7..467475741 100644 --- a/chrome/browser/ui/page_info/page_info.h +++ b/chrome/browser/ui/page_info/page_info.h
@@ -91,7 +91,8 @@ SITE_IDENTITY_STATUS_MALWARE, SITE_IDENTITY_STATUS_SOCIAL_ENGINEERING, SITE_IDENTITY_STATUS_UNWANTED_SOFTWARE, - SITE_IDENTITY_STATUS_PASSWORD_REUSE, + SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE, + SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE, }; // Events for UMA. Do not reorder or change! Exposed in header so enum is
diff --git a/chrome/browser/ui/page_info/page_info_ui.cc b/chrome/browser/ui/page_info/page_info_ui.cc index 60ea5d08..04d709c 100644 --- a/chrome/browser/ui/page_info/page_info_ui.cc +++ b/chrome/browser/ui/page_info/page_info_ui.cc
@@ -250,9 +250,15 @@ return CreateSecurityDescription(SecuritySummaryColor::RED, IDS_PAGE_INFO_UNWANTED_SOFTWARE_SUMMARY, IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS); - case PageInfo::SITE_IDENTITY_STATUS_PASSWORD_REUSE: + case PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE: #if defined(SAFE_BROWSING_DB_LOCAL) - return CreateSecurityDescriptionForPasswordReuse(); + return CreateSecurityDescriptionForPasswordReuse( + /*is_enterprise_password=*/false); +#endif + case PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE: +#if defined(SAFE_BROWSING_DB_LOCAL) + return CreateSecurityDescriptionForPasswordReuse( + /*is_enterprise_password=*/true); #endif case PageInfo::SITE_IDENTITY_STATUS_DEPRECATED_SIGNATURE_ALGORITHM: case PageInfo::SITE_IDENTITY_STATUS_UNKNOWN:
diff --git a/chrome/browser/ui/page_info/page_info_ui.h b/chrome/browser/ui/page_info/page_info_ui.h index 3e46dd5..b835485 100644 --- a/chrome/browser/ui/page_info/page_info_ui.h +++ b/chrome/browser/ui/page_info/page_info_ui.h
@@ -221,7 +221,8 @@ #if defined(SAFE_BROWSING_DB_LOCAL) // Creates security description for password reuse case. virtual std::unique_ptr<PageInfoUI::SecurityDescription> - CreateSecurityDescriptionForPasswordReuse() const = 0; + CreateSecurityDescriptionForPasswordReuse( + bool is_enterprise_password) const = 0; #endif };
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc index 0784718..4bcdd9f6 100644 --- a/chrome/browser/ui/page_info/page_info_unittest.cc +++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -95,7 +95,8 @@ #if defined(SAFE_BROWSING_DB_LOCAL) std::unique_ptr<PageInfoUI::SecurityDescription> - CreateSecurityDescriptionForPasswordReuse() const override { + CreateSecurityDescriptionForPasswordReuse( + bool unused_is_enterprise_password) const override { std::unique_ptr<PageInfoUI::SecurityDescription> security_description( new PageInfoUI::SecurityDescription()); security_description->summary_style = SecuritySummaryColor::RED; @@ -445,15 +446,27 @@ } #if defined(SAFE_BROWSING_DB_LOCAL) -TEST_F(PageInfoTest, PasswordReuse) { +TEST_F(PageInfoTest, SignInPasswordReuse) { security_info_.security_level = security_state::DANGEROUS; security_info_.malicious_content_status = - security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE; + security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE; SetDefaultUIExpectations(mock_ui()); EXPECT_EQ(PageInfo::SITE_CONNECTION_STATUS_UNENCRYPTED, page_info()->site_connection_status()); - EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_PASSWORD_REUSE, + EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE, + page_info()->site_identity_status()); +} + +TEST_F(PageInfoTest, EnterprisePasswordReuse) { + security_info_.security_level = security_state::DANGEROUS; + security_info_.malicious_content_status = + security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE; + SetDefaultUIExpectations(mock_ui()); + + EXPECT_EQ(PageInfo::SITE_CONNECTION_STATUS_UNENCRYPTED, + page_info()->site_connection_status()); + EXPECT_EQ(PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE, page_info()->site_identity_status()); } #endif
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index 6dd1bca0..2f88fdf 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -900,8 +900,10 @@ chrome::ShowBadFlagsPrompt(web_contents); InfoBarService* infobar_service = InfoBarService::FromWebContents(web_contents); - if (!google_apis::HasKeysConfigured()) + if (!google_apis::HasAPIKeyConfigured() || + !google_apis::HasOAuthClientConfigured()) { GoogleApiKeysInfoBarDelegate::Create(infobar_service); + } if (ObsoleteSystem::IsObsoleteNowOrSoon()) { PrefService* local_state = g_browser_process->local_state(); if (!local_state ||
diff --git a/chrome/browser/ui/tab_dialogs.h b/chrome/browser/ui/tab_dialogs.h index 3a8d97a..5a53144c 100644 --- a/chrome/browser/ui/tab_dialogs.h +++ b/chrome/browser/ui/tab_dialogs.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/callback_forward.h" #include "base/supports_user_data.h" #include "ui/gfx/native_widget_types.h" @@ -44,7 +45,8 @@ // Shows or hides the hung renderer dialog. virtual void ShowHungRendererDialog( - content::RenderWidgetHost* render_widget_host) = 0; + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) = 0; virtual void HideHungRendererDialog( content::RenderWidgetHost* render_widget_host) = 0; virtual bool IsShowingHungRendererDialog() = 0;
diff --git a/chrome/browser/ui/test/test_browser_dialog.cc b/chrome/browser/ui/test/test_browser_dialog.cc index 83e93f3..9cc73d48 100644 --- a/chrome/browser/ui/test/test_browser_dialog.cc +++ b/chrome/browser/ui/test/test_browser_dialog.cc
@@ -12,9 +12,8 @@ #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_CHROMEOS) -#include "ash/public/cpp/config.h" #include "ash/shell.h" // mash-ok -#include "chrome/browser/chromeos/ash_config.h" +#include "ui/base/ui_base_features.h" #endif #if defined(OS_MACOSX) @@ -137,7 +136,7 @@ // Under mash, GetAllWidgets() uses MusClient to get the list of root windows. // Otherwise, GetAllWidgets() relies on AuraTestHelper to get the root window, // but that is not available in browser_tests, so use ash::Shell directly. - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { widgets_ = views::test::WidgetTest::GetAllWidgets(); } else { for (aura::Window* root_window : ash::Shell::GetAllRootWindows())
diff --git a/chrome/browser/ui/views/accelerator_table.cc b/chrome/browser/ui/views/accelerator_table.cc index e0d08c7a..1bb9442 100644 --- a/chrome/browser/ui/views/accelerator_table.cc +++ b/chrome/browser/ui/views/accelerator_table.cc
@@ -151,7 +151,6 @@ {ui::VKEY_BROWSER_SEARCH, ui::EF_NONE, IDC_FOCUS_SEARCH}, {ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR, IDC_SHOW_AVATAR_MENU}, - {ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_EXIT}, #endif // !OS_CHROMEOS #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_MACOSX)
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index 1996756..09e4dc1 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -22,7 +22,6 @@ #include "ash/wm/window_state_delegate.h" #include "ash/wm/window_state_observer.h" #include "base/logging.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/note_taking_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profiles_state.h" @@ -40,6 +39,7 @@ #include "ui/aura/window_observer.h" #include "ui/base/hit_test.h" #include "ui/base/models/simple_menu_model.h" +#include "ui/base/ui_base_features.h" #include "ui/events/event_constants.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/skia_util.h" @@ -198,8 +198,7 @@ views::Widget* widget) { ChromeNativeAppWindowViewsAura::OnBeforePanelWidgetInit(init_params, widget); - if (chromeos::GetAshConfig() != ash::Config::MASH && - ash::Shell::HasInstance()) { + if (features::IsAshInBrowserProcess() && ash::Shell::HasInstance()) { // Open a new panel on the target root. init_params->context = ash::Shell::GetRootWindowForNewWindows(); init_params->bounds = gfx::Rect(GetPreferredSize()); @@ -230,7 +229,7 @@ if (IsFrameless()) return true; - return HasFrameColor() && chromeos::GetAshConfig() != ash::Config::MASH; + return HasFrameColor() && features::IsAshInBrowserProcess(); } /////////////////////////////////////////////////////////////////////////////// @@ -329,7 +328,7 @@ if (IsFrameless()) return CreateNonStandardAppFrame(); - if (chromeos::GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return nullptr; if (app_window()->window_type_is_panel()) { @@ -399,7 +398,7 @@ SkRegion* draggable_region = GetDraggableRegion(); // Set the NativeAppWindow's draggable region on the mus window. if (draggable_region && !draggable_region->isEmpty() && widget() && - chromeos::GetAshConfig() == ash::Config::MASH) { + !features::IsAshInBrowserProcess()) { // Supply client area insets that encompass all draggable regions. gfx::Insets insets(draggable_region->getBounds().bottom(), 0, 0, 0);
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index 87a8174..cf88b99 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -53,6 +53,10 @@ const SkColor kFooterBackgroundColor = gfx::kGoogleGrey050; const SkColor kSeparatorColor = gfx::kGoogleGrey200; +// A space between the input element and the dropdown, so that the dropdown's +// border doesn't look too close to the element. +constexpr int kElementBorderPadding = 1; + int GetCornerRadius() { return ChromeLayoutProvider::Get()->GetCornerRadiusMetric( views::EMPHASIS_MEDIUM); @@ -573,9 +577,18 @@ gfx::Size size = CalculatePreferredSize(); gfx::Rect popup_bounds; - PopupViewCommon().CalculatePopupVerticalBounds( - size.height(), gfx::ToEnclosingRect(controller_->element_bounds()), - controller_->container_view(), &popup_bounds); + // When a bubble border is shown, the contents area (inside the shadow) is + // supposed to be aligned with input element boundaries. + gfx::Rect element_bounds = + gfx::ToEnclosingRect(controller_->element_bounds()); + // Consider the element is |kElementBorderPadding| pixels larger at the top + // and at the bottom in order to reposition the dropdown, so that it doesn't + // look too close to the element. + element_bounds.Inset(/*horizontal=*/0, /*vertical=*/-kElementBorderPadding); + + PopupViewCommon().CalculatePopupVerticalBounds(size.height(), element_bounds, + controller_->container_view(), + &popup_bounds); // Adjust the width to compensate for a scroll bar, if necessary, and for // other rules. @@ -592,8 +605,8 @@ size.set_width(AdjustWidth(size.width() + scroll_width)); PopupViewCommon().CalculatePopupHorizontalBounds( - size.width(), gfx::ToEnclosingRect(controller_->element_bounds()), - controller_->container_view(), controller_->IsRTL(), &popup_bounds); + size.width(), element_bounds, controller_->container_view(), + controller_->IsRTL(), &popup_bounds); SetSize(size);
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc index b4bf288..cda75ff 100644 --- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc +++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
@@ -31,7 +31,6 @@ #include "ui/native_theme/native_theme.h" #include "ui/views/background.h" #include "ui/views/border.h" -#include "ui/views/bubble/tooltip_icon.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/combobox/combobox.h" #include "ui/views/controls/image_view.h" @@ -219,12 +218,6 @@ storage_row_->AddChildView(storage_checkbox_); storage_row_layout->SetFlexForView(storage_checkbox_, 1); - views::TooltipIcon* icon = new views::TooltipIcon(l10n_util::GetStringUTF16( - IDS_AUTOFILL_CARD_UNMASK_PROMPT_STORAGE_TOOLTIP)); - const int kTooltipWidth = 233; - icon->set_bubble_width(kTooltipWidth); - storage_row_->AddChildView(icon); - return storage_row_; }
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc index d7d63e8..b23e26b4 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -51,8 +51,8 @@ #if defined(OS_CHROMEOS) #include "ash/public/interfaces/constants.mojom.h" -#include "chrome/browser/chromeos/ash_config.h" #include "content/public/common/content_switches.h" +#include "ui/base/ui_base_features.h" #else // defined(OS_CHROMEOS) #include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h" #endif // defined(OS_CHROMEOS) @@ -156,7 +156,7 @@ #if defined(OS_CHROMEOS) // Start up the window service and the ash system UI service. - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { connection->GetConnector()->StartService( service_manager::Identity(ui::mojom::kServiceName)); connection->GetConnector()->StartService( @@ -165,7 +165,7 @@ #endif #if defined(OS_CHROMEOS) - if (chromeos::GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) return; #endif
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h index 63df04f..434a1f0 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h
@@ -55,7 +55,8 @@ std::unique_ptr<wm::WMState> wm_state_; - // Only used when running in ash::Config::MASH. + // Only used when Ash is running out of process. + // TODO: make ash specific. std::unique_ptr<views::MusClient> mus_client_; #endif
diff --git a/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc b/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc index 1217576e..0e82680 100644 --- a/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc +++ b/chrome/browser/ui/views/chrome_views_delegate_chromeos.cc
@@ -6,11 +6,10 @@ #include "ash/accelerators/accelerator_controller.h" #include "ash/shell.h" -#include "ash/wm/window_state.h" #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/threading/thread_task_runner_handle.h" -#include "chrome/browser/ui/ash/ash_util.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -30,7 +29,7 @@ DCHECK(base::MessageLoopForUI::IsCurrent()); // Early return because mash chrome does not have access to ash::Shell - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) return views::ViewsDelegate::ProcessMenuAcceleratorResult::LEAVE_MENU_OPEN; ash::AcceleratorController* accelerator_controller = @@ -59,11 +58,9 @@ gfx::Rect* bounds) const { // On ChromeOS a window won't span across displays. Adjust the bounds to fit // the work area. - aura::Window* window = widget->GetNativeView(); display::Display display = display::Screen::GetScreen()->GetDisplayMatching(*bounds); bounds->AdjustToFit(display.work_area()); - ash::wm::GetWindowState(window)->set_minimum_visibility(true); } views::Widget::InitParams::WindowOpacity @@ -84,7 +81,7 @@ // Classic ash requires a parent or a context that it can use to look up a // root window to find a WindowParentingClient. Mash handles window parenting // inside ash, see ash::CreateAndParentTopLevelWindow(). - if (!ash_util::IsRunningInMash() && !params->parent && !params->context) + if (features::IsAshInBrowserProcess() && !params->parent && !params->context) params->context = ash::Shell::GetRootWindowForNewWindows(); // By returning null Widget creates the default NativeWidget implementation,
diff --git a/chrome/browser/ui/views/confirm_quit_bubble_controller.cc b/chrome/browser/ui/views/confirm_quit_bubble_controller.cc index 7413232..bfa898504 100644 --- a/chrome/browser/ui/views/confirm_quit_bubble_controller.cc +++ b/chrome/browser/ui/views/confirm_quit_bubble_controller.cc
@@ -8,13 +8,13 @@ #include "base/feature_list.h" #include "base/memory/singleton.h" -#include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/confirm_quit.h" #include "chrome/browser/ui/views/confirm_quit_bubble.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "content/public/browser/notification_service.h" #include "ui/base/accelerators/accelerator.h" @@ -59,10 +59,10 @@ BrowserList::RemoveObserver(this); } -bool ConfirmQuitBubbleController::HandleKeyboardEvent( - const ui::Accelerator& accelerator) { +void ConfirmQuitBubbleController::OnKeyEvent(ui::KeyEvent* event) { + const ui::Accelerator accelerator(*event); if (state_ == State::kQuitting) - return false; + return; if (accelerator.key_code() == kAcceleratorKeyCode && accelerator.modifiers() == kAcceleratorModifiers && accelerator.key_state() == ui::Accelerator::KeyState::PRESSED && @@ -70,10 +70,12 @@ if (state_ == State::kWaiting) { Browser* browser = BrowserList::GetInstance()->GetLastActive(); PrefService* prefs = browser ? browser->profile()->GetPrefs() : nullptr; - if (prefs && !prefs->GetBoolean(prefs::kConfirmToQuitEnabled)) { + if (!IsFeatureEnabled() || + (prefs && !prefs->GetBoolean(prefs::kConfirmToQuitEnabled))) { confirm_quit::RecordHistogram(confirm_quit::kNoConfirm); Quit(); - return true; + event->SetHandled(); + return; } if (browser) { browser_ = browser; @@ -89,18 +91,16 @@ view_->Show(); hide_timer_->Start(FROM_HERE, confirm_quit::kShowDuration, this, &ConfirmQuitBubbleController::OnTimerElapsed); - return true; - } - if (state_ == State::kReleased) { + event->SetHandled(); + } else if (state_ == State::kReleased) { // The accelerator was pressed while the bubble was showing. Consider // this a confirmation to quit. second_press_start_time_ = accelerator.time_stamp(); ConfirmQuit(); - return true; + event->SetHandled(); } - } - if (accelerator.key_code() == kAcceleratorKeyCode && - accelerator.key_state() == ui::Accelerator::KeyState::RELEASED) { + } else if (accelerator.key_code() == kAcceleratorKeyCode && + accelerator.key_state() == ui::Accelerator::KeyState::RELEASED) { if (state_ == State::kPressed) { state_ = State::kReleased; } else if (state_ == State::kConfirmed) { @@ -114,9 +114,26 @@ } Quit(); } - return true; + event->SetHandled(); } - return false; +} + +void ConfirmQuitBubbleController::OnBrowserRemoved(Browser* browser) { + // A browser is definitely no longer active if it is removed. + OnBrowserNoLongerActive(browser); +} + +void ConfirmQuitBubbleController::OnBrowserNoLongerActive(Browser* browser) { + if (browser == browser_) + Reset(); +} + +void ConfirmQuitBubbleController::DoQuit() { + chrome::Exit(); +} + +bool ConfirmQuitBubbleController::IsFeatureEnabled() { + return base::FeatureList::IsEnabled(features::kWarnBeforeQuitting); } void ConfirmQuitBubbleController::AnimationProgressed( @@ -133,16 +150,6 @@ AnimationProgressed(animation); } -void ConfirmQuitBubbleController::OnBrowserRemoved(Browser* browser) { - // A browser is definitely no longer active if it is removed. - OnBrowserNoLongerActive(browser); -} - -void ConfirmQuitBubbleController::OnBrowserNoLongerActive(Browser* browser) { - if (browser == browser_) - Reset(); -} - void ConfirmQuitBubbleController::Observe( int type, const content::NotificationSource& source, @@ -199,17 +206,5 @@ DCHECK(state_ == State::kWaiting || state_ == State::kConfirmed); state_ = State::kQuitting; browser_ = nullptr; - if (quit_action_) { - std::move(quit_action_).Run(); - } else { - // Delay quitting because doing so destroys objects that may be used when - // unwinding the stack. - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - base::BindOnce(chrome::Exit)); - } -} - -void ConfirmQuitBubbleController::SetQuitActionForTest( - base::OnceClosure quit_action) { - quit_action_ = std::move(quit_action); + DoQuit(); }
diff --git a/chrome/browser/ui/views/confirm_quit_bubble_controller.h b/chrome/browser/ui/views/confirm_quit_bubble_controller.h index 378d89e..89bf12c 100644 --- a/chrome/browser/ui/views/confirm_quit_bubble_controller.h +++ b/chrome/browser/ui/views/confirm_quit_bubble_controller.h
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/browser_list_observer.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "ui/events/event_handler.h" #include "ui/gfx/animation/animation_delegate.h" class ConfirmQuitBubbleBase; @@ -26,26 +27,41 @@ class SlideAnimation; } -namespace ui { -class Accelerator; -} - // Manages showing and hiding the confirm-to-quit bubble. Requests Chrome to be // closed if the quit accelerator is held down or pressed twice in succession. +// The singleton instance of this class is added as a PreTargetHandler for each +// browser window. class ConfirmQuitBubbleController : public gfx::AnimationDelegate, public BrowserListObserver, - public content::NotificationObserver { + public content::NotificationObserver, + public ui::EventHandler { public: static ConfirmQuitBubbleController* GetInstance(); ~ConfirmQuitBubbleController() override; - // Returns true if the event was handled. - bool HandleKeyboardEvent(const ui::Accelerator& accelerator); + // ui::EventHandler: + void OnKeyEvent(ui::KeyEvent* event) override; + + protected: + // |animation| is used to fade out all browser windows. + ConfirmQuitBubbleController(std::unique_ptr<ConfirmQuitBubbleBase> bubble, + std::unique_ptr<base::Timer> hide_timer, + std::unique_ptr<gfx::SlideAnimation> animation); + + // BrowserListObserver: + void OnBrowserRemoved(Browser* browser) override; + void OnBrowserNoLongerActive(Browser* browser) override; + + // Runs the quit action now. Virtual so tests can override the quit action. + virtual void DoQuit(); + + // Returns true if the confirm-to-quit feature is enabled. Virtual so tests + // can override the setting. + virtual bool IsFeatureEnabled(); private: friend struct base::DefaultSingletonTraits<ConfirmQuitBubbleController>; - friend class ConfirmQuitBubbleControllerTest; enum class State { // The accelerator has not been pressed. @@ -66,21 +82,12 @@ kQuitting, }; - // |animation| is used to fade out all browser windows. - ConfirmQuitBubbleController(std::unique_ptr<ConfirmQuitBubbleBase> bubble, - std::unique_ptr<base::Timer> hide_timer, - std::unique_ptr<gfx::SlideAnimation> animation); - ConfirmQuitBubbleController(); // gfx::AnimationDelegate: void AnimationProgressed(const gfx::Animation* animation) override; void AnimationEnded(const gfx::Animation* animation) override; - // BrowserListObserver: - void OnBrowserRemoved(Browser* browser) override; - void OnBrowserNoLongerActive(Browser* browser) override; - // content::NotificationObserver: void Observe(int type, const content::NotificationSource& source, @@ -100,11 +107,9 @@ // releases the accelerator. void ConfirmQuit(); - // Runs the quit action now. + // Updates state and calls DoQuit(). void Quit(); - void SetQuitActionForTest(base::OnceClosure quit_action); - std::unique_ptr<ConfirmQuitBubbleBase> const view_; State state_; @@ -122,8 +127,6 @@ std::unique_ptr<gfx::SlideAnimation> const browser_hide_animation_; - base::OnceClosure quit_action_; - content::NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(ConfirmQuitBubbleController);
diff --git a/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc b/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc index afa1c98..f1c72250 100644 --- a/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc +++ b/chrome/browser/ui/views/confirm_quit_bubble_controller_unittest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/views/confirm_quit_bubble.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/accelerators/accelerator.h" +#include "ui/events/event.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/animation/slide_animation.h" @@ -28,6 +29,30 @@ DISALLOW_COPY_AND_ASSIGN(TestConfirmQuitBubble); }; +class TestConfirmQuitBubbleController : public ConfirmQuitBubbleController { + public: + TestConfirmQuitBubbleController( + std::unique_ptr<ConfirmQuitBubbleBase> bubble, + std::unique_ptr<base::Timer> hide_timer, + std::unique_ptr<gfx::SlideAnimation> animation) + : ConfirmQuitBubbleController(std::move(bubble), + std::move(hide_timer), + std::move(animation)) {} + + void DeactivateBrowser() { OnBrowserNoLongerActive(nullptr); } + + bool quit_called() const { return quit_called_; } + + private: + void DoQuit() override { quit_called_ = true; } + + bool IsFeatureEnabled() override { return true; } + + bool quit_called_ = false; + + DISALLOW_COPY_AND_ASSIGN(TestConfirmQuitBubbleController); +}; + class TestSlideAnimation : public gfx::SlideAnimation { public: TestSlideAnimation() : gfx::SlideAnimation(nullptr) {} @@ -52,28 +77,21 @@ std::make_unique<base::MockTimer>(false, false); bubble_ = bubble.get(); timer_ = timer.get(); - controller_.reset(new ConfirmQuitBubbleController( + controller_.reset(new TestConfirmQuitBubbleController( std::move(bubble), std::move(timer), std::make_unique<TestSlideAnimation>())); - - quit_called_ = false; - controller_->SetQuitActionForTest(base::BindOnce( - &ConfirmQuitBubbleControllerTest::OnQuit, base::Unretained(this))); } void TearDown() override { controller_.reset(); } - void OnQuit() { quit_called_ = true; } - void SendAccelerator(bool quit, bool press, bool repeat) { ui::KeyboardCode key = quit ? ui::VKEY_Q : ui::VKEY_P; int modifiers = ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN; if (repeat) modifiers |= ui::EF_IS_REPEAT; - ui::Accelerator::KeyState state = press - ? ui::Accelerator::KeyState::PRESSED - : ui::Accelerator::KeyState::RELEASED; - controller_->HandleKeyboardEvent(ui::Accelerator(key, modifiers, state)); + ui::EventType type = press ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED; + ui::KeyEvent event(type, key, modifiers); + controller_->OnKeyEvent(&event); } void PressQuitAccelerator() { SendAccelerator(true, true, false); } @@ -86,17 +104,13 @@ void ReleaseOtherAccelerator() { SendAccelerator(false, false, false); } - void DeactivateBrowser() { controller_->OnBrowserNoLongerActive(nullptr); } - - std::unique_ptr<ConfirmQuitBubbleController> controller_; + std::unique_ptr<TestConfirmQuitBubbleController> controller_; // Owned by |controller_|. TestConfirmQuitBubble* bubble_; // Owned by |controller_|. base::MockTimer* timer_; - - bool quit_called_ = false; }; // Pressing and holding the shortcut should quit. @@ -104,9 +118,9 @@ PressQuitAccelerator(); EXPECT_TRUE(timer_->IsRunning()); timer_->Fire(); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); ReleaseQuitAccelerator(); - EXPECT_TRUE(quit_called_); + EXPECT_TRUE(controller_->quit_called()); } // Pressing the shortcut twice should quit. @@ -116,9 +130,9 @@ EXPECT_TRUE(timer_->IsRunning()); PressQuitAccelerator(); EXPECT_FALSE(timer_->IsRunning()); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); ReleaseQuitAccelerator(); - EXPECT_TRUE(quit_called_); + EXPECT_TRUE(controller_->quit_called()); } // Pressing the shortcut once should not quit. @@ -127,7 +141,7 @@ ReleaseQuitAccelerator(); EXPECT_TRUE(timer_->IsRunning()); timer_->Fire(); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); } // Repeated presses should not be counted. @@ -137,7 +151,7 @@ ReleaseQuitAccelerator(); EXPECT_TRUE(timer_->IsRunning()); timer_->Fire(); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); } // Other keys shouldn't matter. @@ -149,9 +163,9 @@ EXPECT_TRUE(timer_->IsRunning()); PressQuitAccelerator(); EXPECT_FALSE(timer_->IsRunning()); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); ReleaseQuitAccelerator(); - EXPECT_TRUE(quit_called_); + EXPECT_TRUE(controller_->quit_called()); } // The controller state should be reset when the browser loses focus. @@ -159,25 +173,25 @@ // Press but don't release the accelerator. PressQuitAccelerator(); EXPECT_TRUE(timer_->IsRunning()); - DeactivateBrowser(); + controller_->DeactivateBrowser(); EXPECT_FALSE(timer_->IsRunning()); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); ReleaseQuitAccelerator(); // Press and release the accelerator. PressQuitAccelerator(); ReleaseQuitAccelerator(); EXPECT_TRUE(timer_->IsRunning()); - DeactivateBrowser(); + controller_->DeactivateBrowser(); EXPECT_FALSE(timer_->IsRunning()); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); // Press and hold the accelerator. PressQuitAccelerator(); EXPECT_TRUE(timer_->IsRunning()); timer_->Fire(); EXPECT_FALSE(timer_->IsRunning()); - DeactivateBrowser(); + controller_->DeactivateBrowser(); ReleaseQuitAccelerator(); - EXPECT_FALSE(quit_called_); + EXPECT_FALSE(controller_->quit_called()); }
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc b/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc index a17daf3..d87b685f 100644 --- a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc +++ b/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc
@@ -99,7 +99,8 @@ // DialogBrowserTest: void ShowUi(const std::string& name) override { - test::GetAppListClient()->ActivateItem(kCrostiniTerminalId, 0); + ShowCrostiniInstallerView(browser()->profile(), + CrostiniUISurface::kSettings); } // BrowserTestBase:
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc index 837e769..478ca47 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "chrome/browser/media/webrtc/desktop_media_list.h" #include "chrome/browser/media/webrtc/window_icon_util.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h" @@ -20,9 +21,12 @@ #include "content/public/browser/browser_thread.h" #include "extensions/grit/extensions_browser_resources.h" #include "ui/accessibility/ax_node_data.h" -#include "ui/aura/window.h" #include "ui/base/resource/resource_bundle.h" +#if defined(OS_CHROMEOS) +#include "ui/aura/window.h" +#endif + using content::DesktopMediaID; namespace {
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index b30ebb2..9636cb9b 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h" #include "base/callback.h" +#include "build/build_config.h" #include "chrome/browser/media/webrtc/desktop_media_list.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" @@ -20,7 +21,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents_delegate.h" -#include "ui/aura/window_tree_host.h" #include "ui/base/l10n/l10n_util.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/canvas.h" @@ -33,11 +33,19 @@ #include "ui/views/window/dialog_client_view.h" #include "ui/wm/core/shadow_types.h" +#if defined(USE_AURA) +#include "ui/aura/window_tree_host.h" +#endif + +#if defined(OS_MACOSX) +#include "chrome/browser/ui/cocoa/media_picker/create_desktop_media_picker_cocoa.h" +#endif + using content::DesktopMediaID; namespace { -#if !defined(OS_CHROMEOS) +#if !defined(OS_CHROMEOS) && defined(USE_AURA) DesktopMediaID::Id AcceleratedWidgetToDesktopMediaId( gfx::AcceleratedWidget accelerated_widget) { #if defined(OS_WIN) @@ -223,6 +231,7 @@ // the Id is passed to DesktopMediaList. DesktopMediaID dialog_window_id; if (!modal_dialog) { +#if defined(USE_AURA) dialog_window_id = DesktopMediaID::RegisterAuraWindow( DesktopMediaID::TYPE_WINDOW, widget->GetNativeWindow()); @@ -230,7 +239,8 @@ #if !defined(OS_CHROMEOS) dialog_window_id.id = AcceleratedWidgetToDesktopMediaId( widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget()); -#endif +#endif // !defined(OS_CHROMEOS) +#endif // defined(USE_AURA) } for (auto* list_view : list_views_) @@ -449,5 +459,11 @@ // static std::unique_ptr<DesktopMediaPicker> DesktopMediaPicker::Create() { - return std::unique_ptr<DesktopMediaPicker>(new DesktopMediaPickerViews()); +#if defined(OS_MACOSX) + std::unique_ptr<DesktopMediaPicker> cocoa_ui = + CreateDesktopMediaPickerCocoa(); + if (cocoa_ui) + return cocoa_ui; +#endif + return std::make_unique<DesktopMediaPickerViews>(); }
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc index d92929e..fe8407d 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "chrome/browser/media/webrtc/fake_desktop_media_list.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_source_view.h" @@ -59,6 +60,12 @@ picker_params.app_name = app_name; picker_params.target_name = app_name; picker_params.request_audio = true; +#if defined(OS_MACOSX) + // On Mac, we don't have a NativeView to provide to + // DialogDelegate::CreateDialogWidget for the default MODAL_TYPE_CHILD + // default. MODAL_TYPE_WINDOW works around this. + picker_params.modality = ui::ModalType::MODAL_TYPE_WINDOW; +#endif picker_views_->Show(picker_params, std::move(source_lists), base::Bind(&DesktopMediaPickerViewsTest::OnPickerDone, base::Unretained(this)));
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash.cc b/chrome/browser/ui/views/frame/browser_frame_ash.cc index 4c31792..f55099b 100644 --- a/chrome/browser/ui/views/frame/browser_frame_ash.cc +++ b/chrome/browser/ui/views/frame/browser_frame_ash.cc
@@ -7,8 +7,8 @@ #include <memory> // This file is only instantiated in classic ash/mus. It is never used in mash. -// See native_browser_frame_factory_chromeos.cc switches on GetAshConfig(). -#include "ash/public/cpp/config.h" +// See native_browser_frame_factory_chromeos.cc switches on +// features::IsAshInBrowserProcess(). #include "ash/public/cpp/window_properties.h" #include "ash/public/cpp/window_state_type.h" #include "ash/shell.h" // mash-ok @@ -18,13 +18,13 @@ #include "ash/wm/window_util.h" // mash-ok #include "base/macros.h" #include "build/build_config.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" +#include "ui/base/ui_base_features.h" #include "ui/views/view.h" namespace { @@ -63,7 +63,7 @@ BrowserView* browser_view) : views::NativeWidgetAura(browser_frame), browser_view_(browser_view) { - DCHECK_NE(chromeos::GetAshConfig(), ash::Config::MASH); + DCHECK(features::IsAshInBrowserProcess()); GetNativeWindow()->SetName("BrowserFrameAsh"); Browser* browser = browser_view->browser(); ash::wm::WindowState* window_state =
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc index cfc1d94..a7cc5d9 100644 --- a/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_frame_ash_browsertest.cc
@@ -4,11 +4,11 @@ #include "chrome/browser/ui/views/frame/browser_frame_ash.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/test/base/in_process_browser_test.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/views/widget/widget.h" @@ -83,7 +83,7 @@ Browser* browser = new Browser(params); browser->window()->Show(); - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { WidgetBoundsWatcher watch( BrowserView::GetBrowserViewForBrowser(browser)->GetWidget(), original_bounds); @@ -114,7 +114,7 @@ expectation.set_y(original_bounds.y()); } - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { WidgetBoundsWatcher watch( BrowserView::GetBrowserViewForBrowser(browser)->GetWidget(), expectation);
diff --git a/chrome/browser/ui/views/frame/browser_frame_mac.mm b/chrome/browser/ui/views/frame/browser_frame_mac.mm index 6d005a8a..b965f14 100644 --- a/chrome/browser/ui/views/frame/browser_frame_mac.mm +++ b/chrome/browser/ui/views/frame/browser_frame_mac.mm
@@ -147,7 +147,7 @@ // it means that the event was not handled, so we must return either // NOT_HANDLED or NOT_HANDLED_IS_SHORTCUT. if (EventUsesPerformKeyEquivalent(event.os_event)) { - int command_id = CommandForKeyEvent(event.os_event); + int command_id = CommandForKeyEvent(event.os_event).chrome_command; if (command_id == -1) command_id = DelayedWebContentsCommandForKeyEvent(event.os_event); if (command_id != -1)
diff --git a/chrome/browser/ui/views/frame/browser_frame_mash.cc b/chrome/browser/ui/views/frame/browser_frame_mash.cc index 2dcb1ed..c3edd520 100644 --- a/chrome/browser/ui/views/frame/browser_frame_mash.cc +++ b/chrome/browser/ui/views/frame/browser_frame_mash.cc
@@ -8,13 +8,11 @@ #include <memory> -#include "ash/public/cpp/config.h" #include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/window_properties.h" #include "ash/public/cpp/window_state_type.h" #include "ash/public/interfaces/window_properties.mojom.h" #include "ash/public/interfaces/window_style.mojom.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/ui/browser_window_state.h" #include "chrome/browser/ui/views/frame/browser_frame.h" #include "chrome/browser/ui/views/frame/browser_frame_ash.h" @@ -25,6 +23,7 @@ #include "services/ui/public/interfaces/window_tree.mojom.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/mus/window_tree_host_mus_init_params.h" +#include "ui/base/ui_base_features.h" #include "ui/views/mus/desktop_window_tree_host_mus.h" #include "ui/views/mus/mus_client.h" #include "ui/views/mus/window_manager_frame_values.h" @@ -36,7 +35,7 @@ browser_view_(browser_view) { DCHECK(browser_frame_); DCHECK(browser_view_); - DCHECK_EQ(chromeos::GetAshConfig(), ash::Config::MASH); + DCHECK(!features::IsAshInBrowserProcess()); } BrowserFrameMash::~BrowserFrameMash() {}
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_chromeos.cc index 9e0a2ac..a04eca7 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_chromeos.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_factory_chromeos.cc
@@ -2,19 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/public/cpp/config.h" #include "build/build_config.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_mash.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "ui/base/ui_base_features.h" namespace chrome { BrowserNonClientFrameView* CreateBrowserNonClientFrameView( BrowserFrame* frame, BrowserView* browser_view) { - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { BrowserNonClientFrameViewMash* frame_view = new BrowserNonClientFrameViewMash(frame, browser_view); frame_view->Init();
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 8e65b5b..f77784e 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1130,6 +1130,11 @@ } void BrowserView::DestroyBrowser() { +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) + GetWidget()->GetNativeView()->RemovePreTargetHandler( + ConfirmQuitBubbleController::GetInstance()); +#endif + // After this returns other parts of Chrome are going to be shutdown. Close // the window now so that we are deleted immediately and aren't left holding // references to deleted objects. @@ -1352,14 +1357,6 @@ return content::KeyboardEventProcessingResult::NOT_HANDLED; } -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) - if (base::FeatureList::IsEnabled(features::kWarnBeforeQuitting) && - ConfirmQuitBubbleController::GetInstance()->HandleKeyboardEvent( - accelerator)) { - return content::KeyboardEventProcessingResult::HANDLED_WANTS_KEY_UP; - } -#endif // defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) - #if defined(OS_CHROMEOS) if (ash_util::IsAcceleratorDeprecated(accelerator)) { return (event.GetType() == blink::WebInputEvent::kRawKeyDown) @@ -2123,14 +2120,6 @@ // BrowserView, ui::AcceleratorTarget overrides: bool BrowserView::AcceleratorPressed(const ui::Accelerator& accelerator) { -#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) - if (base::FeatureList::IsEnabled(features::kWarnBeforeQuitting) && - ConfirmQuitBubbleController::GetInstance()->HandleKeyboardEvent( - accelerator)) { - return true; - } -#endif // defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) - int command_id; // Though AcceleratorManager should not send unknown |accelerator| to us, it's // still possible the command cannot be executed now. @@ -2160,6 +2149,11 @@ GetWidget()->SetNativeWindowProperty(Profile::kProfileKey, browser_->profile()); +#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) + GetWidget()->GetNativeView()->AddPreTargetHandler( + ConfirmQuitBubbleController::GetInstance()); +#endif + #if defined(USE_AURA) // Stow a pointer to the browser's profile onto the window handle so // that windows will be styled with the appropriate NativeTheme. @@ -2821,6 +2815,8 @@ return !IsImmersiveModeEnabled(); } +/////////////////////////////////////////////////////////////////////////////// +// BrowserView, extension::ExtensionKeybindingRegistry::Delegate implementation: extensions::ActiveTabPermissionGranter* BrowserView::GetActiveTabPermissionGranter() { content::WebContents* web_contents = GetActiveWebContents();
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 13b53b5c..c3455b3 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -266,7 +266,7 @@ return toolbar_button_provider_; } - // Overridden from BrowserWindow: + // BrowserWindow: void Show() override; void ShowInactive() override; void Hide() override; @@ -396,7 +396,7 @@ BookmarkBarView* GetBookmarkBarView() const; LocationBarView* GetLocationBarView() const; - // Overridden from TabStripModelObserver: + // TabStripModelObserver: void TabInsertedAt(TabStripModel* tab_strip_model, content::WebContents* contents, int index, @@ -409,11 +409,11 @@ void WillCloseAllTabs() override; void CloseAllTabsCanceled() override; - // Overridden from ui::AcceleratorProvider: + // ui::AcceleratorProvider: bool GetAcceleratorForCommandId(int command_id, ui::Accelerator* accelerator) const override; - // Overridden from views::WidgetDelegate: + // views::WidgetDelegate: bool CanResize() const override; bool CanMaximize() const override; bool CanMinimize() const override; @@ -441,11 +441,11 @@ const views::Widget* GetWidget() const override; void GetAccessiblePanes(std::vector<View*>* panes) override; - // Overridden from views::WidgetObserver: + // views::WidgetObserver: void OnWidgetDestroying(views::Widget* widget) override; void OnWidgetActivationChanged(views::Widget* widget, bool active) override; - // Overridden from views::ClientView: + // views::ClientView: bool CanClose() override; int NonClientHitTest(const gfx::Point& point) override; gfx::Size GetMinimumSize() const override; @@ -453,7 +453,7 @@ // infobars::InfoBarContainer::Delegate: void InfoBarContainerStateChanged(bool is_animating) override; - // Overridden from views::View: + // views::View: const char* GetClassName() const override; void Layout() override; void OnGestureEvent(ui::GestureEvent* event) override; @@ -465,17 +465,17 @@ void GetAccessibleNodeData(ui::AXNodeData* node_data) override; void OnThemeChanged() override; - // Overridden from ui::AcceleratorTarget: + // ui::AcceleratorTarget: bool AcceleratorPressed(const ui::Accelerator& accelerator) override; - // ExclusiveAccessContext overrides + // ExclusiveAccessContext: Profile* GetProfile() override; content::WebContents* GetActiveWebContents() override; void HideDownloadShelf() override; void UnhideDownloadShelf() override; ExclusiveAccessBubbleViews* GetExclusiveAccessBubble() override; - // ExclusiveAccessBubbleViewsContext overrides + // ExclusiveAccessBubbleViewsContext: ExclusiveAccessManager* GetExclusiveAccessManager() override; views::Widget* GetBubbleAssociatedWidget() override; ui::AcceleratorProvider* GetAcceleratorProvider() override; @@ -487,7 +487,7 @@ void DestroyAnyExclusiveAccessBubble() override; bool CanTriggerOnMouse() const override; - // extension::ExtensionKeybindingRegistry::Delegate overrides + // extension::ExtensionKeybindingRegistry::Delegate: extensions::ActiveTabPermissionGranter* GetActiveTabPermissionGranter() override;
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc index 49e27817..6503545f 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -9,7 +9,6 @@ #include "ash/public/interfaces/window_state_type.mojom.h" #include "base/macros.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/tablet_mode_client.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" @@ -25,6 +24,7 @@ #include "ui/aura/mus/property_converter.h" #include "ui/aura/mus/window_port_mus.h" #include "ui/aura/window.h" +#include "ui/base/ui_base_features.h" #include "ui/compositor/layer.h" #include "ui/compositor/paint_context.h" #include "ui/compositor/paint_recorder.h" @@ -159,7 +159,7 @@ bool ImmersiveModeControllerAsh::ShouldStayImmersiveAfterExitingFullscreen() { // TODO(crbug.com/760811): Support tablet mode in mash. - if (ash_util::IsRunningInMash()) + if (!features::IsAshInBrowserProcess()) return false; return !browser_view_->IsBrowserTypeNormal() && @@ -177,7 +177,7 @@ return; // TODO(crbug.com/760811): Support tablet mode in mash. - if (ash_util::IsRunningInMash() || + if (!features::IsAshInBrowserProcess() || !TabletModeClient::Get()->tablet_mode_enabled()) { return; } @@ -197,7 +197,7 @@ observers_enabled_ = enable; aura::Window* native_window = browser_view_->GetNativeWindow(); - aura::Window* target_window = ash_util::IsRunningInMash() + aura::Window* target_window = !features::IsAshInBrowserProcess() ? native_window->GetRootWindow() : native_window; @@ -223,7 +223,7 @@ } void ImmersiveModeControllerAsh::CreateMashRevealWidget() { - if (!ash_util::IsRunningInMash()) + if (features::IsAshInBrowserProcess()) return; DCHECK(!mash_reveal_widget_);
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc index 045bb7a..34a1fad 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -12,7 +12,6 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/macros.h" #include "base/test/test_mock_time_task_runner.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/profiles/profile_io_data.h" #include "chrome/browser/ssl/cert_verifier_browser_test.h" @@ -33,6 +32,7 @@ #include "content/public/common/content_switches.h" #include "net/cert/mock_cert_verifier.h" #include "ui/aura/client/aura_constants.h" +#include "ui/base/ui_base_features.h" #include "ui/views/animation/test/ink_drop_host_view_test_api.h" class ImmersiveModeControllerAshHostedAppBrowserTest @@ -271,7 +271,7 @@ LaunchAppBrowser(); ASSERT_FALSE(controller()->IsEnabled()); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - DCHECK_NE(ash::Config::MASH, chromeos::GetAshConfig()); + ASSERT_TRUE(features::IsAshInBrowserProcess()); BrowserNonClientFrameViewAsh* frame_view = static_cast<BrowserNonClientFrameViewAsh*>( browser_view->GetWidget()->non_client_view()->frame_view()); @@ -327,7 +327,7 @@ LaunchAppBrowser(false); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - DCHECK_NE(ash::Config::MASH, chromeos::GetAshConfig()); + ASSERT_TRUE(features::IsAshInBrowserProcess()); frame_view = static_cast<BrowserNonClientFrameViewAsh*>( browser_view->GetWidget()->non_client_view()->frame_view());
diff --git a/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc b/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc index 27b59a7..6fa1b03 100644 --- a/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc +++ b/chrome/browser/ui/views/frame/native_browser_frame_factory_chromeos.cc
@@ -4,14 +4,14 @@ #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/ui/views/frame/browser_frame_ash.h" #include "chrome/browser/ui/views/frame/browser_frame_mash.h" +#include "ui/base/ui_base_features.h" NativeBrowserFrame* NativeBrowserFrameFactory::Create( BrowserFrame* browser_frame, BrowserView* browser_view) { - if (chromeos::GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return new BrowserFrameMash(browser_frame, browser_view); return new BrowserFrameAsh(browser_frame, browser_view); }
diff --git a/chrome/browser/ui/views/harmony/harmony_typography_provider.cc b/chrome/browser/ui/views/harmony/harmony_typography_provider.cc index 13b86b4ff..cd066972 100644 --- a/chrome/browser/ui/views/harmony/harmony_typography_provider.cc +++ b/chrome/browser/ui/views/harmony/harmony_typography_provider.cc
@@ -192,7 +192,7 @@ case views::style::STYLE_DISABLED: return SkColorSetRGB(0x9e, 0x9e, 0x9e); case views::style::STYLE_LINK: - return gfx::kGoogleBlue600; + return gfx::kGoogleBlue700; case STYLE_SECONDARY: case STYLE_EMPHASIZED_SECONDARY: case STYLE_HINT:
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc index 56a9cf6..f5b408c 100644 --- a/chrome/browser/ui/views/hung_renderer_view.cc +++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -74,30 +74,45 @@ void HungPagesTableModel::InitForWebContents( WebContents* contents, - content::RenderWidgetHost* render_widget_host) { - process_observer_.RemoveAll(); - widget_observer_.RemoveAll(); + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { + DCHECK(contents); + DCHECK(render_widget_host); + DCHECK(!hang_monitor_restarter.is_null()); + + DCHECK(!render_widget_host_); + DCHECK(!process_observer_.IsObservingSources()); + DCHECK(!widget_observer_.IsObservingSources()); + DCHECK(tab_observers_.empty()); + render_widget_host_ = render_widget_host; - tab_observers_.clear(); + hang_monitor_restarter_ = std::move(hang_monitor_restarter); - if (contents) { - for (auto* hung_contents : - GetHungWebContentsList(contents, render_widget_host->GetProcess())) { - tab_observers_.push_back( - std::make_unique<WebContentsObserverImpl>(this, hung_contents)); - } + for (auto* hung_contents : + GetHungWebContentsList(contents, render_widget_host->GetProcess())) { + tab_observers_.push_back( + std::make_unique<WebContentsObserverImpl>(this, hung_contents)); } - if (render_widget_host_) { - process_observer_.Add(render_widget_host_->GetProcess()); - widget_observer_.Add(render_widget_host_); - } + process_observer_.Add(render_widget_host_->GetProcess()); + widget_observer_.Add(render_widget_host_); // The world is different. if (observer_) observer_->OnModelChanged(); } +void HungPagesTableModel::Reset() { + process_observer_.RemoveAll(); + widget_observer_.RemoveAll(); + tab_observers_.clear(); + render_widget_host_ = nullptr; +} + +void HungPagesTableModel::RestartHangMonitorTimeout() { + hang_monitor_restarter_.Run(); +} + /////////////////////////////////////////////////////////////////////////////// // HungPagesTableModel, ui::TableModel implementation: @@ -218,7 +233,8 @@ // static void HungRendererDialogView::Show( WebContents* contents, - content::RenderWidgetHost* render_widget_host) { + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { if (logging::DialogsAreSuppressed()) return; @@ -232,7 +248,8 @@ return; #endif HungRendererDialogView* view = HungRendererDialogView::Create(window); - view->ShowForWebContents(contents, render_widget_host); + view->ShowForWebContents(contents, render_widget_host, + std::move(hang_monitor_restarter)); } // static @@ -264,7 +281,8 @@ void HungRendererDialogView::ShowForWebContents( WebContents* contents, - content::RenderWidgetHost* render_widget_host) { + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { DCHECK(contents && GetWidget()); // Don't show the warning unless the foreground window is the frame, or this @@ -306,7 +324,8 @@ // renderer may hang while this one is showing, and we don't want to reset // the list of hung pages for a potentially unrelated renderer while this // one is showing. - hung_pages_table_model_->InitForWebContents(contents, render_widget_host); + hung_pages_table_model_->InitForWebContents( + contents, render_widget_host, std::move(hang_monitor_restarter)); UpdateLabels(); @@ -458,9 +477,7 @@ void HungRendererDialogView::RestartHangTimer() { // Start waiting again for responsiveness. - auto* render_widget_host = hung_pages_table_model_->GetRenderWidgetHost(); - if (render_widget_host) - render_widget_host->RestartHangMonitorTimeoutIfNecessary(); + hung_pages_table_model_->RestartHangMonitorTimeout(); } void HungRendererDialogView::UpdateLabels() { @@ -476,6 +493,6 @@ // - Close is async and we don't want hanging references, and // - While the dialog is active, [X] maps to restarting the hang timer, but // while closing we don't want that action. - hung_pages_table_model_->InitForWebContents(nullptr, nullptr); + hung_pages_table_model_->Reset(); GetWidget()->Close(); }
diff --git a/chrome/browser/ui/views/hung_renderer_view.h b/chrome/browser/ui/views/hung_renderer_view.h index cac20ab..b1a9aba 100644 --- a/chrome/browser/ui/views/hung_renderer_view.h +++ b/chrome/browser/ui/views/hung_renderer_view.h
@@ -5,6 +5,10 @@ #ifndef CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_HUNG_RENDERER_VIEW_H_ +#include <memory> +#include <vector> + +#include "base/callback.h" #include "base/macros.h" #include "base/scoped_observer.h" #include "components/favicon/content/content_favicon_driver.h" @@ -46,7 +50,15 @@ ~HungPagesTableModel() override; void InitForWebContents(content::WebContents* hung_contents, - content::RenderWidgetHost* render_widget_host); + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter); + + // Resets the model to the uninitialized state (e.g. unregisters observers + // added by InitForWebContents and disassociates this model from any + // particular WebContents and/or RenderWidgetHost). + void Reset(); + + void RestartHangMonitorTimeout(); // Returns the hung RenderWidgetHost, or null if there aren't any WebContents. content::RenderWidgetHost* GetRenderWidgetHost(); @@ -106,6 +118,10 @@ content::RenderWidgetHost* render_widget_host_ = nullptr; + // Callback that restarts the hang timeout (e.g. if the user wants to wait + // some more until the renderer process responds). + base::RepeatingClosure hang_monitor_restarter_; + ScopedObserver<content::RenderProcessHost, content::RenderProcessHostObserver> process_observer_; @@ -129,7 +145,8 @@ // Shows or hides the hung renderer dialog for the given WebContents. static void Show(content::WebContents* contents, - content::RenderWidgetHost* render_widget_host); + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter); static void Hide(content::WebContents* contents, content::RenderWidgetHost* render_widget_host); @@ -138,7 +155,8 @@ virtual void ShowForWebContents( content::WebContents* contents, - content::RenderWidgetHost* render_widget_host); + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter); virtual void EndForWebContents(content::WebContents* contents, content::RenderWidgetHost* render_widget_host);
diff --git a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc index 88f6fa6f0..06eee28 100644 --- a/chrome/browser/ui/views/hung_renderer_view_browsertest.cc +++ b/chrome/browser/ui/views/hung_renderer_view_browsertest.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/bind_helpers.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -37,8 +38,9 @@ // DialogBrowserTest: void ShowUi(const std::string& name) override { auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - HungRendererDialogView::Show( - web_contents, web_contents->GetRenderViewHost()->GetWidget()); + HungRendererDialogView::Show(web_contents, + web_contents->GetRenderViewHost()->GetWidget(), + base::DoNothing::Repeatedly()); if (name == "MultiplePages") { auto* web_contents2 = chrome::DuplicateTabAt(browser(), 0);
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index b150ad0..9291812d 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -780,7 +780,13 @@ } void LocationBarView::RefreshBackground() { - SkColor background_color = GetColor(OmniboxPart::LOCATION_BAR_BACKGROUND); + // Note we are not using hover state color when focused; only in steady state. + const OmniboxPartState state = + (omnibox_view_->HasFocus() || !omnibox_view_->IsHovered()) + ? OmniboxPartState::NORMAL + : OmniboxPartState::HOVERED; + SkColor background_color = + GetOmniboxColor(OmniboxPart::LOCATION_BAR_BACKGROUND, tint(), state); SkColor border_color = GetBorderColor(); if (IsRounded()) { @@ -1257,6 +1263,11 @@ RefreshBackground(); } +void LocationBarView::OnOmniboxHoverChanged() { + RefreshBackground(); + SchedulePaint(); +} + //////////////////////////////////////////////////////////////////////////////// // LocationBarView, private DropdownBarHostDelegate implementation:
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index e60228a..57cf3b0 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -267,6 +267,9 @@ void OnOmniboxFocused(); void OnOmniboxBlurred(); + // Called when omnibox detects change in hover state + void OnOmniboxHoverChanged(); + private: FRIEND_TEST_ALL_PREFIXES(SecurityIndicatorTest, CheckIndicatorText); FRIEND_TEST_ALL_PREFIXES(TouchLocationBarViewBrowserTest,
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_view.cc index 9034d10..8db847a 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/views/media_router/cast_dialog_view.h" +#include "base/optional.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/media_router/cast_dialog_controller.h" #include "chrome/browser/ui/media_router/cast_dialog_model.h" @@ -119,14 +120,19 @@ } void CastDialogView::OnModelUpdated(const CastDialogModel& model) { - if (model.media_sinks.empty()) { + if (model.media_sinks().empty()) { ShowNoSinksView(); } else { + // If |sink_buttons_| is empty, the sink list was empty before this update. + // In that case, select the first active sink, so that its session can be + // stopped with one click. + if (sink_buttons_.empty()) + selected_sink_index_ = model.GetFirstActiveSinkIndex().value_or(0); ShowScrollView(); - PopulateScrollView(model.media_sinks); + PopulateScrollView(model.media_sinks()); RestoreSinkListState(); } - dialog_title_ = model.dialog_header; + dialog_title_ = model.dialog_header(); MaybeSizeToContents(); }
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.h b/chrome/browser/ui/views/media_router/cast_dialog_view.h index 7d12f39..b55ea3f6 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.h +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.h
@@ -75,6 +75,7 @@ void ExecuteCommand(int command_id, int event_flags) override; // Called by tests. + size_t selected_sink_index_for_test() const { return selected_sink_index_; } const std::vector<CastDialogSinkButton*>& sink_buttons_for_test() const { return sink_buttons_; }
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc index 603843d..2e8b9a5 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc
@@ -54,8 +54,8 @@ CastDialogModel CreateModelWithSinks(std::vector<UIMediaSink> sinks) { CastDialogModel model; - model.dialog_header = base::UTF8ToUTF16("Dialog header"); - model.media_sinks = std::move(sinks); + model.set_dialog_header(base::UTF8ToUTF16("Dialog header")); + model.set_media_sinks(std::move(sinks)); return model; } @@ -112,6 +112,10 @@ dialog_->ButtonPressed(dialog_->sink_buttons_for_test()[1], mouse_event); } + size_t selected_sink_index() { + return dialog_->selected_sink_index_for_test(); + } + views::ScrollView* scroll_view() { return dialog_->scroll_view_for_test(); } views::View* no_sinks_view() { return dialog_->no_sinks_view_for_test(); } @@ -163,56 +167,70 @@ InitializeDialogWithModel(model); EXPECT_TRUE(dialog_->ShouldShowCloseButton()); - EXPECT_EQ(model.dialog_header, dialog_->GetWindowTitle()); + EXPECT_EQ(model.dialog_header(), dialog_->GetWindowTitle()); EXPECT_EQ(ui::DIALOG_BUTTON_OK, dialog_->GetDialogButtons()); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_START_CASTING_BUTTON), dialog_->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK)); } -TEST_F(CastDialogViewTest, ChooseSinks) { +TEST_F(CastDialogViewTest, StartCasting) { + std::vector<UIMediaSink> media_sinks = {CreateAvailableSink(), + CreateAvailableSink()}; + media_sinks[0].id = "sink0"; + media_sinks[1].id = "sink1"; + CastDialogModel model = CreateModelWithSinks(std::move(media_sinks)); + InitializeDialogWithModel(model); + + // Activate the main action button. The sink at index 0 should be selected by + // default when there are no active sinks. + EXPECT_EQ(0u, selected_sink_index()); + EXPECT_CALL(controller_, StartCasting(model.media_sinks()[0].id, TAB_MIRROR)); + dialog_->Accept(); +} + +TEST_F(CastDialogViewTest, StopCasting) { CastDialogModel model = CreateModelWithSinks({CreateAvailableSink(), CreateConnectedSink()}); InitializeDialogWithModel(model); - // Activate the main action button. The sink at index 0 should be selected by - // default. - EXPECT_CALL(controller_, StartCasting(model.media_sinks[0].id, TAB_MIRROR)); - dialog_->Accept(); - - // The label on the main action button should be updated when a different sink - // is chosen. - SelectSinkAtIndex(1); + // When there is an active sink, that should be selected by default. + EXPECT_EQ(1u, selected_sink_index()); EXPECT_EQ(l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_STOP_CASTING_BUTTON), dialog_->GetDialogButtonLabel(ui::DIALOG_BUTTON_OK)); - EXPECT_CALL(controller_, StopCasting(model.media_sinks[1].route_id)); + EXPECT_CALL(controller_, StopCasting(model.media_sinks()[1].route_id)); dialog_->Accept(); } TEST_F(CastDialogViewTest, UpdateModel) { - CastDialogModel model = - CreateModelWithSinks({CreateAvailableSink(), CreateConnectedSink()}); + std::vector<UIMediaSink> media_sinks = {CreateAvailableSink(), + CreateConnectedSink()}; + CastDialogModel model = CreateModelWithSinks(media_sinks); InitializeDialogWithModel(model); SelectSinkAtIndex(1); - model.media_sinks[1].state = UIMediaSinkState::AVAILABLE; - model.media_sinks[1].route_id = ""; - model.media_sinks[1].cast_modes = {PRESENTATION}; + media_sinks[1].state = UIMediaSinkState::AVAILABLE; + media_sinks[1].route_id = ""; + media_sinks[1].cast_modes = {PRESENTATION}; + model.set_media_sinks(std::move(media_sinks)); dialog_->OnModelUpdated(model); // Sink selection should be retained across a model update. - EXPECT_CALL(controller_, StartCasting(model.media_sinks[1].id, PRESENTATION)); + EXPECT_CALL(controller_, + StartCasting(model.media_sinks()[1].id, PRESENTATION)); dialog_->Accept(); } TEST_F(CastDialogViewTest, ShowAlternativeSources) { - CastDialogModel model = CreateModelWithSinks({CreateConnectedSink()}); - model.media_sinks[0].cast_modes = {TAB_MIRROR, PRESENTATION, LOCAL_FILE}; + std::vector<UIMediaSink> media_sinks = {CreateConnectedSink()}; + media_sinks[0].cast_modes = {TAB_MIRROR, PRESENTATION, LOCAL_FILE}; + CastDialogModel model = CreateModelWithSinks(media_sinks); InitializeDialogWithModel(model); // Press the button to show the alternative sources menu. dialog_->ButtonPressed(sources_button(), CreateMouseEvent()); EXPECT_EQ(1, sources_menu_model()->GetItemCount()); EXPECT_EQ(LOCAL_FILE, sources_menu_model()->GetCommandIdAt(0)); - model.media_sinks[0].cast_modes = {TAB_MIRROR, DESKTOP_MIRROR, LOCAL_FILE}; + media_sinks[0].cast_modes = {TAB_MIRROR, DESKTOP_MIRROR, LOCAL_FILE}; + model.set_media_sinks(std::move(media_sinks)); dialog_->OnModelUpdated(model); dialog_->ButtonPressed(sources_button(), CreateMouseEvent()); EXPECT_EQ(2, sources_menu_model()->GetItemCount()); @@ -221,18 +239,19 @@ } TEST_F(CastDialogViewTest, CastToAlternativeSources) { - CastDialogModel model = CreateModelWithSinks({CreateConnectedSink()}); - model.media_sinks[0].cast_modes = {DESKTOP_MIRROR, LOCAL_FILE}; + std::vector<UIMediaSink> media_sinks = {CreateConnectedSink()}; + media_sinks[0].cast_modes = {DESKTOP_MIRROR, LOCAL_FILE}; + CastDialogModel model = CreateModelWithSinks(std::move(media_sinks)); InitializeDialogWithModel(model); // Press the button to show the alternative sources menu. dialog_->ButtonPressed(sources_button(), CreateMouseEvent()); ASSERT_EQ(2, sources_menu_model()->GetItemCount()); EXPECT_CALL(controller_, - StartCasting(model.media_sinks[0].id, DESKTOP_MIRROR)); + StartCasting(model.media_sinks()[0].id, DESKTOP_MIRROR)); sources_menu_model()->ActivatedAt(0); Mock::VerifyAndClearExpectations(&controller_); - EXPECT_CALL(controller_, StartCasting(model.media_sinks[0].id, LOCAL_FILE)); + EXPECT_CALL(controller_, StartCasting(model.media_sinks()[0].id, LOCAL_FILE)); sources_menu_model()->ActivatedAt(1); } @@ -242,8 +261,9 @@ // The picker should be disabled when there are no sinks. EXPECT_FALSE(sources_button()->enabled()); - model.media_sinks.push_back(CreateConnectedSink()); - model.media_sinks[0].cast_modes = {TAB_MIRROR, PRESENTATION}; + std::vector<UIMediaSink> media_sinks = {CreateConnectedSink()}; + media_sinks[0].cast_modes = {TAB_MIRROR, PRESENTATION}; + model.set_media_sinks(std::move(media_sinks)); dialog_->OnModelUpdated(model); // The picker should be disabled if the selected sink doesn't support non-tab // sources. @@ -257,7 +277,8 @@ EXPECT_TRUE(no_sinks_view()->visible()); EXPECT_FALSE(scroll_view()); - model.media_sinks.push_back(CreateConnectedSink()); + std::vector<UIMediaSink> media_sinks = {CreateConnectedSink()}; + model.set_media_sinks(std::move(media_sinks)); dialog_->OnModelUpdated(model); // The scroll view should be shown when there are sinks. EXPECT_FALSE(no_sinks_view());
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.cc b/chrome/browser/ui/views/media_router/media_router_views_ui.cc index d1d8375c..d58bc61 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.cc +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.cc
@@ -44,8 +44,13 @@ void MediaRouterViewsUI::StartCasting(const std::string& sink_id, MediaCastMode cast_mode) { - CreateRoute(sink_id, cast_mode); - UpdateSinks(); + if (cast_mode == LOCAL_FILE) { + local_file_sink_id_ = sink_id; + OpenFileDialog(); + } else { + CreateRoute(sink_id, cast_mode); + UpdateSinks(); + } } void MediaRouterViewsUI::StopCasting(const std::string& route_id) { @@ -81,17 +86,18 @@ } void MediaRouterViewsUI::UpdateSinks() { - model_.dialog_header = - l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_AUTO_CAST_MODE); - model_.media_sinks.clear(); + model_.set_dialog_header( + l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_AUTO_CAST_MODE)); + std::vector<UIMediaSink> media_sinks; for (const MediaSinkWithCastModes& sink : GetEnabledSinks()) { auto route_it = std::find_if( routes().begin(), routes().end(), [&sink](const MediaRoute& route) { return route.media_sink_id() == sink.sink.id(); }); const MediaRoute* route = route_it == routes().end() ? nullptr : &*route_it; - model_.media_sinks.push_back(ConvertToUISink(sink, route, issue_)); + media_sinks.push_back(ConvertToUISink(sink, route, issue_)); } + model_.set_media_sinks(std::move(media_sinks)); for (CastDialogController::Observer& observer : observers_) observer.OnModelUpdated(model_); } @@ -131,4 +137,15 @@ UpdateSinks(); } +void MediaRouterViewsUI::FileDialogFileSelected( + const ui::SelectedFileInfo& file_info) { + CreateRoute(local_file_sink_id_.value(), LOCAL_FILE); + local_file_sink_id_.reset(); +} + +void MediaRouterViewsUI::FileDialogSelectionFailed(const IssueInfo& issue) { + MediaRouterUIBase::FileDialogSelectionFailed(issue); + local_file_sink_id_.reset(); +} + } // namespace media_router
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.h b/chrome/browser/ui/views/media_router/media_router_views_ui.h index fd6dedd..c8c05f63 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.h +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.h
@@ -52,9 +52,17 @@ const MediaRoute* route, const base::Optional<Issue>& issue); + // MediaRouterFileDialogDelegate: + void FileDialogFileSelected(const ui::SelectedFileInfo& file_info) override; + void FileDialogSelectionFailed(const IssueInfo& issue) override; + // Contains up-to-date data to show in the dialog. CastDialogModel model_; + // This value is set when the user opens a file picker, and used when a file + // is selected and casting starts. + base::Optional<MediaSink::Id> local_file_sink_id_; + // Observers for dialog model updates. base::ObserverList<CastDialogController::Observer> observers_;
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc b/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc index 5305730..8f45ca7 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc +++ b/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc
@@ -86,7 +86,7 @@ EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>(Invoke([](const CastDialogModel& model) { - EXPECT_TRUE(model.media_sinks.empty()); + EXPECT_TRUE(model.media_sinks().empty()); }))); ui_->AddObserver(&observer); @@ -95,8 +95,8 @@ sink_with_cast_modes.cast_modes = {MediaCastMode::TAB_MIRROR}; EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>(Invoke([&sink](const CastDialogModel& model) { - EXPECT_EQ(1u, model.media_sinks.size()); - const UIMediaSink& ui_sink = model.media_sinks[0]; + EXPECT_EQ(1u, model.media_sinks().size()); + const UIMediaSink& ui_sink = model.media_sinks()[0]; EXPECT_EQ(sink.id(), ui_sink.id); EXPECT_EQ(base::UTF8ToUTF16(sink.name()), ui_sink.friendly_name); EXPECT_EQ(UIMediaSinkState::AVAILABLE, ui_sink.state); @@ -110,8 +110,8 @@ EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce( WithArg<0>(Invoke([&sink, &route](const CastDialogModel& model) { - EXPECT_EQ(1u, model.media_sinks.size()); - const UIMediaSink& ui_sink = model.media_sinks[0]; + EXPECT_EQ(1u, model.media_sinks().size()); + const UIMediaSink& ui_sink = model.media_sinks()[0]; EXPECT_EQ(sink.id(), ui_sink.id); EXPECT_EQ(UIMediaSinkState::CONNECTED, ui_sink.state); EXPECT_EQ(route.media_route_id(), ui_sink.route_id); @@ -152,8 +152,8 @@ EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>(Invoke([&sink](const CastDialogModel& model) { - EXPECT_EQ(1u, model.media_sinks.size()); - EXPECT_EQ(sink.id(), model.media_sinks[0].id); + EXPECT_EQ(1u, model.media_sinks().size()); + EXPECT_EQ(sink.id(), model.media_sinks()[0].id); }))); ui_->OnResultsUpdated({sink_with_cast_modes, pseudo_sink_with_cast_modes}); ui_->RemoveObserver(&observer); @@ -171,16 +171,16 @@ // CONNECTING. EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>(Invoke([&sink](const CastDialogModel& model) { - ASSERT_EQ(1u, model.media_sinks.size()); - EXPECT_EQ(UIMediaSinkState::CONNECTING, model.media_sinks[0].state); + ASSERT_EQ(1u, model.media_sinks().size()); + EXPECT_EQ(UIMediaSinkState::CONNECTING, model.media_sinks()[0].state); }))); ui_->StartCasting(kSinkId, MediaCastMode::TAB_MIRROR); // Once a route is created for the sink, its state should become CONNECTED. EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>(Invoke([&sink](const CastDialogModel& model) { - ASSERT_EQ(1u, model.media_sinks.size()); - EXPECT_EQ(UIMediaSinkState::CONNECTED, model.media_sinks[0].state); + ASSERT_EQ(1u, model.media_sinks().size()); + EXPECT_EQ(UIMediaSinkState::CONNECTED, model.media_sinks()[0].state); }))); MediaRoute route(kRouteId, MediaSource(kSourceId), kSinkId, "", true, true); ui_->OnRoutesUpdated({route}, {}); @@ -212,19 +212,19 @@ EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>( Invoke([&sink1, &sink2, &issue_title](const CastDialogModel& model) { - EXPECT_EQ(2u, model.media_sinks.size()); - EXPECT_EQ(model.media_sinks[0].id, sink1.id()); - EXPECT_FALSE(model.media_sinks[0].issue.has_value()); - EXPECT_EQ(model.media_sinks[1].id, sink2.id()); - EXPECT_EQ(model.media_sinks[1].issue->info().title, issue_title); + EXPECT_EQ(2u, model.media_sinks().size()); + EXPECT_EQ(model.media_sinks()[0].id, sink1.id()); + EXPECT_FALSE(model.media_sinks()[0].issue.has_value()); + EXPECT_EQ(model.media_sinks()[1].id, sink2.id()); + EXPECT_EQ(model.media_sinks()[1].issue->info().title, issue_title); }))); mock_router_.GetIssueManager()->AddIssue(issue); EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>(Invoke([&sink2](const CastDialogModel& model) { - EXPECT_EQ(2u, model.media_sinks.size()); - EXPECT_EQ(model.media_sinks[1].id, sink2.id()); - EXPECT_FALSE(model.media_sinks[1].issue.has_value()); + EXPECT_EQ(2u, model.media_sinks().size()); + EXPECT_EQ(model.media_sinks()[1].id, sink2.id()); + EXPECT_FALSE(model.media_sinks()[1].issue.has_value()); }))); mock_router_.GetIssueManager()->ClearIssue(issue_id); ui_->RemoveObserver(&observer);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc index 9855f47..0371858 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
@@ -16,11 +16,13 @@ #include "chrome/browser/ui/views/omnibox/omnibox_text_view.h" #include "chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h" #include "chrome/grit/generated_resources.h" +#include "chrome/grit/theme_resources.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/vector_icons.h" #include "extensions/common/image_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/material_design/material_design_controller.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/image/canvas_image_source.h" #include "ui/gfx/paint_vector_icon.h" @@ -296,6 +298,7 @@ } else { // Determine if we have a local icon (or else it will be downloaded). const gfx::VectorIcon* vector_icon = nullptr; + int idr_image = 0; if (match.answer) { switch (match.answer->type()) { case SuggestionAnswer::ANSWER_TYPE_CURRENCY: @@ -310,6 +313,9 @@ case SuggestionAnswer::ANSWER_TYPE_SUNRISE: vector_icon = &omnibox::kAnswerSunriseIcon; break; + case SuggestionAnswer::ANSWER_TYPE_TRANSLATION: + idr_image = IDR_OMNIBOX_TRANSLATION_ROUND; + break; case SuggestionAnswer::ANSWER_TYPE_WEATHER: // Weather icons are downloaded. Do nothing. break; @@ -317,11 +323,16 @@ vector_icon = &omnibox::kAnswerWhenIsIcon; break; default: + vector_icon = &omnibox::kAnswerDefaultIcon; break; } if (vector_icon) { image_view_->SetImage(gfx::CreateVectorIcon( *vector_icon, kNewAnswerImageSize, gfx::kGoogleBlue600)); + } else if (idr_image) { + image_view_->SetImage( + ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + idr_image)); } // Always set the image size so that downloaded images get the correct // size (such as Weather answers).
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index 5f4492d..4318363b 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -124,6 +124,7 @@ LocationBarView* location_bar, const gfx::FontList& font_list) : OmniboxView(controller, std::move(client)), + hovered_(false), popup_window_mode_(popup_window_mode), security_level_(security_state::NONE), saved_selection_for_focus_change_(gfx::Range::InvalidRange()), @@ -252,6 +253,10 @@ OnBoundsChanged(gfx::Rect()); } +bool OmniboxViewViews::IsHovered() const { + return hovered_; +} + void OmniboxViewViews::EmphasizeURLComponents() { if (!location_bar_view_) return; @@ -606,6 +611,15 @@ friendly_suggestion_text_prefix_length_ = 0; } +void OmniboxViewViews::SetHovered(bool hovered) { + if (hovered != hovered_) { + hovered_ = hovered; + if (location_bar_view_) { + location_bar_view_->OnOmniboxHoverChanged(); + } + } +} + bool OmniboxViewViews::UnapplySteadyStateElisions(UnelisionGesture gesture) { if (!OmniboxFieldTrial::IsHideSteadyStateUrlSchemeAndSubdomainsEnabled()) return false; @@ -847,6 +861,13 @@ TextChanged(); } +void OmniboxViewViews::OnMouseMoved(const ui::MouseEvent& event) { + SetHovered(true); +} +void OmniboxViewViews::OnMouseExited(const ui::MouseEvent& event) { + SetHovered(false); +} + void OmniboxViewViews::OnGestureEvent(ui::GestureEvent* event) { if (!HasFocus() && event->type() == ui::ET_GESTURE_TAP_DOWN) { select_all_on_gesture_tap_ = true;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index ec6c47d..83ad19a 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -95,6 +95,9 @@ // Otherwise, resets the text indent to default. void UpdateTextIndent(); + // Returns true if the omnibox is currently hovered. + bool IsHovered() const; + // OmniboxView: void EmphasizeURLComponents() override; void Update() override; @@ -136,6 +139,8 @@ FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, MaintainCursorAfterFocusCycle); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, OnBlur); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, DoNotNavigateOnDrop); + FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, + MouseMoveAndExitSetsHoveredState); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, FirstMouseClickFocusesOnly); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, @@ -185,6 +190,9 @@ void ClearAccessibilityLabel(); + // Sets the hovered state for omnibox. + void SetHovered(bool hovered); + // Returns true if the user text was updated with the full URL (without // steady-state elisions). |gesture| is the user gesture causing unelision. bool UnapplySteadyStateElisions(UnelisionGesture gesture); @@ -238,6 +246,10 @@ bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override; void ExecuteTextEditCommand(ui::TextEditCommand command) override; + // views::View: + void OnMouseMoved(const ui::MouseEvent& event) override; + void OnMouseExited(const ui::MouseEvent& event) override; + // chromeos::input_method::InputMethodManager::CandidateWindowObserver: #if defined(OS_CHROMEOS) void CandidateWindowOpened( @@ -274,6 +286,9 @@ // TemplateURLServiceObserver: void OnTemplateURLServiceChanged() override; + // Holds hover state for visual hinting. + bool hovered_; + // When true, the location bar view is read only and also is has a slightly // different presentation (smaller font size). This is used for popups. bool popup_window_mode_;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc index 69a935e..e3f2a5d 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -203,6 +203,11 @@ void SetUp() override; void TearDown() override; + ui::MouseEvent CreateEvent(ui::EventType type, int flags) { + return ui::MouseEvent(type, gfx::Point(0, 0), gfx::Point(), + ui::EventTimeForNow(), flags, 0); + } + private: content::TestBrowserThreadBundle thread_bundle_; TestingProfile profile_; @@ -440,6 +445,23 @@ EXPECT_FALSE(omnibox_view()->model()->user_input_in_progress()); } +TEST_F(OmniboxViewViewsTest, MouseMoveAndExitSetsHoveredState) { + // Starting state should not be hovered + EXPECT_EQ(omnibox_view()->IsHovered(), false); + + // Moving the mouse over the view should put the view in the hovered state. + omnibox_view()->OnMouseMoved(CreateEvent(ui::ET_MOUSE_MOVED, 0)); + EXPECT_EQ(omnibox_view()->IsHovered(), true); + + // Continuing to move over the view should not change the state. + omnibox_view()->OnMouseMoved(CreateEvent(ui::ET_MOUSE_MOVED, 0)); + EXPECT_EQ(omnibox_view()->IsHovered(), true); + + // But exiting should revert the HOVERED state. + omnibox_view()->OnMouseExited(CreateEvent(ui::ET_MOUSE_MOVED, 0)); + EXPECT_EQ(omnibox_view()->IsHovered(), false); +} + class OmniboxViewViewsSteadyStateElisionsTest : public OmniboxViewViewsTest { protected: const int kCharacterWidth = 10;
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc index a3085d6..2d1da516 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -951,7 +951,8 @@ #if defined(SAFE_BROWSING_DB_LOCAL) std::unique_ptr<PageInfoUI::SecurityDescription> -PageInfoBubbleView::CreateSecurityDescriptionForPasswordReuse() const { +PageInfoBubbleView::CreateSecurityDescriptionForPasswordReuse( + bool is_enterprise_password) const { std::unique_ptr<PageInfoUI::SecurityDescription> security_description( new PageInfoUI::SecurityDescription()); security_description->summary_style = SecuritySummaryColor::RED; @@ -960,7 +961,12 @@ security_description->details = safe_browsing::ChromePasswordProtectionService:: GetPasswordProtectionService(profile_) - ->GetWarningDetailText(); + ->GetWarningDetailText( + is_enterprise_password + ? safe_browsing::LoginReputationClientRequest:: + PasswordReuseEvent::ENTERPRISE_PASSWORD + : safe_browsing::LoginReputationClientRequest:: + PasswordReuseEvent::SIGN_IN_PASSWORD); return security_description; } #endif
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_bubble_view.h index 3c9b74b..123b313 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.h +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
@@ -137,7 +137,8 @@ void SetIdentityInfo(const IdentityInfo& identity_info) override; #if defined(SAFE_BROWSING_DB_LOCAL) std::unique_ptr<PageInfoUI::SecurityDescription> - CreateSecurityDescriptionForPasswordReuse() const override; + CreateSecurityDescriptionForPasswordReuse( + bool is_enterprise_password) const override; #endif // Creates the contents of the |site_settings_view_|. The ownership of the
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc index b10aae1..0c5c8d8 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
@@ -41,6 +41,8 @@ const char kSyncPasswordPageInfoHistogramName[] = "PasswordProtection.PageInfoAction.SyncPasswordEntry"; +const char kEnterprisePasswordPageInfoHistogramName[] = + "PasswordProtection.PageInfoAction.NonGaiaEnterprisePasswordEntry"; class ClickEvent : public ui::Event { public: @@ -133,7 +135,8 @@ constexpr char kMalware[] = "Malware"; constexpr char kDeceptive[] = "Deceptive"; constexpr char kUnwantedSoftware[] = "UnwantedSoftware"; - constexpr char kPasswordReuse[] = "PasswordReuse"; + constexpr char kSignInPasswordReuse[] = "SignInPasswordReuse"; + constexpr char kEnterprisePasswordReuse[] = "EnterprisePasswordReuse"; constexpr char kMixedContentForm[] = "MixedContentForm"; constexpr char kMixedContent[] = "MixedContent"; constexpr char kAllowAllPermissions[] = "AllowAllPermissions"; @@ -185,8 +188,12 @@ } else if (name == kUnwantedSoftware) { identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_UNWANTED_SOFTWARE; - } else if (name == kPasswordReuse) { - identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_PASSWORD_REUSE; + } else if (name == kSignInPasswordReuse) { + identity.identity_status = + PageInfo::SITE_IDENTITY_STATUS_SIGN_IN_PASSWORD_REUSE; + } else if (name == kEnterprisePasswordReuse) { + identity.identity_status = + PageInfo::SITE_IDENTITY_STATUS_ENTERPRISE_PASSWORD_REUSE; } else if (name == kMixedContentForm) { identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_ADMIN_PROVIDED_CERT; @@ -348,17 +355,17 @@ OpenSiteSettingsForUrl(browser(), url)); } -// Test opening page info bubble that matches SB_THREAT_TYPE_PASSWORD_REUSE -// threat type. +// Test opening page info bubble that matches +// SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE threat type. IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, - VerifyPasswordReusePageInfoBubble) { + VerifySignInPasswordReusePageInfoBubble) { ASSERT_TRUE(embedded_test_server()->Start()); base::HistogramTester histograms; histograms.ExpectTotalCount(kSyncPasswordPageInfoHistogramName, 0); ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL("/")); // Update security state of the current page to match - // SB_THREAT_TYPE_PASSWORD_REUSE. + // SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE. safe_browsing::ChromePasswordProtectionService* service = safe_browsing::ChromePasswordProtectionService:: GetPasswordProtectionService(browser()->profile()); @@ -367,7 +374,6 @@ service->ShowModalWarning(contents, "token", safe_browsing::LoginReputationClientRequest:: PasswordReuseEvent::SIGN_IN_PASSWORD); - base::RunLoop().RunUntilIdle(); OpenPageInfoBubble(browser()); views::View* change_password_button = GetView( @@ -380,7 +386,7 @@ SecurityStateTabHelper::FromWebContents(contents); security_state::SecurityInfo security_info; helper->GetSecurityInfo(&security_info); - ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE, security_info.malicious_content_status); // Verify these two buttons are showing. @@ -390,15 +396,86 @@ // Verify clicking on button will increment corresponding bucket of // PasswordProtection.PageInfoAction.SyncPasswordEntry histogram. PerformMouseClickOnView(change_password_button); - EXPECT_THAT(histograms.GetAllSamples(kSyncPasswordPageInfoHistogramName), - testing::ElementsAre(base::Bucket(0 /*SHOWN*/, 1), - base::Bucket(1 /*CHANGE_PASSWORD*/, 1))); + EXPECT_THAT( + histograms.GetAllSamples(kSyncPasswordPageInfoHistogramName), + testing::ElementsAre( + base::Bucket(safe_browsing::PasswordProtectionService::SHOWN, 1), + base::Bucket( + safe_browsing::PasswordProtectionService::CHANGE_PASSWORD, 1))); PerformMouseClickOnView(whitelist_password_reuse_button); - EXPECT_THAT(histograms.GetAllSamples(kSyncPasswordPageInfoHistogramName), - testing::ElementsAre(base::Bucket(0 /*SHOWN*/, 1), - base::Bucket(1 /*CHANGE_PASSWORD*/, 1), - base::Bucket(4 /*MARK_AS_LEGITIMATE*/, 1))); + EXPECT_THAT( + histograms.GetAllSamples(kSyncPasswordPageInfoHistogramName), + testing::ElementsAre( + base::Bucket(safe_browsing::PasswordProtectionService::SHOWN, 1), + base::Bucket( + safe_browsing::PasswordProtectionService::CHANGE_PASSWORD, 1), + base::Bucket( + safe_browsing::PasswordProtectionService::MARK_AS_LEGITIMATE, + 1))); + // Security state will change after whitelisting. + helper->GetSecurityInfo(&security_info); + EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_NONE, + security_info.malicious_content_status); +} + +// Test opening page info bubble that matches +// SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE threat type. +IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, + VerifyEnterprisePasswordReusePageInfoBubble) { + ASSERT_TRUE(embedded_test_server()->Start()); + base::HistogramTester histograms; + ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL("/")); + + // Update security state of the current page to match + // SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE. + safe_browsing::ChromePasswordProtectionService* service = + safe_browsing::ChromePasswordProtectionService:: + GetPasswordProtectionService(browser()->profile()); + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + service->ShowModalWarning(contents, "token", + safe_browsing::LoginReputationClientRequest:: + PasswordReuseEvent::ENTERPRISE_PASSWORD); + + OpenPageInfoBubble(browser()); + views::View* change_password_button = GetView( + browser(), PageInfoBubbleView::VIEW_ID_PAGE_INFO_BUTTON_CHANGE_PASSWORD); + views::View* whitelist_password_reuse_button = GetView( + browser(), + PageInfoBubbleView::VIEW_ID_PAGE_INFO_BUTTON_WHITELIST_PASSWORD_REUSE); + + SecurityStateTabHelper* helper = + SecurityStateTabHelper::FromWebContents(contents); + security_state::SecurityInfo security_info; + helper->GetSecurityInfo(&security_info); + ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE, + security_info.malicious_content_status); + + // Verify these two buttons are showing. + EXPECT_TRUE(change_password_button->visible()); + EXPECT_TRUE(whitelist_password_reuse_button->visible()); + + // Verify clicking on button will increment corresponding bucket of + // PasswordProtection.PageInfoAction.NonGaiaEnterprisePasswordEntry histogram. + PerformMouseClickOnView(change_password_button); + EXPECT_THAT( + histograms.GetAllSamples(kEnterprisePasswordPageInfoHistogramName), + testing::ElementsAre( + base::Bucket(safe_browsing::PasswordProtectionService::SHOWN, 1), + base::Bucket( + safe_browsing::PasswordProtectionService::CHANGE_PASSWORD, 1))); + + PerformMouseClickOnView(whitelist_password_reuse_button); + EXPECT_THAT( + histograms.GetAllSamples(kEnterprisePasswordPageInfoHistogramName), + testing::ElementsAre( + base::Bucket(safe_browsing::PasswordProtectionService::SHOWN, 1), + base::Bucket( + safe_browsing::PasswordProtectionService::CHANGE_PASSWORD, 1), + base::Bucket( + safe_browsing::PasswordProtectionService::MARK_AS_LEGITIMATE, + 1))); // Security state will change after whitelisting. helper->GetSecurityInfo(&security_info); EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_NONE,
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_browsertest.cc index 97b6f5e..379a722a 100644 --- a/chrome/browser/ui/views/payments/payment_request_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_browsertest.cc
@@ -294,9 +294,9 @@ NavigateTo("/payment_request_payment_method_identifier_test.html"); InvokePaymentRequestWithJs( "buyHelper([{" - " supportedMethods: ['mastercard']," + " supportedMethods: 'mastercard'," "}, {" - " supportedMethods: ['basic-card']" + " supportedMethods: 'basic-card'" "}]);"); std::vector<PaymentRequest*> requests = @@ -324,7 +324,9 @@ NavigateTo("/payment_request_payment_method_identifier_test.html"); InvokePaymentRequestWithJs( "buyHelper([{" - " supportedMethods: ['visa', 'basic-card']" + " supportedMethods: 'visa'" + "}, {" + " supportedMethods: 'basic-card'" "}]);"); std::vector<PaymentRequest*> requests = @@ -352,9 +354,11 @@ NavigateTo("/payment_request_payment_method_identifier_test.html"); InvokePaymentRequestWithJs( "buyHelper([{" - " supportedMethods: ['mastercard', 'visa']" + " supportedMethods: 'mastercard'" "}, {" - " supportedMethods: ['basic-card']," + " supportedMethods: 'visa'" + "}, {" + " supportedMethods: 'basic-card'," " data: {" " supportedNetworks: ['visa', 'mastercard', 'jcb']," " }" @@ -377,9 +381,9 @@ NavigateTo("/payment_request_payment_method_identifier_test.html"); InvokePaymentRequestWithJs( "buyHelper([{" - " supportedMethods: ['https://bobpay.xyz']" + " supportedMethods: 'https://bobpay.xyz'" "}, {" - " supportedMethods: ['basic-card']" + " supportedMethods: 'basic-card'" "}]);"); std::vector<PaymentRequest*> requests = @@ -398,11 +402,17 @@ NavigateTo("/payment_request_payment_method_identifier_test.html"); InvokePaymentRequestWithJs( "buyHelper([{" - " supportedMethods: ['https://bobpay.xyz', 'https://bobpay.xyz']" + " supportedMethods: 'https://bobpay.xyz'" "}, {" - " supportedMethods: ['mastercard', 'visa', 'https://alicepay.com']" + " supportedMethods: 'https://bobpay.xyz'" "}, {" - " supportedMethods: ['basic-card']," + " supportedMethods: 'mastercard'" + "}, {" + " supportedMethods: 'visa'" + "}, {" + " supportedMethods: 'https://alicepay.com'" + "}, {" + " supportedMethods: 'basic-card'," " data: {" " supportedNetworks: ['visa', 'mastercard', 'jcb']," " }"
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 657da3e..9b21404 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -412,15 +412,16 @@ this, browser_)); avatar_menu_->RebuildMenu(); + Profile* profile = browser_->profile(); ProfileOAuth2TokenService* oauth2_token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(browser_->profile()); + ProfileOAuth2TokenServiceFactory::GetForProfile(profile); if (oauth2_token_service) oauth2_token_service->AddObserver(this); // If view mode is PROFILE_CHOOSER but there is an auth error, force // ACCOUNT_MANAGEMENT mode. - if (IsProfileChooser(view_mode_) && HasAuthError(browser_->profile()) && - signin::IsAccountConsistencyMirrorEnabled() && + if (IsProfileChooser(view_mode_) && HasAuthError(profile) && + AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile) && avatar_menu_->GetItemAt(avatar_menu_->GetActiveProfileIndex()) .signed_in) { view_mode_ = profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT; @@ -458,7 +459,8 @@ view_mode_ == profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH) { // The account management UI is only available through the // --account-consistency=mirror flag. - ShowViewFromMode(signin::IsAccountConsistencyMirrorEnabled() + ShowViewFromMode(AccountConsistencyModeManager::IsMirrorEnabledForProfile( + browser_->profile()) ? profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT : profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER); } @@ -476,7 +478,8 @@ // The account management view should only be displayed if the active profile // is signed in. if (view_to_display == profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) { - DCHECK(signin::IsAccountConsistencyMirrorEnabled()); + DCHECK(AccountConsistencyModeManager::IsMirrorEnabledForProfile( + browser_->profile())); const AvatarMenu::Item& active_item = avatar_menu->GetItemAt( avatar_menu->GetActiveProfileIndex()); if (!active_item.signed_in) { @@ -656,12 +659,12 @@ account_id_to_remove_.clear(); ShowViewFromMode(profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT); } else if (sender == gaia_signin_cancel_button_) { + Profile* profile = browser_->profile(); // The account management view is only available with the // --account-consistency=mirror flag. bool account_management_available = - SigninManagerFactory::GetForProfile(browser_->profile()) - ->IsAuthenticated() && - signin::IsAccountConsistencyMirrorEnabled(); + SigninManagerFactory::GetForProfile(profile)->IsAuthenticated() && + AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile); ShowViewFromMode(account_management_available ? profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT : profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER); @@ -978,22 +981,23 @@ views::View* ProfileChooserView::CreateCurrentProfileView( const AvatarMenu::Item& avatar_item, bool is_guest) { - const bool sync_disabled = !browser_->profile()->IsSyncAllowed(); + Profile* profile = browser_->profile(); + const bool sync_disabled = !profile->IsSyncAllowed(); if (!is_guest && sync_disabled) return CreateDiceSyncErrorView(avatar_item, sync_ui_util::NO_SYNC_ERROR, 0); if (!avatar_item.signed_in && dice_enabled_ && - SyncPromoUI::ShouldShowSyncPromo(browser_->profile())) { + SyncPromoUI::ShouldShowSyncPromo(profile)) { return CreateDiceSigninView(); } ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); views::View* view = new views::View(); - bool account_consistency_enabled = - signin::IsAccountConsistencyMirrorEnabled(); + bool mirror_enabled = + AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile); int content_list_vert_spacing = - account_consistency_enabled + mirror_enabled ? provider->GetDistanceMetric(DISTANCE_CONTENT_LIST_VERTICAL_MULTI) : provider->GetDistanceMetric(DISTANCE_CONTENT_LIST_VERTICAL_SINGLE); view->SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -1001,16 +1005,15 @@ 0)); auto current_profile_photo = std::make_unique<BadgedProfilePhoto>( - GetProfileBadgeType(browser_->profile()), avatar_item.icon); + GetProfileBadgeType(profile), avatar_item.icon); const base::string16 profile_name = - profiles::GetAvatarNameForProfile(browser_->profile()->GetPath()); + profiles::GetAvatarNameForProfile(profile->GetPath()); // Show the profile name by itself if not signed in or account consistency is // disabled. Otherwise, show the email attached to the profile. - bool show_email = - !is_guest && avatar_item.signed_in && !account_consistency_enabled; + bool show_email = !is_guest && avatar_item.signed_in && !mirror_enabled; const base::string16 hover_button_title = - dice_enabled_ && browser_->profile()->IsSyncAllowed() + dice_enabled_ && profile->IsSyncAllowed() ? l10n_util::GetStringUTF16(IDS_PROFILES_SYNC_COMPLETE_TITLE) : profile_name; HoverButton* profile_card = new HoverButton( @@ -1032,7 +1035,7 @@ // The available links depend on the type of profile that is active. if (avatar_item.signed_in) { - if (account_consistency_enabled) { + if (mirror_enabled) { base::string16 button_text = l10n_util::GetStringUTF16( IsProfileChooser(view_mode_) ? IDS_PROFILES_PROFILE_MANAGE_ACCOUNTS_BUTTON @@ -1049,8 +1052,8 @@ return view; } - if (!dice_enabled_ && SigninManagerFactory::GetForProfile(browser_->profile()) - ->IsSigninAllowed()) { + if (!dice_enabled_ && + SigninManagerFactory::GetForProfile(profile)->IsSigninAllowed()) { views::View* extra_links_view = new views::View(); extra_links_view->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kVertical,
diff --git a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc index 2db5666..4a60d32 100644 --- a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc +++ b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc
@@ -31,9 +31,10 @@ void ShowPasswordReuseModalWarningDialog( content::WebContents* web_contents, ChromePasswordProtectionService* service, + ReusedPasswordType password_type, OnWarningDone done_callback) { PasswordReuseModalWarningDialog* dialog = new PasswordReuseModalWarningDialog( - web_contents, service, std::move(done_callback)); + web_contents, service, password_type, std::move(done_callback)); constrained_window::CreateBrowserModalDialogViews( dialog, web_contents->GetTopLevelNativeWindow()) ->Show(); @@ -43,6 +44,7 @@ PasswordReuseModalWarningDialog::PasswordReuseModalWarningDialog( content::WebContents* web_contents, ChromePasswordProtectionService* service, + ReusedPasswordType password_type, OnWarningDone done_callback) : content::WebContentsObserver(web_contents), done_callback_(std::move(done_callback)), @@ -59,7 +61,7 @@ views::Label* message_body_label = new views::Label( service_ - ? service_->GetWarningDetailText() + ? service_->GetWarningDetailText(password_type) : l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS)); message_body_label->SetMultiLine(true); message_body_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
diff --git a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.h b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.h index 0b22877c..3fd6712 100644 --- a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.h +++ b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.h
@@ -24,6 +24,7 @@ public: PasswordReuseModalWarningDialog(content::WebContents* web_contents, ChromePasswordProtectionService* service, + ReusedPasswordType password_type, OnWarningDone done_callback); ~PasswordReuseModalWarningDialog() override;
diff --git a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog_browsertest.cc b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog_browsertest.cc index 1e9b5d8..3bab191 100644 --- a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog_browsertest.cc +++ b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog_browsertest.cc
@@ -32,6 +32,7 @@ browser()->tab_strip_model()->GetActiveWebContents(); dialog_ = new PasswordReuseModalWarningDialog( web_contents, nullptr, + LoginReputationClientRequest::PasswordReuseEvent::SIGN_IN_PASSWORD, base::BindOnce(&PasswordReuseModalWarningTest::DialogCallback, base::Unretained(this))); constrained_window::CreateBrowserModalDialogViews(
diff --git a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc index 41bd637b..4748021 100644 --- a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc +++ b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
@@ -31,10 +31,10 @@ #if defined(OS_CHROMEOS) #include "ash/shell.h" // mash-ok -#include "chrome/browser/chromeos/ash_config.h" #include "mojo/public/cpp/bindings/type_converter.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/screen.h" #endif @@ -190,7 +190,7 @@ // TODO(sergeyu): The notification bar must be shown on the monitor that's // being captured. Make sure it's always the case. Currently we always capture // the primary monitor. - if (chromeos::GetAshConfig() != ash::Config::MASH) { + if (features::IsAshInBrowserProcess()) { params.context = ash::Shell::GetPrimaryRootWindow(); } else { const display::Display primary_display =
diff --git a/chrome/browser/ui/views/tab_dialogs_views.cc b/chrome/browser/ui/views/tab_dialogs_views.cc index f093aa9..b7f43a0 100644 --- a/chrome/browser/ui/views/tab_dialogs_views.cc +++ b/chrome/browser/ui/views/tab_dialogs_views.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/views/tab_dialogs_views.h" #include <memory> +#include <utility> #include "build/build_config.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" @@ -46,8 +47,10 @@ } void TabDialogsViews::ShowHungRendererDialog( - content::RenderWidgetHost* render_widget_host) { - HungRendererDialogView::Show(web_contents_, render_widget_host); + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { + HungRendererDialogView::Show(web_contents_, render_widget_host, + std::move(hang_monitor_restarter)); } void TabDialogsViews::HideHungRendererDialog(
diff --git a/chrome/browser/ui/views/tab_dialogs_views.h b/chrome/browser/ui/views/tab_dialogs_views.h index 695d17c..43a2c1ee 100644 --- a/chrome/browser/ui/views/tab_dialogs_views.h +++ b/chrome/browser/ui/views/tab_dialogs_views.h
@@ -18,7 +18,8 @@ gfx::NativeView GetDialogParentView() const override; void ShowCollectedCookies() override; void ShowHungRendererDialog( - content::RenderWidgetHost* render_widget_host) override; + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override; void HideHungRendererDialog( content::RenderWidgetHost* render_widget_host) override; bool IsShowingHungRendererDialog() override;
diff --git a/chrome/browser/ui/views/tabs/glow_hover_controller.cc b/chrome/browser/ui/views/tabs/glow_hover_controller.cc index cb7cbef..d0af8b41 100644 --- a/chrome/browser/ui/views/tabs/glow_hover_controller.cc +++ b/chrome/browser/ui/views/tabs/glow_hover_controller.cc
@@ -11,7 +11,7 @@ static const double kPronouncedOpacityScale = 1.0; // How long the hover state takes. -static const int kTrackHoverDurationMs = 400; +static const int kTrackHoverDurationMs = 200; GlowHoverController::GlowHoverController(views::View* view) : view_(view), animation_(this), opacity_scale_(kSubtleOpacityScale) {
diff --git a/chrome/browser/ui/views/tabs/stacked_tab_strip_layout_unittest.cc b/chrome/browser/ui/views/tabs/stacked_tab_strip_layout_unittest.cc index f69fb5c..27a92271 100644 --- a/chrome/browser/ui/views/tabs/stacked_tab_strip_layout_unittest.cc +++ b/chrome/browser/ui/views/tabs/stacked_tab_strip_layout_unittest.cc
@@ -122,13 +122,6 @@ return result; } - void Validate(int active_index, int max_width) { - // Make sure none of the tabs are more than 90 apart - // (tab_size(100) + padding (-10)). - for (int j = 1; j < view_model_.view_size(); ++j) - EXPECT_LE(ideal_x(j) - ideal_x(j - 1), max_width - 100); - } - int ideal_x(int index) const { return view_model_.ideal_bounds(index).x(); } @@ -151,9 +144,8 @@ for (int i = 120; i < 600; ++i) { for (int j = 0; j < 12; ++j) { Reset(&layout, 0, i, 0, j); - Validate(j, i); - if (HasNonfatalFailure()) - return; + for (int k = 1; k < view_model_.view_size(); ++k) + EXPECT_LE(ideal_x(k) - ideal_x(k - 1), 90); } } }
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 09d946b..4a40b3f 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -84,9 +84,6 @@ // transitioning a tab from normal to pinned tab. constexpr int kPinnedTabExtraWidthToRenderAsNormal = 30; -// How opaque to make the hover state (out of 1). -constexpr float kHoverOpacity = 0.33; - // Opacity of the active tab background painted over inactive selected tabs. constexpr float kSelectedTabOpacity = 0.3; @@ -423,6 +420,21 @@ return path; } +float Lerp(float v0, float v1, float t) { + return v0 + (v1 - v0) * t; +} + +// Produces lerp parameter from a range and value within the range, then uses +// it to Lerp from v0 to v1. +float LerpFromRange(float v0, + float v1, + float range_start, + float range_end, + float value_in_range) { + const float t = (value_in_range - range_start) / (range_end - range_start); + return Lerp(v0, v1, t); +} + } // namespace // Tab ------------------------------------------------------------------------- @@ -580,8 +592,9 @@ gfx::Size(icon_->GetPreferredSize().width(), contents_rect.height() - favicon_bounds.y())); if (center_favicon_) { - favicon_bounds.set_x(contents_rect.CenterPoint().x() - - gfx::kFaviconSize / 2); + // When centering the favicon, the favicon is allowed to escape the normal + // contents rect. + favicon_bounds.set_x(Center(width(), gfx::kFaviconSize)); } else { MaybeAdjustLeftForPinnedTab(&favicon_bounds, gfx::kFaviconSize); } @@ -607,11 +620,16 @@ const gfx::Size close_button_size(close_button_->GetPreferredSize()); const int top = contents_rect.y() + Center(contents_rect.height(), close_button_size.height()); - close_x = contents_rect.right() - close_button_size.width(); - const int left = after_title_padding; + // Clamp the close button position to "centered within the tab"; this should + // only have an effect when animating in a new active tab, which might start + // out narrower than the minimum active tab width. + close_x = std::max(contents_rect.right() - close_button_size.width(), + Center(width(), close_button_size.width())); + const int left = std::min(after_title_padding, close_x); close_button_->SetPosition(gfx::Point(close_x - left, 0)); const int bottom = height() - close_button_size.height() - top; - const int right = width() - contents_rect.right(); + const int right = + std::max(0, width() - (close_x + close_button_size.width())); close_button_->SetBorder( views::CreateEmptyBorder(top, left, bottom, right)); close_button_->SizeToPreferredSize(); @@ -643,13 +661,16 @@ // Size the title to fill the remaining width and use all available height. bool show_title = ShouldRenderAsNormalTab(); if (show_title) { - // When computing the spacing from the favicon, don't count the actual - // icon view width (which will include extra room for the alert indicator), - // but rather the normal favicon width which is what it will look like. - const int title_left = showing_icon_ - ? (favicon_bounds.x() + gfx::kFaviconSize + - GetLayoutConstant(TAB_PRE_TITLE_PADDING)) - : start; + int title_left = start; + if (showing_icon_) { + // When computing the spacing from the favicon, don't count the actual + // icon view width (which will include extra room for the alert + // indicator), but rather the normal favicon width which is what it will + // look like. + const int after_favicon = favicon_bounds.x() + gfx::kFaviconSize + + GetLayoutConstant(TAB_PRE_TITLE_PADDING); + title_left = std::max(title_left, after_favicon); + } int title_right = contents_rect.right(); if (showing_alert_indicator_) { title_right = alert_indicator_button_->x() - after_title_padding; @@ -1129,9 +1150,10 @@ // TODO(pkasting): https://crbug.com/533570 This code is broken when the // current width is less than the pinned width. bounds->set_x( - bounds->x() + static_cast<int>( + bounds->x() + + gfx::ToRoundedInt( (1 - static_cast<float>(ideal_delta) / - static_cast<float>(kPinnedTabExtraWidthToRenderAsNormal)) * + static_cast<float>(kPinnedTabExtraWidthToRenderAsNormal)) * (ideal_x - bounds->x()))); } @@ -1200,11 +1222,16 @@ // but would require knowing then the image from the ThemeProvider had been // changed, and invalidating when the tab's x-coordinate or background_offset_ // changed. - // Similarly, if |paint_hover_effect|, we don't try to cache since hover - // effects change on every invalidation and we would need to invalidate the - // cache based on the hover states. + // + // If |paint_hover_effect|, we don't try to cache since hover effects change + // on every invalidation and we would need to invalidate the cache based on + // the hover states. + // Finally, in refresh, we don't cache for non-integral scale factors, since + // tabs draw with slightly different offsets so as to pixel-align the layout + // rect (see ScaleAndAlignBounds()). const float scale = canvas->image_scale(); - if (fill_id || paint_hover_effect) { + if (fill_id || paint_hover_effect || + (MD::IsRefreshUi() && (std::trunc(scale) != scale))) { gfx::Path fill_path = GetInteriorPath(scale, bounds(), endcap_width); PaintTabBackgroundFill(canvas, fill_path, active, paint_hover_effect, active_color, inactive_color, fill_id, y_offset); @@ -1468,14 +1495,24 @@ float Tab::GetThrobValue() const { const bool is_selected = IsSelected(); - float val = is_selected ? kSelectedTabOpacity : 0; - const float offset = - is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity; + double val = is_selected ? kSelectedTabOpacity : 0; + + // Wrapping in closure to only compute offset when needed (animate or hover). + const auto offset = [=] { + // Opacity boost varies on tab width. + constexpr float kHoverOpacityMin = 0.5f; + constexpr float kHoverOpacityMax = 0.65f; + const float hoverOpacity = LerpFromRange( + kHoverOpacityMin, kHoverOpacityMax, float{GetStandardSize().width()}, + float{GetMinimumInactiveSize().width()}, float{bounds().width()}); + return is_selected ? (kSelectedTabThrobScale * hoverOpacity) : hoverOpacity; + }; if (pulse_animation_.is_animating()) - val += pulse_animation_.GetCurrentValue() * offset; + val += pulse_animation_.GetCurrentValue() * offset(); else if (hover_controller_.ShouldDraw()) - val += hover_controller_.GetAnimationValue() * offset; + val += hover_controller_.GetAnimationValue() * offset(); + return val; }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index d980dab..c1a355f 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -15,7 +15,6 @@ #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" @@ -47,6 +46,7 @@ #include "ash/public/cpp/window_properties.h" // nogncheck #include "ash/public/interfaces/window_state_type.mojom.h" // nogncheck #include "chrome/browser/ui/ash/tablet_mode_client.h" +#include "ui/base/ui_base_features.h" #include "ui/wm/core/coordinate_conversion.h" #endif @@ -761,7 +761,7 @@ double ratio = static_cast<double>(attached_tabstrip_->current_inactive_width()) / Tab::GetStandardSize().width(); - threshold = static_cast<int>(ratio * kHorizontalMoveThreshold); + threshold = gfx::ToRoundedInt(ratio * kHorizontalMoveThreshold); } // else case: touch tabs never shrink. @@ -1035,9 +1035,9 @@ tabs_to_source.erase(tabs_to_source.begin() + source_tab_index_ + 1, tabs_to_source.end()); int new_x = attached_tabstrip_->GetSizeNeededForTabs(tabs_to_source) - - tabs[source_tab_index_]->width() + - static_cast<int>(offset_to_width_ratio_ * - tabs[source_tab_index_]->width()); + tabs[source_tab_index_]->width() + + gfx::ToRoundedInt(offset_to_width_ratio_ * + tabs[source_tab_index_]->width()); mouse_offset_.set_x(new_x); // Transfer ownership of us to the new tabstrip as well as making sure the @@ -1877,7 +1877,7 @@ // under the mouse cursor. gfx::Rect tab_bounds = (*drag_bounds)[source_tab_index_]; gfx::Point offset( - static_cast<int>(tab_bounds.width() * offset_to_width_ratio_) + + gfx::ToRoundedInt(tab_bounds.width() * offset_to_width_ratio_) + tab_bounds.x(), 0); views::View::ConvertPointToWidget(attached_tabstrip_, &offset); @@ -1916,7 +1916,8 @@ // TODO(erg): Temporarily disable getting location from the gesture // recognizer in mash until the mus side/window manager side RunMoveLoop() is // fixed to understand routing touch events. crbug.com/769507 - if (!ash_util::IsRunningInMash() && event_source_ == EVENT_SOURCE_TOUCH && + if (features::IsAshInBrowserProcess() && + event_source_ == EVENT_SOURCE_TOUCH && aura::Env::GetInstance()->is_touch_down()) { views::Widget* widget = GetAttachedBrowserWidget(); DCHECK(widget);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 3b5a97d..9518951 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -606,21 +606,23 @@ if (stacked_layout_) return true; - // If the tab is currently clipped, it shouldn't be visible. Note that we - // allow dragged tabs to draw over any trailing "New Tab button" region as - // well, because either the New Tab button will be hidden, or the dragged tabs - // will be animating back to their normal positions and we don't want to hide - // them in the New Tab button region in case they re-appear after leaving it. - // (This prevents flickeriness.) We never draw non-dragged tabs in New Tab - // button area, even when the button is invisible, so that they don't appear - // to "pop in" when the button disappears. - // TODO: Probably doesn't work for RTL + // If the tab is currently clipped by the trailing edge of the strip, it + // shouldn't be visible. int right_edge = tab->bounds().right(); - const bool trailing_new_tab_button = - (controller_->GetNewTabButtonPosition() == TRAILING) || - (MayHideNewTabButtonWhileDragging() && !tab->dragging()); - const int tabstrip_right = - trailing_new_tab_button ? GetTabAreaWidth() : width(); + int tabstrip_right = width() - GetFrameGrabWidth(); + // When there's a trailing new tab button that hides during tab dragging, the + // calculation above allows dragged tabs to draw over that region as well, + // since if the button is hidden there's no reason not to, and if it's showing + // the dragged tabs are animating back to their normal positions, and we don't + // want them to vanish in this region and then pop back in after leaving it. + // But for non-dragged tabs or when the new tab button never hides, disallow + // drawing over the new tab button area. + // TODO: Probably doesn't work for RTL + if ((controller_->GetNewTabButtonPosition() != LEADING) && + (!tab->dragging() || !MayHideNewTabButtonWhileDragging())) { + tabstrip_right -= GetNewTabButtonWidth(IsIncognito()) + + TabToFollowingNewTabButtonSpacing(); + } if (right_edge > tabstrip_right) return false; @@ -1055,10 +1057,8 @@ if (current_bounds.x() < previous_bounds.x()) return true; // Can happen during dragging. - if (previous_bounds.right() - Tab::GetOverlap() != current_bounds.x()) { - *clip = border_callback.Run(previous_bounds); - clip->offset(SkIntToScalar(previous_bounds.x() - current_bounds.x()), 0); - } + *clip = border_callback.Run(previous_bounds); + clip->offset(SkIntToScalar(previous_bounds.x() - current_bounds.x()), 0); } return true; } @@ -1177,7 +1177,12 @@ if (!tab->IsSelected()) { if (!stacked_layout_) { // In Refresh mode, defer the painting of the hovered tab to below. - if (MD::IsRefreshUi() && tab->IsMouseHovered() && !hovered_tab) { + if (MD::IsRefreshUi() && tab->IsMouseHovered()) { + // Since two adjacent tabs overlap, they can both return as being + // hovered. Favor the left-most tab by ensuring the current + // |hovered_tab| is painted before assigning from |tab|. + if (hovered_tab) + hovered_tab->Paint(paint_info); hovered_tab = tab; } else { tab->Paint(paint_info); @@ -1307,8 +1312,9 @@ needed_tab_width = std::min(std::max(needed_tab_width, min_selected_width), largest_min_tab_width); } - return gfx::Size(needed_tab_width + GetFrameGrabWidth() + - GetNewTabButtonWidth(IsIncognito()), + return gfx::Size(needed_tab_width + TabToFollowingNewTabButtonSpacing() + + GetNewTabButtonWidth(IsIncognito()) + + GetFrameGrabWidth(), Tab::GetMinimumInactiveSize().height()); } @@ -1496,28 +1502,16 @@ return in_tab_close_; } -int TabStrip::GetNewTabButtonSpacing() const { - constexpr int kSpacing[] = {-5, -6, 6, 8, 8}; - const auto mode = MD::GetMode(); - int spacing = kSpacing[mode]; - - // Not sure if we can reach here with no tabs (e.g. during startup), but not - // crashing in that case is easy. - if (MD::IsRefreshUi() && tab_count()) { - const int adjacent_tab_index = - (controller_->GetNewTabButtonPosition() == LEADING) ? 0 - : tab_count() - 1; - spacing -= tab_at(adjacent_tab_index)->GetCornerRadius(); - } - - return spacing; +int TabStrip::GetNewTabButtonWidth(bool is_incognito) const { + return GetLayoutSize(NEW_TAB_BUTTON, is_incognito).width(); } -int TabStrip::GetNewTabButtonWidth(bool is_incognito) const { - int width = GetLayoutSize(NEW_TAB_BUTTON, is_incognito).width(); - if (controller_->GetNewTabButtonPosition() != TRAILING) - width += GetNewTabButtonSpacing(); - return width; +int TabStrip::TabToFollowingNewTabButtonSpacing() const { + if (controller_->GetNewTabButtonPosition() != AFTER_TABS) + return 0; + + constexpr int kNewTabButtonSpacing[] = {-5, -6, 6, 0, 0}; + return kNewTabButtonSpacing[MD::GetMode()]; } bool TabStrip::MayHideNewTabButtonWhileDragging() const { @@ -1677,14 +1671,12 @@ : 0; } -int TabStrip::NewTabButtonX() const { +int TabStrip::NewTabButtonIdealX() const { const auto position = controller_->GetNewTabButtonPosition(); if (position == LEADING) return 0; - // This is not GetTabAreaWidth() because we don't want to subtract the - // separator region between the tabs and the new tab button. - const int tab_area_width = width() - new_tab_button_bounds_.width(); + const int tab_area_width = width() - GetNewTabButtonWidth(IsIncognito()); if (position == TRAILING) return tab_area_width; @@ -1693,7 +1685,7 @@ // tabstrip. Constrain the x-coordinate of the new tab button so that it is // always visible. return std::min(tab_area_width - GetFrameGrabWidth(), - trailing_x + GetNewTabButtonSpacing()); + trailing_x + TabToFollowingNewTabButtonSpacing()); } int TabStrip::GetSizeNeededForTabs(const Tabs& tabs) { @@ -2161,7 +2153,7 @@ tabs_.set_ideal_bounds(i, tabs_bounds[i]); } - new_tab_button_bounds_.set_origin(gfx::Point(NewTabButtonX(), 0)); + new_tab_button_bounds_.set_origin(gfx::Point(NewTabButtonIdealX(), 0)); if (GetTabsMaxX() != old_max_x) { for (TabStripObserver& observer : observers_) @@ -2188,7 +2180,8 @@ } int TabStrip::GetTabAreaWidth() const { - return width() - GetFrameGrabWidth() - GetNewTabButtonWidth(IsIncognito()); + return width() - GetFrameGrabWidth() - GetNewTabButtonWidth(IsIncognito()) - + TabToFollowingNewTabButtonSpacing(); } void TabStrip::StartResizeLayoutAnimation() { @@ -2231,6 +2224,8 @@ bool TabStrip::IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords) { + if (!tab->visible()) + return false; gfx::Point point_in_tab_coords(point_in_tabstrip_coords); View::ConvertPointToTarget(this, tab, &point_in_tab_coords); return tab->HitTestPoint(point_in_tab_coords);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index db78ff4..cc02d3f 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -347,12 +347,14 @@ // Returns whether the close button should be highlighted after a remove. bool ShouldHighlightCloseButtonAfterRemove(); - // Returns the spacing between the new tab button and the adjacent tab. - int GetNewTabButtonSpacing() const; - // Returns the width needed for the new tab button (and padding). int GetNewTabButtonWidth(bool is_incognito) const; + // If the new tab button position is AFTER_TABS, returns the spacing to use + // between the trailing edge of the tabs and the leading edge of the new tab + // button. For other button positions, returns 0. + int TabToFollowingNewTabButtonSpacing() const; + // Returns whether dragging tabs should ever result in the new tab button // being hidden. bool MayHideNewTabButtonWhileDragging() const; @@ -399,7 +401,7 @@ // Returns the X coordinate the new tab button should be placed at. Requires // |tabs_| to have correct ideal bounds. - int NewTabButtonX() const; + int NewTabButtonIdealX() const; // Returns the size needed for the specified tabs. This is invoked during drag // and drop to calculate offsets and positioning.
diff --git a/chrome/browser/ui/views/tabs/window_finder_chromeos.cc b/chrome/browser/ui/views/tabs/window_finder_chromeos.cc index e0d96367..aaf58e5 100644 --- a/chrome/browser/ui/views/tabs/window_finder_chromeos.cc +++ b/chrome/browser/ui/views/tabs/window_finder_chromeos.cc
@@ -5,9 +5,8 @@ #include "chrome/browser/ui/views/tabs/window_finder.h" #include "chrome/browser/ui/views/tabs/window_finder_mus.h" -#include "ash/public/cpp/config.h" -#include "chrome/browser/chromeos/ash_config.h" #include "ui/aura/window.h" +#include "ui/base/ui_base_features.h" gfx::NativeWindow GetLocalProcessWindowAtPointAsh( const gfx::Point& screen_point, @@ -16,7 +15,7 @@ gfx::NativeWindow WindowFinder::GetLocalProcessWindowAtPoint( const gfx::Point& screen_point, const std::set<gfx::NativeWindow>& ignore) { - if (chromeos::GetAshConfig() == ash::Config::MASH) { + if (!features::IsAshInBrowserProcess()) { gfx::NativeWindow mus_result = nullptr; if (GetLocalProcessWindowAtPointMus(screen_point, ignore, &mus_result)) return mus_result;
diff --git a/chrome/browser/ui/views/task_manager_view_browsertest.cc b/chrome/browser/ui/views/task_manager_view_browsertest.cc index b463e10..42ffd25b 100644 --- a/chrome/browser/ui/views/task_manager_view_browsertest.cc +++ b/chrome/browser/ui/views/task_manager_view_browsertest.cc
@@ -36,6 +36,11 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/views/controls/table/table_view.h" +#if defined(OS_CHROMEOS) +#include "ui/display/display.h" +#include "ui/display/screen.h" +#endif + namespace task_manager { using browsertest_util::WaitForTaskManagerRows; @@ -334,4 +339,36 @@ EXPECT_EQ(GetTable()->FirstSelectedRow(), FindRowForTab(tabs[2])); } +// Make sure the task manager's bounds are saved across instances on Chrome OS. +#if defined(OS_CHROMEOS) +IN_PROC_BROWSER_TEST_F(TaskManagerViewTest, RestoreBounds) { + chrome::ShowTaskManager(browser()); + + const gfx::Rect default_bounds = + GetView()->GetWidget()->GetWindowBoundsInScreen(); + const gfx::Rect non_default_bounds = default_bounds + gfx::Vector2d(0, 17); + + GetView()->GetWidget()->SetBounds(non_default_bounds); + GetView()->GetWidget()->CloseNow(); + + chrome::ShowTaskManager(browser()); + EXPECT_EQ(non_default_bounds, + GetView()->GetWidget()->GetWindowBoundsInScreen()); + + // Also make sure that the task manager is not restored off-screen. + // This is a regression test for https://crbug.com/308606 + display::Display display = + display::Screen::GetScreen()->GetDisplayMatching(non_default_bounds); + const gfx::Rect offscreen_bounds = + default_bounds + gfx::Vector2d(0, display.bounds().bottom()); + GetView()->GetWidget()->SetBounds(offscreen_bounds); + GetView()->GetWidget()->CloseNow(); + + chrome::ShowTaskManager(browser()); + gfx::Rect restored_bounds = GetView()->GetWidget()->GetWindowBoundsInScreen(); + EXPECT_NE(offscreen_bounds, restored_bounds); + EXPECT_TRUE(display.bounds().Contains(restored_bounds)); +} +#endif + } // namespace task_manager
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index 4444e28..d996293 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -27,7 +27,6 @@ #include "chrome/browser/chromeos/system/timezone_resolver_manager.h" #include "chrome/browser/chromeos/tpm_firmware_update.h" #include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/ash/tablet_mode_client.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" @@ -47,6 +46,7 @@ #include "google_apis/google_api_keys.h" #include "services/service_manager/public/cpp/connector.h" #include "ui/aura/window_tree_host.h" +#include "ui/base/ui_base_features.h" #include "ui/display/display.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" @@ -92,7 +92,7 @@ version_info_updater_(this) { DCHECK(js_calls_container); set_call_js_prefix(kJsScreenPath); - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { AccessibilityManager* accessibility_manager = AccessibilityManager::Get(); CHECK(accessibility_manager); accessibility_subscription_ = accessibility_manager->RegisterCallback( @@ -442,7 +442,7 @@ } void CoreOobeHandler::UpdateA11yState() { - if (ash_util::IsRunningInMash()) { + if (!features::IsAshInBrowserProcess()) { NOTIMPLEMENTED(); return; } @@ -464,9 +464,11 @@ void CoreOobeHandler::UpdateOobeUIVisibility() { const std::string& display = oobe_ui_->display_type(); - CallJSOrDefer("showAPIKeysNotice", !google_apis::HasKeysConfigured() && - (display == OobeUI::kOobeDisplay || - display == OobeUI::kLoginDisplay)); + bool has_api_keys_configured = google_apis::HasAPIKeyConfigured() && + google_apis::HasOAuthClientConfigured(); + CallJSOrDefer("showAPIKeysNotice", + !has_api_keys_configured && (display == OobeUI::kOobeDisplay || + display == OobeUI::kLoginDisplay)); // Don't show version label on the stable channel by default. bool should_show_version = true; @@ -518,7 +520,7 @@ void CoreOobeHandler::UpdateKeyboardState() { // TODO(mash): Support virtual keyboard under MASH. There is no // KeyboardController in the browser process under MASH. - if (!ash_util::IsRunningInMash()) { + if (features::IsAshInBrowserProcess()) { auto* keyboard_controller = keyboard::KeyboardController::Get(); if (keyboard_controller->enabled()) { const bool is_keyboard_shown = keyboard_controller->keyboard_visible();
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc index 9156951c..67ef883 100644 --- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/files/file_util.h" +#include "base/json/json_reader.h" #include "base/logging.h" #include "base/macros.h" #include "base/values.h" @@ -114,15 +115,18 @@ } constexpr struct { + const char* id; int title_id; int subtitle_id; authpolicy::KerberosEncryptionTypes encryption_types; } kEncryptionTypes[] = { - {IDS_AD_ENCRYPTION_STRONG_TITLE, IDS_AD_ENCRYPTION_STRONG_SUBTITLE, + {"strong", IDS_AD_ENCRYPTION_STRONG_TITLE, + IDS_AD_ENCRYPTION_STRONG_SUBTITLE, authpolicy::KerberosEncryptionTypes::ENC_TYPES_STRONG}, - {IDS_AD_ENCRYPTION_ALL_TITLE, IDS_AD_ENCRYPTION_ALL_SUBTITLE, + {"all", IDS_AD_ENCRYPTION_ALL_TITLE, IDS_AD_ENCRYPTION_ALL_SUBTITLE, authpolicy::KerberosEncryptionTypes::ENC_TYPES_ALL}, - {IDS_AD_ENCRYPTION_LEGACY_TITLE, IDS_AD_ENCRYPTION_LEGACY_SUBTITLE, + {"legacy", IDS_AD_ENCRYPTION_LEGACY_TITLE, + IDS_AD_ENCRYPTION_LEGACY_SUBTITLE, authpolicy::KerberosEncryptionTypes::ENC_TYPES_LEGACY}}; std::unique_ptr<base::ListValue> GetEncryptionTypesList() { @@ -136,7 +140,7 @@ enc_option->SetKey( "subtitle", base::Value(l10n_util::GetStringUTF16(enc_types.subtitle_id))); - enc_option->SetKey("value", base::Value(enc_types.encryption_types)); + enc_option->SetKey("value", base::Value(enc_types.id)); enc_option->SetKey( "selected", base::Value(default_types == enc_types.encryption_types)); encryption_list->Append(std::move(enc_option)); @@ -144,6 +148,16 @@ return encryption_list; } +authpolicy::KerberosEncryptionTypes TranslateEncryptionTypesString( + const std::string& string_id) { + for (const auto& enc_types : kEncryptionTypes) { + if (enc_types.id == string_id) + return enc_types.encryption_types; + } + NOTREACHED(); + return authpolicy::KerberosEncryptionTypes::ENC_TYPES_STRONG; +} + } // namespace // EnrollmentScreenHandler, public ------------------------------ @@ -178,6 +192,8 @@ &EnrollmentScreenHandler::HandleCompleteLogin); AddCallback("oauthEnrollAdCompleteLogin", &EnrollmentScreenHandler::HandleAdCompleteLogin); + AddCallback("oauthEnrollAdUnlockConfiguration", + &EnrollmentScreenHandler::HandleAdUnlockConfiguration); AddCallback("oauthEnrollRetry", &EnrollmentScreenHandler::HandleRetry); AddCallback("frameLoadingCompleted", @@ -223,14 +239,21 @@ } void EnrollmentScreenHandler::ShowActiveDirectoryScreen( + const std::string& domain_join_config, const std::string& machine_name, const std::string& username, authpolicy::ErrorType error) { observe_network_failure_ = false; + if (!domain_join_config.empty()) { + active_directory_domain_join_config_ = domain_join_config; + show_unlock_password_ = true; + } switch (error) { case authpolicy::ERROR_NONE: { - CallJS("invalidateAd", machine_name, username, - static_cast<int>(ActiveDirectoryErrorState::NONE)); + CallJS("setAdJoinParams", std::string() /* machineName */, + std::string() /* userName */, + static_cast<int>(ActiveDirectoryErrorState::NONE), + show_unlock_password_); ShowStep(kEnrollmentStepAdJoin); return; } @@ -240,31 +263,34 @@ return; case authpolicy::ERROR_PARSE_UPN_FAILED: case authpolicy::ERROR_BAD_USER_NAME: - CallJS("invalidateAd", machine_name, username, - static_cast<int>(ActiveDirectoryErrorState::BAD_USERNAME)); + CallJS("setAdJoinParams", machine_name, username, + static_cast<int>(ActiveDirectoryErrorState::BAD_USERNAME), + show_unlock_password_); ShowStep(kEnrollmentStepAdJoin); return; case authpolicy::ERROR_BAD_PASSWORD: - CallJS("invalidateAd", machine_name, username, - static_cast<int>(ActiveDirectoryErrorState::BAD_PASSWORD)); + CallJS("setAdJoinParams", machine_name, username, + static_cast<int>(ActiveDirectoryErrorState::BAD_AUTH_PASSWORD), + show_unlock_password_); ShowStep(kEnrollmentStepAdJoin); return; case authpolicy::ERROR_MACHINE_NAME_TOO_LONG: - CallJS( - "invalidateAd", machine_name, username, - static_cast<int>(ActiveDirectoryErrorState::MACHINE_NAME_TOO_LONG)); + CallJS("setAdJoinParams", machine_name, username, + static_cast<int>(ActiveDirectoryErrorState::MACHINE_NAME_TOO_LONG), + show_unlock_password_); ShowStep(kEnrollmentStepAdJoin); return; case authpolicy::ERROR_INVALID_MACHINE_NAME: - CallJS("invalidateAd", machine_name, username, - static_cast<int>(ActiveDirectoryErrorState::MACHINE_NAME_INVALID)); + CallJS("setAdJoinParams", machine_name, username, + static_cast<int>(ActiveDirectoryErrorState::MACHINE_NAME_INVALID), + show_unlock_password_); ShowStep(kEnrollmentStepAdJoin); return; case authpolicy::ERROR_PASSWORD_EXPIRED: ShowError(IDS_AD_PASSWORD_EXPIRED, true); return; case authpolicy::ERROR_JOIN_ACCESS_DENIED: - ShowError(IDS_AD_USER_DENIED_TO_JOIN_MACHINE, true); + ShowError(IDS_AD_USER_DENIED_TO_JOIN_DEVICE, true); return; case authpolicy::ERROR_USER_HIT_JOIN_QUOTA: ShowError(IDS_AD_USER_HIT_JOIN_QUOTA, true); @@ -516,17 +542,25 @@ builder->Add("oauthEnrollWorking", IDS_ENTERPRISE_ENROLLMENT_WORKING_MESSAGE); // Do not use AddF for this string as it will be rendered by the JS code. builder->Add("oauthEnrollAbeSuccess", IDS_ENTERPRISE_ENROLLMENT_ABE_SUCCESS); - builder->Add("oauthEnrollAdMachineNameInput", - IDS_AD_MACHINE_NAME_INPUT_LABEL); + builder->Add("oauthEnrollAdMachineNameInput", IDS_AD_DEVICE_NAME_INPUT_LABEL); + builder->Add("oauthEnrollAdMachineNameInputRegex", + IDS_AD_DEVICE_NAME_REGEX_INPUT_LABEL); builder->Add("oauthEnrollAdDomainJoinWelcomeMessage", IDS_AD_DOMAIN_JOIN_WELCOME_MESSAGE); builder->Add("adEnrollmentLoginUsername", IDS_AD_ENROLLMENT_LOGIN_USER); builder->Add("adLoginInvalidUsername", IDS_AD_INVALID_USERNAME); builder->Add("adLoginPassword", IDS_AD_LOGIN_PASSWORD); builder->Add("adLoginInvalidPassword", IDS_AD_INVALID_PASSWORD); - builder->Add("adJoinErrorMachineNameInvalid", IDS_AD_MACHINENAME_INVALID); - builder->Add("adJoinErrorMachineNameTooLong", IDS_AD_MACHINENAME_TOO_LONG); + builder->Add("adJoinErrorMachineNameInvalid", IDS_AD_DEVICE_NAME_INVALID); + builder->Add("adJoinErrorMachineNameTooLong", IDS_AD_DEVICE_NAME_TOO_LONG); + builder->Add("adJoinErrorMachineNameDoesntMatchRegex", + IDS_AD_DEVICE_NAME_DOESNT_MATCH_REGEX); builder->Add("adJoinMoreOptions", IDS_AD_MORE_OPTIONS_BUTTON); + builder->Add("adUnlockConfig", IDS_AD_UNLOCK_CONFIG); + builder->Add("adUnlockButton", IDS_AD_UNLOCK_CONFIG_UNLOCK_BUTTON); + builder->Add("adUnlockPassword", IDS_AD_UNLOCK_CONFIG_PASSWORD); + builder->Add("adUnlockIncorrectPassword", IDS_AD_UNLOCK_INCORRECT_PASSWORD); + builder->Add("adUnlockPasswordSkip", IDS_AD_UNLOCK_PASSWORD_SKIP); builder->Add("adJoinOrgUnit", IDS_AD_ORG_UNIT_HINT); builder->Add("adJoinCancel", IDS_AD_CANCEL_BUTTON); builder->Add("adJoinConfirm", IDS_AD_CONFIRM_BUTTON); @@ -543,6 +577,7 @@ builder->Add("licenseCountTemplate", IDS_ENTERPRISE_ENROLLMENT_LICENSES_REMAINING_TEMPLATE); builder->Add("selectEncryption", IDS_AD_ENCRYPTION_SELECTION_SELECT); + builder->Add("selectConfiguration", IDS_AD_CONFIG_SELECTION_SELECT); } void EnrollmentScreenHandler::GetAdditionalParameters( @@ -559,6 +594,33 @@ error_screen_->GetParentScreen() == kScreenId); } +void EnrollmentScreenHandler::OnAdConfigurationUnlocked( + std::string unlocked_data) { + if (unlocked_data.empty()) { + CallJS("setAdJoinParams", std::string() /* machineName */, + std::string() /* userName */, + static_cast<int>(ActiveDirectoryErrorState::BAD_UNLOCK_PASSWORD), + show_unlock_password_); + return; + } + std::unique_ptr<base::ListValue> options = + base::ListValue::From(base::JSONReader::Read( + unlocked_data, base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS)); + if (!options) { + ShowError(IDS_AD_JOIN_CONFIG_NOT_PARSED, true); + show_unlock_password_ = false; + CallJS("setAdJoinConfiguration", base::ListValue()); + return; + } + base::DictionaryValue custom; + custom.SetKey( + "name", + base::Value(l10n_util::GetStringUTF8(IDS_AD_CONFIG_SELECTION_CUSTOM))); + options->GetList().push_back(std::move(custom)); + show_unlock_password_ = false; + CallJS("setAdJoinConfiguration", *options); +} + void EnrollmentScreenHandler::UpdateState(NetworkError::ErrorReason reason) { UpdateStateInternal(reason, false); } @@ -682,13 +744,22 @@ void EnrollmentScreenHandler::HandleAdCompleteLogin( const std::string& machine_name, const std::string& distinguished_name, - int encryption_types, + const std::string& encryption_types, const std::string& user_name, const std::string& password) { observe_network_failure_ = false; DCHECK(controller_); controller_->OnActiveDirectoryCredsProvided( - machine_name, distinguished_name, encryption_types, user_name, password); + machine_name, distinguished_name, + TranslateEncryptionTypesString(encryption_types), user_name, password); +} + +void EnrollmentScreenHandler::HandleAdUnlockConfiguration( + const std::string& password) { + AuthPolicyLoginHelper::DecryptConfiguration( + active_directory_domain_join_config_, password, + base::BindOnce(&EnrollmentScreenHandler::OnAdConfigurationUnlocked, + weak_ptr_factory_.GetWeakPtr())); } void EnrollmentScreenHandler::HandleRetry() {
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h index f34bde1b..e24c99f 100644 --- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
@@ -29,7 +29,8 @@ MACHINE_NAME_INVALID = 1, MACHINE_NAME_TOO_LONG = 2, BAD_USERNAME = 3, - BAD_PASSWORD = 4, + BAD_AUTH_PASSWORD = 4, + BAD_UNLOCK_PASSWORD = 5, }; // WebUIMessageHandler implementation which handles events occurring on the @@ -55,7 +56,8 @@ void ShowSigninScreen() override; void ShowLicenseTypeSelectionScreen( const base::DictionaryValue& license_types) override; - void ShowActiveDirectoryScreen(const std::string& machine_name, + void ShowActiveDirectoryScreen(const std::string& domain_join_config, + const std::string& machine_name, const std::string& username, authpolicy::ErrorType error) override; void ShowAttributePromptScreen(const std::string& asset_id, @@ -85,9 +87,10 @@ const std::string& auth_code); void HandleAdCompleteLogin(const std::string& machine_name, const std::string& distinguished_name, - int encryption_types, + const std::string& encryption_types, const std::string& user_name, const std::string& password); + void HandleAdUnlockConfiguration(const std::string& password); void HandleRetry(); void HandleFrameLoadingCompleted(); void HandleDeviceAttributesProvided(const std::string& asset_id, @@ -130,6 +133,9 @@ // enrollment sign-in page. bool IsEnrollmentScreenHiddenByError() const; + // Called after configuration seed was unlocked. + void OnAdConfigurationUnlocked(std::string unlocked_data); + // Keeps the controller for this view. Controller* controller_ = nullptr; @@ -138,6 +144,12 @@ // The enrollment configuration. policy::EnrollmentConfig config_; + // Active Directory configuration in the form of encrypted binary data. + std::string active_directory_domain_join_config_; + + // Whether unlock password input step should be shown. + bool show_unlock_password_ = false; + // True if screen was not shown yet. bool first_show_ = true;
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 657160b1..f303a03e 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -698,7 +698,7 @@ break; case authpolicy::ERROR_BAD_PASSWORD: CallJS("invalidateAd", username, - static_cast<int>(ActiveDirectoryErrorState::BAD_PASSWORD)); + static_cast<int>(ActiveDirectoryErrorState::BAD_AUTH_PASSWORD)); break; default: CallJS("invalidateAd", username, @@ -838,7 +838,8 @@ void GaiaScreenHandler::HandleGetIsSamlUserPasswordless( const std::string& callback_id, - const std::string& typed_email) { + const std::string& typed_email, + const std::string& gaia_id) { AllowJavascript(); // TODO(emaxx,https://crbug.com/826417): Determine the result value based on // known_user properties if the user already existed, or the
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h index df68d9a0..faff4f5 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -135,7 +135,8 @@ void HandleUpdateGaiaDialogVisibility(bool visible); void HandleShowAddUser(const base::ListValue* args); void HandleGetIsSamlUserPasswordless(const std::string& callback_id, - const std::string& typed_email); + const std::string& typed_email, + const std::string& gaia_id); void OnShowAddUser(); // Really handles the complete login message.
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 14d2918..4ac32cb 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -29,7 +29,6 @@ #include "chrome/browser/extensions/signin/gaia_auth_extension_loader.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/webui/about_ui.h" #include "chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h" @@ -52,7 +51,6 @@ #include "chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h" -#include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h" #include "chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.h" @@ -67,6 +65,7 @@ #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/voice_interaction_value_prop_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/wait_for_container_ready_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/user_image_source.h" #include "chrome/browser/ui/webui/test_files_request_filter.h" @@ -86,6 +85,7 @@ #include "content/public/browser/web_ui_data_source.h" #include "content/public/common/content_switches.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_features.h" #include "ui/base/webui/web_ui_util.h" #include "ui/display/display.h" #include "ui/events/devices/input_device.h" @@ -265,7 +265,7 @@ AddScreenHandler(std::make_unique<UpdateScreenHandler>()); if (display_type_ == kOobeDisplay) - AddScreenHandler(std::make_unique<NetworkScreenHandler>(core_handler_)); + AddScreenHandler(std::make_unique<WelcomeScreenHandler>(core_handler_)); AddScreenHandler(std::make_unique<EnableDebuggingScreenHandler>()); @@ -392,7 +392,7 @@ // TODO(felixe): Display iteration and primary display selection not supported // in Mash. See http://crbug.com/720917. - if (!ash_util::IsRunningInMash() && IsRemoraRequisitioned()) + if (features::IsAshInBrowserProcess() && IsRemoraRequisitioned()) oobe_display_chooser_ = std::make_unique<OobeDisplayChooser>(); } @@ -403,8 +403,8 @@ return core_handler_; } -NetworkView* OobeUI::GetNetworkView() { - return GetView<NetworkScreenHandler>(); +WelcomeView* OobeUI::GetWelcomeView() { + return GetView<WelcomeScreenHandler>(); } EulaView* OobeUI::GetEulaView() {
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h index 82de193..d6cd358 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -47,7 +47,7 @@ class LoginScreenContext; class NativeWindowDelegate; class NetworkStateInformer; -class NetworkView; +class WelcomeView; class OobeDisplayChooser; class RecommendAppsScreenView; class SigninScreenHandler; @@ -99,7 +99,7 @@ ~OobeUI() override; CoreOobeView* GetCoreOobeView(); - NetworkView* GetNetworkView(); + WelcomeView* GetWelcomeView(); EulaView* GetEulaView(); UpdateView* GetUpdateView(); EnableDebuggingScreenView* GetEnableDebuggingScreenView();
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 1e546f4..8c6e8967 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -37,7 +37,6 @@ #include "chrome/browser/browser_process_platform_part_chromeos.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" -#include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/language_preferences.h" #include "chrome/browser/chromeos/lock_screen_apps/state_controller.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.h" @@ -113,6 +112,7 @@ #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/ui_base_features.h" #include "ui/base/webui/web_ui_util.h" #include "ui/chromeos/devicetype_utils.h" #include "ui/gfx/color_analysis.h" @@ -329,7 +329,7 @@ WallpaperControllerClient::Get()->AddObserver(std::move(ptr_info)); // TODO(tbarzic): This is needed for login UI - remove it when login switches // to views implementation (or otherwise, make it work under mash). - if (GetAshConfig() != ash::Config::MASH) + if (features::IsAshInBrowserProcess()) detachable_base_observer_.Add(ash::Shell::Get()->detachable_base_handler()); } @@ -1747,7 +1747,7 @@ bool requires_update) {} void SigninScreenHandler::UpdateDetachableBaseChangedError() { - if (GetAshConfig() == ash::Config::MASH) + if (!features::IsAshInBrowserProcess()) return; auto pairing_status =
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.cc similarity index 87% rename from chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc rename to chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.cc index 0991b4c0..1b3047e9 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.cc
@@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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/webui/chromeos/login/network_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h" #include <stddef.h> @@ -20,7 +20,7 @@ #include "chrome/browser/chromeos/customization/customization_document.h" #include "chrome/browser/chromeos/idle_detector.h" #include "chrome/browser/chromeos/login/screens/core_oobe_view.h" -#include "chrome/browser/chromeos/login/screens/network_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include "chrome/browser/chromeos/login/ui/input_events_blocker.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" @@ -46,28 +46,28 @@ namespace { -const char kJsScreenPath[] = "login.NetworkScreen"; +const char kJsScreenPath[] = "login.WelcomeScreen"; } // namespace namespace chromeos { -// NetworkScreenHandler, public: ----------------------------------------------- +// WelcomeScreenHandler, public: ----------------------------------------------- -NetworkScreenHandler::NetworkScreenHandler(CoreOobeView* core_oobe_view) +WelcomeScreenHandler::WelcomeScreenHandler(CoreOobeView* core_oobe_view) : BaseScreenHandler(kScreenId), core_oobe_view_(core_oobe_view) { set_call_js_prefix(kJsScreenPath); DCHECK(core_oobe_view_); } -NetworkScreenHandler::~NetworkScreenHandler() { +WelcomeScreenHandler::~WelcomeScreenHandler() { if (screen_) screen_->OnViewDestroyed(this); } -// NetworkScreenHandler, NetworkScreenView implementation: --------------------- +// WelcomeScreenHandler, WelcomeScreenView implementation: --------------------- -void NetworkScreenHandler::Show() { +void WelcomeScreenHandler::Show() { if (!page_is_ready()) { show_on_init_ = true; return; @@ -92,54 +92,52 @@ handler->SetTechnologyEnabled(NetworkTypePattern::Physical(), true, chromeos::network_handler::ErrorCallback()); - base::DictionaryValue network_screen_params; - network_screen_params.SetBoolean("isDeveloperMode", - base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kSystemDevMode)); - ShowScreenWithData(kScreenId, &network_screen_params); + base::DictionaryValue welcome_screen_params; + welcome_screen_params.SetBoolean( + "isDeveloperMode", base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kSystemDevMode)); + ShowScreenWithData(kScreenId, &welcome_screen_params); core_oobe_view_->InitDemoModeDetection(); } -void NetworkScreenHandler::Hide() { -} +void WelcomeScreenHandler::Hide() {} -void NetworkScreenHandler::Bind(NetworkScreen* screen) { +void WelcomeScreenHandler::Bind(WelcomeScreen* screen) { screen_ = screen; BaseScreenHandler::SetBaseScreen(screen_); } -void NetworkScreenHandler::Unbind() { +void WelcomeScreenHandler::Unbind() { screen_ = nullptr; BaseScreenHandler::SetBaseScreen(nullptr); } -void NetworkScreenHandler::ShowError(const base::string16& message) { +void WelcomeScreenHandler::ShowError(const base::string16& message) { CallJS("showError", message); } -void NetworkScreenHandler::ClearErrors() { +void WelcomeScreenHandler::ClearErrors() { if (page_is_ready()) core_oobe_view_->ClearErrors(); } -void NetworkScreenHandler::StopDemoModeDetection() { +void WelcomeScreenHandler::StopDemoModeDetection() { core_oobe_view_->StopDemoModeDetection(); } -void NetworkScreenHandler::ShowConnectingStatus( +void WelcomeScreenHandler::ShowConnectingStatus( bool connecting, - const base::string16& network_id) { -} + const base::string16& network_id) {} -void NetworkScreenHandler::ReloadLocalizedContent() { +void WelcomeScreenHandler::ReloadLocalizedContent() { base::DictionaryValue localized_strings; GetOobeUI()->GetLocalizedStrings(&localized_strings); core_oobe_view_->ReloadContent(localized_strings); } -// NetworkScreenHandler, BaseScreenHandler implementation: -------------------- +// WelcomeScreenHandler, BaseScreenHandler implementation: -------------------- -void NetworkScreenHandler::DeclareLocalizedValues( +void WelcomeScreenHandler::DeclareLocalizedValues( ::login::LocalizedValuesBuilder* builder) { if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation()) builder->Add("networkScreenGreeting", IDS_REMORA_CONFIRM_MESSAGE); @@ -199,7 +197,7 @@ network_element::AddLocalizedValuesToBuilder(builder); } -void NetworkScreenHandler::GetAdditionalParameters( +void WelcomeScreenHandler::GetAdditionalParameters( base::DictionaryValue* dict) { const std::string application_locale = g_browser_process->GetApplicationLocale(); @@ -259,7 +257,7 @@ dict->Set("timezoneList", GetTimezoneList()); } -void NetworkScreenHandler::Initialize() { +void WelcomeScreenHandler::Initialize() { if (show_on_init_) { show_on_init_ = false; Show(); @@ -270,10 +268,10 @@ ReloadLocalizedContent(); } -// NetworkScreenHandler, private: ---------------------------------------------- +// WelcomeScreenHandler, private: ---------------------------------------------- // static -std::unique_ptr<base::ListValue> NetworkScreenHandler::GetTimezoneList() { +std::unique_ptr<base::ListValue> WelcomeScreenHandler::GetTimezoneList() { std::string current_timezone_id; CrosSettings::Get()->GetString(kSystemTimezone, ¤t_timezone_id);
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h similarity index 70% rename from chrome/browser/ui/webui/chromeos/login/network_screen_handler.h rename to chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h index cbf4f712..73157f5 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h
@@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// 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_WEBUI_CHROMEOS_LOGIN_NETWORK_SCREEN_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_NETWORK_SCREEN_HANDLER_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WELCOME_SCREEN_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WELCOME_SCREEN_HANDLER_H_ #include <memory> #include <string> @@ -11,7 +11,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "chrome/browser/chromeos/base/locale_util.h" -#include "chrome/browser/chromeos/login/screens/network_view.h" +#include "chrome/browser/chromeos/login/screens/welcome_view.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "ui/base/ime/chromeos/component_extension_ime_manager.h" #include "ui/base/ime/chromeos/input_method_manager.h" @@ -25,18 +25,18 @@ class CoreOobeView; -// WebUI implementation of NetworkScreenView. It is used to interact with +// WebUI implementation of WelcomeScreenView. It is used to interact with // the welcome screen (part of the page) of the OOBE. -class NetworkScreenHandler : public NetworkView, public BaseScreenHandler { +class WelcomeScreenHandler : public WelcomeView, public BaseScreenHandler { public: - explicit NetworkScreenHandler(CoreOobeView* core_oobe_view); - ~NetworkScreenHandler() override; + explicit WelcomeScreenHandler(CoreOobeView* core_oobe_view); + ~WelcomeScreenHandler() override; private: - // NetworkView implementation: + // WelcomeView implementation: void Show() override; void Hide() override; - void Bind(NetworkScreen* screen) override; + void Bind(WelcomeScreen* screen) override; void Unbind() override; void ShowError(const base::string16& message) override; void ClearErrors() override; @@ -55,7 +55,7 @@ static std::unique_ptr<base::ListValue> GetTimezoneList(); CoreOobeView* core_oobe_view_ = nullptr; - NetworkScreen* screen_ = nullptr; + WelcomeScreen* screen_ = nullptr; // Keeps whether screen should be shown right after initialization. bool show_on_init_ = false; @@ -63,9 +63,9 @@ // Position of the network control. gfx::Point network_control_pos_; - DISALLOW_COPY_AND_ASSIGN(NetworkScreenHandler); + DISALLOW_COPY_AND_ASSIGN(WelcomeScreenHandler); }; } // namespace chromeos -#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_NETWORK_SCREEN_HANDLER_H_ +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_WELCOME_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc index cc411f1e..6e42b95 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -62,113 +62,6 @@ namespace media_router { -// Observes a WebContents and requests fullscreening of its first -// video element. The request is sent after the WebContents is loaded and tab -// capture has begun. Marked final to prevent inheritance so delete calls are -// contained to scenarios documented below. -class MediaRouterUI::WebContentsFullscreenOnLoadedObserver final - : public content::WebContentsObserver { - public: - WebContentsFullscreenOnLoadedObserver(const GURL& file_url, - content::WebContents* web_contents) - : file_url_(file_url), capture_poll_timer_(false, false) { - DCHECK(file_url_.SchemeIsFile()); - DCHECK(fullscreen_request_time_.is_null()); - - // If the WebContents is loading, start listening, otherwise just call the - // fullscreen function. - - // This class destroys itself in the following situations (at least one of - // which will occur): - // * after loading is complete and, - // ** capture has begun and fullscreen requested, - // ** kMaxSecondsToWaitForCapture seconds have passed without capture, - // * another navigation is started, - // * the WebContents is destroyed. - if (web_contents->IsLoading()) { - Observe(web_contents); - } else { - FullScreenFirstVideoElement(web_contents); - } - } - ~WebContentsFullscreenOnLoadedObserver() override {} - - // content::WebContentsObserver implementation. - void DidStopLoading() override { - FullScreenFirstVideoElement(web_contents()); - } - - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override { - // If the user takes over and navigates away from the file, stop listening. - // (It is possible however for this listener to be created before the - // navigation to the requested file triggers, so provided we're still on the - // same URL, go ahead and keep listening). - if (file_url_ != navigation_handle->GetURL()) { - delete this; - } - } - - void WebContentsDestroyed() override { - // If the WebContents is destroyed we will never trigger and need to clean - // up. - delete this; - } - - private: - const GURL file_url_; - - // Time intervals used by the logic that detects if capture has started. - const int kMaxSecondsToWaitForCapture = 10; - const int kPollIntervalInSeconds = 1; - - // The time at which fullscreen was requested. - base::TimeTicks fullscreen_request_time_; - - // Poll timer to monitor the capturer count when fullscreening local files. - // - // TODO(crbug.com/540965): Add a method to WebContentsObserver to report - // capturer count changes and get rid of this polling-based approach. - base::Timer capture_poll_timer_; - - // Sends a request for full screen to the WebContents targeted at the first - // video element. The request is only sent after capture has begun. - void FullScreenFirstVideoElement(content::WebContents* web_contents) { - if (file_url_ != web_contents->GetLastCommittedURL()) { - // The user has navigated before the casting started. Do not attempt to - // fullscreen and cleanup. - return; - } - - fullscreen_request_time_ = base::TimeTicks::Now(); - FullscreenIfContentCaptured(web_contents); - } - - void FullscreenIfContentCaptured(content::WebContents* web_contents) { - if (web_contents->IsBeingCaptured()) { - content::mojom::FullscreenVideoElementHandlerAssociatedPtr client; - web_contents->GetMainFrame() - ->GetRemoteAssociatedInterfaces() - ->GetInterface(&client); - client->RequestFullscreenVideoElement(); - delete this; - return; - } else if (base::TimeTicks::Now() - fullscreen_request_time_ > - base::TimeDelta::FromSeconds(kMaxSecondsToWaitForCapture)) { - // If content capture hasn't started within the timeout skip fullscreen. - DLOG(WARNING) << "Capture of local content did not start within timeout"; - delete this; - return; - } - - capture_poll_timer_.Start( - FROM_HERE, base::TimeDelta::FromSeconds(kPollIntervalInSeconds), - base::BindRepeating( - &WebContentsFullscreenOnLoadedObserver::FullscreenIfContentCaptured, - base::Unretained(this), web_contents)); - } -}; - MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) : ConstrainedWebDialogUI(web_ui), ui_initialized_(false), @@ -211,35 +104,6 @@ StartObservingIssues(); } -bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id, - MediaCastMode cast_mode) { - // Default the tab casting the content to the initiator, and change if - // necessary. - content::WebContents* tab_contents = initiator(); - - // TODO(http://crbug.com/842787): Code is duplicated between MRUI and MRUIBase - // until MRUIBase supports local file casting. - base::Optional<RouteParameters> params; - if (cast_mode == MediaCastMode::LOCAL_FILE) { - GURL url = media_router_file_dialog_->GetLastSelectedFileUrl(); - tab_contents = OpenTabWithUrl(url); - params = GetLocalFileRouteParameters(sink_id, url, tab_contents); - } else { - params = GetRouteParameters(sink_id, cast_mode); - } - if (!params) { - SendIssueForUnableToCast(cast_mode); - return false; - } - - GetIssueManager()->ClearNonBlockingIssues(); - GetMediaRouter()->CreateRoute(params->source_id, sink_id, params->origin, - tab_contents, - std::move(params->route_response_callbacks), - params->timeout, params->incognito); - return true; -} - bool MediaRouterUI::ConnectRoute(const MediaSink::Id& sink_id, const MediaRoute::Id& route_id) { base::Optional<RouteParameters> params = @@ -256,14 +120,6 @@ return true; } -void MediaRouterUI::OpenFileDialog() { - if (!media_router_file_dialog_) { - media_router_file_dialog_ = std::make_unique<MediaRouterFileDialog>(this); - } - - media_router_file_dialog_->OpenFileDialog(GetBrowser()); -} - void MediaRouterUI::SearchSinksAndCreateRoute( const MediaSink::Id& sink_id, const std::string& search_criteria, @@ -396,7 +252,7 @@ void MediaRouterUI::InitForTest( std::unique_ptr<MediaRouterFileDialog> file_dialog) { - media_router_file_dialog_ = std::move(file_dialog); + set_media_router_file_dialog_for_test(std::move(file_dialog)); } MediaRouterUI::UIMediaRouteControllerObserver::UIMediaRouteControllerObserver( @@ -419,34 +275,11 @@ ui_->OnRouteControllerInvalidated(); } -Browser* MediaRouterUI::GetBrowser() { - CHECK(initiator()); - return chrome::FindBrowserWithWebContents(initiator()); -} - -content::WebContents* MediaRouterUI::OpenTabWithUrl(const GURL url) { - // Check if the current page is a new tab. If so open file in current page. - // If not then open a new page. - if (initiator()->GetVisibleURL() == chrome::kChromeUINewTabURL) { - content::NavigationController::LoadURLParams load_params(url); - load_params.transition_type = ui::PAGE_TRANSITION_GENERATED; - initiator()->GetController().LoadURLWithParams(load_params); - return initiator(); - } else { - return chrome::AddSelectedTabWithURL(GetBrowser(), url, - ui::PAGE_TRANSITION_LINK); - } -} - void MediaRouterUI::FileDialogFileSelected( const ui::SelectedFileInfo& file_info) { handler_->UserSelectedLocalMediaFile(file_info.display_name); } -void MediaRouterUI::FileDialogSelectionFailed(const IssueInfo& issue) { - AddIssue(issue); -} - void MediaRouterUI::OnIssue(const Issue& issue) { if (ui_initialized_) handler_->UpdateIssue(issue); @@ -491,12 +324,6 @@ SendIssueForRouteTimeout(cast_mode, presentation_request_source_name); } -void MediaRouterUI::MaybeReportFileInformation( - const RouteRequestResult& result) { - if (result.result_code() == RouteRequestResult::OK) - media_router_file_dialog_->MaybeReportLastSelectedFileInformation(); -} - void MediaRouterUI::HandleCreateSessionRequestRouteResponse( const RouteRequestResult&) { Close(); @@ -536,54 +363,6 @@ UpdateCastModes(); } -base::Optional<RouteParameters> MediaRouterUI::GetLocalFileRouteParameters( - const MediaSink::Id& sink_id, - const GURL& file_url, - content::WebContents* tab_contents) { - RouteParameters params; - SessionID::id_type tab_id = SessionTabHelper::IdForTab(tab_contents).id(); - params.source_id = MediaSourceForTab(tab_id).id(); - - // Use a placeholder URL as origin for local file casting, which is - // essentially mirroring. - params.origin = url::Origin::Create(GURL(chrome::kChromeUIMediaRouterURL)); - - int request_id = current_route_request() ? current_route_request()->id : -1; - params.route_response_callbacks.push_back(base::BindOnce( - &MediaRouterUI::OnRouteResponseReceived, weak_factory_.GetWeakPtr(), - request_id, sink_id, MediaCastMode::LOCAL_FILE, - base::UTF8ToUTF16(GetTruncatedPresentationRequestSourceName()))); - - params.route_response_callbacks.push_back( - base::BindOnce(&MediaRouterUIBase::MaybeReportCastingSource, - weak_factory_.GetWeakPtr(), MediaCastMode::LOCAL_FILE)); - - params.route_response_callbacks.push_back(base::BindOnce( - &MediaRouterUI::MaybeReportFileInformation, weak_factory_.GetWeakPtr())); - - params.route_response_callbacks.push_back( - base::BindOnce(&MediaRouterUI::FullScreenFirstVideoElement, - weak_factory_.GetWeakPtr(), file_url, tab_contents)); - - params.timeout = GetRouteRequestTimeout(MediaCastMode::LOCAL_FILE); - CHECK(initiator()); - params.incognito = initiator()->GetBrowserContext()->IsOffTheRecord(); - - return base::make_optional(std::move(params)); -} - -// TODO(crbug.com/792547): Refactor FullScreenFirstVideoElement() and -// MaybeReportFileInformation() into a local media casting specific location -// instead of here in the main ui. -void MediaRouterUI::FullScreenFirstVideoElement( - const GURL& file_url, - content::WebContents* web_contents, - const RouteRequestResult& result) { - if (result.result_code() == RouteRequestResult::OK) { - new WebContentsFullscreenOnLoadedObserver(file_url, web_contents); - } -} - void MediaRouterUI::UpdateCastModes() { // Gets updated cast modes from |query_result_manager()| and forwards it to // UI.
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.h b/chrome/browser/ui/webui/media_router/media_router_ui.h index e20c5b6..acf5fe7 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.h +++ b/chrome/browser/ui/webui/media_router/media_router_ui.h
@@ -9,16 +9,11 @@ #include "base/strings/string16.h" #include "chrome/browser/media/router/mojo/media_route_controller.h" #include "chrome/browser/ui/media_router/media_cast_mode.h" -#include "chrome/browser/ui/media_router/media_router_file_dialog.h" #include "chrome/browser/ui/media_router/media_router_ui_base.h" #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h" #include "chrome/common/media_router/media_route.h" #include "chrome/common/media_router/media_sink.h" -namespace ui { -struct SelectedFileInfo; -} - namespace media_router { struct MediaStatus; @@ -26,10 +21,7 @@ class RouteRequestResult; // Functions as an intermediary between MediaRouter and WebUI Cast dialog. -class MediaRouterUI - : public MediaRouterUIBase, - public ConstrainedWebDialogUI, - public MediaRouterFileDialog::MediaRouterFileDialogDelegate { +class MediaRouterUI : public MediaRouterUIBase, public ConstrainedWebDialogUI { public: // |web_ui| owns this object and is used to initialize the base class. explicit MediaRouterUI(content::WebUI* web_ui); @@ -41,17 +33,10 @@ // Notifies this instance that the UI has been initialized. virtual void OnUIInitialized(); - // MediaRouterUIBase: - bool CreateRoute(const MediaSink::Id& sink_id, - MediaCastMode cast_mode) override; - // Calls MediaRouter to join the given route. bool ConnectRoute(const MediaSink::Id& sink_id, const MediaRoute::Id& route_id); - // Called to open a file dialog with the media_router_ui file dialog handler. - void OpenFileDialog(); - // Calls MediaRouter to search route providers for sinks matching // |search_criteria| with the source that is currently associated with // |cast_mode|. The user's domain |domain| is also used. @@ -140,7 +125,6 @@ UpdateSinksWhenDialogMovesToAnotherDisplay); class UIIssuesObserver; - class WebContentsFullscreenOnLoadedObserver; class UIMediaRouteControllerObserver : public MediaRouteController::Observer { public: @@ -159,15 +143,8 @@ DISALLOW_COPY_AND_ASSIGN(UIMediaRouteControllerObserver); }; - // Retrieves the browser associated with this UI. - Browser* GetBrowser(); - - // Opens the URL in a tab, returns the tab it was opened in. - content::WebContents* OpenTabWithUrl(const GURL url); - // MediaRouterFileDialogDelegate: void FileDialogFileSelected(const ui::SelectedFileInfo& file_info) override; - void FileDialogSelectionFailed(const IssueInfo& issue) override; void OnIssue(const Issue& issue) override; void OnIssueCleared() override; @@ -183,10 +160,6 @@ const base::string16& presentation_request_source_name, const RouteRequestResult& result) override; - // Sends a request to the file dialog to log UMA stats for the file that was - // cast if the result is successful. - void MaybeReportFileInformation(const RouteRequestResult& result); - void HandleCreateSessionRequestRouteResponse( const RouteRequestResult&) override; @@ -202,17 +175,6 @@ const content::PresentationRequest& presentation_request) override; void OnDefaultPresentationRemoved() override; - // Populates route-related parameters for CreateRoute() when doing file - // casting. - base::Optional<RouteParameters> GetLocalFileRouteParameters( - const MediaSink::Id& sink_id, - const GURL& file_url, - content::WebContents* tab_contents); - - void FullScreenFirstVideoElement(const GURL& file_url, - content::WebContents* web_contents, - const RouteRequestResult& result); - // Updates the set of supported cast modes and sends the updated set to // |handler_|. void UpdateCastModes(); @@ -256,10 +218,6 @@ // updates. std::unique_ptr<UIMediaRouteControllerObserver> route_controller_observer_; - // The dialog that handles opening the file dialog and validating and - // returning the results. - std::unique_ptr<MediaRouterFileDialog> media_router_file_dialog_; - // If set, a cast mode that is required to be shown first. base::Optional<MediaCastMode> forced_cast_mode_;
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index 37c3757..f5be7d6 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/printing/printer_manager_dialog.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -1339,8 +1340,7 @@ void PrintPreviewHandler::RegisterForGaiaCookieChanges() { DCHECK(!gaia_cookie_manager_service_); Profile* profile = Profile::FromWebUI(web_ui()); - if (signin::IsAccountConsistencyMirrorEnabled() && - !profile->IsOffTheRecord()) { + if (AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)) { gaia_cookie_manager_service_ = GaiaCookieManagerServiceFactory::GetForProfile(profile); if (gaia_cookie_manager_service_)
diff --git a/chrome/browser/ui/webui/reset_password/reset_password_ui.cc b/chrome/browser/ui/webui/reset_password/reset_password_ui.cc index 5aa829a..47d0dad 100644 --- a/chrome/browser/ui/webui/reset_password/reset_password_ui.cc +++ b/chrome/browser/ui/webui/reset_password/reset_password_ui.cc
@@ -53,8 +53,14 @@ safe_browsing::ChromePasswordProtectionService* service = safe_browsing:: ChromePasswordProtectionService::GetPasswordProtectionService(profile); if (service) { + // Uses |REUSED_PASSWORD_TYPE_UNKNOWN| as a default value. + // ChromePasswordProtectionService::OnUserAction(..) will figure it out + // what type password it is based on user state. service->OnUserAction( - web_contents_, safe_browsing::PasswordProtectionService::INTERSTITIAL, + web_contents_, + safe_browsing::LoginReputationClientRequest::PasswordReuseEvent:: + REUSED_PASSWORD_TYPE_UNKNOWN, + safe_browsing::PasswordProtectionService::INTERSTITIAL, safe_browsing::PasswordProtectionService::CHANGE_PASSWORD); } }
diff --git a/chrome/browser/ui/webui/settings/change_password_handler.cc b/chrome/browser/ui/webui/settings/change_password_handler.cc index 6d64f7bb..090962a 100644 --- a/chrome/browser/ui/webui/settings/change_password_handler.cc +++ b/chrome/browser/ui/webui/settings/change_password_handler.cc
@@ -54,6 +54,8 @@ void ChangePasswordHandler::HandleChangePassword(const base::ListValue* args) { service_->OnUserAction( web_ui()->GetWebContents(), + safe_browsing::LoginReputationClientRequest::PasswordReuseEvent:: + SIGN_IN_PASSWORD, safe_browsing::PasswordProtectionService::CHROME_SETTINGS, safe_browsing::PasswordProtectionService::CHANGE_PASSWORD); }
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc new file mode 100644 index 0000000..ca84973 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
@@ -0,0 +1,38 @@ +// 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/webui/settings/chromeos/multidevice_handler.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/logging.h" +#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h" +#include "content/public/browser/web_ui.h" + +namespace chromeos { + +namespace settings { + +MultideviceHandler::MultideviceHandler() = default; +MultideviceHandler::~MultideviceHandler() = default; + +void MultideviceHandler::OnJavascriptAllowed() {} +void MultideviceHandler::OnJavascriptDisallowed() {} + +void MultideviceHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback( + "showMultiDeviceSetupDialog", + base::BindRepeating(&MultideviceHandler::HandleShowMultiDeviceSetupDialog, + base::Unretained(this))); +} + +void MultideviceHandler::HandleShowMultiDeviceSetupDialog( + const base::ListValue* args) { + DCHECK(args->empty()); + multidevice_setup::MultiDeviceSetupDialog::Show(); +} + +} // namespace settings + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h new file mode 100644 index 0000000..3ab88522 --- /dev/null +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
@@ -0,0 +1,38 @@ +// 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_WEBUI_SETTINGS_CHROMEOS_MULTIDEVICE_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_MULTIDEVICE_HANDLER_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" + +namespace chromeos { + +namespace settings { + +// Chrome "Multidevice" (a.k.a. "Connected Devices") settings page UI handler. +class MultideviceHandler : public ::settings::SettingsPageUIHandler { + public: + MultideviceHandler(); + ~MultideviceHandler() override; + + // content::WebUIMessageHandler: + void RegisterMessages() override; + + // ::settings::SettingsPageUIHandler: + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; + + private: + void HandleShowMultiDeviceSetupDialog(const base::ListValue* args); + + DISALLOW_COPY_AND_ASSIGN(MultideviceHandler); +}; + +} // namespace settings + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_MULTIDEVICE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 2846f79..7e01868e 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -229,7 +229,6 @@ IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_TITLE}, {"appearanceSettingsDescription", IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_DESCRIPTION}, - {"keyboardHeading", IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_HEADING}, {"keyboardAndTextInputHeading", IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_AND_TEXT_INPUT_HEADING}, {"keyboardSettingsTitle", @@ -1601,8 +1600,6 @@ #endif {"syncUnifiedConsentToggleTitle", IDS_SETTINGS_PEOPLE_SYNC_UNIFIED_CONSENT_TOGGLE_TITLE}, - {"syncUnifiedConsentToggleSubtitle", - IDS_SETTINGS_PEOPLE_SYNC_UNIFIED_CONSENT_TOGGLE_SUBTITLE}, {"syncOverview", IDS_SETTINGS_SYNC_OVERVIEW}, {"syncDisabledByAdministrator", IDS_SETTINGS_SYNC_DISABLED_BY_ADMINISTRATOR}, @@ -1619,7 +1616,6 @@ IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_PLURAL}, {"deleteProfileWarningWithoutCounts", IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITHOUT_COUNTS}, - {"syncDisconnectExplanation", IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION}, {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM}, {"sync", IDS_SETTINGS_SYNC}, {"syncDescription", IDS_SETTINGS_SYNC_DESCRIPTION}, @@ -1729,8 +1725,9 @@ // The syncDisconnect text differs depending on Dice-enabledness. if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile)) { LocalizedString sync_disconnect_strings[] = { - {"syncDisconnect", IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_CONFIRM}, - {"syncDisconnectTitle", IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_TITLE}, + {"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF}, + {"syncDisconnectTitle", + IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE}, {"syncDisconnectDeleteProfile", IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_CHECKBOX}, {"syncDisconnectConfirm", @@ -1738,6 +1735,12 @@ }; AddLocalizedStringsBulk(html_source, sync_disconnect_strings, arraysize(sync_disconnect_strings)); + + html_source->AddString( + "syncDisconnectExplanation", + l10n_util::GetStringFUTF8( + IDS_SETTINGS_SYNC_DISCONNECT_AND_SIGN_OUT_EXPLANATION, + base::ASCIIToUTF16(sync_dashboard_url))); } #endif @@ -2322,10 +2325,6 @@ IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_CONFIRMATION}, {"siteSettingsSiteClearStorageDialogTitle", IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_DIALOG_TITLE}, - {"siteSettingsSiteGroupResetDialogTitle", - IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_DIALOG_TITLE}, - {"siteSettingsSiteGroupResetConfirmation", - IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_CONFIRMATION}, {"siteSettingsSiteResetAll", IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_ALL}, {"siteSettingsSiteResetConfirmation", IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_CONFIRMATION},
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index ff3197ef..76542bd 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -75,7 +75,6 @@ #include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" #include "chrome/browser/signin/account_tracker_service_factory.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h" @@ -92,12 +91,14 @@ #include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/smb_handler.h" #include "chrome/common/chrome_switches.h" #include "chromeos/account_manager/account_manager.h" #include "chromeos/account_manager/account_manager_factory.h" #include "chromeos/chromeos_switches.h" #include "components/arc/arc_util.h" +#include "ui/base/ui_base_features.h" #else // !defined(OS_CHROMEOS) #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" @@ -209,6 +210,8 @@ AddSettingsPageUIHandler( std::make_unique<chromeos::settings::KeyboardHandler>()); AddSettingsPageUIHandler( + std::make_unique<chromeos::settings::MultideviceHandler>()); + AddSettingsPageUIHandler( std::make_unique<chromeos::settings::PointerHandler>()); AddSettingsPageUIHandler( std::make_unique<chromeos::settings::SmbHandler>(profile)); @@ -309,7 +312,7 @@ html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable()); // TODO(mash): Support Chrome power settings in Mash. crbug.com/644348 - bool enable_power_settings = !ash_util::IsRunningInMash(); + bool enable_power_settings = features::IsAshInBrowserProcess(); html_source->AddBoolean("enablePowerSettings", enable_power_settings); if (enable_power_settings) { AddSettingsPageUIHandler(std::make_unique<chromeos::settings::PowerHandler>(
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler.cc b/chrome/browser/ui/webui/signin/inline_login_handler.cc index f5017e4..0738564 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler.cc
@@ -33,6 +33,9 @@ #include "google_apis/gaia/gaia_urls.h" #include "net/base/url_util.h" +const char kSignInPromoQueryKeyShowAccountManagement[] = + "showAccountManagement"; + InlineLoginHandler::InlineLoginHandler() : weak_ptr_factory_(this) {} InlineLoginHandler::~InlineLoginHandler() {} @@ -174,7 +177,7 @@ main_frame_url = net::AppendOrReplaceQueryParameter( main_frame_url, signin::kSignInPromoQueryKeyAutoClose, "1"); main_frame_url = net::AppendOrReplaceQueryParameter( - main_frame_url, signin::kSignInPromoQueryKeyShowAccountManagement, "1"); + main_frame_url, kSignInPromoQueryKeyShowAccountManagement, "1"); main_frame_url = net::AppendOrReplaceQueryParameter( main_frame_url, signin::kSignInPromoQueryKeyForceKeepData, "1"); if (base::FeatureList::IsEnabled(
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler.h b/chrome/browser/ui/webui/signin/inline_login_handler.h index e297523..58abbe7 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler.h +++ b/chrome/browser/ui/webui/signin/inline_login_handler.h
@@ -17,6 +17,8 @@ enum class AccessPoint; } +extern const char kSignInPromoQueryKeyShowAccountManagement[]; + // The base class handler for the inline login WebUI. class InlineLoginHandler : public content::WebUIMessageHandler { public:
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index fb25b23..689f05ec 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/signin/about_signin_internals_factory.h" +#include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/local_auth.h" @@ -138,6 +139,22 @@ UserManager::Hide(); } +// Returns true if the showAccountManagement parameter in the given url is set +// to true. +bool ShouldShowAccountManagement(const GURL& url, bool is_mirror_enabled) { + if (!is_mirror_enabled) + return false; + + std::string value; + if (net::GetValueForKeyInQuery(url, kSignInPromoQueryKeyShowAccountManagement, + &value)) { + int enabled = 0; + if (base::StringToInt(value, &enabled) && enabled == 1) + return true; + } + return false; +} + } // namespace InlineSigninHelper::InlineSigninHelper( @@ -254,10 +271,12 @@ if (signin::IsAutoCloseEnabledInURL(current_url_)) { // Close the gaia sign in tab via a task to make sure we aren't in the // middle of any webui handler code. + bool show_account_management = ShouldShowAccountManagement( + current_url_, + AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile_)); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&InlineLoginHandlerImpl::CloseTab, handler_, - signin::ShouldShowAccountManagement(current_url_))); + FROM_HERE, base::BindOnce(&InlineLoginHandlerImpl::CloseTab, handler_, + show_account_management)); } if (reason == signin_metrics::Reason::REASON_REAUTHENTICATION || @@ -761,11 +780,14 @@ if (result == OneClickSigninSyncStarter::SYNC_SETUP_FAILURE) { RedirectToNtpOrAppsPage(contents, access_point); } else if (auto_close) { + bool show_account_management = ShouldShowAccountManagement( + current_url, + AccountConsistencyModeManager::IsMirrorEnabledForProfile( + Profile::FromBrowserContext(contents->GetBrowserContext()))); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&InlineLoginHandlerImpl::CloseTab, - weak_factory_.GetWeakPtr(), - signin::ShouldShowAccountManagement(current_url))); + weak_factory_.GetWeakPtr(), show_account_management)); } else { RedirectToNtpOrAppsPageIfNecessary(contents, access_point); }
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash.cc b/chrome/browser/ui/window_sizer/window_sizer_ash.cc index 05aee65..efde9b9 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/ui/window_sizer/window_sizer.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h"
diff --git a/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc b/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc new file mode 100644 index 0000000..e64ba1f --- /dev/null +++ b/chrome/browser/unified_consent/chrome_unified_consent_service_client.cc
@@ -0,0 +1,40 @@ +// 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/unified_consent/chrome_unified_consent_service_client.h" + +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" + +ChromeUnifiedConsentServiceClient::ChromeUnifiedConsentServiceClient( + PrefService* pref_service) + : pref_service_(pref_service) {} + +void ChromeUnifiedConsentServiceClient::SetAlternateErrorPagesEnabled( + bool enabled) { + pref_service_->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled); +} + +void ChromeUnifiedConsentServiceClient::SetMetricsReportingEnabled( + bool enabled) { + // TODO(http://crbug.com/800974): Implement this method. + NOTIMPLEMENTED(); +} + +void ChromeUnifiedConsentServiceClient::SetSearchSuggestEnabled(bool enabled) { + // TODO(http://crbug.com/800974): Implement this method. + NOTIMPLEMENTED(); +} + +void ChromeUnifiedConsentServiceClient::SetSafeBrowsingExtendedReportingEnabled( + bool enabled) { + // TODO(http://crbug.com/800974): Implement this method. + NOTIMPLEMENTED(); +} + +void ChromeUnifiedConsentServiceClient::SetNetworkPredictionEnabled( + bool enabled) { + // TODO(http://crbug.com/800974): Implement this method. + NOTIMPLEMENTED(); +}
diff --git a/chrome/browser/unified_consent/chrome_unified_consent_service_client.h b/chrome/browser/unified_consent/chrome_unified_consent_service_client.h new file mode 100644 index 0000000..95a6d20 --- /dev/null +++ b/chrome/browser/unified_consent/chrome_unified_consent_service_client.h
@@ -0,0 +1,30 @@ +// 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_UNIFIED_CONSENT_CHROME_UNIFIED_CONSENT_SERVICE_CLIENT_H_ +#define CHROME_BROWSER_UNIFIED_CONSENT_CHROME_UNIFIED_CONSENT_SERVICE_CLIENT_H_ + +#include "base/macros.h" +#include "components/unified_consent/unified_consent_service_client.h" + +class PrefService; + +class ChromeUnifiedConsentServiceClient : public UnifiedConsentServiceClient { + public: + ChromeUnifiedConsentServiceClient(PrefService* pref_service); + ~ChromeUnifiedConsentServiceClient() override = default; + + void SetAlternateErrorPagesEnabled(bool enabled) override; + void SetMetricsReportingEnabled(bool enabled) override; + void SetSearchSuggestEnabled(bool enabled) override; + void SetSafeBrowsingExtendedReportingEnabled(bool enabled) override; + void SetNetworkPredictionEnabled(bool enabled) override; + + private: + PrefService* pref_service_; + + DISALLOW_COPY_AND_ASSIGN(ChromeUnifiedConsentServiceClient); +}; + +#endif // CHROME_BROWSER_UNIFIED_CONSENT_CHROME_UNIFIED_CONSENT_SERVICE_CLIENT_H_
diff --git a/chrome/browser/unified_consent/unified_consent_service_factory.cc b/chrome/browser/unified_consent/unified_consent_service_factory.cc index ce2284c..fad5d14 100644 --- a/chrome/browser/unified_consent/unified_consent_service_factory.cc +++ b/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -8,8 +8,12 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/unified_consent_helper.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/browser/unified_consent/chrome_unified_consent_service_client.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/unified_consent/unified_consent_service.h" UnifiedConsentServiceFactory::UnifiedConsentServiceFactory() @@ -17,6 +21,7 @@ "UnifiedConsentService", BrowserContextDependencyManager::GetInstance()) { DependsOn(IdentityManagerFactory::GetInstance()); + DependsOn(ProfileSyncServiceFactory::GetInstance()); } UnifiedConsentServiceFactory::~UnifiedConsentServiceFactory() = default; @@ -46,7 +51,9 @@ return nullptr; return new UnifiedConsentService( - profile->GetPrefs(), IdentityManagerFactory::GetForProfile(profile)); + new ChromeUnifiedConsentServiceClient(profile->GetPrefs()), + profile->GetPrefs(), IdentityManagerFactory::GetForProfile(profile), + ProfileSyncServiceFactory::GetForProfile(profile)); } bool UnifiedConsentServiceFactory::ServiceIsNULLWhileTesting() const { @@ -54,5 +61,5 @@ } bool UnifiedConsentServiceFactory::ServiceIsCreatedWithBrowserContext() const { - return true; + return false; }
diff --git a/chrome/browser/vr/elements/button_unittest.cc b/chrome/browser/vr/elements/button_unittest.cc index 6f508a4e..be3dd5d 100644 --- a/chrome/browser/vr/elements/button_unittest.cc +++ b/chrome/browser/vr/elements/button_unittest.cc
@@ -16,19 +16,19 @@ gfx::Transform xform = button.hit_plane()->LocalTransform(); - button.OnHoverEnter(gfx::PointF(0.5f, 0.5f)); + button.OnHoverEnter(gfx::PointF(0.5f, 0.5f), base::TimeTicks()); EXPECT_EQ(xform.ToString(), button.hit_plane()->LocalTransform().ToString()); - button.OnHoverLeave(); + button.OnHoverLeave(base::TimeTicks()); button.set_hover_offset(0.04f); - button.OnHoverEnter(gfx::PointF(0.5f, 0.5f)); + button.OnHoverEnter(gfx::PointF(0.5f, 0.5f), base::TimeTicks()); EXPECT_NE(xform.ToString(), button.hit_plane()->LocalTransform().ToString()); - button.OnHoverLeave(); + button.OnHoverLeave(base::TimeTicks()); button.SetEnabled(false); - button.OnHoverEnter(gfx::PointF(0.5f, 0.5f)); + button.OnHoverEnter(gfx::PointF(0.5f, 0.5f), base::TimeTicks()); EXPECT_EQ(xform.ToString(), button.hit_plane()->LocalTransform().ToString()); - button.OnHoverLeave(); + button.OnHoverLeave(base::TimeTicks()); } } // namespace vr
diff --git a/chrome/browser/vr/elements/disc_button_unittest.cc b/chrome/browser/vr/elements/disc_button_unittest.cc index 1952db3..7b8df43 100644 --- a/chrome/browser/vr/elements/disc_button_unittest.cc +++ b/chrome/browser/vr/elements/disc_button_unittest.cc
@@ -30,7 +30,7 @@ cc::TransformOperation hit_plane_op = button.hit_plane()->GetTargetTransform().at(UiElement::kScaleIndex); - button.OnHoverEnter(gfx::PointF(0.5f, 0.5f)); + button.OnHoverEnter(gfx::PointF(0.5f, 0.5f), base::TimeTicks()); cc::TransformOperation foreground_op_hover = button.foreground()->GetTargetTransform().at(UiElement::kTranslateIndex); cc::TransformOperation background_op_hover =
diff --git a/chrome/browser/vr/elements/environment/stars.h b/chrome/browser/vr/elements/environment/stars.h index 026ba56..2040b847 100644 --- a/chrome/browser/vr/elements/environment/stars.h +++ b/chrome/browser/vr/elements/environment/stars.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/time/time.h" #include "chrome/browser/vr/elements/ui_element.h" #include "chrome/browser/vr/renderers/base_renderer.h"
diff --git a/chrome/browser/vr/elements/invisible_hit_target.cc b/chrome/browser/vr/elements/invisible_hit_target.cc index 2db584b..3a53c66e 100644 --- a/chrome/browser/vr/elements/invisible_hit_target.cc +++ b/chrome/browser/vr/elements/invisible_hit_target.cc
@@ -14,13 +14,14 @@ void InvisibleHitTarget::Render(UiElementRenderer* renderer, const CameraModel& model) const {} -void InvisibleHitTarget::OnHoverEnter(const gfx::PointF& position) { - UiElement::OnHoverEnter(position); +void InvisibleHitTarget::OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp) { + UiElement::OnHoverEnter(position, timestamp); hovered_ = true; } -void InvisibleHitTarget::OnHoverLeave() { - UiElement::OnHoverLeave(); +void InvisibleHitTarget::OnHoverLeave(base::TimeTicks timestamp) { + UiElement::OnHoverLeave(timestamp); hovered_ = false; }
diff --git a/chrome/browser/vr/elements/invisible_hit_target.h b/chrome/browser/vr/elements/invisible_hit_target.h index 560030f..2269fd6 100644 --- a/chrome/browser/vr/elements/invisible_hit_target.h +++ b/chrome/browser/vr/elements/invisible_hit_target.h
@@ -19,8 +19,9 @@ void Render(UiElementRenderer* renderer, const CameraModel& model) const final; - void OnHoverEnter(const gfx::PointF& position) override; - void OnHoverLeave() override; + void OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnHoverLeave(base::TimeTicks timestamp) override; bool hovered() const { return hovered_; }
diff --git a/chrome/browser/vr/elements/keyboard.cc b/chrome/browser/vr/elements/keyboard.cc index b0a4954..bcaeb1b 100644 --- a/chrome/browser/vr/elements/keyboard.cc +++ b/chrome/browser/vr/elements/keyboard.cc
@@ -63,35 +63,39 @@ UpdateDelegateVisibility(); } -void Keyboard::OnHoverEnter(const gfx::PointF& position) { +void Keyboard::OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp) { if (!delegate_) return; delegate_->OnHoverEnter(position); } -void Keyboard::OnHoverLeave() { +void Keyboard::OnHoverLeave(base::TimeTicks) { if (!delegate_) return; delegate_->OnHoverLeave(); } -void Keyboard::OnHoverMove(const gfx::PointF& position) { +void Keyboard::OnHoverMove(const gfx::PointF& position, + base::TimeTicks timestamp) { if (!delegate_) return; delegate_->OnHoverMove(position); } -void Keyboard::OnButtonDown(const gfx::PointF& position) { +void Keyboard::OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp) { if (!delegate_) return; delegate_->OnButtonDown(position); } -void Keyboard::OnButtonUp(const gfx::PointF& position) { +void Keyboard::OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp) { if (!delegate_) return;
diff --git a/chrome/browser/vr/elements/keyboard.h b/chrome/browser/vr/elements/keyboard.h index e485e49..612b63b 100644 --- a/chrome/browser/vr/elements/keyboard.h +++ b/chrome/browser/vr/elements/keyboard.h
@@ -31,11 +31,15 @@ int target_property_id, cc::KeyframeModel* keyframe_model) override; - void OnHoverEnter(const gfx::PointF& position) override; - void OnHoverLeave() override; - void OnHoverMove(const gfx::PointF& position) override; - void OnButtonDown(const gfx::PointF& position) override; - void OnButtonUp(const gfx::PointF& position) override; + void OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnHoverLeave(base::TimeTicks timestamp) override; + void OnHoverMove(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp) override; class Renderer : public BaseRenderer { public:
diff --git a/chrome/browser/vr/elements/platform_ui_element.cc b/chrome/browser/vr/elements/platform_ui_element.cc index f45041f..b0a3fdb 100644 --- a/chrome/browser/vr/elements/platform_ui_element.cc +++ b/chrome/browser/vr/elements/platform_ui_element.cc
@@ -26,34 +26,39 @@ } } -void PlatformUiElement::OnHoverEnter(const gfx::PointF& position) { +void PlatformUiElement::OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp) { if (delegate_) - delegate_->OnHoverEnter(position); + delegate_->OnHoverEnter(position, timestamp); } -void PlatformUiElement::OnHoverLeave() { +void PlatformUiElement::OnHoverLeave(base::TimeTicks timestamp) { if (delegate_) - delegate_->OnHoverLeave(); + delegate_->OnHoverLeave(timestamp); } -void PlatformUiElement::OnHoverMove(const gfx::PointF& position) { +void PlatformUiElement::OnHoverMove(const gfx::PointF& position, + base::TimeTicks timestamp) { if (delegate_) - delegate_->OnHoverMove(position); + delegate_->OnHoverMove(position, timestamp); } -void PlatformUiElement::OnButtonDown(const gfx::PointF& position) { +void PlatformUiElement::OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp) { if (delegate_) - delegate_->OnButtonDown(position); + delegate_->OnButtonDown(position, timestamp); } -void PlatformUiElement::OnButtonUp(const gfx::PointF& position) { +void PlatformUiElement::OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp) { if (delegate_) - delegate_->OnButtonUp(position); + delegate_->OnButtonUp(position, timestamp); } -void PlatformUiElement::OnTouchMove(const gfx::PointF& position) { +void PlatformUiElement::OnTouchMove(const gfx::PointF& position, + base::TimeTicks timestamp) { if (delegate_) - delegate_->OnTouchMove(position); + delegate_->OnTouchMove(position, timestamp); } void PlatformUiElement::OnFlingCancel(
diff --git a/chrome/browser/vr/elements/platform_ui_element.h b/chrome/browser/vr/elements/platform_ui_element.h index 60454d9..425bf0d 100644 --- a/chrome/browser/vr/elements/platform_ui_element.h +++ b/chrome/browser/vr/elements/platform_ui_element.h
@@ -22,12 +22,17 @@ PlatformUiElement(); ~PlatformUiElement() override; - void OnHoverEnter(const gfx::PointF& position) override; - void OnHoverLeave() override; - void OnHoverMove(const gfx::PointF& position) override; - void OnButtonDown(const gfx::PointF& position) override; - void OnButtonUp(const gfx::PointF& position) override; - void OnTouchMove(const gfx::PointF& position) override; + void OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnHoverLeave(base::TimeTicks timestamp) override; + void OnHoverMove(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnTouchMove(const gfx::PointF& position, + base::TimeTicks timestamp) override; void OnFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture, const gfx::PointF& position) override; void OnScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture,
diff --git a/chrome/browser/vr/elements/repositioner.cc b/chrome/browser/vr/elements/repositioner.cc index 64d7cc9b..346d264f 100644 --- a/chrome/browser/vr/elements/repositioner.cc +++ b/chrome/browser/vr/elements/repositioner.cc
@@ -69,8 +69,7 @@ } void Repositioner::Reset() { - transform_.MakeIdentity(); - set_world_space_transform_dirty(); + reset_yaw_ = true; } void Repositioner::UpdateTransform(const gfx::Transform& head_pose) { @@ -79,9 +78,16 @@ gfx::Vector3dF head_up = vr::GetUpVector(head_pose); gfx::Vector3dF head_forward = vr::GetForwardVector(head_pose); - transform_ = initial_transform_; - transform_.ConcatTransform(gfx::Transform( - gfx::Quaternion(initial_laser_direction_, laser_direction_))); + if (reset_yaw_) { + gfx::Vector3dF current_right = {1, 0, 0}; + transform_.TransformVector(¤t_right); + transform_.ConcatTransform( + gfx::Transform(gfx::Quaternion(current_right, {1, 0, 0}))); + } else { + transform_ = initial_transform_; + transform_.ConcatTransform(gfx::Transform( + gfx::Quaternion(initial_laser_direction_, laser_direction_))); + } gfx::Vector3dF new_right = {1, 0, 0}; transform_.TransformVector(&new_right); @@ -127,8 +133,9 @@ } bool Repositioner::OnBeginFrame(const gfx::Transform& head_pose) { - if (enabled_) { + if (enabled_ || reset_yaw_) { UpdateTransform(head_pose); + reset_yaw_ = false; return true; } return false;
diff --git a/chrome/browser/vr/elements/repositioner.h b/chrome/browser/vr/elements/repositioner.h index 726ce952..ac6b83e 100644 --- a/chrome/browser/vr/elements/repositioner.h +++ b/chrome/browser/vr/elements/repositioner.h
@@ -52,6 +52,7 @@ bool enabled_ = false; bool has_moved_beyond_threshold_ = false; + bool reset_yaw_ = false; gfx::Transform transform_; gfx::Vector3dF laser_direction_;
diff --git a/chrome/browser/vr/elements/text_input.cc b/chrome/browser/vr/elements/text_input.cc index be6d83a6..6d550e0 100644 --- a/chrome/browser/vr/elements/text_input.cc +++ b/chrome/browser/vr/elements/text_input.cc
@@ -68,7 +68,8 @@ delegate_ = text_input_delegate; } -void TextInput::OnButtonDown(const gfx::PointF& position) { +void TextInput::OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp) { // Reposition the cursor based on click position. int cursor_position = text_element_->GetCursorPositionFromPoint(position); @@ -83,7 +84,8 @@ } } -void TextInput::OnButtonUp(const gfx::PointF& position) { +void TextInput::OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp) { RequestFocus(); }
diff --git a/chrome/browser/vr/elements/text_input.h b/chrome/browser/vr/elements/text_input.h index 068289fc..4da02f9b 100644 --- a/chrome/browser/vr/elements/text_input.h +++ b/chrome/browser/vr/elements/text_input.h
@@ -34,8 +34,10 @@ OnInputEditedCallback input_edit_callback); ~TextInput() override; - void OnButtonDown(const gfx::PointF& position) override; - void OnButtonUp(const gfx::PointF& position) override; + void OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp) override; + void OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp) override; void OnFocusChanged(bool focused) override; void OnInputEdited(const EditedText& info) override; void OnInputCommitted(const EditedText& info) override;
diff --git a/chrome/browser/vr/elements/text_input_unittest.cc b/chrome/browser/vr/elements/text_input_unittest.cc index 1dedccf..b2d1669 100644 --- a/chrome/browser/vr/elements/text_input_unittest.cc +++ b/chrome/browser/vr/elements/text_input_unittest.cc
@@ -107,7 +107,7 @@ // Clicking on the text field should request focus. EXPECT_CALL(*text_input_delegate_, RequestFocus(_)).InSequence(in_sequence_); - text_input_->OnButtonUp(gfx::PointF()); + text_input_->OnButtonUp(gfx::PointF(), base::TimeTicks()); // Focusing on an input field should show the keyboard and tell the delegate // the field's content. @@ -150,7 +150,7 @@ TEST_F(TextInputSceneTest, ClickOnTextGrabsFocus) { EXPECT_CALL(*text_input_delegate_, RequestFocus(_)); - text_input_->get_text_element()->OnButtonUp({0, 0}); + text_input_->get_text_element()->OnButtonUp({0, 0}, base::TimeTicks()); } TEST(TextInputTest, ControllerInteractionsSentToDelegate) { @@ -166,11 +166,11 @@ EXPECT_CALL(*kb_delegate, OnButtonDown(_)).InSequence(s); EXPECT_CALL(*kb_delegate, OnButtonUp(_)).InSequence(s); gfx::PointF p; - keyboard->OnHoverEnter(p); - keyboard->OnHoverLeave(); - keyboard->OnHoverMove(p); - keyboard->OnButtonDown(p); - keyboard->OnButtonUp(p); + keyboard->OnHoverEnter(p, base::TimeTicks()); + keyboard->OnHoverLeave(base::TimeTicks()); + keyboard->OnHoverMove(p, base::TimeTicks()); + keyboard->OnButtonDown(p, base::TimeTicks()); + keyboard->OnButtonUp(p, base::TimeTicks()); } TEST(TextInputTest, HintText) { @@ -281,14 +281,14 @@ element->get_text_element()->PrepareToDrawForTest(); // Click on the left edge of the field. - element->OnButtonDown(gfx::PointF(0.0, 0.5)); - element->OnButtonUp(gfx::PointF(0.0, 0.5)); + element->OnButtonDown(gfx::PointF(0.0, 0.5), base::TimeTicks()); + element->OnButtonUp(gfx::PointF(0.0, 0.5), base::TimeTicks()); element->get_text_element()->PrepareToDrawForTest(); auto x1 = element->get_text_element()->GetRawCursorBounds().x(); // Click on the right edge of the field. - element->OnButtonDown(gfx::PointF(1.0, 0.5)); - element->OnButtonUp(gfx::PointF(1.0, 0.5)); + element->OnButtonDown(gfx::PointF(1.0, 0.5), base::TimeTicks()); + element->OnButtonUp(gfx::PointF(1.0, 0.5), base::TimeTicks()); element->get_text_element()->PrepareToDrawForTest(); auto x2 = element->get_text_element()->GetRawCursorBounds().x(); @@ -300,8 +300,8 @@ info.current.selection_end = info.current.text.size(); element->UpdateInput(info); EXPECT_GT(element->edited_text().current.SelectionSize(), 0u); - element->OnButtonDown(gfx::PointF(0.5, 0.5)); - element->OnButtonUp(gfx::PointF(0.5, 0.5)); + element->OnButtonDown(gfx::PointF(0.5, 0.5), base::TimeTicks()); + element->OnButtonUp(gfx::PointF(0.5, 0.5), base::TimeTicks()); EXPECT_EQ(element->edited_text().current.SelectionSize(), 0u); }
diff --git a/chrome/browser/vr/elements/ui_element.cc b/chrome/browser/vr/elements/ui_element.cc index b864ffa..c1cfa05 100644 --- a/chrome/browser/vr/elements/ui_element.cc +++ b/chrome/browser/vr/elements/ui_element.cc
@@ -153,7 +153,8 @@ void UiElement::Initialize(SkiaSurfaceProvider* provider) {} -void UiElement::OnHoverEnter(const gfx::PointF& position) { +void UiElement::OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp) { if (GetSounds().hover_enter != kSoundNone && audio_delegate_) { audio_delegate_->PlaySound(GetSounds().hover_enter); } @@ -161,62 +162,66 @@ if (event_handlers_.hover_enter) { event_handlers_.hover_enter.Run(); } else if (parent() && bubble_events()) { - parent()->OnHoverEnter(position); + parent()->OnHoverEnter(position, timestamp); } } -void UiElement::OnHoverLeave() { +void UiElement::OnHoverLeave(base::TimeTicks timestamp) { if (GetSounds().hover_leave != kSoundNone && audio_delegate_) { audio_delegate_->PlaySound(GetSounds().hover_leave); } if (event_handlers_.hover_leave) { event_handlers_.hover_leave.Run(); } else if (parent() && bubble_events()) { - parent()->OnHoverLeave(); + parent()->OnHoverLeave(timestamp); } } -void UiElement::OnHoverMove(const gfx::PointF& position) { +void UiElement::OnHoverMove(const gfx::PointF& position, + base::TimeTicks timestamp) { if (GetSounds().hover_move != kSoundNone && audio_delegate_) { audio_delegate_->PlaySound(GetSounds().hover_move); } if (event_handlers_.hover_move) { event_handlers_.hover_move.Run(position); } else if (parent() && bubble_events()) { - parent()->OnHoverMove(position); + parent()->OnHoverMove(position, timestamp); } } -void UiElement::OnButtonDown(const gfx::PointF& position) { +void UiElement::OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp) { if (GetSounds().button_down != kSoundNone && audio_delegate_) { audio_delegate_->PlaySound(GetSounds().button_down); } if (event_handlers_.button_down) { event_handlers_.button_down.Run(); } else if (parent() && bubble_events()) { - parent()->OnButtonDown(position); + parent()->OnButtonDown(position, timestamp); } } -void UiElement::OnButtonUp(const gfx::PointF& position) { +void UiElement::OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp) { if (GetSounds().button_up != kSoundNone && audio_delegate_) { audio_delegate_->PlaySound(GetSounds().button_up); } if (event_handlers_.button_up) { event_handlers_.button_up.Run(); } else if (parent() && bubble_events()) { - parent()->OnButtonUp(position); + parent()->OnButtonUp(position, timestamp); } } -void UiElement::OnTouchMove(const gfx::PointF& position) { +void UiElement::OnTouchMove(const gfx::PointF& position, + base::TimeTicks timestamp) { if (GetSounds().touch_move != kSoundNone && audio_delegate_) { audio_delegate_->PlaySound(GetSounds().touch_move); } if (event_handlers_.touch_move) { event_handlers_.touch_move.Run(position); } else if (parent() && bubble_events()) { - parent()->OnTouchMove(position); + parent()->OnTouchMove(position, timestamp); } }
diff --git a/chrome/browser/vr/elements/ui_element.h b/chrome/browser/vr/elements/ui_element.h index 0ec0403..60c8428 100644 --- a/chrome/browser/vr/elements/ui_element.h +++ b/chrome/browser/vr/elements/ui_element.h
@@ -149,12 +149,17 @@ virtual void Initialize(SkiaSurfaceProvider* provider); // Controller interaction methods. - virtual void OnHoverEnter(const gfx::PointF& position); - virtual void OnHoverLeave(); - virtual void OnHoverMove(const gfx::PointF& position); - virtual void OnButtonDown(const gfx::PointF& position); - virtual void OnButtonUp(const gfx::PointF& position); - virtual void OnTouchMove(const gfx::PointF& position); + virtual void OnHoverEnter(const gfx::PointF& position, + base::TimeTicks timestamp); + virtual void OnHoverLeave(base::TimeTicks timestamp); + virtual void OnHoverMove(const gfx::PointF& position, + base::TimeTicks timestamp); + virtual void OnButtonDown(const gfx::PointF& position, + base::TimeTicks timestamp); + virtual void OnButtonUp(const gfx::PointF& position, + base::TimeTicks timestamp); + virtual void OnTouchMove(const gfx::PointF& position, + base::TimeTicks timestamp); virtual void OnFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture, const gfx::PointF& position); virtual void OnScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture,
diff --git a/chrome/browser/vr/elements/ui_element_unittest.cc b/chrome/browser/vr/elements/ui_element_unittest.cc index 19e1cea..7ea7891d8 100644 --- a/chrome/browser/vr/elements/ui_element_unittest.cc +++ b/chrome/browser/vr/elements/ui_element_unittest.cc
@@ -498,21 +498,21 @@ ElementEventHandlers child_handlers(child_ptr); // Events on grand_child don't bubble up the parent chain. - grand_child_ptr->OnHoverEnter(gfx::PointF()); - grand_child_ptr->OnHoverMove(gfx::PointF()); - grand_child_ptr->OnHoverLeave(); - grand_child_ptr->OnButtonDown(gfx::PointF()); - grand_child_ptr->OnButtonUp(gfx::PointF()); + grand_child_ptr->OnHoverEnter(gfx::PointF(), base::TimeTicks()); + grand_child_ptr->OnHoverMove(gfx::PointF(), base::TimeTicks()); + grand_child_ptr->OnHoverLeave(base::TimeTicks()); + grand_child_ptr->OnButtonDown(gfx::PointF(), base::TimeTicks()); + grand_child_ptr->OnButtonUp(gfx::PointF(), base::TimeTicks()); child_handlers.ExpectCalled(false); element_handlers.ExpectCalled(false); // Events on grand_child bubble up the parent chain. grand_child_ptr->set_bubble_events(true); - grand_child_ptr->OnHoverEnter(gfx::PointF()); - grand_child_ptr->OnHoverMove(gfx::PointF()); - grand_child_ptr->OnHoverLeave(); - grand_child_ptr->OnButtonDown(gfx::PointF()); - grand_child_ptr->OnButtonUp(gfx::PointF()); + grand_child_ptr->OnHoverEnter(gfx::PointF(), base::TimeTicks()); + grand_child_ptr->OnHoverMove(gfx::PointF(), base::TimeTicks()); + grand_child_ptr->OnHoverLeave(base::TimeTicks()); + grand_child_ptr->OnButtonDown(gfx::PointF(), base::TimeTicks()); + grand_child_ptr->OnButtonUp(gfx::PointF(), base::TimeTicks()); child_handlers.ExpectCalled(true); // Events don't bubble to element since it doesn't have the bubble_events bit // set.
diff --git a/chrome/browser/vr/font_fallback.cc b/chrome/browser/vr/font_fallback.cc index 3de6d83..38f44e2 100644 --- a/chrome/browser/vr/font_fallback.cc +++ b/chrome/browser/vr/font_fallback.cc
@@ -13,9 +13,9 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "third_party/icu/source/common/unicode/uscript.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkTypeface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" #include "ui/gfx/platform_font_linux.h" namespace vr {
diff --git a/chrome/browser/vr/model/controller_model.h b/chrome/browser/vr/model/controller_model.h index f99c3480..78752fa 100644 --- a/chrome/browser/vr/model/controller_model.h +++ b/chrome/browser/vr/model/controller_model.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_VR_MODEL_CONTROLLER_MODEL_H_ #define CHROME_BROWSER_VR_MODEL_CONTROLLER_MODEL_H_ +#include "base/time/time.h" #include "chrome/browser/vr/platform_controller.h" #include "chrome/browser/vr/ui_input_manager.h" #include "chrome/browser/vr/vr_export.h" @@ -36,6 +37,9 @@ bool recentered = false; bool app_button_long_pressed = false; PlatformController::Handedness handedness = PlatformController::kRightHanded; + base::TimeTicks last_orientation_timestamp; + base::TimeTicks last_touch_timestamp; + base::TimeTicks last_button_timestamp; }; } // namespace vr
diff --git a/chrome/browser/vr/platform_ui_input_delegate.cc b/chrome/browser/vr/platform_ui_input_delegate.cc index edbeaba..ab9f596 100644 --- a/chrome/browser/vr/platform_ui_input_delegate.cc +++ b/chrome/browser/vr/platform_ui_input_delegate.cc
@@ -21,7 +21,6 @@ } // namespace PlatformUiInputDelegate::PlatformUiInputDelegate() {} - PlatformUiInputDelegate::PlatformUiInputDelegate( PlatformInputHandler* input_handler) : input_handler_(input_handler) {} @@ -29,43 +28,48 @@ PlatformUiInputDelegate::~PlatformUiInputDelegate() = default; void PlatformUiInputDelegate::OnHoverEnter( - const gfx::PointF& normalized_hit_point) { - SendGestureToTarget( - MakeMouseEvent(blink::WebInputEvent::kMouseEnter, normalized_hit_point)); + const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp) { + SendGestureToTarget(MakeMouseEvent(blink::WebInputEvent::kMouseEnter, + normalized_hit_point, timestamp)); } -void PlatformUiInputDelegate::OnHoverLeave() { +void PlatformUiInputDelegate::OnHoverLeave(base::TimeTicks timestamp) { // Note that we send an out of bounds mouse leave event. With blink feature // UpdateHoverPostLayout turned on, a MouseMove event will dispatched post a // Layout. Sending a mouse leave event at 0,0 will result continuous // MouseMove events sent to the content if the content keeps relayout itself. // See https://crbug.com/762573 for details. - SendGestureToTarget( - MakeMouseEvent(blink::WebInputEvent::kMouseLeave, kOutOfBoundsPoint)); + SendGestureToTarget(MakeMouseEvent(blink::WebInputEvent::kMouseLeave, + kOutOfBoundsPoint, timestamp)); } void PlatformUiInputDelegate::OnHoverMove( - const gfx::PointF& normalized_hit_point) { - SendGestureToTarget( - MakeMouseEvent(blink::WebInputEvent::kMouseMove, normalized_hit_point)); + const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp) { + SendGestureToTarget(MakeMouseEvent(blink::WebInputEvent::kMouseMove, + normalized_hit_point, timestamp)); } void PlatformUiInputDelegate::OnButtonDown( - const gfx::PointF& normalized_hit_point) { - SendGestureToTarget( - MakeTouchEvent(blink::WebInputEvent::kTouchStart, normalized_hit_point)); + const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp) { + SendGestureToTarget(MakeTouchEvent(blink::WebInputEvent::kTouchStart, + normalized_hit_point, timestamp)); } void PlatformUiInputDelegate::OnButtonUp( - const gfx::PointF& normalized_hit_point) { - SendGestureToTarget( - MakeTouchEvent(blink::WebInputEvent::kTouchEnd, normalized_hit_point)); + const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp) { + SendGestureToTarget(MakeTouchEvent(blink::WebInputEvent::kTouchEnd, + normalized_hit_point, timestamp)); } void PlatformUiInputDelegate::OnTouchMove( - const gfx::PointF& normalized_hit_point) { - SendGestureToTarget( - MakeTouchEvent(blink::WebInputEvent::kTouchMove, normalized_hit_point)); + const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp) { + SendGestureToTarget(MakeTouchEvent(blink::WebInputEvent::kTouchMove, + normalized_hit_point, timestamp)); } void PlatformUiInputDelegate::OnFlingCancel( @@ -113,30 +117,12 @@ std::unique_ptr<blink::WebMouseEvent> PlatformUiInputDelegate::MakeMouseEvent( blink::WebInputEvent::Type type, - const gfx::PointF& normalized_web_content_location) const { - // TODO(acondor): Remove dependency on platform controller. - if (!controller_) - return nullptr; - + const gfx::PointF& normalized_web_content_location, + base::TimeTicks timestamp) const { gfx::Point location = CalculateLocation(normalized_web_content_location); - blink::WebInputEvent::Modifiers modifiers = - controller_->IsButtonDown(PlatformController::kButtonSelect) - ? blink::WebInputEvent::kLeftButtonDown - : blink::WebInputEvent::kNoModifiers; - base::TimeTicks timestamp; - switch (type) { - case blink::WebInputEvent::kMouseMove: - case blink::WebInputEvent::kMouseEnter: - case blink::WebInputEvent::kMouseLeave: - timestamp = controller_->GetLastOrientationTimestamp(); - break; - default: - NOTREACHED(); - } - - auto mouse_event = - std::make_unique<blink::WebMouseEvent>(type, modifiers, timestamp); + auto mouse_event = std::make_unique<blink::WebMouseEvent>( + type, blink::WebInputEvent::kNoModifiers, timestamp); mouse_event->pointer_type = blink::WebPointerProperties::PointerType::kMouse; mouse_event->button = blink::WebPointerProperties::Button::kLeft; mouse_event->SetPositionInWidget(location.x(), location.y()); @@ -146,30 +132,23 @@ std::unique_ptr<blink::WebTouchEvent> PlatformUiInputDelegate::MakeTouchEvent( blink::WebInputEvent::Type type, - const gfx::PointF& normalized_web_content_location) const { - // TODO(acondor): Remove dependency on platform controller. - if (!controller_) - return nullptr; - + const gfx::PointF& normalized_web_content_location, + base::TimeTicks timestamp) const { gfx::Point location = CalculateLocation(normalized_web_content_location); blink::WebInputEvent::Modifiers modifiers = blink::WebInputEvent::kNoModifiers; - base::TimeTicks timestamp; blink::WebTouchPoint::State touch_state = blink::WebTouchPoint::kStateUndefined; switch (type) { case blink::WebInputEvent::kTouchStart: touch_state = blink::WebTouchPoint::kStatePressed; - timestamp = controller_->GetLastButtonTimestamp(); break; case blink::WebInputEvent::kTouchEnd: touch_state = blink::WebTouchPoint::kStateReleased; - timestamp = controller_->GetLastButtonTimestamp(); break; case blink::WebInputEvent::kTouchMove: touch_state = blink::WebTouchPoint::kStateMoved; - timestamp = controller_->GetLastOrientationTimestamp(); break; default: NOTREACHED();
diff --git a/chrome/browser/vr/platform_ui_input_delegate.h b/chrome/browser/vr/platform_ui_input_delegate.h index 4d5bddf..a2857f7 100644 --- a/chrome/browser/vr/platform_ui_input_delegate.h +++ b/chrome/browser/vr/platform_ui_input_delegate.h
@@ -18,6 +18,10 @@ #include "third_party/blink/public/platform/web_input_event.h" #include "ui/gfx/geometry/size.h" +namespace base { +class TimeTicks; +} // namespace base + namespace blink { class WebGestureEvent; class WebMouseEvent; @@ -30,7 +34,6 @@ namespace vr { -class PlatformController; class PlatformInputHandler; // This class is responsible for processing all events and gestures for @@ -45,12 +48,17 @@ // The following functions are virtual so that they may be overridden in the // MockContentInputDelegate. - VIRTUAL_FOR_MOCKS void OnHoverEnter(const gfx::PointF& normalized_hit_point); - VIRTUAL_FOR_MOCKS void OnHoverLeave(); - VIRTUAL_FOR_MOCKS void OnHoverMove(const gfx::PointF& normalized_hit_point); - VIRTUAL_FOR_MOCKS void OnButtonDown(const gfx::PointF& normalized_hit_point); - VIRTUAL_FOR_MOCKS void OnButtonUp(const gfx::PointF& normalized_hit_point); - VIRTUAL_FOR_MOCKS void OnTouchMove(const gfx::PointF& normalized_hit_point); + VIRTUAL_FOR_MOCKS void OnHoverEnter(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp); + VIRTUAL_FOR_MOCKS void OnHoverLeave(base::TimeTicks timestamp); + VIRTUAL_FOR_MOCKS void OnHoverMove(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp); + VIRTUAL_FOR_MOCKS void OnButtonDown(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp); + VIRTUAL_FOR_MOCKS void OnButtonUp(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp); + VIRTUAL_FOR_MOCKS void OnTouchMove(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp); VIRTUAL_FOR_MOCKS void OnFlingCancel( std::unique_ptr<blink::WebGestureEvent> gesture, const gfx::PointF& normalized_hit_point); @@ -64,10 +72,6 @@ std::unique_ptr<blink::WebGestureEvent> gesture, const gfx::PointF& normalized_hit_point); - void SetPlatformController(PlatformController* controller) { - controller_ = controller; - } - void SetSize(int width, int height) { size_ = {width, height}; } void SetPlatformInputHandlerForTest(PlatformInputHandler* input_handler) { input_handler_ = input_handler; @@ -82,10 +86,12 @@ blink::WebGestureEvent& gesture); std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent( blink::WebInputEvent::Type type, - const gfx::PointF& normalized_web_content_location) const; + const gfx::PointF& normalized_web_content_location, + base::TimeTicks timestamp) const; std::unique_ptr<blink::WebTouchEvent> MakeTouchEvent( blink::WebInputEvent::Type type, - const gfx::PointF& normalized_web_content_location) const; + const gfx::PointF& normalized_web_content_location, + base::TimeTicks timestamp) const; gfx::Point CalculateLocation( const gfx::PointF& normalized_web_content_location) const; @@ -93,9 +99,6 @@ PlatformInputHandler* input_handler_ = nullptr; - // TODO(acondor): Remove dependency on platform controller. - PlatformController* controller_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(PlatformUiInputDelegate); };
diff --git a/chrome/browser/vr/test/mock_content_input_delegate.h b/chrome/browser/vr/test/mock_content_input_delegate.h index 7906b65..d644b60 100644 --- a/chrome/browser/vr/test/mock_content_input_delegate.h +++ b/chrome/browser/vr/test/mock_content_input_delegate.h
@@ -17,11 +17,19 @@ MockContentInputDelegate(); ~MockContentInputDelegate() override; - MOCK_METHOD1(OnHoverEnter, void(const gfx::PointF& normalized_hit_point)); - MOCK_METHOD0(OnHoverLeave, void()); - MOCK_METHOD1(OnHoverMove, void(const gfx::PointF& normalized_hit_point)); - MOCK_METHOD1(OnButtonDown, void(const gfx::PointF& normalized_hit_point)); - MOCK_METHOD1(OnButtonUp, void(const gfx::PointF& normalized_hit_point)); + MOCK_METHOD2(OnHoverEnter, + void(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp)); + MOCK_METHOD1(OnHoverLeave, void(base::TimeTicks timestamp)); + MOCK_METHOD2(OnHoverMove, + void(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp)); + MOCK_METHOD2(OnButtonDown, + void(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp)); + MOCK_METHOD2(OnButtonUp, + void(const gfx::PointF& normalized_hit_point, + base::TimeTicks timestamp)); // As move-only parameters aren't supported by mock methods, we will override // the functions explicitly and fwd the calls to the mocked functions.
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 70536ad..70f4570 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -254,6 +254,9 @@ case ui::DomCode::US_P: model_->toggle_mode(kModeRepositionWindow); break; + case ui::DomCode::US_G: + recentered_ = true; + break; case ui::DomCode::US_X: ui_->OnAppButtonClicked(); break; @@ -389,6 +392,8 @@ touchpad_pressed_ ? UiInputManager::DOWN : UiInputManager::UP; controller_model.touchpad_touch_position = touchpad_touch_position_; controller_model.touching_touchpad = touching_touchpad_; + controller_model.recentered = recentered_; + recentered_ = false; controller_model.laser_origin = mouse_point_near; controller_model.laser_direction = mouse_point_far - mouse_point_near;
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h index 3d2ae39..781a5c1 100644 --- a/chrome/browser/vr/testapp/vr_test_context.h +++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -112,6 +112,7 @@ bool show_web_vr_splash_screen_ = false; bool voice_search_enabled_ = false; bool touching_touchpad_ = false; + bool recentered_ = false; base::TimeTicks page_load_start_; int tab_id_ = 0;
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index e000b51..291a0ee9 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc
@@ -437,10 +437,6 @@ content_input_delegate_->SetSize(width, height); } -void Ui::OnPlatformControllerInitialized(PlatformController* controller) { - content_input_delegate_->SetPlatformController(controller); -} - bool Ui::IsControllerVisible() const { UiElement* controller_group = scene_->GetUiElementByName(kControllerGroup); return controller_group && controller_group->GetTargetOpacity() > 0.0f; @@ -557,10 +553,10 @@ DCHECK(prompt); auto* button = prompt->GetDescendantByType(kTypePromptPrimaryButton); DCHECK(button); - button->OnHoverEnter({0.5f, 0.5f}); - button->OnButtonDown({0.5f, 0.5f}); - button->OnButtonUp({0.5f, 0.5f}); - button->OnHoverLeave(); + button->OnHoverEnter({0.5f, 0.5f}, base::TimeTicks::Now()); + button->OnButtonDown({0.5f, 0.5f}, base::TimeTicks::Now()); + button->OnButtonUp({0.5f, 0.5f}, base::TimeTicks::Now()); + button->OnHoverLeave(base::TimeTicks::Now()); } void Ui::PerformControllerActionForTesting(
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h index 9a4171d..9c01ff55 100644 --- a/chrome/browser/vr/ui.h +++ b/chrome/browser/vr/ui.h
@@ -159,7 +159,6 @@ bool SkipsRedrawWhenNotDirty() const; void OnSwapContents(int new_content_id); void OnContentBoundsChanged(int width, int height); - void OnPlatformControllerInitialized(PlatformController* controller); void OnUiRequestedNavigation(); void SetFloorHeight(float floor_height);
diff --git a/chrome/browser/vr/ui_input_manager.cc b/chrome/browser/vr/ui_input_manager.cc index 362b60e..dcaca409 100644 --- a/chrome/browser/vr/ui_input_manager.cc +++ b/chrome/browser/vr/ui_input_manager.cc
@@ -108,23 +108,28 @@ SendFlingCancel(gesture_list, element_local_point); SendScrollEnd(gesture_list, element_local_point, controller_model.touchpad_button_state); - SendButtonUp(element_local_point, controller_model.touchpad_button_state); - SendHoverLeave(target_element); + SendButtonUp(element_local_point, controller_model.touchpad_button_state, + controller_model.last_button_timestamp); + SendHoverLeave(target_element, controller_model.last_orientation_timestamp); // Sending update events. if (in_scroll_) { SendScrollUpdate(gesture_list, element_local_point); } else if (in_click_) { - SendTouchMove(element_local_point); + SendTouchMove(element_local_point, + controller_model.last_orientation_timestamp); } else { - SendHoverMove(target_element, reticle_model->target_local_point); + SendHoverMove(target_element, reticle_model->target_local_point, + controller_model.last_orientation_timestamp); } // Sending begin events. - SendHoverEnter(target_element, reticle_model->target_local_point); + SendHoverEnter(target_element, reticle_model->target_local_point, + controller_model.last_orientation_timestamp); SendScrollBegin(target_element, gesture_list, element_local_point); SendButtonDown(target_element, reticle_model->target_local_point, - controller_model.touchpad_button_state); + controller_model.touchpad_button_state, + controller_model.last_button_timestamp); previous_button_state_ = controller_model.touchpad_button_state; } @@ -133,7 +138,7 @@ if (hover_target_id_) { UiElement* prev_hovered = scene_->GetUiElementById(hover_target_id_); if (prev_hovered) - prev_hovered->OnHoverLeave(); + prev_hovered->OnHoverLeave(base::TimeTicks::Now()); hover_target_id_ = 0; } } @@ -218,35 +223,38 @@ gesture_list->erase(gesture_list->begin()); } -void UiInputManager::SendHoverLeave(UiElement* current_target) { +void UiInputManager::SendHoverLeave(UiElement* current_target, + base::TimeTicks timestamp) { if (hover_target_id_ && (!current_target || current_target->id() != hover_target_id_)) { UiElement* prev_hovered = scene_->GetUiElementById(hover_target_id_); - if (prev_hovered) { - prev_hovered->OnHoverLeave(); - } + if (prev_hovered) + prev_hovered->OnHoverLeave(timestamp); hover_target_id_ = 0; } } void UiInputManager::SendHoverEnter(UiElement* target, - const gfx::PointF& target_point) { + const gfx::PointF& target_point, + base::TimeTicks timestamp) { if (!target || target->id() == hover_target_id_) return; if ((in_click_ || in_scroll_) && target->id() != input_capture_element_id_) return; - target->OnHoverEnter(target_point); + target->OnHoverEnter(target_point, timestamp); hover_target_id_ = target->id(); } void UiInputManager::SendHoverMove(UiElement* target, - const gfx::PointF& target_point) { + const gfx::PointF& target_point, + base::TimeTicks timestamp) { if (target && target->id() == hover_target_id_) - target->OnHoverMove(target_point); + target->OnHoverMove(target_point, timestamp); } void UiInputManager::SendButtonUp(const gfx::PointF& target_point, - ButtonState button_state) { + ButtonState button_state, + base::TimeTicks timestamp) { if (!in_click_ || previous_button_state_ == button_state || button_state != ButtonState::UP) { return; @@ -256,7 +264,7 @@ return; UiElement* element = scene_->GetUiElementById(input_capture_element_id_); if (element) { - element->OnButtonUp(target_point); + element->OnButtonUp(target_point, timestamp); // Clicking outside of the focused element causes it to lose focus. if (element->id() != focused_element_id_ && element->focusable()) UnfocusFocusedElement(); @@ -267,26 +275,28 @@ void UiInputManager::SendButtonDown(UiElement* target, const gfx::PointF& target_point, - ButtonState button_state) { + ButtonState button_state, + base::TimeTicks timestamp) { if (previous_button_state_ == button_state || button_state != ButtonState::DOWN) { return; } in_click_ = true; if (target) { - target->OnButtonDown(target_point); + target->OnButtonDown(target_point, timestamp); input_capture_element_id_ = target->id(); } else { input_capture_element_id_ = 0; } } -void UiInputManager::SendTouchMove(const gfx::PointF& target_point) { +void UiInputManager::SendTouchMove(const gfx::PointF& target_point, + base::TimeTicks timestamp) { if (!input_capture_element_id_) return; UiElement* element = scene_->GetUiElementById(input_capture_element_id_); if (element) - element->OnTouchMove(target_point); + element->OnTouchMove(target_point, timestamp); } UiElement* UiInputManager::GetTargetElement(
diff --git a/chrome/browser/vr/ui_input_manager.h b/chrome/browser/vr/ui_input_manager.h index 42bdf9a..ea214e4 100644 --- a/chrome/browser/vr/ui_input_manager.h +++ b/chrome/browser/vr/ui_input_manager.h
@@ -87,15 +87,23 @@ void SendScrollUpdate(GestureList* gesture_list, const gfx::PointF& target_point); - void SendHoverLeave(UiElement* current_target); - void SendHoverEnter(UiElement* target, const gfx::PointF& target_point); - void SendHoverMove(UiElement* target, const gfx::PointF& target_point); + void SendHoverLeave(UiElement* current_target, base::TimeTicks timestamp); + void SendHoverEnter(UiElement* target, + const gfx::PointF& target_point, + base::TimeTicks timestamp); + void SendHoverMove(UiElement* target, + const gfx::PointF& target_point, + base::TimeTicks timestamp); - void SendButtonUp(const gfx::PointF& target_point, ButtonState button_state); + void SendButtonUp(const gfx::PointF& target_point, + ButtonState button_state, + base::TimeTicks timestamp); void SendButtonDown(UiElement* target, const gfx::PointF& target_point, - ButtonState button_state); - void SendTouchMove(const gfx::PointF& target_point); + ButtonState button_state, + base::TimeTicks timestamp); + void SendTouchMove(const gfx::PointF& target_point, + base::TimeTicks timestamp); UiElement* GetTargetElement(const ControllerModel& controller_model, ReticleModel* reticle_model,
diff --git a/chrome/browser/vr/ui_input_manager_unittest.cc b/chrome/browser/vr/ui_input_manager_unittest.cc index 5d990fa..f5b7287 100644 --- a/chrome/browser/vr/ui_input_manager_unittest.cc +++ b/chrome/browser/vr/ui_input_manager_unittest.cc
@@ -45,12 +45,17 @@ MockRect() = default; ~MockRect() override = default; - MOCK_METHOD1(OnHoverEnter, void(const gfx::PointF& position)); - MOCK_METHOD0(OnHoverLeave, void()); - MOCK_METHOD1(OnHoverMove, void(const gfx::PointF& position)); - MOCK_METHOD1(OnButtonDown, void(const gfx::PointF& position)); - MOCK_METHOD1(OnButtonUp, void(const gfx::PointF& position)); - MOCK_METHOD1(OnTouchMove, void(const gfx::PointF& position)); + MOCK_METHOD2(OnHoverEnter, + void(const gfx::PointF& position, base::TimeTicks timestamp)); + MOCK_METHOD1(OnHoverLeave, void(base::TimeTicks timestamp)); + MOCK_METHOD2(OnHoverMove, + void(const gfx::PointF& position, base::TimeTicks timestamp)); + MOCK_METHOD2(OnButtonDown, + void(const gfx::PointF& position, base::TimeTicks timestamp)); + MOCK_METHOD2(OnButtonUp, + void(const gfx::PointF& position, base::TimeTicks timestamp)); + MOCK_METHOD2(OnTouchMove, + void(const gfx::PointF& position, base::TimeTicks timestamp)); MOCK_METHOD2(OnScrollBegin, void(std::unique_ptr<blink::WebGestureEvent>, const gfx::PointF&)); @@ -218,12 +223,12 @@ input_manager_->RequestFocus(p_element->id()); // Focus child. - EXPECT_CALL(*p_child, OnHoverEnter(_)).InSequence(s); - EXPECT_CALL(*p_child, OnButtonDown(_)).InSequence(s); + EXPECT_CALL(*p_child, OnHoverEnter(_, _)).InSequence(s); + EXPECT_CALL(*p_child, OnButtonDown(_, _)).InSequence(s); HandleInput(kForwardVector, kDown); - EXPECT_CALL(*p_child, OnButtonUp(_)).InSequence(s); + EXPECT_CALL(*p_child, OnButtonUp(_, _)).InSequence(s); EXPECT_CALL(*p_element, OnFocusChanged(false)).InSequence(s); - EXPECT_CALL(*p_child, OnHoverMove(_)).InSequence(s); + EXPECT_CALL(*p_child, OnHoverMove(_, _)).InSequence(s); HandleInput(kForwardVector, kUp); } @@ -244,8 +249,8 @@ input_manager_->RequestFocus(p_element->id()); // Focus child. - EXPECT_CALL(*p_child, OnHoverEnter(_)).InSequence(s); - EXPECT_CALL(*p_child, OnButtonDown(_)).InSequence(s); + EXPECT_CALL(*p_child, OnHoverEnter(_, _)).InSequence(s); + EXPECT_CALL(*p_child, OnButtonDown(_, _)).InSequence(s); EXPECT_CALL(*p_element, OnFocusChanged(false)).Times(0).InSequence(s); HandleInput(kForwardVector, kDown); } @@ -283,30 +288,30 @@ StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f); // Move over the test element. - EXPECT_CALL(*p_element, OnHoverEnter(_)); + EXPECT_CALL(*p_element, OnHoverEnter(_, _)); HandleInput(kForwardVector, kUp); - EXPECT_CALL(*p_element, OnHoverMove(_)); + EXPECT_CALL(*p_element, OnHoverMove(_, _)); HandleInput(kForwardVector, kUp); Mock::VerifyAndClearExpectations(p_element); // Press the button while on the element. - EXPECT_CALL(*p_element, OnHoverMove(_)); - EXPECT_CALL(*p_element, OnButtonDown(_)); + EXPECT_CALL(*p_element, OnHoverMove(_, _)); + EXPECT_CALL(*p_element, OnButtonDown(_, _)); HandleInput(kForwardVector, kDown); Mock::VerifyAndClearExpectations(p_element); - EXPECT_CALL(*p_element, OnTouchMove(_)); + EXPECT_CALL(*p_element, OnTouchMove(_, _)); HandleInput(kForwardVector, kDown); Mock::VerifyAndClearExpectations(p_element); // Release the button while on the element. - EXPECT_CALL(*p_element, OnButtonUp(_)); - EXPECT_CALL(*p_element, OnHoverMove(_)); + EXPECT_CALL(*p_element, OnButtonUp(_, _)); + EXPECT_CALL(*p_element, OnHoverMove(_, _)); HandleInput(kForwardVector, kUp); Mock::VerifyAndClearExpectations(p_element); // Move off of the element. - EXPECT_CALL(*p_element, OnHoverLeave()); + EXPECT_CALL(*p_element, OnHoverLeave(_)); HandleInput(kBackwardVector, kUp); Mock::VerifyAndClearExpectations(p_element); @@ -319,14 +324,14 @@ // Press on an element, move away, then release. The element should receive // hover leave, but keep receiving touch move events until release. - EXPECT_CALL(*p_element, OnHoverEnter(_)); - EXPECT_CALL(*p_element, OnButtonDown(_)); + EXPECT_CALL(*p_element, OnHoverEnter(_, _)); + EXPECT_CALL(*p_element, OnButtonDown(_, _)); HandleInput(kForwardVector, kDown); - EXPECT_CALL(*p_element, OnHoverLeave()); - EXPECT_CALL(*p_element, OnTouchMove(_)); + EXPECT_CALL(*p_element, OnHoverLeave(_)); + EXPECT_CALL(*p_element, OnTouchMove(_, _)); HandleInput(kBackwardVector, kDown); Mock::VerifyAndClearExpectations(p_element); - EXPECT_CALL(*p_element, OnButtonUp(_)); + EXPECT_CALL(*p_element, OnButtonUp(_, _)); HandleInput(kBackwardVector, kUp); Mock::VerifyAndClearExpectations(p_element); } @@ -340,25 +345,25 @@ StrictMock<MockRect>* p_back_element = CreateAndAddMockElement(5.f); // Press on an element. - EXPECT_CALL(*p_front_element, OnHoverEnter(_)); - EXPECT_CALL(*p_front_element, OnButtonDown(_)); + EXPECT_CALL(*p_front_element, OnHoverEnter(_, _)); + EXPECT_CALL(*p_front_element, OnButtonDown(_, _)); HandleInput(kForwardVector, kDown); // Point to another element while pressing. - EXPECT_CALL(*p_front_element, OnHoverLeave()); - EXPECT_CALL(*p_front_element, OnTouchMove(_)); + EXPECT_CALL(*p_front_element, OnHoverLeave(_)); + EXPECT_CALL(*p_front_element, OnTouchMove(_, _)); HandleInput(kBackwardVector, kDown); // Point again to the previous element while pressing. - EXPECT_CALL(*p_front_element, OnTouchMove(_)); - EXPECT_CALL(*p_front_element, OnHoverEnter(_)); + EXPECT_CALL(*p_front_element, OnTouchMove(_, _)); + EXPECT_CALL(*p_front_element, OnHoverEnter(_, _)); HandleInput(kForwardVector, kDown); // Point to second element and release. - EXPECT_CALL(*p_front_element, OnButtonUp(_)); - EXPECT_CALL(*p_front_element, OnHoverLeave()); - EXPECT_CALL(*p_back_element, OnHoverEnter(_)); + EXPECT_CALL(*p_front_element, OnButtonUp(_, _)); + EXPECT_CALL(*p_front_element, OnHoverLeave(_)); + EXPECT_CALL(*p_back_element, OnHoverEnter(_, _)); HandleInput(kBackwardVector, kUp); // Point again to first element. - EXPECT_CALL(*p_back_element, OnHoverLeave()); - EXPECT_CALL(*p_front_element, OnHoverEnter(_)); + EXPECT_CALL(*p_back_element, OnHoverLeave(_)); + EXPECT_CALL(*p_front_element, OnHoverEnter(_, _)); HandleInput(kForwardVector, kUp); } @@ -373,7 +378,7 @@ // Scroll on an element. AddGesture(blink::WebGestureEvent::kGestureScrollBegin); - EXPECT_CALL(*p_front_element, OnHoverEnter(_)); + EXPECT_CALL(*p_front_element, OnHoverEnter(_, _)); EXPECT_CALL(*p_front_element, OnScrollBegin(_, _)); HandleInput(kForwardVector, kUp); EXPECT_TRUE(gesture_list_.empty()); @@ -384,7 +389,7 @@ // Move away. AddGesture(blink::WebGestureEvent::kGestureScrollUpdate); - EXPECT_CALL(*p_front_element, OnHoverLeave()); + EXPECT_CALL(*p_front_element, OnHoverLeave(_)); EXPECT_CALL(*p_front_element, OnScrollUpdate(_, _)); HandleInput(kBackwardVector, kUp); EXPECT_TRUE(gesture_list_.empty()); @@ -392,12 +397,12 @@ // Release scroll. AddGesture(blink::WebGestureEvent::kGestureScrollEnd); EXPECT_CALL(*p_front_element, OnScrollEnd(_, _)); - EXPECT_CALL(*p_back_element, OnHoverEnter(_)); + EXPECT_CALL(*p_back_element, OnHoverEnter(_, _)); HandleInput(kBackwardVector, kUp); EXPECT_TRUE(gesture_list_.empty()); // Start scrolling on a new element. - EXPECT_CALL(*p_back_element, OnHoverMove(_)); + EXPECT_CALL(*p_back_element, OnHoverMove(_, _)); AddGesture(blink::WebGestureEvent::kGestureScrollBegin); EXPECT_CALL(*p_back_element, OnScrollBegin(_, _)); HandleInput(kBackwardVector, kUp); @@ -417,7 +422,7 @@ p_element->AddChild(std::move(child)); AddGesture(blink::WebGestureEvent::kGestureScrollBegin); - EXPECT_CALL(*p_element, OnHoverEnter(_)); + EXPECT_CALL(*p_element, OnHoverEnter(_, _)); EXPECT_CALL(*p_element, OnScrollBegin(_, _)); EXPECT_CALL(*p_child, OnScrollBegin(_, _)).Times(0); HandleInput(kForwardVector, kUp); @@ -430,7 +435,7 @@ StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f); // Hover on an element. - EXPECT_CALL(*p_element, OnHoverEnter(_)); + EXPECT_CALL(*p_element, OnHoverEnter(_, _)); HandleInput(kForwardVector, kUp); // Remove and retain the element from the scene, and ensure that it receives @@ -442,8 +447,8 @@ // Re-add the element to the scene, and press on it to lock it for input. scene_->AddUiElement(kRoot, std::move(deleted_element)); scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose); - EXPECT_CALL(*p_element, OnHoverEnter(_)); - EXPECT_CALL(*p_element, OnButtonDown(_)); + EXPECT_CALL(*p_element, OnHoverEnter(_, _)); + EXPECT_CALL(*p_element, OnButtonDown(_, _)); HandleInput(kForwardVector, kDown); // Remove the element again, move off the element, and release to ensure that @@ -514,7 +519,7 @@ // Unless we suppress content move events during clicks, this will cause us to // call OnContentMove on the delegate. We should do this suppression, so we // set the expected number of calls to zero. - EXPECT_CALL(*content_input_delegate_, OnHoverMove(testing::_)).Times(0); + EXPECT_CALL(*content_input_delegate_, OnHoverMove(_, _)).Times(0); input_manager_->HandleInput(MsToTicks(1), RenderInfo(), controller_model, &reticle_model, &gesture_list);
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 92a5f2f..c86f6c0 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -1109,6 +1109,9 @@ repositioner->AddBinding(VR_BIND_FUNC( gfx::Vector3dF, Model, model_, model->controller.laser_direction, Repositioner, repositioner.get(), set_laser_direction)); + repositioner->AddBinding( + VR_BIND(bool, Model, model_, model->controller.recentered, Repositioner, + repositioner.get(), if (value) { view->Reset(); })); scene_->AddUiElement(k2dBrowsingRoot, std::move(repositioner)); auto hider = Create<UiElement>(k2dBrowsingVisibiltyHider, kPhaseNone);
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index ba2676f..7c2d2e0 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -1049,19 +1049,21 @@ RunForMs(kAnimationTimeMs); VerifyButtonColor(button, scheme.disc_button_colors.foreground, scheme.disc_button_colors.background, "normal"); - button->hit_plane()->OnHoverEnter(gfx::PointF(0.5f, 0.5f)); + button->hit_plane()->OnHoverEnter(gfx::PointF(0.5f, 0.5f), + base::TimeTicks()); RunForMs(kAnimationTimeMs); VerifyButtonColor(button, scheme.disc_button_colors.foreground, scheme.disc_button_colors.background_hover, "hover"); - button->hit_plane()->OnButtonDown(gfx::PointF(0.5f, 0.5f)); + button->hit_plane()->OnButtonDown(gfx::PointF(0.5f, 0.5f), + base::TimeTicks()); RunForMs(kAnimationTimeMs); VerifyButtonColor(button, scheme.disc_button_colors.foreground, scheme.disc_button_colors.background_down, "down"); - button->hit_plane()->OnHoverMove(gfx::PointF()); + button->hit_plane()->OnHoverMove(gfx::PointF(), base::TimeTicks()); RunForMs(kAnimationTimeMs); VerifyButtonColor(button, scheme.disc_button_colors.foreground, scheme.disc_button_colors.background, "move"); - button->hit_plane()->OnButtonUp(gfx::PointF()); + button->hit_plane()->OnButtonUp(gfx::PointF(), base::TimeTicks()); RunForMs(kAnimationTimeMs); VerifyButtonColor(button, scheme.disc_button_colors.foreground, scheme.disc_button_colors.background, "up"); @@ -1226,11 +1228,16 @@ repositioner->set_laser_direction(kForwardVector); repositioner->SetEnabled(true); - repositioner->set_laser_direction({0, 1, 0}); + repositioner->set_laser_direction({1, 0, 0}); OnBeginFrame(); EXPECT_NE(original, repositioner->world_space_transform()); repositioner->SetEnabled(false); + + model_->controller.recentered = true; + + OnBeginFrame(); + EXPECT_EQ(original, repositioner->world_space_transform()); } // No element in the controller root's subtree should be hit testable.
diff --git a/chrome/chrome_watcher/BUILD.gn b/chrome/chrome_watcher/BUILD.gn index 0783cc8..39e9e3d 100644 --- a/chrome/chrome_watcher/BUILD.gn +++ b/chrome/chrome_watcher/BUILD.gn
@@ -60,6 +60,7 @@ "//base", "//base:base_static", "//chrome/common:non_code_constants", + "//chrome/common/win:eventlog_messages", "//chrome/install_static:secondary_module", "//chrome_elf", "//components/browser_watcher",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 0b5e0e7..2443e6b6 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -322,7 +322,7 @@ #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) // A feature that controls whether Chrome warns about incompatible applications. const base::Feature kIncompatibleApplicationsWarning{ - "IncompatibleApplicationsWarning", base::FEATURE_DISABLED_BY_DEFAULT}; + "IncompatibleApplicationsWarning", base::FEATURE_ENABLED_BY_DEFAULT}; #endif #if !defined(OS_ANDROID)
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index dc15489..d733d27a 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -280,12 +280,20 @@ "extension_types": ["extension", "platform_app"], "location": "policy" }, - "enterprise.platformKeys": { + "enterprise.platformKeys": [{ "channel": "stable", "platforms": ["chromeos"], "extension_types": ["extension", "platform_app", "legacy_packaged_app"], "location": "policy" - }, + }, { + "channel": "stable", + "platforms": ["chromeos"], + "extension_types": ["extension"], + "location": "external_component", + "whitelist": [ + "EC8EA268128FECE14CEC68B90686D87755D87083" // http://crbug.com/854695 + ] + }], "enterprise.platformKeysPrivate": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app"],
diff --git a/chrome/common/extensions/docs/static/css/out/site.css b/chrome/common/extensions/docs/static/css/out/site.css index 74f5e62..f94724e 100644 --- a/chrome/common/extensions/docs/static/css/out/site.css +++ b/chrome/common/extensions/docs/static/css/out/site.css
@@ -1,4 +1,4 @@ /*! Copyright 2014 The Chromium Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. - */#fatnav li,nav ol,nav ul{list-style:none}img,legend{border:0}*,legend{padding:0}main,sub,sup{position:relative}html,table{line-height:1.5em}b,strong,table caption,th{font-weight:700}figure img,td,th{border:1px solid #dbdbdb}mark,pre b{background:#ff0}.published,dfn{font-style:italic}#fatnav .toplevel,#logo{-o-user-select:none;-ms-user-select:none}.nav-arrow,a,a:link,a:visited{transition:opacity .3s ease 0s}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}body,figure,form{margin:0}a{background:0 0}a:focus{outline:dotted thin}a:active,a:hover{outline:0}p,pre{margin:1.5em 0}h1{margin-top:.75em;margin-bottom:.75em}abbr[title]{border-bottom:1px dotted}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}mark{color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}img{-ms-interpolation-mode:bicubic;max-width:100%;vertical-align:middle}svg:not(:root){overflow:hidden}fieldset{margin:0 2px;border-color:silver;border-width:.0625em;border-style:solid;padding:.4625em .875em .9125em}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;vertical-align:baseline}button,input{line-height:normal}button,select{text-transform:none}#fatnav .toplevel,.label{text-transform:uppercase}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}#fatnav .expandee,*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-size:100%}.g-section:after{content:".";display:block;height:0;clear:both;visibility:hidden}.g-unit .g-section:after{clear:none}.g-unit .g-section{width:100%;overflow:hidden}.g-section,.g-unit{zoom:1}.g-split>.g-unit{float:right;text-align:right}.g-split>.g-first{float:left;text-align:left}.g-tpl-160 .g-unit,.g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit{display:block;margin:0 0 0 160px;width:auto;float:none}.g-tpl-160 .g-first,.g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first{display:block;margin:0;width:160px;float:left}.g-tpl-25-75 .g-unit,.g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit{width:74.999%;float:right;display:inline;margin:0}.g-tpl-25-75 .g-first,.g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first{width:24.999%;float:left;display:inline;margin:0}.g-tpl-75-25 .g-unit,.g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit{width:24.999%;float:right;display:inline;margin:0}.g-tpl-75-25 .g-first,.g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first{width:74.999%;float:left;display:inline;margin:0}.g-tpl-33-67 .g-unit,.g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit{width:66.999%;float:right;display:inline;margin:0}.g-tpl-33-67 .g-first,.g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first{width:32.999%;float:left;display:inline;margin:0}.g-tpl-67-33 .g-unit,.g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit{width:32.999%;float:right;display:inline;margin:0}.g-tpl-67-33 .g-first,.g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first{width:66.999%;float:left;display:inline;margin:0}.g-tpl-50-50 .g-unit,.g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit{width:49.999%;float:right;display:inline;margin:0}.g-tpl-50-50 .g-first,.g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first{width:49.999%;float:left;display:inline;margin:0}.g-tpl-nest .g-unit{float:left;width:auto;display:inline;margin:0}.g-tpl-nest-alt .g-unit{float:right;width:auto;display:inline;margin:0}.g-content{margin-right:30px}.g-last .g-content{margin-right:0}@media only screen and (max-width:580px){.g-unit.g-unit{float:none!important}.g-content{margin-right:0}}*{margin:0;box-sizing:border-box}body{overflow:auto}.gc-container{max-width:870px;margin:auto;width:90%}#gc-pagecontent>.g-section{margin:40px 0}main{margin-bottom:50px}footer[role=contentinfo]{padding:40px 0 50px}@media only screen and (max-width:580px){.gc-container{width:auto}#gc-pagecontent{margin:auto;width:90%}#gc-pagecontent>.g-section{margin:20px 0}footer[role=contentinfo]{padding:20px 30px}}@media only screen and (min-width:581px) and (max-width:990px){.gc-container{width:95%}}figure{margin:20px 0}table{border-spacing:0;width:100%;border-collapse:collapse;margin:2em 0}table caption{margin-bottom:1em;text-align:left}th{background:#e8e8e8}tr{border-bottom:1px solid #dbdbdb}table+tr{border-top:1px solid #dbdbdb}td,th{padding:1em 1.5em;text-align:left}pre{background-color:#f7f7f7;box-shadow:0 2px 4px rgba(0,0,0,.15),0 0 3px rgba(0,0,0,.15);padding:.99em;overflow-x:auto;white-space:pre;font-size:.95em;line-height:1.8em}#fatnav,#fatnav .expandee li,.api table#intro .title,.google-button,.kbd{white-space:nowrap}pre a{text-decoration:underline!important}pre b{font-weight:400}pre strike{text-decoration:none;background-image:linear-gradient(rgba(0,0,0,0) 7px,#cc1f1f 7px,#cc1f1f 9px,rgba(0,0,0,0) 9px)}pre[data-filename]:hover::after{visibility:visible}.element-invisible{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.hidden{display:none}.button,.button-alt{display:inline-block;font-weight:700;text-decoration:none!important;text-align:center}.label{color:inherit;margin-bottom:5px;font-size:11.2px;font-weight:700}.published{font-size:11.2px;color:#bebebe;line-height:16.8px}.description{margin:20px 0}.description:last-child{margin-bottom:0}#gc-footer{background:#f5f5f5}.button{background:#0370ea;background-image:linear-gradient(to bottom,#008dfd 0,#0370ea 100%);border:1px solid #076bd2;border-radius:3px;color:#fff!important;font-size:13px;line-height:1.3;padding:5px 20px;text-shadow:1px 1px 1px #076bd2}.button:hover{background-image:linear-gradient(to bottom,#008dfd 30%,#0370ea 100%);cursor:pointer}.button a{color:inherit!important}.button-alt{background:#eee;background-image:linear-gradient(to top,#dcdcdc 46%,#fafafa 87%);border:1px solid #d6d6d6;border-radius:3px;color:#333!important;font-size:12px;line-height:24px;padding:0 15px;text-shadow:none}h2,h3{line-height:1.12em}.button-alt:hover{background-image:linear-gradient(to top,#dcdcdc 20%,#fafafa 87%);cursor:pointer}.google-button{background-color:#f5f5f5;border-radius:2px 0 0;border:1px solid rgba(0,0,0,.1);padding:5px 12px;text-align:center}.google-button:hover{border-color:#c6c6c6;box-shadow:0 -1px 1px rgba(0,0,0,.1)}.google-button:active{background-color:#f1f1f1;box-shadow:inset 0 0 2px rgba(0,0,0,.2)}.screenshot,.screenshot img{margin:1em 0}.video-container{position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden;margin:0 0 20px}h1+h1,h4,h5,h6{margin-top:0}.video-container embed,.video-container iframe,.video-container object{position:absolute;top:0;left:0;width:100%;height:100%}#topnav,pre{position:relative}aside.caution,aside.note,aside.warning,div.caution,div.note,div.warning,p.caution,p.note,p.warning{background-color:#f5f5f5;border-bottom:1px solid;border-top:1px solid;overflow:hidden;max-width:85%;padding:1em}aside.note,div.note,p.note{border-color:#36C}aside.caution,div.caution,p.caution{border-color:#FC3}aside.warning,div.warning,p.warning{border-color:#A03}aside.warning em,aside.warning strong,div.warning em,div.warning strong,p.warning em,p.warning strong{color:#A03}body,html{color:#777}.permalink{display:none;margin-left:5px}.has-permalink:hover .permalink{display:initial}.no-permalink .permalink{display:none!important}#gc-footer .links a{margin-right:20px}#gc-footer #cc-info{font-size:11.2px}#social-buttons{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center}#logo,#topnav{-webkit-box-align:center}#social-buttons>*{margin-left:10px}#social-buttons img{margin:-4px 0 0 1px}@media only screen and (max-width:580px){.more-section .g-last .g-content{padding-bottom:0;border:none}.more-section .g-content{border:1px solid #dbdbdb;border-width:0 0 1px;padding-bottom:20px;margin-bottom:20px}#gc-footer .links a{display:inline-block}}h2,h4,h5,h6{margin-bottom:0}#scroll-to-top,#send-feedback{border-bottom:none;bottom:0;position:fixed;z-index:5}#scroll-to-top{border-left:0;left:0}#send-feedback{border-right:0;right:0}html{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif}body{font-size:13px}h1,h2,h3,h4,h5,h6{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;font-weight:600;color:#000}h1,h2{font-weight:300}h1{font-size:2.625em;line-height:1.14286em}h2{font-size:1.875em;margin-top:1.6em}h3{font-size:1.125em;margin-top:1.33333em;margin-bottom:.53333em}h4{font-size:1.1em;line-height:1.36364em}h5,h6{font-size:1em;line-height:1.5em}p{margin:1.5em 0}p.caption p,p.noindent{text-indent:0}p.caption{text-align:left;margin-top:9px;font-weight:700}blockquote,cite{margin:.75em .8em}.lightbox p.caption{color:#fff}a:focus,a:hover,a:link:focus,a:link:hover,a:visited:focus,a:visited:hover,footer[role=contentinfo] a:focus,footer[role=contentinfo] a:hover,footer[role=contentinfo] a:link:focus,footer[role=contentinfo] a:link:hover,footer[role=contentinfo] a:visited:focus,footer[role=contentinfo] a:visited:hover{color:#39f}a,a:link,a:visited{color:#39c;font-weight:700;text-decoration:none;word-wrap:break-word}a.section-anchor{display:block;padding-top:3.33em}footer[role=contentinfo]{font-size:.84615385em}footer[role=contentinfo] a,footer[role=contentinfo] a:link,footer[role=contentinfo] a:visited{color:#999;font-weight:400;font-weight:600;text-decoration:none;word-wrap:break-word}table{font-size:13px}td dl{margin:.4em 0}td dt{margin:0 0 .4em}em{padding-right:2px}figcaption{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;color:#aaa}cite{color:#c3c3c3;font-style:normal}canvas{background:#fff;margin:1.5em 0}.code,code,pre{color:#080;font-family:"Source Code Pro",sans-serif}a>code{color:#39c}pre{margin:2em 0;word-wrap:break-word}pre[data-filename]::after{visibility:hidden;content:attr(data-filename);background-color:#aaa;color:#fff;padding:2px 12px;position:absolute;right:0;top:0}.static-code-container{line-height:1em;clear:both}code,kbd,samp{margin:1.5em 0;line-height:1em}.item-list ul,dl,menu,ol,ul{margin:.8em 0}ul{padding-left:1.28em}ol{padding-left:1.52em}hr{height:1px;border:0;border-bottom:1px solid #dbdbdb;margin:1.5em 0}[data-list-item]{display:list-item}.kbd{background-color:#f7f7f7;border:1px solid #ccc;color:#333;font-size:11px;line-height:1.4;text-shadow:0 1px 0 #fff;font-family:Arial,Helvetica,sans-serif;display:inline-block;padding:.1em .6em;margin:0 .1em;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 2px #fff inset;border-radius:3px}#fatnav,#logo,#logo a,#topnav{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex}#topnav{display:flex;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;height:64px}#logo{display:flex;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;user-select:none}#logo a{display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;color:#828282;font-size:2em;font-weight:400;letter-spacing:-1px}#logo a img{margin-bottom:-4px;height:40px;width:123px}#logo .collase-icon{display:none;background:url(../../images/burger-icon.png) 50% 100% no-repeat;background-size:cover;width:20px;height:20px}#logo .collase-icon.active{background-position:50% 0}#logo_google_dev{max-height:180px;margin:auto}#fatnav{height:100%;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#fatnav>ul{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:0;margin:0}#fatnav .toplevel{color:#aaa;font-weight:600;-webkit-user-select:none;-moz-user-select:none;user-select:none}#fatnav .toplevel::after{content:'';background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPJJREFUeNpiyc/Pn8XAwDATiM8yEAaMQBwBxHxMQMIdiE8D8Vog1sGjyQGqbhkQK4A0PoKaFATEF4F4MRCrImnQBuJtQLwfiI2hYk9AGl2AuB2I/wAxiB8DxNeAeA4QzwXiS0DsCdXwHIj9gHgqSOFPIK4CYksgvgJVwALEyUCcBDWMAeoSkO2bGZAEQeAM1CmtUNth4BkQ+wJxHBC/hwkyoQXALyCuAWILIL4MxIugAbYFI3iNZ54BR4fNtcXo0QEy9B+ywBGtWMzoAAquBWLk6EDXhBIdLNDokINGRwBQAUiiCYhvI0VHN1LIjpjoAAgwAMoSTlKlzAY4AAAAAElFTkSuQmCC) no-repeat;background-size:9px;display:inline-block;height:5px;width:14px;margin-left:10px;margin-bottom:2px}#fatnav .expandee a.highlight,#fatnav .expandee a:hover,#fatnav .expandee li.submenu.active{background-image:linear-gradient(205deg,rgba(229,229,229,.7) 0,rgba(233,233,233,.7) 20%,rgba(244,244,244,.7) 100%)}#fatnav .pillar{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;padding:0 20px;cursor:pointer;z-index:1002}#fatnav .expandee{display:none;position:absolute;z-index:1001;left:0;width:100%;box-sizing:border-box;background-color:#f5f5f5;padding:20px 0;cursor:initial;margin:0}#fatnav .expandee a{font-weight:600;padding:.5em 0;display:block;color:#828282}#fatnav .expandee a.highlight{color:#000}#fatnav .expandee li.submenu{color:#333;font-size:1.1em;font-weight:700;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#fatnav .expandee li.submenu>ul{font-size:.8em;padding:15px 0 0;margin:0}#fatnav .expandee li.submenu .category{border-bottom:1px solid #e8e8e8}#fatnav .expandee li.submenu .category:last-child{border:none}#fatnav .expandee li.submenu .category a{overflow:hidden;text-overflow:ellipsis}#fatnav .expandee li.submenu .category>ul{display:none}#fatnav .expandee li.submenu .category ul{padding:0}#search{display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex;-webkit-align-self:stretch;-moz-align-self:stretch;-ms-align-self:stretch;-o-align-self:stretch;align-self:stretch;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;width:auto;padding:0 20px;cursor:pointer}#search img{height:16px;width:16px;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#search .expandee{padding:20px}#search .expandee input[type=search]{width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;background:url(../../images/search.png) 15px 55% no-repeat #fff;background-size:20px;border:1px solid #dbdbdb;padding:10px 10px 10px 40px;font-size:1.4em;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;font-family:inherit;font-weight:300}@media only screen and (min-width:580px){#topnav{padding:15px 0 0}#fatnav .pillar.highlight .toplevel{color:#000}#fatnav .pillar.active{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) right 0 no-repeat #f5f5f5}#fatnav .pillar.active .toplevel::after{background-position:0 -5px}#fatnav .pillar.active .expandee{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-orient:vertical;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row}#fatnav .pillar.active .expandee::after{position:absolute;background-image:linear-gradient(to top,rgba(255,255,255,0) 0,rgba(211,211,211,.5) 25%,#d3d3d3 50%,rgba(211,211,211,.5) 75%,rgba(255,255,255,0) 100%);right:0;top:0;content:'';width:1px!important;height:100%}#fatnav .pillar .expandee{min-height:400px;font-size:.9em;box-shadow:0 3px 4px rgba(0,0,0,.12);top:64px}#fatnav .pillar .expandee .submenu{padding:0 20px;border-right:1px solid #e8e8e8}#fatnav .pillar .expandee .submenu:last-child{border:none}#search{margin-right:-4px}#search.active{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) right 0 no-repeat #f5f5f5}#search.active .expandee{display:block;top:64px}}@media only screen and (max-width:580px){#fatnav .pillar,#fatnav>ul,#topnav{-webkit-box-orient:vertical}#topnav{-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;height:auto}#fatnav{width:100%;max-height:0;overflow:hidden;background:#f5f5f5}#fatnav.active{max-height:5000px}#fatnav>ul{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}#fatnav .toplevel{width:100%;height:50px;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-pack:1;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;justify-content:center;display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex}#fatnav .pillar.active .expandee,#logo .collase-icon{display:initial}#fatnav .pillar{-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;padding:0;border-bottom:1px solid #dbdbdb}#fatnav .expandee{position:relative;padding:0;background-color:rgba(229,229,229,.7)}#fatnav .expandee li.submenu{padding:10px 15px}#fatnav .expandee li.submenu:not(:last-child){border-color:#ccc}#fatnav .expandee li.submenu>ul{background-color:inherit}#logo{height:50px;width:90%}#logo a{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#search{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-ordinal-group:-1;-webkit-order:-1;-moz-order:-1;-ms-order:-1;-o-order:-1;order:-1;padding:15px 15px 0}#search img{display:none}#search .expandee{display:block}}#gc-pagecontent .g-section h1,#gc-pagecontent .g-section h2,#gc-pagecontent .g-section h3{margin:0}#featured .screenshot,#upcoming-events .screenshot{margin-top:0}#upcoming-events article{border:1px solid #dbdbdb;border-width:0 0 1px;padding:20px 0}#upcoming-events article:first-child{padding-top:0}#upcoming-events article:last-child{padding-bottom:0;border:none}#site-sections{background-color:#f5f5f5;padding:20px;text-align:center}#site-sections h2{padding-top:20px}#site-sections h2::before{display:block;content:'';background:url(../../images/mocks/bucket_icons.png) 12px 50% no-repeat;width:100px;height:65px;background-size:cover;margin:auto auto 20px}#site-sections h2.multidevice::before{background-position:-91px 50%}#site-sections h2.platform::before{background-position:-194px 50%}#developer-news{margin-top:4em}#developer-news .g-content{margin-right:20px}#developer-news h1{margin-bottom:40px!important}@media only screen and (min-width:580px){#featured{padding-right:30px;padding-bottom:10px;border:1px solid #dbdbdb;border-width:0 1px 0 0}#featured img{margin-bottom:20px}}.inline-toc .toc .toc li,.pillar-content>.g-section:not(:last-of-type){border-bottom:1px solid #dbdbdb}.pillar-content h1{font-size:42px}.pillar-content>.g-section{padding:3em 0}.pillar-content>.g-section>h2{font-size:30px;margin-bottom:1.5em!important}.pillar-content .article-list article{position:relative;overflow:hidden;width:100%;padding:1.9em;background-color:#f5f5f5;box-shadow:0 2px 4px rgba(0,0,0,.15),0 0 3px rgba(0,0,0,.15);line-height:1.5em;margin-bottom:1.5em}.inline-site-toc,.inline-toc{line-height:1.3em}.pillar-content .article-list article.new::after{content:'new';background:#2e82c9;position:absolute;-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg);top:-4px;right:-20px;color:#fff;font-size:.9em;width:60px;text-align:center;padding-top:8px}.pillar-content .article-list article p{font-weight:300}.pillar-content #further-resources .g-content h2::before{display:inline-block;content:'';background:url(../../images/further-resources-icons.svg) 0 50% no-repeat;width:50px;height:43px;background-size:cover;margin:auto auto 5px;vertical-align:middle}.pillar-content #further-resources .g-content h2.school::before{background-position:0 50%}.pillar-content #further-resources .g-content h2.chat::before{background-position:-54px 50%}.pillar-content #further-resources .g-content h2.puzzle::before{background-position:-108px 50%}@media only screen and (max-width:580px){.pillar-content>.g-section{padding:2em 0}}@media only screen and (min-width:580px){.pillar-content .article-list{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-flex-wrap:wrap;-moz-flex-wrap:wrap;-ms-flex-wrap:wrap;-o-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:1;-webkit-justify-content:space-between;-moz-justify-content:space-between;-ms-justify-content:space-between;-o-justify-content:space-between;justify-content:space-between;-webkit-box-align:stretch;-webkit-align-items:stretch;-moz-align-items:stretch;-ms-align-items:stretch;-o-align-items:stretch;align-items:stretch}.pillar-content .article-list article{-webkit-box-flex:auto;-webkit-flex:auto;-moz-flex:auto;-ms-flex:auto;-o-flex:auto;flex:auto;margin-right:1.5em;width:45%}.pillar-content .article-list article:last-of-type,.pillar-content .article-list article:nth-child(2n){margin-right:0}}@media only screen and (min-width:990px){.pillar-content .article-list article{width:30%}.pillar-content .article-list article:nth-child(2n){margin-right:1.5em}.pillar-content .article-list article:last-of-type,.pillar-content .article-list article:nth-child(3n){margin-right:0}}@supports not (flex-wrap:wrap){.pillar-content .article-list{display:block}@media only screen and (min-width:580px){.pillar-content .article-list article{flex:none;float:left;width:48%}}@media only screen and (min-width:990px){.pillar-content .article-list article{width:31.8058%}}}.load-more-articles{overflow:hidden;margin:2em auto .3em;text-align:center;width:100%}.inline-site-toc .site-related h3,.inline-toc .related h3{margin-top:0}.load-more-articles a,.load-more-articles a:hover{color:#000;transition:opacity .3s ease 0s}.nav-arrow{background:top center no-repeat;display:inline-block;opacity:.5;padding-top:50px}.nav-arrow:hover{opacity:1}.down-arrow{background-image:url(../../images/down-arrow.png)}.inline-site-toc a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:.5em 0}.inline-site-toc a,.inline-site-toc a:link,.inline-site-toc a:visited{color:#aaa;font-weight:400}.inline-site-toc a:focus,.inline-site-toc a:hover,.inline-site-toc a:link:focus,.inline-site-toc a:link:hover,.inline-site-toc a:visited:focus,.inline-site-toc a:visited:hover{color:#000}.inline-site-toc span .show{display:block;content:"+ or -"}.inline-site-toc li{display:none}.inline-site-toc li .show{display:block;content:"+ or -"}.inline-site-toc li.show,.inline-site-toc li.show>ol>li{display:block}.inline-site-toc li.toplevel span{display:none}.inline-site-toc #toc,.inline-site-toc #toc .toplevel.active .toc,.inline-site-toc li li.selected li{display:block}.inline-site-toc li.toplevel li{padding-left:1em}.inline-site-toc li.toplevel>ol.toc>li{font-size:15px;margin:0;padding:15px 1em;border-bottom:1px solid #dbdbdb}.inline-site-toc li.toplevel>ol>li{cursor:default}.inline-site-toc li.toplevel>ol>li.show{background-color:#f0f0f0}.inline-site-toc li.toplevel>ol>li>ol>li:first-child{padding-top:10px}.inline-site-toc li li a,.inline-site-toc li li a:link,.inline-site-toc li li a:visited{color:#aaa}.inline-site-toc li li a:focus,.inline-site-toc li li a:hover,.inline-site-toc li li a:link:focus,.inline-site-toc li li a:link:hover,.inline-site-toc li li a:visited:focus,.inline-site-toc li li a:visited:hover{color:#000}.inline-site-toc li li.selected>a{font-weight:700;color:#000}.inline-site-toc .site-related{display:block;background-color:#f5f5f5;padding:0;width:inherit}.inline-site-toc .site-related li a.active{color:#000}.inline-site-toc #toc .toplevel>a{font-weight:700;color:#000}.inline-site-toc #toc .toplevel>a.hastoc::after{content:'+';-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;text-align:right}.inline-site-toc #toc .toplevel.active>a.hastoc::after{content:""}.inline-site-toc .toc{margin:0;padding:0}.inline-site-toc .toc .toc li{font-size:13px}.inline-site-toc ol.toc ol.toc ol.toc li{margin:0}.inline-toc a,.inline-toc a:link,.inline-toc a:visited{color:#aaa;font-weight:400}.demo td.name,.demo th.name,dl.nice dt{font-weight:700}.inline-toc a:focus,.inline-toc a:hover,.inline-toc a:link:focus,.inline-toc a:link:hover,.inline-toc a:visited:focus,.inline-toc a:visited:hover{color:#000}.inline-toc li li a,.inline-toc li li a:link,.inline-toc li li a:visited{color:#aaa}.inline-toc .related li a.active,.inline-toc li li a:focus,.inline-toc li li a:hover,.inline-toc li li a:link:focus,.inline-toc li li a:link:hover,.inline-toc li li a:visited:focus,.inline-toc li li a:visited:hover{color:#000}.inline-toc a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:.5em 0}.inline-toc .related{display:block;background-color:#f5f5f5;box-shadow:0 3px 4px rgba(0,0,0,.12);padding:1em 1em .5em;margin-bottom:1em}.inline-toc .related li a:hover{background-image:linear-gradient(205deg,rgba(229,229,229,.7) 0,rgba(233,233,233,.7) 20%,rgba(244,244,244,.7) 100%)}.inline-toc #toc{display:none}.inline-toc #toc .toplevel>a{font-weight:700;color:#000}.inline-toc #toc .toplevel>a.hastoc::after{content:'+';-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;text-align:right}.inline-toc #toc .toplevel.active .toc{display:block}.inline-toc #toc .toplevel.active>a.hastoc{content:"-"}.inline-toc .toc{margin:0;paddiing:0;border-top:1px solid #dbdbdb}.inline-toc .toc .toc{display:none}.inline-toc .toc .toc li{padding-left:1em}#cc-info{font-style:italic;font-size:.8em;color:#848484}#cc-info .cc-logo img{width:90px;height:32px}.h1-step{display:block;font-size:.5em;line-height:150%}.anchor-link-icon{padding-left:1px}@media only screen and (min-width:580px){.inline-site-toc{float:left;width:175px;overflow-x:hidden}.inline-toc{width:20%;float:right;margin:0 4% 20px;overflow:auto;overflow-x:hidden}.inline-toc #toc{display:block}.article-content{border-right:1px solid #f5f5f5;min-height:750px}.article-content [itemprop=articleBody]{margin-left:195px}.cc-logo{margin:0 0 0 auto}}@media only screen and (min-width:581px) and (max-width:990px){.inline-toc{width:-20%}.inline-site-toc{float:left;width:175px;overflow-x:hidden}}@media only screen and (max-width:580px){.article-content [itemprop=articleBody]>.collapsible{height:58px;overflow:hidden}.article-content [itemprop=articleBody]>.collapsible.active{height:auto}.article-content [itemprop=articleBody]>.collapsible.active h2::before{content:'-'}.article-content [itemprop=articleBody]>.collapsible h2{position:relative;margin:0;padding:15px 15px 15px 0;border-top:1px solid #dbdbdb;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.article-content [itemprop=articleBody]>.collapsible h2::before{position:absolute;right:0;content:'+'}.article-content [itemprop=articleBody] .related{margin:20px 0}.hidden{display:none}}dl.nice:after,dl.nice:before{display:table;content:" "}dl.nice:after{clear:both}dl.nice dt{float:left;width:160px;clear:left}dl.nice dt.full-width{width:100%}dl.nice dd{margin:0 0 15px 180px}@media (max-width:580px){dl.nice dd,dl.nice dt{width:100%}dl.nice dd{margin-left:0}}.api{color:#333;font-size:14px}.api .api-summary td,.api .api-summary th{padding:5px 10px}.api .api-reference .description{margin-left:20px}.api .api-reference table .innerTable{margin:10px 0}.api .api-reference table .innerTable td,.api .api-reference table .innerTable th{padding:5px 10px;border:1px solid #eee}.api .api-reference table .innerTable th{background:0 0}.api .api-reference table p{margin-top:.75em;margin-bottom:.75em}.api .api-reference table p:first-child{margin-top:0}.api .api-reference td,.api .api-reference th{vertical-align:top;border:1px solid #eee}.api .api-reference th{background:#fafafa}.api .api-reference h2{background-color:#e8e8e8;padding:20px;margin-left:-20px;margin-right:-20px}.api .api-reference h3{margin-top:3em}.api .availability{color:#A03}.demo *{box-sizing:border-box;webkit-box-sizing:border-box}.demo div{flex:1 1 auto}.demo div .panel-info{border-top:1px solid #ccc;margin-top:20px;padding-top:20px}.demo div.Demo-body{border:1px solid #dfdfdf;display:flex;flex-direction:column;padding:10px;position:relative}.demo td,.demo th,.demo tr{border:none}.demo div.Demo-body embed{display:block;flex:1 1 auto}.demo div.Demo-content,.demo div.intro{display:flex;flex-direction:column}.demo header{padding:0}.demo .intro{max-width:360px;padding-right:40px}.demo p{margin:0 0 1em}.demo p.note{background:0 0;border:none;padding:0;width:100%}.demo section{display:flex;flex:1 1 auto;flex-direction:row;padding:0 25px 25px 0} + */#fatnav li,nav ol,nav ul{list-style:none}img,legend{border:0}*,legend{padding:0}main,sub,sup{position:relative}html,table{line-height:1.5em}b,strong,table caption,th{font-weight:700}figure img,td,th{border:1px solid #dbdbdb}mark,pre b{background:#ff0}.published,dfn{font-style:italic}#fatnav .toplevel,#logo{-o-user-select:none;-ms-user-select:none}.nav-arrow,a,a:link,a:visited{transition:opacity .3s ease 0s}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}body,figure,form{margin:0}a{background:0 0}a:focus{outline:dotted thin}a:active,a:hover{outline:0}p,pre{margin:1.5em 0}h1{margin-top:.75em;margin-bottom:.75em}abbr[title]{border-bottom:1px dotted}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}mark{color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}img{-ms-interpolation-mode:bicubic;max-width:100%;vertical-align:middle}svg:not(:root){overflow:hidden}fieldset{margin:0 2px;border-color:silver;border-width:.0625em;border-style:solid;padding:.4625em .875em .9125em}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;vertical-align:baseline}button,input{line-height:normal}button,select{text-transform:none}#fatnav .toplevel,.label{text-transform:uppercase}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}#fatnav .expandee,*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-size:100%}.g-section:after{content:".";display:block;height:0;clear:both;visibility:hidden}.g-unit .g-section:after{clear:none}.g-unit .g-section{width:100%;overflow:hidden}.g-section,.g-unit{zoom:1}.g-split>.g-unit{float:right;text-align:right}.g-split>.g-first{float:left;text-align:left}.g-tpl-160 .g-unit,.g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit{display:block;margin:0 0 0 160px;width:auto;float:none}.g-tpl-160 .g-first,.g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first{display:block;margin:0;width:160px;float:left}.g-tpl-25-75 .g-unit,.g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit{width:74.999%;float:right;display:inline;margin:0}.g-tpl-25-75 .g-first,.g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first{width:24.999%;float:left;display:inline;margin:0}.g-tpl-75-25 .g-unit,.g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit{width:24.999%;float:right;display:inline;margin:0}.g-tpl-75-25 .g-first,.g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first{width:74.999%;float:left;display:inline;margin:0}.g-tpl-33-67 .g-unit,.g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit{width:66.999%;float:right;display:inline;margin:0}.g-tpl-33-67 .g-first,.g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first{width:32.999%;float:left;display:inline;margin:0}.g-tpl-67-33 .g-unit,.g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit{width:32.999%;float:right;display:inline;margin:0}.g-tpl-67-33 .g-first,.g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first{width:66.999%;float:left;display:inline;margin:0}.g-tpl-50-50 .g-unit,.g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit{width:49.999%;float:right;display:inline;margin:0}.g-tpl-50-50 .g-first,.g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first{width:49.999%;float:left;display:inline;margin:0}.g-tpl-nest .g-unit{float:left;width:auto;display:inline;margin:0}.g-tpl-nest-alt .g-unit{float:right;width:auto;display:inline;margin:0}.g-content{margin-right:30px}.g-last .g-content{margin-right:0}@media only screen and (max-width:580px){.g-unit.g-unit{float:none!important}.g-content{margin-right:0}}*{margin:0;box-sizing:border-box}body{overflow:auto}.gc-container{max-width:870px;margin:auto;width:90%}#gc-pagecontent>.g-section{margin:40px 0}main{margin-bottom:50px}footer[role=contentinfo]{padding:40px 0 50px}@media only screen and (max-width:580px){.gc-container{width:auto}#gc-pagecontent{margin:auto;width:90%}#gc-pagecontent>.g-section{margin:20px 0}footer[role=contentinfo]{padding:20px 30px}}@media only screen and (min-width:581px) and (max-width:990px){.gc-container{width:95%}}figure{margin:20px 0}table{border-spacing:0;width:100%;border-collapse:collapse;margin:2em 0}table caption{margin-bottom:1em;text-align:left}th{background:#e8e8e8}tr{border-bottom:1px solid #dbdbdb}table+tr{border-top:1px solid #dbdbdb}td,th{padding:1em 1.5em;text-align:left}pre{background-color:#f7f7f7;box-shadow:0 2px 4px rgba(0,0,0,.15),0 0 3px rgba(0,0,0,.15);padding:.99em;overflow-x:auto;white-space:pre;font-size:.95em;line-height:1.8em}#fatnav,#fatnav .expandee li,.api table#intro .title,.google-button,.kbd{white-space:nowrap}pre a{text-decoration:underline!important}pre b{font-weight:400}pre strike{text-decoration:none;background-image:linear-gradient(rgba(0,0,0,0) 7px,#cc1f1f 7px,#cc1f1f 9px,rgba(0,0,0,0) 9px)}pre[data-filename]:hover::after{visibility:visible}.element-invisible{position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.hidden{display:none}.button,.button-alt{display:inline-block;font-weight:700;text-decoration:none!important;text-align:center}.label{color:inherit;margin-bottom:5px;font-size:11.2px;font-weight:700}.published{font-size:11.2px;color:#bebebe;line-height:16.8px}.description{margin:20px 0}.description:last-child{margin-bottom:0}#gc-footer{background:#f5f5f5}.button{background:#0370ea;background-image:linear-gradient(to bottom,#008dfd 0,#0370ea 100%);border:1px solid #076bd2;border-radius:3px;color:#fff!important;font-size:13px;line-height:1.3;padding:5px 20px;text-shadow:1px 1px 1px #076bd2}.button:hover{background-image:linear-gradient(to bottom,#008dfd 30%,#0370ea 100%);cursor:pointer}.button a{color:inherit!important}.button-alt{background:#eee;background-image:linear-gradient(to top,#dcdcdc 46%,#fafafa 87%);border:1px solid #d6d6d6;border-radius:3px;color:#333!important;font-size:12px;line-height:24px;padding:0 15px;text-shadow:none}h2,h3{line-height:1.12em}.button-alt:hover{background-image:linear-gradient(to top,#dcdcdc 20%,#fafafa 87%);cursor:pointer}.google-button{background-color:#f5f5f5;border-radius:2px 0 0;border:1px solid rgba(0,0,0,.1);padding:5px 12px;text-align:center}.google-button:hover{border-color:#c6c6c6;box-shadow:0 -1px 1px rgba(0,0,0,.1)}.google-button:active{background-color:#f1f1f1;box-shadow:inset 0 0 2px rgba(0,0,0,.2)}.screenshot,.screenshot img{margin:1em 0}.video-container{position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden;margin:0 0 20px}h1+h1,h4,h5,h6{margin-top:0}.video-container embed,.video-container iframe,.video-container object{position:absolute;top:0;left:0;width:100%;height:100%}#topnav,pre{position:relative}aside.caution,aside.note,aside.warning,div.caution,div.note,div.warning,p.caution,p.note,p.warning{background-color:#f5f5f5;border-bottom:1px solid;border-top:1px solid;overflow:hidden;max-width:85%;padding:1em}aside.note,div.note,p.note{border-color:#36C}aside.caution,div.caution,p.caution{border-color:#FC3}aside.warning,div.warning,p.warning{border-color:#A03}aside.warning em,aside.warning strong,div.warning em,div.warning strong,p.warning em,p.warning strong{color:#A03}body,html{color:#777}.permalink{display:none;margin-left:5px}.has-permalink:hover .permalink{display:initial}.no-permalink .permalink{display:none!important}#gc-footer .links a{margin-right:20px}#gc-footer #cc-info{font-size:11.2px}#social-buttons{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center}#logo,#topnav{-webkit-box-align:center}#social-buttons>*{margin-left:10px}#social-buttons img{margin:-4px 0 0 1px}@media only screen and (max-width:580px){.more-section .g-last .g-content{padding-bottom:0;border:none}.more-section .g-content{border:1px solid #dbdbdb;border-width:0 0 1px;padding-bottom:20px;margin-bottom:20px}#gc-footer .links a{display:inline-block}}h2,h4,h5,h6{margin-bottom:0}#scroll-to-top,#send-feedback{border-bottom:none;bottom:0;position:fixed;z-index:5}#scroll-to-top{border-left:0;left:0}#send-feedback{border-right:0;right:0}html{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif}body{font-size:13px}h1,h2,h3,h4,h5,h6{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;font-weight:600;color:#000}h1,h2{font-weight:300}h1{font-size:2.625em;line-height:1.14286em}h2{font-size:1.875em;margin-top:1.6em}h3{font-size:1.125em;margin-top:1.33333em;margin-bottom:.53333em}h4{font-size:1.1em;line-height:1.36364em}h5,h6{font-size:1em;line-height:1.5em}p{margin:1.5em 0}p.caption p,p.noindent{text-indent:0}p.caption{text-align:left;margin-top:9px;font-weight:700}blockquote,cite{margin:.75em .8em}.lightbox p.caption{color:#fff}a:focus,a:hover,a:link:focus,a:link:hover,a:visited:focus,a:visited:hover,footer[role=contentinfo] a:focus,footer[role=contentinfo] a:hover,footer[role=contentinfo] a:link:focus,footer[role=contentinfo] a:link:hover,footer[role=contentinfo] a:visited:focus,footer[role=contentinfo] a:visited:hover{color:#39f}a,a:link,a:visited{color:#39c;font-weight:700;text-decoration:none;word-wrap:break-word}a.section-anchor{display:block;padding-top:3.33em}footer[role=contentinfo]{font-size:.84615385em}footer[role=contentinfo] a,footer[role=contentinfo] a:link,footer[role=contentinfo] a:visited{color:#999;font-weight:400;font-weight:600;text-decoration:none;word-wrap:break-word}table{font-size:13px}td dl{margin:.4em 0}td dt{margin:0 0 .4em}em{padding-right:2px}figcaption{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;color:#aaa}cite{color:#c3c3c3;font-style:normal}canvas{background:#fff;margin:1.5em 0}.code,code,pre{color:#080;font-family:"Source Code Pro",sans-serif}a>code{color:#39c}pre{margin:2em 0;word-wrap:break-word}pre[data-filename]::after{visibility:hidden;content:attr(data-filename);background-color:#aaa;color:#fff;padding:2px 12px;position:absolute;right:0;top:0}.static-code-container{line-height:1em;clear:both}code,kbd,samp{margin:1.5em 0;line-height:1em}.item-list ul,dl,menu,ol,ul{margin:.8em 0}ul{padding-left:1.28em}ol{padding-left:1.52em}hr{height:1px;border:0;border-bottom:1px solid #dbdbdb;margin:1.5em 0}[data-list-item]{display:list-item}.kbd{background-color:#f7f7f7;border:1px solid #ccc;color:#333;font-size:11px;line-height:1.4;text-shadow:0 1px 0 #fff;font-family:Arial,Helvetica,sans-serif;display:inline-block;padding:.1em .6em;margin:0 .1em;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 2px #fff inset;border-radius:3px}#fatnav,#logo,#logo a,#topnav{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex}#topnav{display:flex;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;height:64px}#logo{display:flex;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;user-select:none}#logo a{display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;color:#828282;font-size:2em;font-weight:400;letter-spacing:-1px}#logo a img{margin-bottom:-4px;height:40px;width:123px}#logo .collase-icon{display:none;background:url(../../images/burger-icon.png) 50% 100% no-repeat;background-size:cover;width:20px;height:20px}#logo .collase-icon.active{background-position:50% 0}#logo_google_dev{max-height:180px;margin:auto}#fatnav{height:100%;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#fatnav>ul{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:0;margin:0}#fatnav .toplevel{color:#aaa;font-weight:600;-webkit-user-select:none;-moz-user-select:none;user-select:none}#fatnav .toplevel::after{content:'';background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPJJREFUeNpiyc/Pn8XAwDATiM8yEAaMQBwBxHxMQMIdiE8D8Vog1sGjyQGqbhkQK4A0PoKaFATEF4F4MRCrImnQBuJtQLwfiI2hYk9AGl2AuB2I/wAxiB8DxNeAeA4QzwXiS0DsCdXwHIj9gHgqSOFPIK4CYksgvgJVwALEyUCcBDWMAeoSkO2bGZAEQeAM1CmtUNth4BkQ+wJxHBC/hwkyoQXALyCuAWILIL4MxIugAbYFI3iNZ54BR4fNtcXo0QEy9B+ywBGtWMzoAAquBWLk6EDXhBIdLNDokINGRwBQAUiiCYhvI0VHN1LIjpjoAAgwAMoSTlKlzAY4AAAAAElFTkSuQmCC) no-repeat;background-size:9px;display:inline-block;height:5px;width:14px;margin-left:10px;margin-bottom:2px}#fatnav .expandee a.highlight,#fatnav .expandee a:hover,#fatnav .expandee li.submenu.active{background-image:linear-gradient(205deg,rgba(229,229,229,.7) 0,rgba(233,233,233,.7) 20%,rgba(244,244,244,.7) 100%)}#fatnav .pillar{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;padding:0 20px;cursor:pointer;z-index:1002}#fatnav .expandee{display:none;position:absolute;z-index:1001;left:0;width:100%;box-sizing:border-box;background-color:#f5f5f5;padding:20px 0;cursor:initial;margin:0}#fatnav .expandee a{font-weight:600;padding:.5em 0;display:block;color:#828282}#fatnav .expandee a.highlight{color:#000}#fatnav .expandee li.submenu{color:#333;font-size:1.1em;font-weight:700;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#fatnav .expandee li.submenu>ul{font-size:.8em;padding:15px 0 0;margin:0}#fatnav .expandee li.submenu .category{border-bottom:1px solid #e8e8e8}#fatnav .expandee li.submenu .category:last-child{border:none}#fatnav .expandee li.submenu .category a{overflow:hidden;text-overflow:ellipsis}#fatnav .expandee li.submenu .category>ul{display:none}#fatnav .expandee li.submenu .category ul{padding:0}#search{display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex;-webkit-align-self:stretch;-moz-align-self:stretch;-ms-align-self:stretch;-o-align-self:stretch;align-self:stretch;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;width:auto;padding:0 20px;cursor:pointer}#search img{height:16px;width:16px;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#search .expandee{padding:20px}#search .expandee input[type=search]{width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;background:url(../../images/search.png) 15px 55% no-repeat #fff;background-size:20px;border:1px solid #dbdbdb;padding:10px 10px 10px 40px;font-size:1.4em;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;font-family:inherit;font-weight:300}@media only screen and (min-width:580px){#topnav{padding:15px 0 0}#fatnav .pillar.highlight .toplevel{color:#000}#fatnav .pillar.active{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) right 0 no-repeat #f5f5f5}#fatnav .pillar.active .toplevel::after{background-position:0 -5px}#fatnav .pillar.active .expandee{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-orient:vertical;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row}#fatnav .pillar.active .expandee::after{position:absolute;background-image:linear-gradient(to top,rgba(255,255,255,0) 0,rgba(211,211,211,.5) 25%,#d3d3d3 50%,rgba(211,211,211,.5) 75%,rgba(255,255,255,0) 100%);right:0;top:0;content:'';width:1px!important;height:100%}#fatnav .pillar .expandee{font-size:.9em;box-shadow:0 3px 4px rgba(0,0,0,.12);top:64px}#fatnav .pillar .expandee .submenu{padding:0 20px;border-right:1px solid #e8e8e8}#fatnav .pillar .expandee .submenu:last-child{border:none}#search{margin-right:-4px}#search.active{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) right 0 no-repeat #f5f5f5}#search.active .expandee{display:block;top:64px}}@media only screen and (max-width:580px){#fatnav .pillar,#fatnav>ul,#topnav{-webkit-box-orient:vertical}#topnav{-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;height:auto}#fatnav{width:100%;max-height:0;overflow:hidden;background:#f5f5f5}#fatnav.active{max-height:5000px}#fatnav>ul{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}#fatnav .toplevel{width:100%;height:50px;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-pack:1;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;justify-content:center;display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex}#fatnav .pillar.active .expandee,#logo .collase-icon{display:initial}#fatnav .pillar{-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;padding:0;border-bottom:1px solid #dbdbdb}#fatnav .expandee{position:relative;padding:0;background-color:rgba(229,229,229,.7)}#fatnav .expandee li.submenu{padding:10px 15px}#fatnav .expandee li.submenu:not(:last-child){border-color:#ccc}#fatnav .expandee li.submenu>ul{background-color:inherit}#logo{height:50px;width:90%}#logo a{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#search{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-ordinal-group:-1;-webkit-order:-1;-moz-order:-1;-ms-order:-1;-o-order:-1;order:-1;padding:15px 15px 0}#search img{display:none}#search .expandee{display:block}}#gc-pagecontent .g-section h1,#gc-pagecontent .g-section h2,#gc-pagecontent .g-section h3{margin:0}#featured .screenshot,#upcoming-events .screenshot{margin-top:0}#upcoming-events article{border:1px solid #dbdbdb;border-width:0 0 1px;padding:20px 0}#upcoming-events article:first-child{padding-top:0}#upcoming-events article:last-child{padding-bottom:0;border:none}#site-sections{background-color:#f5f5f5;padding:20px;text-align:center}#site-sections h2{padding-top:20px}#site-sections h2::before{display:block;content:'';background:url(../../images/mocks/bucket_icons.png) 12px 50% no-repeat;width:100px;height:65px;background-size:cover;margin:auto auto 20px}#site-sections h2.multidevice::before{background-position:-91px 50%}#site-sections h2.platform::before{background-position:-194px 50%}#developer-news{margin-top:4em}#developer-news .g-content{margin-right:20px}#developer-news h1{margin-bottom:40px!important}@media only screen and (min-width:580px){#featured{padding-right:30px;padding-bottom:10px;border:1px solid #dbdbdb;border-width:0 1px 0 0}#featured img{margin-bottom:20px}}.inline-toc .toc .toc li,.pillar-content>.g-section:not(:last-of-type){border-bottom:1px solid #dbdbdb}.pillar-content h1{font-size:42px}.pillar-content>.g-section{padding:3em 0}.pillar-content>.g-section>h2{font-size:30px;margin-bottom:1.5em!important}.pillar-content .article-list article{position:relative;overflow:hidden;width:100%;padding:1.9em;background-color:#f5f5f5;box-shadow:0 2px 4px rgba(0,0,0,.15),0 0 3px rgba(0,0,0,.15);line-height:1.5em;margin-bottom:1.5em}.inline-site-toc,.inline-toc{line-height:1.3em}.pillar-content .article-list article.new::after{content:'new';background:#2e82c9;position:absolute;-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg);top:-4px;right:-20px;color:#fff;font-size:.9em;width:60px;text-align:center;padding-top:8px}.pillar-content .article-list article p{font-weight:300}.pillar-content #further-resources .g-content h2::before{display:inline-block;content:'';background:url(../../images/further-resources-icons.svg) 0 50% no-repeat;width:50px;height:43px;background-size:cover;margin:auto auto 5px;vertical-align:middle}.pillar-content #further-resources .g-content h2.school::before{background-position:0 50%}.pillar-content #further-resources .g-content h2.chat::before{background-position:-54px 50%}.pillar-content #further-resources .g-content h2.puzzle::before{background-position:-108px 50%}@media only screen and (max-width:580px){.pillar-content>.g-section{padding:2em 0}}@media only screen and (min-width:580px){.pillar-content .article-list{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-flex-wrap:wrap;-moz-flex-wrap:wrap;-ms-flex-wrap:wrap;-o-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:1;-webkit-justify-content:space-between;-moz-justify-content:space-between;-ms-justify-content:space-between;-o-justify-content:space-between;justify-content:space-between;-webkit-box-align:stretch;-webkit-align-items:stretch;-moz-align-items:stretch;-ms-align-items:stretch;-o-align-items:stretch;align-items:stretch}.pillar-content .article-list article{-webkit-box-flex:auto;-webkit-flex:auto;-moz-flex:auto;-ms-flex:auto;-o-flex:auto;flex:auto;margin-right:1.5em;width:45%}.pillar-content .article-list article:last-of-type,.pillar-content .article-list article:nth-child(2n){margin-right:0}}@media only screen and (min-width:990px){.pillar-content .article-list article{width:30%}.pillar-content .article-list article:nth-child(2n){margin-right:1.5em}.pillar-content .article-list article:last-of-type,.pillar-content .article-list article:nth-child(3n){margin-right:0}}@supports not (flex-wrap:wrap){.pillar-content .article-list{display:block}@media only screen and (min-width:580px){.pillar-content .article-list article{flex:none;float:left;width:48%}}@media only screen and (min-width:990px){.pillar-content .article-list article{width:31.8058%}}}.load-more-articles{overflow:hidden;margin:2em auto .3em;text-align:center;width:100%}.inline-site-toc .site-related h3,.inline-toc .related h3{margin-top:0}.load-more-articles a,.load-more-articles a:hover{color:#000;transition:opacity .3s ease 0s}.nav-arrow{background:top center no-repeat;display:inline-block;opacity:.5;padding-top:50px}.nav-arrow:hover{opacity:1}.down-arrow{background-image:url(../../images/down-arrow.png)}.inline-site-toc a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:.5em 0}.inline-site-toc a,.inline-site-toc a:link,.inline-site-toc a:visited{color:#aaa;font-weight:400}.inline-site-toc a:focus,.inline-site-toc a:hover,.inline-site-toc a:link:focus,.inline-site-toc a:link:hover,.inline-site-toc a:visited:focus,.inline-site-toc a:visited:hover{color:#000}.inline-site-toc span .show{display:block;content:"+ or -"}.inline-site-toc li{display:none}.inline-site-toc li .show{display:block;content:"+ or -"}.inline-site-toc li.show,.inline-site-toc li.show>ol>li{display:block}.inline-site-toc li.toplevel span{display:none}.inline-site-toc #toc,.inline-site-toc #toc .toplevel.active .toc,.inline-site-toc li li.selected li{display:block}.inline-site-toc li.toplevel li{padding-left:1em}.inline-site-toc li.toplevel>ol.toc>li{font-size:15px;margin:0;padding:15px 1em;border-bottom:1px solid #dbdbdb}.inline-site-toc li.toplevel>ol>li{cursor:default}.inline-site-toc li.toplevel>ol>li.show{background-color:#f0f0f0}.inline-site-toc li.toplevel>ol>li>ol>li:first-child{padding-top:10px}.inline-site-toc li li a,.inline-site-toc li li a:link,.inline-site-toc li li a:visited{color:#aaa}.inline-site-toc li li a:focus,.inline-site-toc li li a:hover,.inline-site-toc li li a:link:focus,.inline-site-toc li li a:link:hover,.inline-site-toc li li a:visited:focus,.inline-site-toc li li a:visited:hover{color:#000}.inline-site-toc li li.selected>a{font-weight:700;color:#000}.inline-site-toc .site-related{display:block;background-color:#f5f5f5;padding:0;width:inherit}.inline-site-toc .site-related li a.active{color:#000}.inline-site-toc #toc .toplevel>a{font-weight:700;color:#000}.inline-site-toc #toc .toplevel>a.hastoc::after{content:'+';-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;text-align:right}.inline-site-toc #toc .toplevel.active>a.hastoc::after{content:""}.inline-site-toc .toc{margin:0;padding:0}.inline-site-toc .toc .toc li{font-size:13px}.inline-site-toc ol.toc ol.toc ol.toc li{margin:0}.inline-toc a,.inline-toc a:link,.inline-toc a:visited{color:#aaa;font-weight:400}.demo td.name,.demo th.name,dl.nice dt{font-weight:700}.inline-toc a:focus,.inline-toc a:hover,.inline-toc a:link:focus,.inline-toc a:link:hover,.inline-toc a:visited:focus,.inline-toc a:visited:hover{color:#000}.inline-toc li li a,.inline-toc li li a:link,.inline-toc li li a:visited{color:#aaa}.inline-toc .related li a.active,.inline-toc li li a:focus,.inline-toc li li a:hover,.inline-toc li li a:link:focus,.inline-toc li li a:link:hover,.inline-toc li li a:visited:focus,.inline-toc li li a:visited:hover{color:#000}.inline-toc a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:.5em 0}.inline-toc .related{display:block;background-color:#f5f5f5;box-shadow:0 3px 4px rgba(0,0,0,.12);padding:1em 1em .5em;margin-bottom:1em}.inline-toc .related li a:hover{background-image:linear-gradient(205deg,rgba(229,229,229,.7) 0,rgba(233,233,233,.7) 20%,rgba(244,244,244,.7) 100%)}.inline-toc #toc{display:none}.inline-toc #toc .toplevel>a{font-weight:700;color:#000}.inline-toc #toc .toplevel>a.hastoc::after{content:'+';-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;text-align:right}.inline-toc #toc .toplevel.active .toc{display:block}.inline-toc #toc .toplevel.active>a.hastoc{content:"-"}.inline-toc .toc{margin:0;paddiing:0;border-top:1px solid #dbdbdb}.inline-toc .toc .toc{display:none}.inline-toc .toc .toc li{padding-left:1em}#cc-info{font-style:italic;font-size:.8em;color:#848484}#cc-info .cc-logo img{width:90px;height:32px}.h1-step{display:block;font-size:.5em;line-height:150%}.anchor-link-icon{padding-left:1px}@media only screen and (min-width:580px){.inline-site-toc{float:left;width:175px;overflow-x:hidden}.inline-toc{width:20%;float:right;margin:0 4% 20px;overflow:auto;overflow-x:hidden}.inline-toc #toc{display:block}.article-content{border-right:1px solid #f5f5f5;min-height:750px}.article-content [itemprop=articleBody]{margin-left:195px}.cc-logo{margin:0 0 0 auto}}@media only screen and (min-width:581px) and (max-width:990px){.inline-toc{width:-20%}.inline-site-toc{float:left;width:175px;overflow-x:hidden}}@media only screen and (max-width:580px){.article-content [itemprop=articleBody]>.collapsible{height:58px;overflow:hidden}.article-content [itemprop=articleBody]>.collapsible.active{height:auto}.article-content [itemprop=articleBody]>.collapsible.active h2::before{content:'-'}.article-content [itemprop=articleBody]>.collapsible h2{position:relative;margin:0;padding:15px 15px 15px 0;border-top:1px solid #dbdbdb;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.article-content [itemprop=articleBody]>.collapsible h2::before{position:absolute;right:0;content:'+'}.article-content [itemprop=articleBody] .related{margin:20px 0}.hidden{display:none}}dl.nice:after,dl.nice:before{display:table;content:" "}dl.nice:after{clear:both}dl.nice dt{float:left;width:160px;clear:left}dl.nice dt.full-width{width:100%}dl.nice dd{margin:0 0 15px 180px}@media (max-width:580px){dl.nice dd,dl.nice dt{width:100%}dl.nice dd{margin-left:0}}.api{color:#333;font-size:14px}.api .api-summary td,.api .api-summary th{padding:5px 10px}.api .api-reference .description{margin-left:20px}.api .api-reference table .innerTable{margin:10px 0}.api .api-reference table .innerTable td,.api .api-reference table .innerTable th{padding:5px 10px;border:1px solid #eee}.api .api-reference table .innerTable th{background:0 0}.api .api-reference table p{margin-top:.75em;margin-bottom:.75em}.api .api-reference table p:first-child{margin-top:0}.api .api-reference td,.api .api-reference th{vertical-align:top;border:1px solid #eee}.api .api-reference th{background:#fafafa}.api .api-reference h2{background-color:#e8e8e8;padding:20px;margin-left:-20px;margin-right:-20px}.api .api-reference h3{margin-top:3em}.api .availability{color:#A03}.demo *{box-sizing:border-box;webkit-box-sizing:border-box}.demo div{flex:1 1 auto}.demo div .panel-info{border-top:1px solid #ccc;margin-top:20px;padding-top:20px}.demo div.Demo-body{border:1px solid #dfdfdf;display:flex;flex-direction:column;padding:10px;position:relative}.demo td,.demo th,.demo tr{border:none}.demo div.Demo-body embed{display:block;flex:1 1 auto}.demo div.Demo-content,.demo div.intro{display:flex;flex-direction:column}.demo header{padding:0}.demo .intro{max-width:360px;padding-right:40px}.demo p{margin:0 0 1em}.demo p.note{background:0 0;border:none;padding:0;width:100%}.demo section{display:flex;flex:1 1 auto;flex-direction:row;padding:0 25px 25px 0}
diff --git a/chrome/common/extensions/docs/templates/articles/api_index.html b/chrome/common/extensions/docs/templates/articles/api_index.html index 468cd879..79c01d4 100644 --- a/chrome/common/extensions/docs/templates/articles/api_index.html +++ b/chrome/common/extensions/docs/templates/articles/api_index.html
@@ -1,4 +1,5 @@ -<h1 class="page_title">JavaScript APIs</h1> +<h1 class="page_title">Chrome APIs</h1> + <p class="doc-family apps"> Chrome provides {{platform}}s with many special-purpose APIs like <code>chrome.runtime</code> and <code>chrome.alarms</code>. @@ -6,6 +7,7 @@ {{?stable_apis}} <h2 id="stable_apis">Stable APIs</h2> + <p> {{+partials.api_table apis:stable_apis is_stable:true/}} </p>
diff --git a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json index 52f4062..8c607a4 100644 --- a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json +++ b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
@@ -4,7 +4,7 @@ "href": "/extensions", "items": [ { - "title": "Learn Extension Basics", + "title": "Extend the Browser", "href": "/extensions", "items": [ { @@ -28,18 +28,28 @@ "href": "/extensions/background_pages" }, { - "title": "Content Scripts", - "href": "/extensions/content_scripts" - }, - { "title": "Design User Interface", "href": "/extensions/user_interface" }, { + "title": "Content Scripts", + "href": "/extensions/content_scripts" + }, + { "title": "Declare Permissions and Warn Users", "href": "/extensions/permission_warnings" }, { + "title": "Give Users Options", + "href": "/extensions/options" + } + ] + }, + { + "title": "Developer Guide", + "href": "/extensions/devguide", + "items": [ + { "title": "Reach Peak Performance", "href": "/extensions/performance" }, @@ -52,16 +62,52 @@ "href": "/extensions/security" }, { + "title": "Debugging", + "href": "/extensions/tut_debugging" + }, + { "title": "OAuth", "href": "/extensions/tut_oauth" }, { - "title": "Give Users Options", - "href": "/extensions/options" + "title": "Accessibility", + "href": "/extensions/a11y" + }, + { + "title": "Content Security Policy", + "href": "/extensions/contentSecurityPolicy" + }, + { + "title": "Cross-Origin XHR", + "href": "/extensions/xhr" + }, + { + "title": "Internationalization", + "href": "/extensions/i18n" + }, + { + "title": "Message Passing", + "href": "/extensions/messaging" + }, + { + "title": "Native Messaging", + "href": "/extensions/nativeMessaging" + }, + { + "title": "Match Patterns", + "href": "/extensions/match_patterns" + }, + { + "title": "Extension Quality Guidelines FAQ", + "href": "/extensions/single_purpose" } ] }, { + "title": "Samples", + "href": "/extensions/samples" + }, + { "title": "Help", "href": "/extensions/faq", "items": [ @@ -86,85 +132,7 @@ ] }, { - "title": "Start Development", - "href": "/extensions/devguide", - "items": [ - { - "title": "Developer Guide", - "href": "/extensions/devguide", - "items": [ - { - "title": "Accessibility", - "href": "/extensions/a11y" - }, - { - "title": "Content Security Policy", - "href": "/extensions/contentSecurityPolicy" - }, - { - "title": "Cross-Origin XHR", - "href": "/extensions/xhr" - }, - { - "title": "Debugging", - "href": "/extensions/tut_debugging" - }, - { - "title": "Extension Quality Guidelines FAQ", - "href": "/extensions/single_purpose" - }, - { - "title": "Internationalization", - "href": "/extensions/i18n" - }, - { - "title": "Message Passing", - "href": "/extensions/messaging" - }, - { - "title": "Native Messaging", - "href": "/extensions/nativeMessaging" - }, - { - "title": "Migrate to Manifest 2", - "href": "/extensions/tut_migration_to_manifest_v2" - }, - { - "title": "Permission Warnings", - "href": "/extensions/permission_warnings" - }, - { - "title": "Optional Permissions", - "href": "/extensions/permissions" - }, - { - "title": "Match Patterns", - "href": "/extensions/match_patterns" - } - ] - }, - { - "title": "Chrome Platform APIs", - "href": "/extensions/api_index", - "items": [ - { - "title": "JavaScript APIs", - "href": "/extensions/api_index" - }, - { - "title": "Web APIs", - "href": "/extensions/api_other" - } - ] - }, - { - "title": "Samples", - "href": "/extensions/samples" - } - ] - }, - { - "title": "Publish and Distribute", + "title": "Web Store Publishing and Distribution", "href": "/webstore", "items": [ { @@ -176,36 +144,6 @@ "href": "/webstore" }, { - "title": "Hosting and Updating", - "href": "/extensions/hosting" - }, - { - "title": "Hosting Policy Changes", - "href": "/extensions/hosting_changes" - }, - { - "title": "One-Time Payments", - "href": "/webstore/one_time_payments" - }, - { - "title": "Google Analytics", - "href": "/extensions/tut_analytics" - }, - { - "title": "Publishing Themes", - "href": "/extensions/themes" - }, - { - "title": "Other Deployment Options", - "href": "/extensions/external_extensions" - } - ] - }, - { - "title": "Publish Extensions", - "href": "/webstore/about_webstore", - "items": [ - { "title": "What Is the Chrome Web Store?", "href": "/webstore/about_webstore" }, @@ -224,6 +162,32 @@ ] }, { + "title": "Publish Extensions", + "href": "/extensions/hosting", + "items": [ + { + "title": "Hosting and Updating", + "href": "/extensions/hosting" + }, + { + "title": "Hosting Policy Changes", + "href": "/extensions/hosting_changes" + }, + { + "title": "Google Analytics", + "href": "/extensions/tut_analytics" + }, + { + "title": "Publishing Themes", + "href": "/extensions/themes" + }, + { + "title": "Other Deployment Options", + "href": "/extensions/external_extensions" + } + ] + }, + { "title": "Monetizing", "href": "/webstore/money", "items": [ @@ -282,6 +246,96 @@ ] } ] + }, + { + "title": "Mobile Chrome", + "href": "/multidevice", + "items": [ + { + "title": "Chrome for a Multi-Device World", + "href": "/multidevice", + "items": [ + { + "title": "User Agents", + "href": "/multidevice/user-agent" + }, + { + "title": "Chrome Custom Tabs", + "href": "/multidevice/android/customtabs" + }, + { + "title": "Mobile Emulation", + "href": "/devtools/docs/mobile-emulation" + }, + { + "title": "Remote Debugging", + "href": "/devtools/docs/remote-debugging" + } + ] + }, + { + "title": "Chrome for Android", + "href": "/multidevice/android/overview", + "items": [ + { + "title": "Overview", + "href": "/multidevice/android/overview" + }, + { + "title": "Android Intents with Chrome", + "href": "/multidevice/android/intents" + }, + { + "title": "Chrome Custom Tabs", + "href": "/multidevice/android/customtabs" + } + ] + }, + { + "title": "Chrome WebView", + "href": "/multidevice/webview/overview", + "items": [ + { + "title": "WebView for Android", + "href": "/multidevice/webview/overview" + }, + { + "title": "Getting Started", + "href": "/multidevice/webview/gettingstarted" + }, + { + "title": "Pixel-Perfect UI", + "href": "/multidevice/webview/pixelperfect" + }, + { + "title": "WebView Workflow", + "href": "/multidevice/webview/workflow" + }, + { + "title": "Tips & Tricks", + "href": "/multidevice/webview/tipsandtricks" + } + ] + }, + { + "title": "Chrome for iOS", + "href": "/multidevice/ios/links", + "items": [ + { + "title": "Opening Links in Chrome", + "href": "/multidevice/ios/links" + }, + { + "title": "User Agent", + "href": "/multidevice/user-agent#chrome_for_ios_user_agent" + } + ] + }, + { + "title": "FAQ", + "href": "/multidevice/faq" + } + ] } ] }, @@ -470,13 +524,9 @@ }, { "title": "Chrome Platform APIs", - "href": "/apps/api_index", + "href": "/apps/manifest", "items": [ { - "title": "JavaScript APIs", - "href": "/apps/api_index" - }, - { "title": "Manifest File Format", "href": "/apps/manifest" }, @@ -757,97 +807,25 @@ ] }, { - "title": "Multi-device", + "title": "Chrome APIs", "items": [ { - "title": "Getting Started", - "href": "/multidevice", + "title": "Extensions APIs", + "href": "/extensions/api_index", "items": [ { - "title": "Chrome for a Multi-Device World", - "href": "/multidevice" - }, - { - "title": "Data Compression Proxy", - "href": "/multidevice/data-compression" - }, - { - "title": "User Agents", - "href": "/multidevice/user-agent" - }, - { - "title": "Mobile Emulation", - "href": "/devtools/docs/mobile-emulation" - }, - { - "title": "Remote Debugging", - "href": "/devtools/docs/remote-debugging" - }, - { - "title": "FAQ", - "href": "/multidevice/faq" + "title": "Extension APIs", + "href": "/extensions/api_index" } ] }, { - "title": "Chrome for Android", - "href": "/multidevice/android/overview", + "title": "Apps APIs", + "href": "/apps/api_index", "items": [ { - "title": "Overview", - "href": "/multidevice/android/overview" - }, - { - "title": "Android Intents with Chrome", - "href": "/multidevice/android/intents" - }, - { - "title": "Add to Homescreen", - "href": "/multidevice/android/installtohomescreen" - }, - { - "title": "Chrome Custom Tabs", - "href": "/multidevice/android/customtabs" - } - ] - }, - { - "title": "Chrome WebView", - "href": "/multidevice/webview/overview", - "items": [ - { - "title": "WebView for Android", - "href": "/multidevice/webview/overview" - }, - { - "title": "Getting Started", - "href": "/multidevice/webview/gettingstarted" - }, - { - "title": "Pixel-Perfect UI", - "href": "/multidevice/webview/pixelperfect" - }, - { - "title": "WebView Workflow", - "href": "/multidevice/webview/workflow" - }, - { - "title": "Tips & Tricks", - "href": "/multidevice/webview/tipsandtricks" - } - ] - }, - { - "title": "Chrome for iOS", - "href": "/multidevice/ios/links", - "items": [ - { - "title": "Opening Links in Chrome", - "href": "/multidevice/ios/links" - }, - { - "title": "User Agent", - "href": "/multidevice/user-agent#chrome_for_ios_user_agent" + "title": "Apps APIs", + "href": "/apps/api_index" } ] }
diff --git a/chrome/common/extensions/permissions/permissions_data_unittest.cc b/chrome/common/extensions/permissions/permissions_data_unittest.cc index c51fb487..e617d5b7 100644 --- a/chrome/common/extensions/permissions/permissions_data_unittest.cc +++ b/chrome/common/extensions/permissions/permissions_data_unittest.cc
@@ -1120,9 +1120,8 @@ // Normal web page. GURL("https://example.com"), - // TODO(https://crbug.com/853064): IPv6 pages should behave like normal - // web pages. - // GURL("http://[2607:f8b0:4005:805::200e]"), + // IPv6 pages should behave like normal web pages. + GURL("http://[2607:f8b0:4005:805::200e]"), // filesystem: urls with web origins should behave like normal web pages. // TODO(https://crbug.com/853392): filesystem: URLs don't work with
diff --git a/chrome/common/safe_browsing/archive_analyzer_results.h b/chrome/common/safe_browsing/archive_analyzer_results.h index b0c6e110..1a612fa3 100644 --- a/chrome/common/safe_browsing/archive_analyzer_results.h +++ b/chrome/common/safe_browsing/archive_analyzer_results.h
@@ -25,6 +25,9 @@ std::vector<base::FilePath> archived_archive_filenames; #if defined(OS_MACOSX) std::vector<uint8_t> signature_blob; + google::protobuf::RepeatedPtrField< + ClientDownloadRequest_DetachedCodeSignature> + detached_code_signatures; #endif // OS_MACOSX ArchiveAnalyzerResults(); ArchiveAnalyzerResults(const ArchiveAnalyzerResults& other);
diff --git a/chrome/common/win/BUILD.gn b/chrome/common/win/BUILD.gn index f6720139..1327f03 100644 --- a/chrome/common/win/BUILD.gn +++ b/chrome/common/win/BUILD.gn
@@ -8,6 +8,7 @@ message_compiler("eventlog_messages") { visibility = [ + "//chrome/chrome_watcher:chrome_watcher", "//chrome/common:common", ":eventlog_provider", ]
diff --git a/chrome/installer/linux/common/desktop.template b/chrome/installer/linux/common/desktop.template index ae19bdd..62f031c 100644 --- a/chrome/installer/linux/common/desktop.template +++ b/chrome/installer/linux/common/desktop.template
@@ -106,6 +106,7 @@ Comment[zh_HK]=連線到網際網路 Comment[zh_TW]=連線到網際網路 Exec=/usr/bin/@@USR_BIN_SYMLINK_NAME@@ %U +StartupNotify=true Terminal=false Icon=@@PACKAGE@@ Type=Application
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc index 864fc4b..443a4b01 100644 --- a/chrome/renderer/media/chrome_key_systems.cc +++ b/chrome/renderer/media/chrome_key_systems.cc
@@ -139,18 +139,24 @@ #if defined(WIDEVINE_CDM_AVAILABLE) static SupportedCodecs GetSupportedCodecs( - const std::vector<media::VideoCodec>& supported_video_codecs) { + const std::vector<media::VideoCodec>& supported_video_codecs, + bool is_secure) { SupportedCodecs supported_codecs = media::EME_CODEC_NONE; - // Audio codecs are always supported. + // Audio codecs are always supported because the CDM only does decrypt-only + // for audio. The only exception is when |is_secure| is true and there's no + // secure video decoder available, which is a signal that secure hardware + // decryption is not available either. // TODO(sandersd): Distinguish these from those that are directly supported, // as those may offer a higher level of protection. - supported_codecs |= media::EME_CODEC_WEBM_OPUS; - supported_codecs |= media::EME_CODEC_WEBM_VORBIS; - supported_codecs |= media::EME_CODEC_MP4_FLAC; + if (!supported_video_codecs.empty() || !is_secure) { + supported_codecs |= media::EME_CODEC_WEBM_OPUS; + supported_codecs |= media::EME_CODEC_WEBM_VORBIS; + supported_codecs |= media::EME_CODEC_MP4_FLAC; #if BUILDFLAG(USE_PROPRIETARY_CODECS) - supported_codecs |= media::EME_CODEC_MP4_AAC; + supported_codecs |= media::EME_CODEC_MP4_AAC; #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) + } // Video codecs are determined by what was registered for the CDM. for (const auto& codec : supported_video_codecs) { @@ -238,10 +244,11 @@ } // Codecs and encryption schemes. - auto supported_codecs = GetSupportedCodecs(capability->video_codecs); + auto supported_codecs = + GetSupportedCodecs(capability->video_codecs, /*is_secure=*/false); const auto& supported_encryption_schemes = capability->encryption_schemes; - auto supported_hw_secure_codecs = - GetSupportedCodecs(capability->hw_secure_video_codecs); + auto supported_hw_secure_codecs = GetSupportedCodecs( + capability->hw_secure_video_codecs, /*is_secure=*/true); // TODO(crbug.com/853261): Support capability->hw_secure_encryption_schemes // and pass it into WidevineKeySystemProperties.
diff --git a/chrome/renderer/pepper/pepper_flash_font_file_host.cc b/chrome/renderer/pepper/pepper_flash_font_file_host.cc index 07e5aee..4313c6a 100644 --- a/chrome/renderer/pepper/pepper_flash_font_file_host.cc +++ b/chrome/renderer/pepper/pepper_flash_font_file_host.cc
@@ -18,7 +18,7 @@ #include "content/public/child/child_process_sandbox_support_linux.h" #include "content/public/common/common_sandbox_support_linux.h" #elif defined(OS_WIN) -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #endif PepperFlashFontFileHost::PepperFlashFontFileHost(
diff --git a/chrome/services/file_util/public/cpp/sandboxed_dmg_analyzer_mac_unittest.cc b/chrome/services/file_util/public/cpp/sandboxed_dmg_analyzer_mac_unittest.cc index 5c61abc..4d230e2 100644 --- a/chrome/services/file_util/public/cpp/sandboxed_dmg_analyzer_mac_unittest.cc +++ b/chrome/services/file_util/public/cpp/sandboxed_dmg_analyzer_mac_unittest.cc
@@ -143,12 +143,20 @@ "2012CE4987B0FA4A5D285DF7E810560E841CFAB3054BC19E1AAB345F862A6C4E", actual_sha256); } else { - ADD_FAILURE() << "Unepxected result file " << binary.file_basename(); + ADD_FAILURE() << "Unexpected result file " << binary.file_basename(); } } EXPECT_TRUE(got_executable); EXPECT_TRUE(got_dylib); + + ASSERT_EQ(1, results.detached_code_signatures.size()); + const safe_browsing::ClientDownloadRequest_DetachedCodeSignature + detached_signature = results.detached_code_signatures.Get(0); + EXPECT_EQ( + "Mach-O in DMG/shell-script.app/Contents/_CodeSignature/CodeSignature", + detached_signature.file_name()); + EXPECT_EQ(1842u, detached_signature.contents().size()); } TEST_F(SandboxedDMGAnalyzerTest, AnalyzeDmgNoSignature) {
diff --git a/chrome/services/file_util/public/mojom/safe_archive_analyzer_param_traits.h b/chrome/services/file_util/public/mojom/safe_archive_analyzer_param_traits.h index 70e1cf399..b630a72 100644 --- a/chrome/services/file_util/public/mojom/safe_archive_analyzer_param_traits.h +++ b/chrome/services/file_util/public/mojom/safe_archive_analyzer_param_traits.h
@@ -86,6 +86,12 @@ IPC_PROTOBUF_MESSAGE_TRAITS_OPTIONAL_COMPLEX_MEMBER(image_headers) IPC_PROTOBUF_MESSAGE_TRAITS_END() +IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN( + safe_browsing::ClientDownloadRequest_DetachedCodeSignature) + IPC_PROTOBUF_MESSAGE_TRAITS_REPEATED_COMPLEX_MEMBER(file_name) + IPC_PROTOBUF_MESSAGE_TRAITS_REPEATED_COMPLEX_MEMBER(contents) +IPC_PROTOBUF_MESSAGE_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(safe_browsing::ArchiveAnalyzerResults) IPC_STRUCT_TRAITS_MEMBER(success) IPC_STRUCT_TRAITS_MEMBER(has_executable) @@ -94,5 +100,6 @@ IPC_STRUCT_TRAITS_MEMBER(archived_archive_filenames) #if defined(OS_MACOSX) IPC_STRUCT_TRAITS_MEMBER(signature_blob) + IPC_STRUCT_TRAITS_MEMBER(detached_code_signatures) #endif // OS_MACOSX IPC_STRUCT_TRAITS_END()
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 868b84f..b1845a63 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1414,6 +1414,7 @@ "../browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h", "../browser/ui/views/bookmarks/bookmark_bubble_view_browsertest.cc", "../browser/ui/views/bookmarks/bookmark_editor_view_browsertest.cc", + "../browser/ui/views/desktop_capture/desktop_media_picker_views_browsertest.cc", "../browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc", "../browser/ui/views/extensions/pwa_confirmation_view_browsertest.cc", "../browser/ui/views/external_protocol_dialog_browsertest.cc", @@ -1621,9 +1622,9 @@ "../browser/chromeos/login/screens/mock_eula_screen.h", "../browser/chromeos/login/screens/mock_wrong_hwid_screen.cc", "../browser/chromeos/login/screens/mock_wrong_hwid_screen.h", - "../browser/chromeos/login/screens/network_screen_browsertest.cc", "../browser/chromeos/login/screens/update_screen_browsertest.cc", "../browser/chromeos/login/screens/user_selection_screen_browsertest.cc", + "../browser/chromeos/login/screens/welcome_screen_browsertest.cc", "../browser/chromeos/login/session/chrome_session_manager_browsertest.cc", "../browser/chromeos/login/session_login_browsertest.cc", "../browser/chromeos/login/signin/device_id_browsertest.cc", @@ -2099,15 +2100,12 @@ data_deps += [ "//remoting/webapp" ] } - if (use_aura) { - sources += [ "../browser/ui/views/desktop_capture/desktop_media_picker_views_browsertest.cc" ] - if (enable_wifi_display) { - sources += [ - "../../extensions/browser/api/display_source/display_source_apitestbase.cc", - "../../extensions/browser/api/display_source/display_source_apitestbase.h", - "../browser/extensions/api/display_source/display_source_wifi_display_apitest.cc", - ] - } + if (use_aura && enable_wifi_display) { + sources += [ + "../../extensions/browser/api/display_source/display_source_apitestbase.cc", + "../../extensions/browser/api/display_source/display_source_apitestbase.h", + "../browser/extensions/api/display_source/display_source_wifi_display_apitest.cc", + ] } if (is_chromeos || (is_linux && use_dbus)) { @@ -4272,6 +4270,7 @@ "../browser/conflicts/module_list_filter_win_unittest.cc", "../browser/conflicts/module_load_attempt_log_listener_win_unittest.cc", "../browser/conflicts/registry_key_watcher_win_unittest.cc", + "../browser/conflicts/third_party_conflicts_manager_win_unittest.cc", "../browser/google/google_update_win_unittest.cc", ] } @@ -4350,6 +4349,7 @@ "../browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc", "../browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc", "../browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc", + "../browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc", "../browser/ui/views/device_chooser_content_view_unittest.cc", "../browser/ui/views/download/download_item_view_unittest.cc", "../browser/ui/views/extensions/chooser_dialog_view_unittest.cc", @@ -4391,7 +4391,6 @@ # Get these compiling on Mac - see http://crbug.com/657883. "../browser/ui/views/crypto_module_password_dialog_view_unittest.cc", - "../browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc", ] } }
diff --git a/chrome/test/android/OWNERS b/chrome/test/android/OWNERS index e62f3f88..dc71630 100644 --- a/chrome/test/android/OWNERS +++ b/chrome/test/android/OWNERS
@@ -1,7 +1,6 @@ bauerb@chromium.org dtrainor@chromium.org jbudorick@chromium.org -mariakhomenko@chromium.org nyquist@chromium.org skyostil@chromium.org tedchoc@chromium.org
diff --git a/chrome/test/base/OWNERS b/chrome/test/base/OWNERS index 3a93d4a..cf49573 100644 --- a/chrome/test/base/OWNERS +++ b/chrome/test/base/OWNERS
@@ -1,6 +1,9 @@ per-file js2gtest.*=dtseng@chromium.org per-file javascript_browser_test.*=dtseng@chromium.org +per-file *javascript*=file://ui/webui/PLATFORM_OWNERS +per-file *web_ui*=file://ui/webui/PLATFORM_OWNERS + per-file *tracing*=file://base/trace_event/OWNERS per-file interactive_test_utils_mac.mm=tapted@chromium.org
diff --git a/chrome/test/base/chrome_test_suite.cc b/chrome/test/base/chrome_test_suite.cc index e969d30..58d4c2b 100644 --- a/chrome/test/base/chrome_test_suite.cc +++ b/chrome/test/base/chrome_test_suite.cc
@@ -87,11 +87,11 @@ ChromeMainDelegate::kNonWildcardDomainNonPortSchemes, ChromeMainDelegate::kNonWildcardDomainNonPortSchemesSize); - // Desktop Identity Consistency (a.k.a. DICE) requires API keys to be - // configured as they are needed for regular web sign-in flows to Google. + // Desktop Identity Consistency (a.k.a. DICE) requires OAuth client to be + // configured as it is needed for regular web sign-in flows to Google. // Ignore this requiement for unit and browser tests to make sure that the // DICE feature gets the right test coverage. - AccountConsistencyModeManager::SetIgnoreMissingApiKeysForTesting(); + AccountConsistencyModeManager::SetIgnoreMissingOAuthClientForTesting(); #if defined(OS_MACOSX) // Look in the framework bundle for resources.
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc index 42fb125..f5d3d50 100644 --- a/chrome/test/chromedriver/server/chromedriver_server.cc +++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -77,20 +77,22 @@ ~HttpServer() override {} - int Start(uint16_t port, bool allow_remote, bool use_ipv4) { + bool Start(uint16_t port, bool allow_remote) { std::unique_ptr<net::ServerSocket> server_socket( new net::TCPServerSocket(NULL, net::NetLogSource())); - int status = use_ipv4 - ? ListenOnIPv4(server_socket.get(), port, allow_remote) - : ListenOnIPv6(server_socket.get(), port, allow_remote); - if (status != net::OK) { - VLOG(0) << "listen on " << (use_ipv4 ? "IPv4" : "IPv6") - << " failed with error " << net::ErrorToShortString(status); - return status; + if (ListenOnIPv4(server_socket.get(), port, allow_remote) != net::OK) { + // This will work on an IPv6-only host, but we will be IPv4-only on + // dual-stack hosts. + // TODO(samuong): change this to listen on both IPv4 and IPv6. + VLOG(0) << "listen on IPv4 failed, trying IPv6"; + if (ListenOnIPv6(server_socket.get(), port, allow_remote) != net::OK) { + VLOG(1) << "listen on both IPv4 and IPv6 failed, giving up"; + return false; + } } server_.reset(new net::HttpServer(std::move(server_socket), this)); net::IPEndPoint address; - return server_->GetLocalAddress(&address); + return server_->GetLocalAddress(&address) == net::OK; } // Overridden from net::HttpServer::Delegate: @@ -172,48 +174,24 @@ } base::LazyInstance<base::ThreadLocalPointer<HttpServer>>::DestructorAtExit - lazy_tls_server_ipv4 = LAZY_INSTANCE_INITIALIZER; -base::LazyInstance<base::ThreadLocalPointer<HttpServer>>::DestructorAtExit - lazy_tls_server_ipv6 = LAZY_INSTANCE_INITIALIZER; + lazy_tls_server = LAZY_INSTANCE_INITIALIZER; void StopServerOnIOThread() { // Note, |server| may be NULL. - HttpServer* server = lazy_tls_server_ipv4.Pointer()->Get(); - lazy_tls_server_ipv4.Pointer()->Set(NULL); - delete server; - - server = lazy_tls_server_ipv6.Pointer()->Get(); - lazy_tls_server_ipv6.Pointer()->Set(NULL); + HttpServer* server = lazy_tls_server.Pointer()->Get(); + lazy_tls_server.Pointer()->Set(NULL); delete server; } void StartServerOnIOThread(uint16_t port, bool allow_remote, const HttpRequestHandlerFunc& handle_request_func) { - std::unique_ptr<HttpServer> temp_server; - - temp_server.reset(new HttpServer(handle_request_func)); - int ipv4_status = temp_server->Start(port, allow_remote, true); - if (ipv4_status == net::OK) { - lazy_tls_server_ipv4.Pointer()->Set(temp_server.release()); - } else if (ipv4_status == net::ERR_ADDRESS_IN_USE) { - printf("IPv4 port not available. Exiting...\n"); + std::unique_ptr<HttpServer> temp_server(new HttpServer(handle_request_func)); + if (!temp_server->Start(port, allow_remote)) { + printf("Port not available. Exiting...\n"); exit(1); } - - temp_server.reset(new HttpServer(handle_request_func)); - int ipv6_status = temp_server->Start(port, allow_remote, false); - if (ipv6_status == net::OK) { - lazy_tls_server_ipv6.Pointer()->Set(temp_server.release()); - } else if (ipv6_status == net::ERR_ADDRESS_IN_USE) { - printf("IPv6 port not available. Exiting...\n"); - exit(1); - } - - if (ipv4_status != net::OK && ipv6_status != net::OK) { - printf("Unable to start server with either IPv4 or IPv6. Exiting...\n"); - exit(1); - } + lazy_tls_server.Pointer()->Set(temp_server.release()); } void RunServer(uint16_t port,
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/early_event_dispatch/manifest.json b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/early_event_dispatch/manifest.json new file mode 100644 index 0000000..838c695e --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/early_event_dispatch/manifest.json
@@ -0,0 +1,10 @@ +{ + // chrome-extension://pkplfbidichfdicaijlchgnapepdginl + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDfX9dHNh948bt00YhZBm3P6E5QLaOt+v8kXVtibQfiPtOD2FTScB/f0wX/EQWVO7BkaSOsRkTPcPIgocyMPYr2FLgqGLFlYT9nQpKJZUFNF5oJ5rG6Nv7ppf4zEB3j6da1IBRTz2yOZ+6O1TMZxol/V62/QcqrJeggsHTEPGLdr9Ua4b1Ka0xKJnJngZljsbw93FI1o+P9dAh5BS6wTPiZI/vmJVjvMTkSTnaZ3n9Go2t7A0XLcSxLcVyuLAd2mAvSN0mIviOukdM66wr7llif71nKuUt+4qvlr/r9HfwzN6pA4jkwhtS1UD+3CmB+wsHwsnohNcuu4FIQ6rgq/7QIDAQAB", + "name": "Worker based background script", + "version": "0.1", + "manifest_version": 2, + "description": "Test for dispatching extension event shortly after Service Worker registration occurs.", + "permissions": ["tabs"], + "background": {"service_worker_script": "service_worker_background.js"} +}
diff --git a/chrome/test/data/extensions/api_test/service_worker/worker_based_background/early_event_dispatch/service_worker_background.js b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/early_event_dispatch/service_worker_background.js new file mode 100644 index 0000000..dd9330d --- /dev/null +++ b/chrome/test/data/extensions/api_test/service_worker/worker_based_background/early_event_dispatch/service_worker_background.js
@@ -0,0 +1,14 @@ +// 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. + +var isInstanceOfServiceWorkerGlobalScope = + ('ServiceWorkerGlobalScope' in self) && + (self instanceof ServiceWorkerGlobalScope); + +if (!isInstanceOfServiceWorkerGlobalScope) { + chrome.test.sendMessage('FAIL'); +} else { + chrome.test.onMessage.addListener(args => + chrome.test.sendMessage(args.data == 'hello' ? 'PASS': 'FAIL')); +}
diff --git a/chrome/test/data/safe_browsing/dmg/generate_test_data.sh b/chrome/test/data/safe_browsing/dmg/generate_test_data.sh index fceec6f..b83934b 100755 --- a/chrome/test/data/safe_browsing/dmg/generate_test_data.sh +++ b/chrome/test/data/safe_browsing/dmg/generate_test_data.sh
@@ -79,6 +79,8 @@ mkdir "${DMG_SOURCE}/.hidden" cp "${THIS_DIR}/../mach_o/lib64.dylib" "${DMG_SOURCE}/.hidden/" + cp -r "${THIS_DIR}/../mach_o/shell-script.app" "${DMG_SOURCE}" + hdiutil create -srcfolder "${DMG_SOURCE}" \ -format UDZO -layout SPUD -volname "Mach-O in DMG" -ov \ -fs JHFS+ "${OUT_DIR}/mach_o_in_dmg"
diff --git a/chrome/test/data/safe_browsing/mach_o/Makefile b/chrome/test/data/safe_browsing/mach_o/Makefile index 4eb76cf..ef5dc90 100644 --- a/chrome/test/data/safe_browsing/mach_o/Makefile +++ b/chrome/test/data/safe_browsing/mach_o/Makefile
@@ -6,7 +6,7 @@ # This must match the commonName in codesign.cfg. KEYCHAIN_IDENTITY=untrusted@goat.local -# Funcitons to add and remove codesigning identity to user's keychain. These +# Funcitons to add and remove codesigning identity to user's keychain. These # are necessary since the codesign utility no longer supports the -k option, # which reads the identity from a file. pre-build = security import codesign.key && security import codesign.crt @@ -37,7 +37,7 @@ openssl req -new -key $< -out $@ -config codesign.cfg codesign.crt: codesign.csr codesign.key codesign.cfg - openssl x509 -req -signkey codesign.key -sha256 \ + openssl x509 -req -signkey codesign.key -sha256 -days 9999 \ -extfile codesign.cfg -extensions req_attrs -in $< -out $@ signedexecutable32: executable32 codesign.crt @@ -72,6 +72,15 @@ zip -r $@ app-with-executables.app rm -r app-with-executables.app +.PHONY: shell-script.app +shell-script.app: + $(call pre-build) + ditto base-bundle.app $@ + mkdir $@/Contents/MacOS || true + echo 'echo "Hello world"' > $@/Contents/MacOS/test-bundle + codesign -f -s $(KEYCHAIN_IDENTITY) $@ + $(call post-build) + .PHONY: test-bundle.app test-bundle.app: signedexecutablefat libsigned64.dylib executable32 $(call pre-build)
diff --git a/chrome/test/data/safe_browsing/mach_o/README b/chrome/test/data/safe_browsing/mach_o/README index 848fb2b..1f4f570a 100644 --- a/chrome/test/data/safe_browsing/mach_o/README +++ b/chrome/test/data/safe_browsing/mach_o/README
@@ -6,6 +6,10 @@ the binaries. Note that recompiling or re-code-signing the binaries will require updating the test's assertions. +In June 2018, the code signing certificate was regenerated because codesign was +no longer accepting the long-expired certificate. Not all artifacts were re- +signed, though. + Note that the executable bit has been removed from all of executable files, since they do not have a common extension (for checkperms.py) and they are only ever treated as data. @@ -13,7 +17,7 @@ The `executableppc' file has no Makefile target, as modern Macs cannot build for PPC. This file was created in a 10.6 VM with Xcode 3.2.6. -Creating the signed binaries requires importing a temporary codesigning -identity into the current user's keychain. This is because the `codesign -k` +Creating the signed binaries requires importing a temporary codesigning +identity into the current user's keychain. This is because the `codesign -k` flag, which specifies a specific keychain file to use, is no longer respected. -The temporary identity will be removed after the test binary is signed. \ No newline at end of file +The temporary identity will be removed after the test binary is signed.
diff --git a/chrome/test/data/safe_browsing/mach_o/codesign.crt b/chrome/test/data/safe_browsing/mach_o/codesign.crt index 9870244a..e2028638 100644 --- a/chrome/test/data/safe_browsing/mach_o/codesign.crt +++ b/chrome/test/data/safe_browsing/mach_o/codesign.crt
@@ -1,8 +1,8 @@ -----BEGIN CERTIFICATE----- -MIIDfTCCAmWgAwIBAgIJAKzs2ufO0WuBMA0GCSqGSIb3DQEBCwUAMGsxCzAJBgNV +MIIDfTCCAmWgAwIBAgIJAMX/nCbbFSgIMA0GCSqGSIb3DQEBCwUAMGsxCzAJBgNV BAYTAlVTMR0wGwYDVQQDDBR1bnRydXN0ZWRAZ29hdC5sb2NhbDERMA8GA1UEBwwI TmV3IFlvcmsxETAPBgNVBAgMCE5ldyBZb3JrMRcwFQYDVQQKDA5VbnRydXN0ZWQg -R29hdDAeFw0xNTA2MDQxODUxNDdaFw0xNTA3MDQxODUxNDdaMGsxCzAJBgNVBAYT +R29hdDAeFw0xODA2MTEyMTA0MjVaFw00NTEwMjYyMTA0MjVaMGsxCzAJBgNVBAYT AlVTMR0wGwYDVQQDDBR1bnRydXN0ZWRAZ29hdC5sb2NhbDERMA8GA1UEBwwITmV3 IFlvcmsxETAPBgNVBAgMCE5ldyBZb3JrMRcwFQYDVQQKDA5VbnRydXN0ZWQgR29h dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMolOFEuV1GiKLjZkFg4 @@ -12,10 +12,10 @@ WEzWetXhuwZB+VJ/M6YJn/IVJahlO3L/8L65dBPPp+gQn52hGnxV0YOaY/G4DdPO mDfq7GQC6//N/Qg/1u9fg0ecSF1zs0zxOMtvuMLpi3ysycMhSKcuD0b34enzk5Mw 7McCAwEAAaMkMCIwEwYDVR0lBAwwCgYIKwYBBQUHAwMwCwYDVR0PBAQDAgeAMA0G -CSqGSIb3DQEBCwUAA4IBAQAxzlc6L7UIF+mwGYloAn5AMTsnjPY8li9g0896FCl7 -f3bDroDmj8NAd9EPYRnVOFGcj6JVAhitxjcnPhsdMs5Cy/vSyHSp3rHnx+DNQ+iq -2LzWXVSusiungZb1y7sgo9CD0zI3HA3SLxGDwHw80HAkxnaR8FAer+1E9zXoj3NG -crNO9AlqZdghlLsktEpHw0/Srkmc1bRyEHymiy/6qh8oM0zqkEuOLe1BrfHbLlI1 -yrlsu3EwKMkBhKPSHQr4oYhpqd4YEmIl6+r/sPFl92HrYFXEOtUINp/Bn7wYKU9V -sNA1SKHZSrb1+tqMlHEdMOa3a+uOAgA5WyJCjgNrvjzU +CSqGSIb3DQEBCwUAA4IBAQA2mw5Myho1aooZWV9/DZMstQNPOHEHd6dFRLhBCXGr +ixYj2ogUrvA1tucGlB48LA8luhahDq+rk0+VbYpTStLVGj+gab5nllvOLLtVIy14 +kj1n3aCMbvf6nVsbfAm4X2+k7RhDns1BLr+Zo5eGk8HzUyk2b6925QY9S1ZpEeF7 +K+De7tsBlpKgOfkxJ1376xLGgzomDxy3DT56UMBGHXdH2dgmkeTwsOs+oTfAnmmz +h2w1fyRAMs+6lbwgnU0BHsVFHApxch1MqXEvtGC4dxbETNJnrQkoP5kJdP+GFTEI +PLSqIgEW0AmV5c1ZjHLPJ1PI/kpJmhgETlCkEu1huGjg -----END CERTIFICATE-----
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/Info.plist b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/Info.plist new file mode 100644 index 0000000..a6082b8 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/Info.plist
@@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>14F27</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>test-bundle</string> + <key>CFBundleIdentifier</key> + <string>google-test.test-bundle</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>test-bundle</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>6D2105</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>14D125</string> + <key>DTSDKName</key> + <string>macosx10.10</string> + <key>DTXcode</key> + <string>0632</string> + <key>DTXcodeBuild</key> + <string>6D2105</string> + <key>LSMinimumSystemVersion</key> + <string>10.10</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2015 test-bundle. All rights reserved.</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist>
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/MacOS/test-bundle b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/MacOS/test-bundle new file mode 100644 index 0000000..bba153a --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/MacOS/test-bundle
@@ -0,0 +1 @@ +echo "Hello world"
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/PkgInfo b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/PkgInfo
@@ -0,0 +1 @@ +APPL???? \ No newline at end of file
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/Resources/Base.lproj/MainMenu.nib b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/Resources/Base.lproj/MainMenu.nib new file mode 100644 index 0000000..483099c7 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/Resources/Base.lproj/MainMenu.nib Binary files differ
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeDirectory b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeDirectory new file mode 100644 index 0000000..3a55f01 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeDirectory Binary files differ
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeRequirements b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeRequirements new file mode 100644 index 0000000..fe30dfdc --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeRequirements Binary files differ
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeRequirements-1 b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeRequirements-1 new file mode 100644 index 0000000..e01bf5ca --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeRequirements-1 Binary files differ
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeResources b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..80e595a4 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeResources
@@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>files</key> + <dict> + <key>Resources/Base.lproj/MainMenu.nib</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + </dict> + <key>files2</key> + <dict> + <key>Resources/Base.lproj/MainMenu.nib</key> + <dict> + <key>hash</key> + <data> + 36VmRur+3AKfYrTxgwnd4cqqjvY= + </data> + <key>hash2</key> + <data> + WrY0LTElfFnl1PVJp3CzDSQPTZ0H5IxCH77PXdma93I= + </data> + </dict> + </dict> + <key>rules</key> + <dict> + <key>^Resources/</key> + <true/> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^Resources/Base\.lproj/</key> + <dict> + <key>weight</key> + <real>1010</real> + </dict> + <key>^version.plist$</key> + <true/> + </dict> + <key>rules2</key> + <dict> + <key>.*\.dSYM($|/)</key> + <dict> + <key>weight</key> + <real>11</real> + </dict> + <key>^(.*/)?\.DS_Store$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>2000</real> + </dict> + <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key> + <dict> + <key>nested</key> + <true/> + <key>weight</key> + <real>10</real> + </dict> + <key>^.*</key> + <true/> + <key>^Info\.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^PkgInfo$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^Resources/.*\.lproj/</key> + <dict> + <key>optional</key> + <true/> + <key>weight</key> + <real>1000</real> + </dict> + <key>^Resources/.*\.lproj/locversion.plist$</key> + <dict> + <key>omit</key> + <true/> + <key>weight</key> + <real>1100</real> + </dict> + <key>^Resources/Base\.lproj/</key> + <dict> + <key>weight</key> + <real>1010</real> + </dict> + <key>^[^/]+$</key> + <dict> + <key>nested</key> + <true/> + <key>weight</key> + <real>10</real> + </dict> + <key>^embedded\.provisionprofile$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + <key>^version\.plist$</key> + <dict> + <key>weight</key> + <real>20</real> + </dict> + </dict> +</dict> +</plist>
diff --git a/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeSignature b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeSignature new file mode 100644 index 0000000..11c8619 --- /dev/null +++ b/chrome/test/data/safe_browsing/mach_o/shell-script.app/Contents/_CodeSignature/CodeSignature Binary files differ
diff --git a/chrome/test/data/webui/print_preview/advanced_dialog_test.js b/chrome/test/data/webui/print_preview/advanced_dialog_test.js index 6036b814..30184af 100644 --- a/chrome/test/data/webui/print_preview/advanced_dialog_test.js +++ b/chrome/test/data/webui/print_preview/advanced_dialog_test.js
@@ -61,8 +61,7 @@ dialog.destination = destination; document.body.appendChild(dialog); - dialog.show(); - Polymer.dom.flush(); + return test_util.whenAttributeIs(dialog.$.dialog, 'open', ''); } /** @@ -100,88 +99,93 @@ // Tests that the search box does not appear when there is only one option, // and that the vendor item is correctly displayed. test(assert(TestNames.AdvancedSettings1Option), function() { - setupDialog(1); - verifyListWithItemCount(1); + return setupDialog(1).then(() => verifyListWithItemCount(1)); }); // Tests that the search box appears when there are two options, and that // the items are correctly displayed. test(assert(TestNames.AdvancedSettings2Options), function() { - setupDialog(2); - verifyListWithItemCount(2); + return setupDialog(2).then(() => verifyListWithItemCount(2)); }); // Tests that the advanced settings dialog correctly updates the settings // value for vendor items when the apply button is clicked. test(assert(TestNames.AdvancedSettingsApply), function() { - setupDialog(3); - setItemValues(); + return setupDialog(3) + .then(() => { + setItemValues(); - const buttons = dialog.shadowRoot.querySelectorAll('button'); - assertEquals(2, buttons.length); - const whenDialogClose = test_util.eventToPromise('close', dialog); + const buttons = dialog.shadowRoot.querySelectorAll('button'); + assertEquals(2, buttons.length); + const whenDialogClose = test_util.eventToPromise('close', dialog); - // Click apply button. - buttons[1].click(); - return whenDialogClose.then(function() { - // Check that the setting has been set. - const setting = dialog.getSettingValue('vendorItems'); - assertEquals(6, setting.printArea); - assertEquals(1, setting.paperType); - assertEquals('XYZ', setting.watermark); - }); + // Click apply button. + buttons[1].click(); + return whenDialogClose; + }) + .then(() => { + // Check that the setting has been set. + const setting = dialog.getSettingValue('vendorItems'); + assertEquals(6, setting.printArea); + assertEquals(1, setting.paperType); + assertEquals('XYZ', setting.watermark); + }); }); // Tests that the advanced settings dialog does not update the settings // value for vendor items when the close button is clicked. test(assert(TestNames.AdvancedSettingsClose), function() { - setupDialog(3); - setItemValues(); + return setupDialog(3) + .then(() => { + setItemValues(); - const buttons = dialog.shadowRoot.querySelectorAll('button'); - assertEquals(2, buttons.length); - const whenDialogClose = test_util.eventToPromise('close', dialog); + const buttons = dialog.shadowRoot.querySelectorAll('button'); + assertEquals(2, buttons.length); + const whenDialogClose = test_util.eventToPromise('close', dialog); - // Click close button. - buttons[0].click(); - return whenDialogClose.then(function() { - // Check that the setting has not been set. - const setting = dialog.getSettingValue('vendorItems'); - assertEquals(undefined, setting.printArea); - assertEquals(undefined, setting.paperType); - assertEquals(undefined, setting.watermark); - }); + // Click close button. + buttons[0].click(); + return whenDialogClose; + }) + .then(() => { + // Check that the setting has not been set. + const setting = dialog.getSettingValue('vendorItems'); + assertEquals(undefined, setting.printArea); + assertEquals(undefined, setting.paperType); + assertEquals(undefined, setting.watermark); + }); }); // Tests that the dialog correctly shows and hides settings based on the // value of the search query. test(assert(TestNames.AdvancedSettingsFilter), function() { - setupDialog(3); - const searchBox = dialog.$.searchBox; - const items = dialog.shadowRoot.querySelectorAll( - 'print-preview-advanced-settings-item'); - const noMatchHint = dialog.$$('.no-settings-match-hint'); + return setupDialog(3).then(() => { + const searchBox = dialog.$.searchBox; + const items = dialog.shadowRoot.querySelectorAll( + 'print-preview-advanced-settings-item'); + const noMatchHint = dialog.$$('.no-settings-match-hint'); - // Query is initialized to null. All items are shown and the hint is - // hidden. - items.forEach(item => assertFalse(item.hidden)); - assertTrue(noMatchHint.hidden); + // Query is initialized to null. All items are shown and the hint is + // hidden. + items.forEach(item => assertFalse(item.hidden)); + assertTrue(noMatchHint.hidden); - // Searching for Watermark should show only the watermark setting. - searchBox.searchQuery = /(Watermark)/i; - items.forEach((item, index) => assertEquals(index != 2, item.hidden)); - assertTrue(noMatchHint.hidden); + // Searching for Watermark should show only the watermark setting. + searchBox.searchQuery = /(Watermark)/i; + items.forEach((item, index) => assertEquals(index != 2, item.hidden)); + assertTrue(noMatchHint.hidden); - // Searching for A4 should show only the print area setting. - searchBox.searchQuery = /(A4)/i; - items.forEach((item, index) => assertEquals(index != 0, item.hidden)); - assertTrue(noMatchHint.hidden); + // Searching for A4 should show only the print area setting. + searchBox.searchQuery = /(A4)/i; + items.forEach((item, index) => assertEquals(index != 0, item.hidden)); + assertTrue(noMatchHint.hidden); - // Searching for WXYZ should show no settings and display the "no match" - // hint. - searchBox.searchQuery = /(WXYZ)/i; - items.forEach(item => assertTrue(item.hidden)); - assertFalse(noMatchHint.hidden); + // Searching for WXYZ should show no settings and display the "no match" + // hint. + searchBox.searchQuery = /(WXYZ)/i; + items.forEach(item => assertTrue(item.hidden)); + assertFalse(noMatchHint.hidden); + }); }); });
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 1468b82..95452b4c 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -974,9 +974,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - '../test_browser_proxy.js', 'test_util.js', - 'test_site_settings_prefs_browser_proxy.js', 'site_entry_tests.js', ]), }; @@ -1836,6 +1834,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ + '../test_browser_proxy.js', 'multidevice_page_tests.js', ]), };
diff --git a/chrome/test/data/webui/settings/multidevice_page_tests.js b/chrome/test/data/webui/settings/multidevice_page_tests.js index 302731b..a61e2d9 100644 --- a/chrome/test/data/webui/settings/multidevice_page_tests.js +++ b/chrome/test/data/webui/settings/multidevice_page_tests.js
@@ -2,12 +2,29 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** @implements {settings.MultideviceBrowserProxy} */ +class TestMultideviceBrowserProxy extends TestBrowserProxy { + constructor() { + super(['showMultiDeviceSetupDialog']); + } + + /** @override */ + showMultiDeviceSetupDialog() { + this.methodCalled('showMultiDeviceSetupDialog'); + } +} + suite('Multidevice', function() { let multidevicePage = null; + let browserProxy = null; + suiteSetup(function() {}); setup(function() { + browserProxy = new TestMultideviceBrowserProxy(); + settings.MultiDeviceBrowserProxyImpl.instance_ = browserProxy; + PolymerTest.clearBody(); multidevicePage = document.createElement('settings-multidevice-page'); assertTrue(!!multidevicePage); @@ -20,7 +37,16 @@ multidevicePage.remove(); }); - test('MainPage', function() { - // TODO: Write test once the setting is actually functional. + const setMode = function(mode) { + multidevicePage.mode = mode; + Polymer.dom.flush(); + }; + + test('pressing setup shows multidevice setup dialog', function() { + setMode(settings.MultiDeviceSettingsMode.NO_HOST_SET); + const button = multidevicePage.$$('paper-button'); + assertTrue(!!button); + MockInteractions.tap(button); + return browserProxy.whenCalled('showMultiDeviceSetupDialog'); }); });
diff --git a/chrome/test/data/webui/settings/multidevice_section_container_tests.js b/chrome/test/data/webui/settings/multidevice_section_container_tests.js index f4f34f3b..7bab29c 100644 --- a/chrome/test/data/webui/settings/multidevice_section_container_tests.js +++ b/chrome/test/data/webui/settings/multidevice_section_container_tests.js
@@ -25,9 +25,13 @@ multideviceSectionContainer.remove(); }); - let isSettingsSectionVisible = function() { + const setMode = function(mode) { + multideviceSectionContainer.mode_ = mode; Polymer.dom.flush(); - let settingsSection = multideviceSectionContainer.$$( + }; + + const isSettingsSectionVisible = function() { + const settingsSection = multideviceSectionContainer.$$( 'settings-section[section="multidevice"]'); return !!settingsSection && !settingsSection.hidden; }; @@ -36,7 +40,7 @@ // Check that the settings-section is visible iff the mode is not // NO_ELIGIBLE_HOSTS. for (let mode of ALL_MODES) { - multideviceSectionContainer.mode_ = mode; + setMode(mode); assertEquals( isSettingsSectionVisible(), mode != settings.MultiDeviceSettingsMode.NO_ELIGIBLE_HOSTS); @@ -44,7 +48,7 @@ // One more loop to ensure we transition in and out of NO_ELIGIBLE_HOSTS // mode. for (let mode of ALL_MODES) { - multideviceSectionContainer.mode_ = mode; + setMode(mode); assertEquals( isSettingsSectionVisible(), mode != settings.MultiDeviceSettingsMode.NO_ELIGIBLE_HOSTS); @@ -55,9 +59,8 @@ 'mode_ property passes to settings-multidevice-page if present', function() { for (let mode of ALL_MODES) { - multideviceSectionContainer.mode_ = mode; - Polymer.dom.flush(); - let multidevicePage = + setMode(mode); + const multidevicePage = multideviceSectionContainer.$$('settings-multidevice-page'); if (mode == settings.MultiDeviceSettingsMode.NO_ELIGIBLE_HOSTS) assertEquals(multidevicePage, null);
diff --git a/chrome/test/data/webui/settings/site_details_permission_tests.js b/chrome/test/data/webui/settings/site_details_permission_tests.js index ecc421b4..f4ff0e8 100644 --- a/chrome/test/data/webui/settings/site_details_permission_tests.js +++ b/chrome/test/data/webui/settings/site_details_permission_tests.js
@@ -244,7 +244,6 @@ test('info string correct for drm disabled source', function() { const origin = 'https://www.example.com'; testElement.category = settings.ContentSettingsTypes.PROTECTED_CONTENT; - testElement.$.details.hidden = false; testElement.site = { origin: origin, embeddingOrigin: origin,
diff --git a/chrome/test/data/webui/settings/site_details_tests.js b/chrome/test/data/webui/settings/site_details_tests.js index 9706e1cb..5d0a9e5 100644 --- a/chrome/test/data/webui/settings/site_details_tests.js +++ b/chrome/test/data/webui/settings/site_details_tests.js
@@ -158,7 +158,7 @@ loadTimeData.overrideValues(loadTimeDataOverride); testElement = createSiteDetails('https://foo.com:443'); assertEquals( - numContentSettings + 1, testElement.getCategoryList().length); + numContentSettings + 1, testElement.getCategoryList_().length); // Check for setting = off at the end to ensure that the setting does // not carry over for the next iteration. @@ -166,7 +166,7 @@ [optionalSiteDetailsContentSettingsTypes[contentSetting]] = false; loadTimeData.overrideValues(loadTimeDataOverride); testElement = createSiteDetails('https://foo.com:443'); - assertEquals(numContentSettings, testElement.getCategoryList().length); + assertEquals(numContentSettings, testElement.getCategoryList_().length); } }); @@ -320,7 +320,7 @@ // Accepting the dialog will make a call to setOriginPermissions. return browserProxy.whenCalled('setOriginPermissions').then((args) => { assertEquals(testElement.origin, args[0]); - assertDeepEquals(testElement.getCategoryList(), args[1]); + assertDeepEquals(testElement.getCategoryList_(), args[1]); assertEquals(settings.ContentSetting.DEFAULT, args[2]); }); });
diff --git a/chrome/test/data/webui/settings/site_entry_tests.js b/chrome/test/data/webui/settings/site_entry_tests.js index 70224e2..b1511b7 100644 --- a/chrome/test/data/webui/settings/site_entry_tests.js +++ b/chrome/test/data/webui/settings/site_entry_tests.js
@@ -22,12 +22,6 @@ ]); /** - * The mock proxy object to use during test. - * @type {TestSiteSettingsPrefsBrowserProxy} - */ - let browserProxy; - - /** * A site list element created before each test. * @type {SiteList} */ @@ -41,9 +35,6 @@ // Initialize a site-list before each test. setup(function() { - browserProxy = new TestSiteSettingsPrefsBrowserProxy(); - settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy; - PolymerTest.clearBody(); testElement = document.createElement('site-entry'); assertTrue(!!testElement); @@ -115,49 +106,4 @@ TEST_MULTIPLE_SITE_GROUP.origins[1], settings.getQueryParameters().get('site')); }); - - test('with single origin does not show overflow menu', function() { - testElement.siteGroup = TEST_SINGLE_SITE_GROUP; - Polymer.dom.flush(); - const overflowMenuButton = testElement.$.overflowMenuButton; - assertTrue(overflowMenuButton.closest('.row-aligned').hidden); - }); - - test( - 'with multiple origins can reset settings via overflow menu', function() { - testElement.siteGroup = TEST_MULTIPLE_SITE_GROUP; - Polymer.dom.flush(); - const overflowMenuButton = testElement.$.overflowMenuButton; - assertFalse(overflowMenuButton.closest('.row-aligned').hidden); - - // Open the reset settings dialog and make sure both cancelling the - // action and resetting all permissions work. - const menuItems = - testElement.getOverflowMenu_().querySelectorAll('.dropdown-item'); - ['cancel-button', 'action-button'].forEach(buttonType => { - // Test clicking on the overflow menu button opens the menu. - assertFalse(testElement.getOverflowMenu_().open); - MockInteractions.tap(overflowMenuButton); - assertTrue(testElement.getOverflowMenu_().open); - - // Open the reset settings dialog and tap the |buttonType| button. - assertFalse(testElement.$.confirmResetSettings.open); - MockInteractions.tap(menuItems[0]); - assertTrue(testElement.$.confirmResetSettings.open); - const actionButtonList = - testElement.$.confirmResetSettings.getElementsByClassName( - buttonType); - assertEquals(1, actionButtonList.length); - MockInteractions.tap(actionButtonList[0]); - - // Check the dialog and overflow menu are now both closed. - assertFalse(testElement.$.confirmResetSettings.open); - assertFalse(testElement.getOverflowMenu_().open); - }); - - // Ensure a call was made to setOriginPermissions for each origin. - assertEquals( - TEST_MULTIPLE_SITE_GROUP.origins.length, - browserProxy.getCallCount('setOriginPermissions')); - }); });
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index 8f0026b7..0a340b4 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -43,6 +43,7 @@ specific_include_rules = { "mash_service_factory.cc": [ + "+ash/ash_service.h", "+ash/components/autoclick/autoclick_application.h", "+ash/components/quick_launch/public", "+ash/components/quick_launch/quick_launch_application.h",
diff --git a/chrome/utility/mash_service_factory.cc b/chrome/utility/mash_service_factory.cc index 3f452b1..815f864 100644 --- a/chrome/utility/mash_service_factory.cc +++ b/chrome/utility/mash_service_factory.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "ash/ash_service.h" #include "ash/components/autoclick/autoclick_application.h" #include "ash/components/quick_launch/public/mojom/constants.mojom.h" #include "ash/components/quick_launch/quick_launch_application.h" @@ -16,11 +17,13 @@ #include "ash/public/interfaces/constants.mojom.h" #include "ash/window_manager_service.h" #include "base/bind.h" +#include "base/feature_list.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "components/services/font/font_service_app.h" #include "components/services/font/public/interfaces/constants.mojom.h" +#include "ui/base/ui_base_features.h" namespace { @@ -54,9 +57,12 @@ std::unique_ptr<service_manager::Service> CreateAshService() { RecordMashServiceLaunch(MashService::kAsh); - const bool show_primary_host_on_connect = true; - return std::make_unique<ash::WindowManagerService>( - show_primary_host_on_connect); + if (base::FeatureList::IsEnabled(features::kMash)) { + const bool show_primary_host_on_connect = true; + return std::make_unique<ash::WindowManagerService>( + show_primary_host_on_connect); + } + return std::make_unique<ash::AshService>(); } std::unique_ptr<service_manager::Service> CreateAutoclickApp() {
diff --git a/chrome/utility/safe_browsing/mac/dmg_analyzer.cc b/chrome/utility/safe_browsing/mac/dmg_analyzer.cc index 93b0521c..7ee5e1c 100644 --- a/chrome/utility/safe_browsing/mac/dmg_analyzer.cc +++ b/chrome/utility/safe_browsing/mac/dmg_analyzer.cc
@@ -11,6 +11,8 @@ #include <vector> #include "base/macros.h" +#include "base/stl_util.h" +#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "chrome/common/safe_browsing/binary_feature_extractor.h" @@ -116,6 +118,11 @@ return true; } +// The first few bytes of a DER-encoded pkcs7-signedData object. +constexpr uint8_t kDERPKCS7SignedData[] = {0x30, 0x80, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0}; + } // namespace void AnalyzeDMGFile(base::File dmg_file, ArchiveAnalyzerResults* results) { @@ -131,19 +138,43 @@ while (iterator.Next()) { std::unique_ptr<ReadStream> stream = iterator.GetReadStream(); - if (!stream || !feature_extractor.IsMachO(stream.get())) + if (!stream) continue; - ClientDownloadRequest_ArchivedBinary* binary = - results->archived_binary.Add(); - binary->set_file_basename(base::UTF16ToUTF8(iterator.GetPath())); + std::string path = base::UTF16ToUTF8(iterator.GetPath()); - if (feature_extractor.ExtractFeatures(stream.get(), binary)) { - binary->set_download_type( - ClientDownloadRequest_DownloadType_MAC_EXECUTABLE); + bool is_detached_code_signature_file = base::EndsWith( + path, "_CodeSignature/CodeSignature", base::CompareCase::SENSITIVE); + + if (is_detached_code_signature_file) { + std::vector<uint8_t> signature_contents; + if (!ReadEntireStream(stream.get(), &signature_contents)) + continue; + + if (memcmp(kDERPKCS7SignedData, signature_contents.data(), + base::size(kDERPKCS7SignedData)) != 0) { + continue; + } + results->has_executable = true; - } else { - results->archived_binary.RemoveLast(); + + ClientDownloadRequest_DetachedCodeSignature* detached_signature = + results->detached_code_signatures.Add(); + detached_signature->set_file_name(path); + detached_signature->set_contents(signature_contents.data(), + signature_contents.size()); + } else if (feature_extractor.IsMachO(stream.get())) { + ClientDownloadRequest_ArchivedBinary* binary = + results->archived_binary.Add(); + binary->set_file_basename(path); + + if (feature_extractor.ExtractFeatures(stream.get(), binary)) { + binary->set_download_type( + ClientDownloadRequest_DownloadType_MAC_EXECUTABLE); + results->has_executable = true; + } else { + results->archived_binary.RemoveLast(); + } } }
diff --git a/chrome/utility/safe_browsing/mac/dmg_test_utils.cc b/chrome/utility/safe_browsing/mac/dmg_test_utils.cc index c3c4ba7..6abbe79 100644 --- a/chrome/utility/safe_browsing/mac/dmg_test_utils.cc +++ b/chrome/utility/safe_browsing/mac/dmg_test_utils.cc
@@ -28,22 +28,6 @@ ASSERT_TRUE(file->IsValid()); } -bool ReadEntireStream(ReadStream* stream, std::vector<uint8_t>* data) { - DCHECK(data->empty()); - uint8_t buffer[1024]; - size_t bytes_read = 0; - do { - bytes_read = 0; - - if (!stream->Read(buffer, sizeof(buffer), &bytes_read)) - return false; - - data->insert(data->end(), buffer, &buffer[bytes_read]); - } while (bytes_read != 0); - - return true; -} - } // namespace test } // namespace dmg } // namespace safe_browsing
diff --git a/chrome/utility/safe_browsing/mac/dmg_test_utils.h b/chrome/utility/safe_browsing/mac/dmg_test_utils.h index 87fa542..f52671f 100644 --- a/chrome/utility/safe_browsing/mac/dmg_test_utils.h +++ b/chrome/utility/safe_browsing/mac/dmg_test_utils.h
@@ -20,10 +20,6 @@ // so this should be called with ASSERT_NO_FATAL_FAILURE(). void GetTestFile(const char* file_name, base::File* file); -// Reads the given |stream| until end-of-stream is reached, storying the read -// bytes into |data|. Returns true on success and false on error. -bool ReadEntireStream(ReadStream* stream, std::vector<uint8_t>* data); - } // namespace test } // namespace dmg } // namespace safe_browsing
diff --git a/chrome/utility/safe_browsing/mac/hfs_unittest.cc b/chrome/utility/safe_browsing/mac/hfs_unittest.cc index 9b9416946..7cb55df4 100644 --- a/chrome/utility/safe_browsing/mac/hfs_unittest.cc +++ b/chrome/utility/safe_browsing/mac/hfs_unittest.cc
@@ -157,7 +157,7 @@ EXPECT_EQ(0, stream->Seek(0, SEEK_SET)); // Read the entire file now. - EXPECT_TRUE(test::ReadEntireStream(stream.get(), &buffer)); + EXPECT_TRUE(ReadEntireStream(stream.get(), &buffer)); EXPECT_EQ("This is a test HFS+ filesystem generated by " "chrome/test/data/safe_browsing/dmg/make_hfs.sh.\n", base::StringPiece(reinterpret_cast<const char*>(&buffer[0]), @@ -176,7 +176,7 @@ EXPECT_FALSE(hfs_reader()->IsDecmpfsCompressed()); std::vector<uint8_t> buffer; - EXPECT_TRUE(test::ReadEntireStream(stream.get(), &buffer)); + EXPECT_TRUE(ReadEntireStream(stream.get(), &buffer)); EXPECT_EQ(768u, buffer.size()); } @@ -191,7 +191,7 @@ EXPECT_FALSE(hfs_reader()->IsDecmpfsCompressed()); std::vector<uint8_t> buffer; - EXPECT_TRUE(test::ReadEntireStream(stream.get(), &buffer)); + EXPECT_TRUE(ReadEntireStream(stream.get(), &buffer)); EXPECT_EQ("fourth/fifth/random", base::StringPiece(reinterpret_cast<const char*>(&buffer[0]), @@ -217,7 +217,7 @@ EXPECT_TRUE(hfs_reader()->IsDecmpfsCompressed()); std::vector<uint8_t> buffer; - EXPECT_TRUE(test::ReadEntireStream(stream.get(), &buffer)); + EXPECT_TRUE(ReadEntireStream(stream.get(), &buffer)); EXPECT_EQ(0u, buffer.size()); }
diff --git a/chrome/utility/safe_browsing/mac/read_stream.cc b/chrome/utility/safe_browsing/mac/read_stream.cc index ac904675..2eaf6da 100644 --- a/chrome/utility/safe_browsing/mac/read_stream.cc +++ b/chrome/utility/safe_browsing/mac/read_stream.cc
@@ -78,5 +78,19 @@ return offset_; } +bool ReadEntireStream(ReadStream* stream, std::vector<uint8_t>* data) { + DCHECK(data->empty()); + uint8_t buffer[1024]; + size_t bytes_read = 0; + do { + if (!stream->Read(buffer, sizeof(buffer), &bytes_read)) + return false; + + data->insert(data->end(), buffer, &buffer[bytes_read]); + } while (bytes_read != 0); + + return true; +} + } // namespace dmg } // namespace safe_browsing
diff --git a/chrome/utility/safe_browsing/mac/read_stream.h b/chrome/utility/safe_browsing/mac/read_stream.h index 231ed15..751e768 100644 --- a/chrome/utility/safe_browsing/mac/read_stream.h +++ b/chrome/utility/safe_browsing/mac/read_stream.h
@@ -9,6 +9,8 @@ #include <stdint.h> #include <unistd.h> +#include <vector> + #include "base/macros.h" namespace safe_browsing { @@ -79,6 +81,10 @@ DISALLOW_COPY_AND_ASSIGN(MemoryReadStream); }; +// Reads the given |stream| until end-of-stream is reached, storying the read +// bytes into |data|. Returns true on success and false on error. +bool ReadEntireStream(ReadStream* stream, std::vector<uint8_t>* data); + } // namespace dmg } // namespace safe_browsing
diff --git a/chrome/utility/safe_browsing/mac/read_stream_unittest.cc b/chrome/utility/safe_browsing/mac/read_stream_unittest.cc index 5ae66ac2..f99233b2 100644 --- a/chrome/utility/safe_browsing/mac/read_stream_unittest.cc +++ b/chrome/utility/safe_browsing/mac/read_stream_unittest.cc
@@ -134,7 +134,7 @@ ReadStreamTest<TypeParam>::CreateStream(kStreamSize); std::vector<uint8_t> data; - EXPECT_TRUE(test::ReadEntireStream(stream.get(), &data)); + EXPECT_TRUE(ReadEntireStream(stream.get(), &data)); EXPECT_EQ(kStreamSize, data.size()); }
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 07692d6..7aae7ee 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -289,6 +289,10 @@ sources += [ "accessibility/accessibility_manager.cc", "accessibility/accessibility_manager.h", + "accessibility/touch_exploration_controller.cc", + "accessibility/touch_exploration_controller.h", + "accessibility/touch_exploration_manager.cc", + "accessibility/touch_exploration_manager.h", "cast_web_view_extension.h", "cast_web_view_extension.h", "ui/aura/accessibility/automation_manager_aura.cc", @@ -316,6 +320,7 @@ "//google_apis:google_apis", "//ui/views:views", "//ui/wm/public:public", + "//ui/events:gesture_detection", ] } @@ -482,6 +487,16 @@ "//ui/events/devices:devices", "//ui/gl:test_support", ] + + if (enable_chromecast_extensions && use_aura) { + sources += [ + "accessibility/touch_exploration_controller_unittest.cc", + ] + deps += [ + "//ui/aura:test_support", + "//ui/events:test_support", + ] + } } if (is_android) {
diff --git a/chromecast/browser/accessibility/accessibility_manager.cc b/chromecast/browser/accessibility/accessibility_manager.cc index 2304883..2720e873 100644 --- a/chromecast/browser/accessibility/accessibility_manager.cc +++ b/chromecast/browser/accessibility/accessibility_manager.cc
@@ -23,6 +23,9 @@ std::make_unique<FocusRingController>(root_window, activation_client); accessibility_focus_ring_controller_ = std::make_unique<AccessibilityFocusRingController>(root_window); + touch_exploration_manager_ = std::make_unique<TouchExplorationManager>( + root_window, activation_client, + accessibility_focus_ring_controller_.get()); } AccessibilityManager::~AccessibilityManager() {} @@ -64,7 +67,7 @@ void AccessibilityManager::SetTouchAccessibilityAnchorPoint( const gfx::Point& anchor_point) { - // TODO(rdaum): Implement + touch_exploration_manager_->SetTouchAccessibilityAnchorPoint(anchor_point); } aura::WindowTreeHost* AccessibilityManager::window_tree_host() const {
diff --git a/chromecast/browser/accessibility/accessibility_manager.h b/chromecast/browser/accessibility/accessibility_manager.h index 760796e..da9669626 100644 --- a/chromecast/browser/accessibility/accessibility_manager.h +++ b/chromecast/browser/accessibility/accessibility_manager.h
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "chromecast/browser/accessibility/touch_exploration_manager.h" #include "chromecast/graphics/accessibility/accessibility_focus_ring_controller.h" namespace aura { @@ -64,6 +65,7 @@ std::unique_ptr<AccessibilityFocusRingController> accessibility_focus_ring_controller_; aura::WindowTreeHost* window_tree_host_; + std::unique_ptr<TouchExplorationManager> touch_exploration_manager_; }; } // namespace shell
diff --git a/chromecast/browser/accessibility/touch_exploration_controller.cc b/chromecast/browser/accessibility/touch_exploration_controller.cc new file mode 100644 index 0000000..8c75228 --- /dev/null +++ b/chromecast/browser/accessibility/touch_exploration_controller.cc
@@ -0,0 +1,1172 @@ +// 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. + +// Copied with modifications from //ash/accessibility, refactored for use in +// chromecast. + +#include "chromecast/browser/accessibility/touch_exploration_controller.h" + +#include <utility> + +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "ui/aura/client/cursor_client.h" +#include "ui/aura/window.h" +#include "ui/aura/window_event_dispatcher.h" +#include "ui/aura/window_tree_host.h" +#include "ui/events/event.h" +#include "ui/events/event_processor.h" +#include "ui/events/event_utils.h" +#include "ui/gfx/geometry/rect.h" + +#define SET_STATE(state) SetState(state, __func__) +#define VLOG_EVENT(event) \ + if (VLOG_IS_ON(1)) \ + VlogEvent(event, __func__) + +namespace chromecast { +namespace shell { + +namespace { + +void SetTouchAccessibilityFlag(ui::Event* event) { + // This flag is used to identify mouse move events that were generated from + // touch exploration in Chrome code. + event->set_flags(event->flags() | ui::EF_TOUCH_ACCESSIBILITY); +} + +} // namespace + +TouchExplorationController::TouchExplorationController( + aura::Window* root_window, + TouchExplorationControllerDelegate* delegate) + : root_window_(root_window), + delegate_(delegate), + state_(NO_FINGERS_DOWN), + anchor_point_state_(ANCHOR_POINT_NONE), + gesture_provider_(new ui::GestureProviderAura(this, this)), + prev_state_(NO_FINGERS_DOWN), + VLOG_on_(true) { + DCHECK(root_window); + root_window->GetHost()->GetEventSource()->AddEventRewriter(this); +} + +TouchExplorationController::~TouchExplorationController() { + root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); +} + +void TouchExplorationController::SetTouchAccessibilityAnchorPoint( + const gfx::Point& anchor_point_dip) { + gfx::Point native_point = anchor_point_dip; + anchor_point_dip_ = gfx::PointF(native_point.x(), native_point.y()); + anchor_point_state_ = ANCHOR_POINT_EXPLICITLY_SET; +} + +void TouchExplorationController::SetExcludeBounds(const gfx::Rect& bounds) { + exclude_bounds_ = bounds; +} + +void TouchExplorationController::SetLiftActivationBounds( + const gfx::Rect& bounds) { + lift_activation_bounds_ = bounds; +} + +ui::EventRewriteStatus TouchExplorationController::RewriteEvent( + const ui::Event& event, + std::unique_ptr<ui::Event>* rewritten_event) { + if (!event.IsTouchEvent()) { + if (event.IsKeyEvent()) { + const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); + VLOG(1) << "\nKeyboard event: " << key_event.GetName() + << "\n Key code: " << key_event.key_code() + << ", Flags: " << key_event.flags() + << ", Is char: " << key_event.is_char(); + } + return ui::EVENT_REWRITE_CONTINUE; + } + const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); + + if (event.type() == ui::ET_TOUCH_PRESSED) + seen_press_ = true; + + // Touch events come through in screen pixels, but untransformed. This is the + // raw coordinate not yet mapped to the root window's coordinate system or the + // screen. Convert it into the root window's coordinate system, in DIP which + // is what the rest of this class expects. + gfx::Point location = touch_event.location(); + gfx::Point root_location = touch_event.root_location(); + root_window_->GetHost()->ConvertPixelsToDIP(&location); + root_window_->GetHost()->ConvertPixelsToDIP(&root_location); + + if (!exclude_bounds_.IsEmpty()) { + bool in_exclude_area = exclude_bounds_.Contains(location); + if (in_exclude_area) { + if (state_ == NO_FINGERS_DOWN) + return ui::EVENT_REWRITE_CONTINUE; + if (touch_event.type() == ui::ET_TOUCH_MOVED || + touch_event.type() == ui::ET_TOUCH_PRESSED) { + return ui::EVENT_REWRITE_DISCARD; + } + // Otherwise, continue handling events. Basically, we want to let + // CANCELLED or RELEASE events through so this can get back to + // the NO_FINGERS_DOWN state. + } + } + + // If the tap timer should have fired by now but hasn't, run it now and + // stop the timer. This is important so that behavior is consistent with + // the timestamps of the events, and not dependent on the granularity of + // the timer. + if (tap_timer_.IsRunning() && + touch_event.time_stamp() - most_recent_press_timestamp_ > + gesture_detector_config_.double_tap_timeout) { + tap_timer_.Stop(); + OnTapTimerFired(); + // Note: this may change the state. We should now continue and process + // this event under this new state. + } + + if (passthrough_timer_.IsRunning() && + event.time_stamp() - most_recent_press_timestamp_ > + gesture_detector_config_.longpress_timeout) { + passthrough_timer_.Stop(); + OnPassthroughTimerFired(); + } + + const ui::EventType type = touch_event.type(); + const int touch_id = touch_event.pointer_details().id; + + // Always update touch ids and touch locations, so we can use those + // no matter what state we're in. + if (type == ui::ET_TOUCH_PRESSED) { + current_touch_ids_.push_back(touch_id); + touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); + } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { + std::vector<int>::iterator it = std::find( + current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); + + // Can happen if touch exploration is enabled while fingers were down + // or if an additional press occurred within the exclusion bounds. + if (it == current_touch_ids_.end()) { + // If we get a RELEASE event and we've never seen a PRESS event + // since TouchExplorationController was instantiated, cancel the + // event so that touch gestures that enable spoken feedback + // don't accidentally trigger other behaviors on release. + if (!seen_press_) { + std::unique_ptr<ui::TouchEvent> new_event(new ui::TouchEvent( + ui::ET_TOUCH_CANCELLED, gfx::Point(), touch_event.time_stamp(), + touch_event.pointer_details())); + new_event->set_location(location); + new_event->set_root_location(root_location); + new_event->set_flags(touch_event.flags()); + *rewritten_event = std::move(new_event); + return ui::EVENT_REWRITE_REWRITTEN; + } + + // Otherwise just pass it through. + return ui::EVENT_REWRITE_CONTINUE; + } + + current_touch_ids_.erase(it); + touch_locations_.erase(touch_id); + } else if (type == ui::ET_TOUCH_MOVED) { + std::vector<int>::iterator it = std::find( + current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); + + // Can happen if touch exploration is enabled while fingers were down. + if (it == current_touch_ids_.end()) + return ui::EVENT_REWRITE_CONTINUE; + + touch_locations_[*it] = gfx::PointF(location); + } else { + NOTREACHED() << "Unexpected event type received: " << event.GetName(); + return ui::EVENT_REWRITE_CONTINUE; + } + VLOG_EVENT(touch_event); + + // In order to avoid accidentally double tapping when moving off the edge + // of the screen, the state will be rewritten to NoFingersDown. + if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) && + FindEdgesWithinInset(location, kLeavingScreenEdge) != NO_EDGE) { + if (VLOG_on_) + VLOG(1) << "Leaving screen"; + + // Indicates to the user that they are leaving the screen. + delegate_->PlayExitScreenEarcon(); + + if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + if (VLOG_on_) { + VLOG(1) << "Reset to no fingers in Rewrite event because the touch " + "release or cancel was on the edge of the screen."; + } + return ui::EVENT_REWRITE_DISCARD; + } + } + + // We now need a TouchEvent that has its coordinates mapped into root window + // DIP. + ui::TouchEvent touch_event_dip = touch_event; + touch_event_dip.set_location(location); + + // If the user is in a gesture state, or if there is a possiblity that the + // user will enter it in the future, we send the event to the gesture + // provider so it can keep track of the state of the fingers. When the user + // leaves one of these states, SET_STATE will set the gesture provider to + // NULL. + if (gesture_provider_.get()) { + if (gesture_provider_->OnTouchEvent(&touch_event_dip)) { + gesture_provider_->OnTouchEventAck( + touch_event_dip.unique_event_id(), false /* event_consumed */, + false /* is_source_touch_event_set_non_blocking */); + } + ProcessGestureEvents(); + } + + ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; + // The rest of the processing depends on what state we're in. + switch (state_) { + case NO_FINGERS_DOWN: + status = InNoFingersDown(touch_event_dip, rewritten_event); + break; + case SINGLE_TAP_PRESSED: + status = InSingleTapPressed(touch_event_dip, rewritten_event); + break; + case SINGLE_TAP_RELEASED: + case TOUCH_EXPLORE_RELEASED: + status = + InSingleTapOrTouchExploreReleased(touch_event_dip, rewritten_event); + break; + case DOUBLE_TAP_PENDING: + status = InDoubleTapPending(touch_event_dip, rewritten_event); + break; + case TOUCH_RELEASE_PENDING: + status = InTouchReleasePending(touch_event_dip, rewritten_event); + break; + case TOUCH_EXPLORATION: + status = InTouchExploration(touch_event_dip, rewritten_event); + break; + case GESTURE_IN_PROGRESS: + status = InGestureInProgress(touch_event_dip, rewritten_event); + break; + case TOUCH_EXPLORE_SECOND_PRESS: + status = InTouchExploreSecondPress(touch_event_dip, rewritten_event); + break; + case ONE_FINGER_PASSTHROUGH: + status = InOneFingerPassthrough(touch_event_dip, rewritten_event); + break; + case CORNER_PASSTHROUGH: + status = InCornerPassthrough(touch_event_dip, rewritten_event); + break; + case WAIT_FOR_NO_FINGERS: + status = InWaitForNoFingers(touch_event_dip, rewritten_event); + break; + case TWO_FINGER_TAP: + status = InTwoFingerTap(touch_event_dip, rewritten_event); + break; + case EDGE_PASSTHROUGH: + status = InEdgePassthrough(touch_event, rewritten_event); + break; + } + if (status == ui::EVENT_REWRITE_REWRITTEN) { + DCHECK(rewritten_event->get()); + SetTouchAccessibilityFlag(rewritten_event->get()); + } + return status; +} + +ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( + const ui::Event& last_event, + std::unique_ptr<ui::Event>* new_event) { + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; +} + +ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + const ui::EventType type = event.type(); + if (type != ui::ET_TOUCH_PRESSED) { + NOTREACHED() << "Unexpected event type received: " << event.GetName(); + return ui::EVENT_REWRITE_CONTINUE; + } + + // If the user enters the screen from the edge then send an earcon, + // and enter passthrough mode so that the system gesture handle can + // handle it. + int edge = FindEdgesWithinInset(event.location(), kLeavingScreenEdge); + if (edge != NO_EDGE) { + delegate_->PlayEnterScreenEarcon(); + SET_STATE(EDGE_PASSTHROUGH); + return ui::EVENT_REWRITE_CONTINUE; + } + + int location = FindEdgesWithinInset(event.location(), kSlopDistanceFromEdge); + // If the press was at a corner, the user might go into corner passthrough + // instead. + bool in_a_bottom_corner = + (BOTTOM_LEFT_CORNER == location) || (BOTTOM_RIGHT_CORNER == location); + if (in_a_bottom_corner) { + passthrough_timer_.Start( + FROM_HERE, gesture_detector_config_.longpress_timeout, this, + &TouchExplorationController::OnPassthroughTimerFired); + } + initial_press_ = std::make_unique<ui::TouchEvent>(event); + most_recent_press_timestamp_ = initial_press_->time_stamp(); + initial_presses_[event.pointer_details().id] = event.location(); + last_unused_finger_event_ = std::make_unique<ui::TouchEvent>(event); + StartTapTimer(); + SET_STATE(SINGLE_TAP_PRESSED); + return ui::EVENT_REWRITE_DISCARD; +} + +ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + const ui::EventType type = event.type(); + + int location = FindEdgesWithinInset(event.location(), kMaxDistanceFromEdge); + bool in_a_bottom_corner = + (location == BOTTOM_LEFT_CORNER) || (location == BOTTOM_RIGHT_CORNER); + // If the event is from the initial press and the location is no longer in the + // corner, then we are not waiting for a corner passthrough anymore. + if (event.pointer_details().id == initial_press_->pointer_details().id && + !in_a_bottom_corner) { + if (passthrough_timer_.IsRunning()) { + passthrough_timer_.Stop(); + // Since the long press timer has been running, it is possible that the + // tap timer has timed out before the long press timer has. If the tap + // timer timeout has elapsed, then fire the tap timer. + if (event.time_stamp() - most_recent_press_timestamp_ > + gesture_detector_config_.double_tap_timeout) { + OnTapTimerFired(); + } + } + } + + if (type == ui::ET_TOUCH_PRESSED) { + initial_presses_[event.pointer_details().id] = event.location(); + SET_STATE(TWO_FINGER_TAP); + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { + if (passthrough_timer_.IsRunning()) + passthrough_timer_.Stop(); + if (current_touch_ids_.size() == 0 && + event.pointer_details().id == initial_press_->pointer_details().id) { + MaybeSendSimulatedTapInLiftActivationBounds(event); + SET_STATE(SINGLE_TAP_RELEASED); + } else if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + } + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_MOVED) { + float distance = (event.location() - initial_press_->location()).Length(); + // If the user does not move far enough from the original position, then the + // resulting movement should not be considered to be a deliberate gesture or + // touch exploration. + if (distance <= gesture_detector_config_.touch_slop) + return ui::EVENT_REWRITE_DISCARD; + + float delta_time = + (event.time_stamp() - most_recent_press_timestamp_).InSecondsF(); + float velocity = distance / delta_time; + if (VLOG_on_) { + VLOG(1) << "\n Delta time: " << delta_time << "\n Distance: " << distance + << "\n Velocity of click: " << velocity + << "\n Minimum swipe velocity: " + << gesture_detector_config_.minimum_swipe_velocity; + } + + // If the user moves fast enough from the initial touch location, start + // gesture detection. Otherwise, jump to the touch exploration mode early. + if (velocity > gesture_detector_config_.minimum_swipe_velocity) { + SET_STATE(GESTURE_IN_PROGRESS); + return InGestureInProgress(event, rewritten_event); + } + anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; + EnterTouchToMouseMode(); + SET_STATE(TOUCH_EXPLORATION); + return InTouchExploration(event, rewritten_event); + } + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; +} + +ui::EventRewriteStatus +TouchExplorationController::InSingleTapOrTouchExploreReleased( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + const ui::EventType type = event.type(); + // If there is more than one finger down, then discard to wait until no + // fingers are down. + if (current_touch_ids_.size() > 1) { + SET_STATE(WAIT_FOR_NO_FINGERS); + return ui::EVENT_REWRITE_DISCARD; + } + if (type == ui::ET_TOUCH_PRESSED) { + // If there is no anchor point for synthesized events because the + // user hasn't touch-explored or focused anything yet, we can't + // send a click, so discard. + if (anchor_point_state_ == ANCHOR_POINT_NONE) { + tap_timer_.Stop(); + return ui::EVENT_REWRITE_DISCARD; + } + // This is the second tap in a double-tap (or double tap-hold). + // We set the tap timer. If it fires before the user lifts their finger, + // one-finger passthrough begins. Otherwise, there is a touch press and + // release at the location of the last touch exploration. + SET_STATE(DOUBLE_TAP_PENDING); + // The old tap timer (from the initial click) is stopped if it is still + // going, and the new one is set. + tap_timer_.Stop(); + StartTapTimer(); + most_recent_press_timestamp_ = event.time_stamp(); + // This will update as the finger moves before a possible passthrough, and + // will determine the offset. + last_unused_finger_event_.reset(new ui::TouchEvent(event)); + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_RELEASED && + anchor_point_state_ == ANCHOR_POINT_NONE) { + // If the previous press was discarded, we need to also handle its + // release. + if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + } + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_MOVED) { + return ui::EVENT_REWRITE_DISCARD; + } + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; +} + +ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + const ui::EventType type = event.type(); + if (type == ui::ET_TOUCH_PRESSED) { + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_MOVED) { + // If the user moves far enough from the initial touch location (outside + // the "slop" region, jump to passthrough mode early. + float delta = (event.location() - initial_press_->location()).Length(); + if (delta > gesture_detector_config_.double_tap_slop) { + tap_timer_.Stop(); + OnTapTimerFired(); + } + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { + if (current_touch_ids_.size() != 0) + return ui::EVENT_REWRITE_DISCARD; + + SendSimulatedClickOrTap(); + + SET_STATE(NO_FINGERS_DOWN); + return ui::EVENT_REWRITE_DISCARD; + } + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; +} + +ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + const ui::EventType type = event.type(); + if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { + if (current_touch_ids_.size() != 0) + return ui::EVENT_REWRITE_DISCARD; + + SendSimulatedClickOrTap(); + SET_STATE(NO_FINGERS_DOWN); + return ui::EVENT_REWRITE_DISCARD; + } + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; +} + +ui::EventRewriteStatus TouchExplorationController::InTouchExploration( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + const ui::EventType type = event.type(); + if (type == ui::ET_TOUCH_PRESSED) { + // Enter split-tap mode. + initial_press_ = std::make_unique<ui::TouchEvent>(event); + tap_timer_.Stop(); + SET_STATE(TOUCH_EXPLORE_SECOND_PRESS); + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { + initial_press_ = std::make_unique<ui::TouchEvent>(event); + StartTapTimer(); + most_recent_press_timestamp_ = event.time_stamp(); + MaybeSendSimulatedTapInLiftActivationBounds(event); + SET_STATE(TOUCH_EXPLORE_RELEASED); + } else if (type != ui::ET_TOUCH_MOVED) { + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; + } + + // Rewrite as a mouse-move event. + gfx::Point location_dip = event.location(); + + // |event| locations are in DIP; see |RewriteEvent|. We need to dispatch + // |screen coords. + root_window_->GetHost()->ConvertDIPToScreenInPixels(&location_dip); + gfx::PointF location_f(location_dip.x(), location_dip.y()); + *rewritten_event = CreateMouseMoveEvent(location_f, event.flags()); + last_touch_exploration_ = std::make_unique<ui::TouchEvent>(event); + if (anchor_point_state_ != ANCHOR_POINT_EXPLICITLY_SET) + anchor_point_dip_ = last_touch_exploration_->location_f(); + + return ui::EVENT_REWRITE_REWRITTEN; +} + +ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + // The events were sent to the gesture provider in RewriteEvent already. + // If no gesture is registered before the tap timer times out, the state + // will change to "wait for no fingers down" or "touch exploration" depending + // on the number of fingers down, and this function will stop being called. + if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + } + return ui::EVENT_REWRITE_DISCARD; +} + +ui::EventRewriteStatus TouchExplorationController::InCornerPassthrough( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + ui::EventType type = event.type(); + + // If the first finger has left the corner, then exit passthrough. + if (event.pointer_details().id == initial_press_->pointer_details().id) { + int edges = FindEdgesWithinInset(event.location(), kSlopDistanceFromEdge); + bool in_a_bottom_corner = + (edges == BOTTOM_LEFT_CORNER) || (edges == BOTTOM_RIGHT_CORNER); + if (type == ui::ET_TOUCH_MOVED && in_a_bottom_corner) + return ui::EVENT_REWRITE_DISCARD; + + if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + return ui::EVENT_REWRITE_DISCARD; + } + SET_STATE(WAIT_FOR_NO_FINGERS); + return ui::EVENT_REWRITE_DISCARD; + } + + std::unique_ptr<ui::TouchEvent> new_event(new ui::TouchEvent( + type, gfx::Point(), event.time_stamp(), event.pointer_details())); + new_event->set_location_f(event.location_f()); + new_event->set_root_location_f(event.location_f()); + new_event->set_flags(event.flags()); + *rewritten_event = std::move(new_event); + + if (current_touch_ids_.size() == 0) + SET_STATE(NO_FINGERS_DOWN); + + return ui::EVENT_REWRITE_REWRITTEN; +} + +ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + if (event.pointer_details().id != initial_press_->pointer_details().id) { + if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + } + return ui::EVENT_REWRITE_DISCARD; + } + std::unique_ptr<ui::TouchEvent> new_event(new ui::TouchEvent( + event.type(), gfx::Point(), event.time_stamp(), event.pointer_details())); + new_event->set_location_f(event.location_f() - passthrough_offset_); + new_event->set_root_location_f(event.location_f() - passthrough_offset_); + new_event->set_flags(event.flags()); + *rewritten_event = std::move(new_event); + if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + } + return ui::EVENT_REWRITE_REWRITTEN; +} + +ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + ui::EventType type = event.type(); + if (type == ui::ET_TOUCH_PRESSED) { + // A third finger being pressed means that a split tap can no longer go + // through. The user enters the wait state, Since there has already been + // a press dispatched when split tap began, the touch needs to be + // cancelled. + std::unique_ptr<ui::TouchEvent> new_event(new ui::TouchEvent( + ui::ET_TOUCH_CANCELLED, gfx::Point(), event.time_stamp(), + initial_press_->pointer_details())); + // TODO(dmazzoni): fix for multiple displays. http://crbug.com/616793 + new_event->set_location_f(anchor_point_dip_); + new_event->set_root_location_f(anchor_point_dip_); + new_event->set_flags(event.flags()); + *rewritten_event = std::move(new_event); + SET_STATE(WAIT_FOR_NO_FINGERS); + return ui::EVENT_REWRITE_REWRITTEN; + } else if (type == ui::ET_TOUCH_MOVED) { + // If the fingers have moved too far from their original locations, + // the user can no longer split tap. + ui::TouchEvent* original_touch; + if (event.pointer_details().id == + last_touch_exploration_->pointer_details().id) { + original_touch = last_touch_exploration_.get(); + } else if (event.pointer_details().id == + initial_press_->pointer_details().id) { + original_touch = initial_press_.get(); + } else { + NOTREACHED(); + SET_STATE(WAIT_FOR_NO_FINGERS); + return ui::EVENT_REWRITE_DISCARD; + } + // Check the distance between the current finger location and the original + // location. The slop for this is a bit more generous since keeping two + // fingers in place is a bit harder. If the user has left the slop, the + // user enters the wait state. + if ((event.location_f() - original_touch->location_f()).Length() > + GetSplitTapTouchSlop()) { + SET_STATE(WAIT_FOR_NO_FINGERS); + } + return ui::EVENT_REWRITE_DISCARD; + } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { + // If the touch exploration finger is lifted, there is no option to return + // to touch explore anymore. The remaining finger acts as a pending + // tap or long tap for the last touch explore location. + if (event.pointer_details().id == + last_touch_exploration_->pointer_details().id) { + SET_STATE(TOUCH_RELEASE_PENDING); + return ui::EVENT_REWRITE_DISCARD; + } + + // Continue to release the touch only if the touch explore finger is the + // only finger remaining. + if (current_touch_ids_.size() != 1) + return ui::EVENT_REWRITE_DISCARD; + + SendSimulatedClickOrTap(); + + SET_STATE(TOUCH_EXPLORATION); + EnterTouchToMouseMode(); + return ui::EVENT_REWRITE_DISCARD; + } + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; +} + +ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + if (current_touch_ids_.size() == 0) + SET_STATE(NO_FINGERS_DOWN); + return ui::EVENT_REWRITE_DISCARD; +} + +void TouchExplorationController::SendSimulatedClickOrTap() { + // If we got an anchor point from ChromeVox, send a double-tap gesture + // and let ChromeVox handle the click. + if (anchor_point_state_ == ANCHOR_POINT_EXPLICITLY_SET) { + delegate_->HandleAccessibilityGesture(ax::mojom::Gesture::kClick); + return; + } + SendSimulatedTap(); +} + +void TouchExplorationController::SendSimulatedTap() { + gfx::Point screen_point(anchor_point_dip_.x(), anchor_point_dip_.y()); + root_window_->GetHost()->ConvertDIPToScreenInPixels(&screen_point); + std::unique_ptr<ui::TouchEvent> touch_press; + touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), + Now(), + initial_press_->pointer_details())); + touch_press->set_location(screen_point); + touch_press->set_root_location(screen_point); + DispatchEvent(touch_press.get()); + + std::unique_ptr<ui::TouchEvent> touch_release; + touch_release.reset(new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(), + Now(), + initial_press_->pointer_details())); + touch_release->set_location(screen_point); + touch_release->set_root_location(screen_point); + DispatchEvent(touch_release.get()); +} + +void TouchExplorationController::MaybeSendSimulatedTapInLiftActivationBounds( + const ui::TouchEvent& event) { + gfx::Point location = event.location(); + gfx::Point anchor_location(anchor_point_dip_.x(), anchor_point_dip_.y()); + if (lift_activation_bounds_.Contains(anchor_location.x(), + anchor_location.y()) && + lift_activation_bounds_.Contains(location)) { + delegate_->PlayTouchTypeEarcon(); + SendSimulatedTap(); + } +} + +ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + ui::EventType type = event.type(); + if (type == ui::ET_TOUCH_PRESSED) { + // This is now a three finger gesture. + SET_STATE(GESTURE_IN_PROGRESS); + return ui::EVENT_REWRITE_DISCARD; + } + + if (type == ui::ET_TOUCH_MOVED) { + // Determine if it was a swipe. + gfx::Point original_location = initial_presses_[event.pointer_details().id]; + float distance = (event.location() - original_location).Length(); + // If the user moves too far from the original position, consider the + // movement a swipe. + if (distance > gesture_detector_config_.touch_slop) { + SET_STATE(GESTURE_IN_PROGRESS); + } + return ui::EVENT_REWRITE_DISCARD; + } + + if (current_touch_ids_.size() != 0) + return ui::EVENT_REWRITE_DISCARD; + + if (type == ui::ET_TOUCH_RELEASED) { + delegate_->HandleAccessibilityGesture(ax::mojom::Gesture::kTap2); + SET_STATE(NO_FINGERS_DOWN); + return ui::EVENT_REWRITE_DISCARD; + } + return ui::EVENT_REWRITE_DISCARD; +} + +ui::EventRewriteStatus TouchExplorationController::InEdgePassthrough( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + if (current_touch_ids_.size() == 0) { + SET_STATE(NO_FINGERS_DOWN); + } + std::unique_ptr<ui::TouchEvent> new_event(new ui::TouchEvent( + event.type(), gfx::Point(), event.time_stamp(), event.pointer_details())); + new_event->set_location_f(event.location_f()); + new_event->set_root_location_f(event.location_f()); + new_event->set_flags(event.flags()); + *rewritten_event = std::move(new_event); + return ui::EVENT_REWRITE_REWRITTEN; +} + +base::TimeTicks TouchExplorationController::Now() { + return ui::EventTimeForNow(); +} + +void TouchExplorationController::StartTapTimer() { + tap_timer_.Start(FROM_HERE, gesture_detector_config_.double_tap_timeout, this, + &TouchExplorationController::OnTapTimerFired); +} + +void TouchExplorationController::OnTapTimerFired() { + switch (state_) { + case SINGLE_TAP_RELEASED: + SET_STATE(NO_FINGERS_DOWN); + break; + case TOUCH_EXPLORE_RELEASED: + SET_STATE(NO_FINGERS_DOWN); + last_touch_exploration_ = + std::make_unique<ui::TouchEvent>(*initial_press_); + anchor_point_dip_ = last_touch_exploration_->location_f(); + anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; + return; + case DOUBLE_TAP_PENDING: { + SET_STATE(ONE_FINGER_PASSTHROUGH); + passthrough_offset_ = + last_unused_finger_event_->location_f() - anchor_point_dip_; + std::unique_ptr<ui::TouchEvent> passthrough_press( + new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), Now(), + last_unused_finger_event_->pointer_details())); + passthrough_press->set_location_f(anchor_point_dip_); + passthrough_press->set_root_location_f(anchor_point_dip_); + DispatchEvent(passthrough_press.get()); + return; + } + case SINGLE_TAP_PRESSED: + if (passthrough_timer_.IsRunning()) + return; + FALLTHROUGH; + case GESTURE_IN_PROGRESS: + // If only one finger is down, go into touch exploration. + if (current_touch_ids_.size() == 1) { + anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; + EnterTouchToMouseMode(); + SET_STATE(TOUCH_EXPLORATION); + break; + } + // Otherwise wait for all fingers to be lifted. + SET_STATE(WAIT_FOR_NO_FINGERS); + return; + case TWO_FINGER_TAP: + SET_STATE(WAIT_FOR_NO_FINGERS); + break; + default: + return; + } + EnterTouchToMouseMode(); + std::unique_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( + initial_press_->location_f(), initial_press_->flags()); + DispatchEvent(mouse_move.get()); + last_touch_exploration_ = std::make_unique<ui::TouchEvent>(*initial_press_); + anchor_point_dip_ = last_touch_exploration_->location_f(); + anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION; +} + +void TouchExplorationController::OnPassthroughTimerFired() { + // The passthrough timer will only fire if if the user has held a finger in + // one of the passthrough corners for the duration of the passthrough timeout. + + // Check that initial press isn't null. Also a check that if the initial + // corner press was released, then it should not be in corner passthrough. + if (!initial_press_ || + touch_locations_.find(initial_press_->pointer_details().id) != + touch_locations_.end()) { + } + + gfx::Point location = + ToRoundedPoint(touch_locations_[initial_press_->pointer_details().id]); + int corner = FindEdgesWithinInset(location, kSlopDistanceFromEdge); + if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) + return; + + if (sound_timer_.IsRunning()) + sound_timer_.Stop(); + delegate_->PlayPassthroughEarcon(); + SET_STATE(CORNER_PASSTHROUGH); + return; +} + +void TouchExplorationController::DispatchEvent(ui::Event* event) { + SetTouchAccessibilityFlag(event); + ignore_result( + root_window_->GetHost()->dispatcher()->OnEventFromSource(event)); +} + +// This is an override for a function that is only called for timer-based events +// like long press. Events that are created synchronously as a result of +// certain touch events are added to the vector accessible via +// GetAndResetPendingGestures(). We only care about swipes (which are created +// synchronously), so we ignore this callback. +void TouchExplorationController::OnGestureEvent(ui::GestureConsumer* consumer, + ui::GestureEvent* gesture) {} + +void TouchExplorationController::ProcessGestureEvents() { + std::vector<std::unique_ptr<ui::GestureEvent>> gestures = + gesture_provider_->GetAndResetPendingGestures(); + bool resolved_gesture = false; + max_gesture_touch_points_ = + std::max(max_gesture_touch_points_, current_touch_ids_.size()); + for (const auto& gesture : gestures) { + if (gesture->type() == ui::ET_GESTURE_SWIPE && + state_ == GESTURE_IN_PROGRESS) { + OnSwipeEvent(gesture.get()); + // The tap timer to leave gesture state is ended, and we now wait for + // all fingers to be released. + tap_timer_.Stop(); + SET_STATE(WAIT_FOR_NO_FINGERS); + return; + } + } + + if (resolved_gesture) + return; + + if (current_touch_ids_.size() == 0) { + switch (max_gesture_touch_points_) { + case 3: + delegate_->HandleAccessibilityGesture(ax::mojom::Gesture::kTap3); + break; + case 4: + delegate_->HandleAccessibilityGesture(ax::mojom::Gesture::kTap4); + break; + default: + break; + } + max_gesture_touch_points_ = 0; + } +} + +void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { + // A swipe gesture contains details for the direction in which the swipe + // occurred. TODO(evy) : Research which swipe results users most want and + // remap these swipes to the best events. Hopefully in the near future + // there will also be a menu for users to pick custom mappings. + ui::GestureEventDetails event_details = swipe_gesture->details(); + int num_fingers = event_details.touch_points(); + if (VLOG_on_) + VLOG(1) << "\nSwipe with " << num_fingers << " fingers."; + + ax::mojom::Gesture gesture = ax::mojom::Gesture::kNone; + if (event_details.swipe_left()) { + switch (num_fingers) { + case 1: + gesture = ax::mojom::Gesture::kSwipeLeft1; + break; + case 2: + gesture = ax::mojom::Gesture::kSwipeLeft2; + break; + case 3: + gesture = ax::mojom::Gesture::kSwipeLeft3; + break; + case 4: + gesture = ax::mojom::Gesture::kSwipeLeft4; + break; + default: + break; + } + } else if (event_details.swipe_up()) { + switch (num_fingers) { + case 1: + gesture = ax::mojom::Gesture::kSwipeUp1; + break; + case 2: + gesture = ax::mojom::Gesture::kSwipeUp2; + break; + case 3: + gesture = ax::mojom::Gesture::kSwipeUp3; + break; + case 4: + gesture = ax::mojom::Gesture::kSwipeUp4; + break; + default: + break; + } + } else if (event_details.swipe_right()) { + switch (num_fingers) { + case 1: + gesture = ax::mojom::Gesture::kSwipeRight1; + break; + case 2: + gesture = ax::mojom::Gesture::kSwipeRight2; + break; + case 3: + gesture = ax::mojom::Gesture::kSwipeRight3; + break; + case 4: + gesture = ax::mojom::Gesture::kSwipeRight4; + break; + default: + break; + } + } else if (event_details.swipe_down()) { + switch (num_fingers) { + case 1: + gesture = ax::mojom::Gesture::kSwipeDown1; + break; + case 2: + gesture = ax::mojom::Gesture::kSwipeDown2; + break; + case 3: + gesture = ax::mojom::Gesture::kSwipeDown3; + break; + case 4: + gesture = ax::mojom::Gesture::kSwipeDown4; + break; + default: + break; + } + } + + if (gesture != ax::mojom::Gesture::kNone) + delegate_->HandleAccessibilityGesture(gesture); +} + +int TouchExplorationController::FindEdgesWithinInset(gfx::Point point_dip, + float inset) { + gfx::RectF inner_bounds_dip(root_window_->bounds()); + inner_bounds_dip.Inset(inset, inset); + + // Bitwise manipulation in order to determine where on the screen the point + // lies. If more than one bit is turned on, then it is a corner where the two + // bit/edges intersect. Otherwise, if no bits are turned on, the point must be + // in the center of the screen. + int result = NO_EDGE; + if (point_dip.x() < inner_bounds_dip.x()) + result |= LEFT_EDGE; + if (point_dip.x() > inner_bounds_dip.right()) + result |= RIGHT_EDGE; + if (point_dip.y() < inner_bounds_dip.y()) + result |= TOP_EDGE; + if (point_dip.y() > inner_bounds_dip.bottom()) + result |= BOTTOM_EDGE; + return result; +} + +void TouchExplorationController::DispatchKeyWithFlags( + const ui::KeyboardCode key, + int flags) { + ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags); + ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags); + DispatchEvent(&key_down); + DispatchEvent(&key_up); + if (VLOG_on_) { + VLOG(1) << "\nKey down: key code : " << key_down.key_code() + << ", flags: " << key_down.flags() + << "\nKey up: key code : " << key_up.key_code() + << ", flags: " << key_up.flags(); + } +} + +base::OnceClosure TouchExplorationController::BindKeyEventWithFlags( + const ui::KeyboardCode key, + int flags) { + return base::BindOnce(&TouchExplorationController::DispatchKeyWithFlags, + base::Unretained(this), key, flags); +} + +std::unique_ptr<ui::MouseEvent> +TouchExplorationController::CreateMouseMoveEvent(const gfx::PointF& location, + int flags) { + // The "synthesized" flag should be set on all events that don't have a + // backing native event. + flags |= ui::EF_IS_SYNTHESIZED; + + // TODO(dmazzoni) http://crbug.com/391008 - get rid of this hack. + // This is a short-term workaround for the limitation that we're using + // the ChromeVox content script to process touch exploration events, but + // ChromeVox needs a way to distinguish between a real mouse move and a + // mouse move generated from touch exploration, so we have touch exploration + // pretend that the command key was down (which becomes the "meta" key in + // JavaScript). We can remove this hack when the ChromeVox content script + // goes away and native accessibility code sends a touch exploration + // event to the new ChromeVox background page via the automation api. + flags |= ui::EF_COMMAND_DOWN; + + std::unique_ptr<ui::MouseEvent> event(new ui::MouseEvent( + ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), Now(), flags, 0)); + event->set_location_f(location); + event->set_root_location_f(location); + return event; +} + +void TouchExplorationController::EnterTouchToMouseMode() { + aura::client::CursorClient* cursor_client = + aura::client::GetCursorClient(root_window_); + if (cursor_client && !cursor_client->IsMouseEventsEnabled()) + cursor_client->EnableMouseEvents(); + if (cursor_client && cursor_client->IsCursorVisible()) + cursor_client->HideCursor(); +} + +void TouchExplorationController::SetState(State new_state, + const char* function_name) { + state_ = new_state; + VlogState(function_name); + // These are the states the user can be in that will never result in a + // gesture before the user returns to NO_FINGERS_DOWN. Therefore, if the + // gesture provider still exists, it's reset to NULL until the user returns + // to NO_FINGERS_DOWN. + switch (new_state) { + case SINGLE_TAP_RELEASED: + case TOUCH_EXPLORE_RELEASED: + case DOUBLE_TAP_PENDING: + case TOUCH_RELEASE_PENDING: + case TOUCH_EXPLORATION: + case TOUCH_EXPLORE_SECOND_PRESS: + case ONE_FINGER_PASSTHROUGH: + case CORNER_PASSTHROUGH: + case WAIT_FOR_NO_FINGERS: + case EDGE_PASSTHROUGH: + if (gesture_provider_.get()) + gesture_provider_.reset(NULL); + max_gesture_touch_points_ = 0; + break; + case NO_FINGERS_DOWN: + gesture_provider_ = std::make_unique<ui::GestureProviderAura>(this, this); + if (sound_timer_.IsRunning()) + sound_timer_.Stop(); + tap_timer_.Stop(); + break; + case SINGLE_TAP_PRESSED: + case GESTURE_IN_PROGRESS: + case TWO_FINGER_TAP: + break; + } +} + +void TouchExplorationController::VlogState(const char* function_name) { + if (!VLOG_on_) + return; + if (prev_state_ == state_) + return; + prev_state_ = state_; + const char* state_string = EnumStateToString(state_); + VLOG(1) << "\n Function name: " << function_name + << "\n State: " << state_string; +} + +void TouchExplorationController::VlogEvent(const ui::TouchEvent& touch_event, + const char* function_name) { + if (!VLOG_on_) + return; + + if (prev_event_ && prev_event_->type() == touch_event.type() && + prev_event_->pointer_details().id == touch_event.pointer_details().id) { + return; + } + // The above statement prevents events of the same type and id from being + // printed in a row. However, if two fingers are down, they would both be + // moving and alternating printing move events unless we check for this. + if (prev_event_ && prev_event_->type() == ui::ET_TOUCH_MOVED && + touch_event.type() == ui::ET_TOUCH_MOVED) { + return; + } + + const std::string& type = touch_event.GetName(); + const gfx::PointF& location = touch_event.location_f(); + const int touch_id = touch_event.pointer_details().id; + + VLOG(1) << "\n Function name: " << function_name << "\n Event Type: " << type + << "\n Location: " << location.ToString() + << "\n Touch ID: " << touch_id; + prev_event_ = std::make_unique<ui::TouchEvent>(touch_event); +} + +const char* TouchExplorationController::EnumStateToString(State state) { + switch (state) { + case NO_FINGERS_DOWN: + return "NO_FINGERS_DOWN"; + case SINGLE_TAP_PRESSED: + return "SINGLE_TAP_PRESSED"; + case SINGLE_TAP_RELEASED: + return "SINGLE_TAP_RELEASED"; + case TOUCH_EXPLORE_RELEASED: + return "TOUCH_EXPLORE_RELEASED"; + case DOUBLE_TAP_PENDING: + return "DOUBLE_TAP_PENDING"; + case TOUCH_RELEASE_PENDING: + return "TOUCH_RELEASE_PENDING"; + case TOUCH_EXPLORATION: + return "TOUCH_EXPLORATION"; + case GESTURE_IN_PROGRESS: + return "GESTURE_IN_PROGRESS"; + case TOUCH_EXPLORE_SECOND_PRESS: + return "TOUCH_EXPLORE_SECOND_PRESS"; + case CORNER_PASSTHROUGH: + return "CORNER_PASSTHROUGH"; + case ONE_FINGER_PASSTHROUGH: + return "ONE_FINGER_PASSTHROUGH"; + case WAIT_FOR_NO_FINGERS: + return "WAIT_FOR_NO_FINGERS"; + case TWO_FINGER_TAP: + return "TWO_FINGER_TAP"; + case EDGE_PASSTHROUGH: + return "EDGE_PASSTHROUGH"; + } + return "Not a state"; +} + +float TouchExplorationController::GetSplitTapTouchSlop() { + return gesture_detector_config_.touch_slop * 3; +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/browser/accessibility/touch_exploration_controller.h b/chromecast/browser/accessibility/touch_exploration_controller.h new file mode 100644 index 0000000..d1544ea --- /dev/null +++ b/chromecast/browser/accessibility/touch_exploration_controller.h
@@ -0,0 +1,540 @@ +// 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. + +// Copied with modifications from //ash/accessibility, refactored for use in +// chromecast. + +#ifndef CHROMECAST_BROWSER_ACCESSIBILITY_TOUCH_EXPLORATION_CONTROLLER_H_ +#define CHROMECAST_BROWSER_ACCESSIBILITY_TOUCH_EXPLORATION_CONTROLLER_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" +#include "base/values.h" +#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/events/event.h" +#include "ui/events/event_rewriter.h" +#include "ui/events/gesture_detection/gesture_detector.h" +#include "ui/events/gestures/gesture_provider_aura.h" +#include "ui/gfx/geometry/point.h" + +namespace aura { +class Window; +} + +namespace ui { +class Event; +class GestureEvent; +class GestureProviderAura; +class TouchEvent; +} // namespace ui + +namespace chromecast { +namespace shell { + +// A delegate to handle commands in response to detected accessibility gesture +// events. +class TouchExplorationControllerDelegate { + public: + virtual ~TouchExplorationControllerDelegate() {} + + // This function should be called when the passthrough earcon should be + // played. + virtual void PlayPassthroughEarcon() = 0; + + // This function should be called when the exit screen earcon should be + // played. + virtual void PlayExitScreenEarcon() = 0; + + // This function should be called when the enter screen earcon should be + // played. + virtual void PlayEnterScreenEarcon() = 0; + + // This function should be called when the touch type earcon should + // be played. + virtual void PlayTouchTypeEarcon() = 0; + + // Called when the user performed an accessibility gesture while in touch + // accessibility mode, that should be forwarded to ChromeVox. + virtual void HandleAccessibilityGesture(ax::mojom::Gesture gesture) = 0; +}; + +// TouchExplorationController is used in tandem with "Spoken Feedback" to +// make the touch UI accessible. Gestures performed in the middle of the screen +// are mapped to accessibility key shortcuts while gestures performed on the +// edge of the screen can change settings. +// +// ** Short version ** +// +// At a high-level, single-finger events are used for accessibility - +// exploring the screen gets turned into mouse moves (which can then be +// spoken by an accessibility service running), a single tap while the user +// is in touch exploration or a double-tap simulates a click, and gestures +// can be used to send high-level accessibility commands. For example, a swipe +// right would correspond to the keyboard short cut shift+search+right. +// Swipes with up to four fingers are also mapped to commands. Slide +// gestures performed on the edge of the screen can change settings +// continuously. For example, sliding a finger along the right side of the +// screen will change the volume. When a user double taps and holds with one +// finger, the finger is passed through as if accessibility was turned off. If +// the user taps the screen with two fingers, the user can silence spoken +// feedback if it is playing. +// +// ** Long version ** +// +// Here are the details of the implementation: +// +// When the first touch is pressed, a 300 ms grace period timer starts. +// +// If the user keeps their finger down for more than 300 ms and doesn't +// perform a supported accessibility gesture in that time (e.g. swipe right), +// they enter touch exploration mode, and all movements are translated into +// synthesized mouse move events. +// +// Also, if the user moves their single finger outside a certain slop region +// (without performing a gesture), they enter touch exploration mode earlier +// than 300 ms. +// +// If the user taps and releases their finger, after 300 ms from the initial +// touch, a single mouse move is fired. +// +// While in touch exploration mode, the user can perform a single tap +// if the user releases their finger and taps before 300 ms passes. +// This will result in a click on the last successful touch exploration +// location. This allows the user to perform a single tap +// anywhere to activate it. (See more information on simulated clicks +// below.) +// +// The user can perform swipe gestures in one of the four cardinal directions +// which will be interpreted and used to control the UI. All gestures will only +// be registered if the fingers move outside the slop, and all fingers will only +// be registered if they are completed within the grace period. If a single +// finger gesture fails to be completed within the grace period, the state +// changes to touch exploration mode. If a multi finger gesture fails to be +// completed within the grace period, the user must lift all fingers before +// completing any more actions. +// +// The user's initial tap sets the anchor point. Simulated events are +// positioned relative to the anchor point, so that after exploring to find +// an object the user can double-tap anywhere on the screen to activate it. +// The anchor point is also set by ChromeVox every time it highlights an +// object on the screen. During touch exploration this ensures that +// any simulated events go to the center of the most recently highlighted +// object, rather than to the exact tap location (which could have drifted +// off of the object). This also ensures that when the current ChromeVox +// object changes due to a gesture or input focus changing, simulated +// events go to that object and not the last location touched by a finger. +// +// When the user double-taps, this is treated as a discrete gestures, and +// and event is sent to ChromeVox to activate the current object, whatever +// that is. However, when the user double-taps and holds, any event from that +// finger is passed through, allowing the user to drag. These events are +// passed through with a location that's relative to the anchor point. +// +// If any other fingers are added or removed during a passthrough, they are +// ignored. Once the passthrough finger is released, passthrough stops and +// the state is reset to the no fingers down state. +// +// If the user enters touch exploration mode, they can click without lifting +// their touch exploration finger by tapping anywhere else on the screen with +// a second finger, while the touch exploration finger is still pressed. +// +// Once touch exploration mode has been activated, it remains in that mode until +// all fingers have been released. +// +// If the user places a finger on the edge of the screen and moves their finger +// past slop, a slide gesture is performed. The user can then slide one finger +// along an edge of the screen and continuously control a setting. Once the user +// enters this state, the boundaries that define an edge expand so that the user +// can now adjust the setting within a slightly bigger width along the screen. +// If the user exits this area without lifting their finger, they will not be +// able to perform any actions, however if they keep their finger down and +// return to the "hot edge," then they can still adjust the setting. In order to +// perform other touch accessibility movements, the user must lift their finger. +// If additional fingers are added while in this state, the user will transition +// to passthrough. +// +// Currently, only the right edge is mapped to control the volume. Volume +// control along the edge of the screen is directly proportional to where the +// user's finger is located on the screen. The top right corner of the screen +// automatically sets the volume to 100% and the bottome right corner of the +// screen automatically sets the volume to 0% once the user has moved past slop. +// +// If the user taps the screen with two fingers and lifts both fingers before +// the grace period has passed, spoken feedback is silenced. +// +// The user can also enter passthrough by placing a finger on one of the bottom +// corners of the screen until an earcon sounds. After the earcon sounds, the +// user is in passthrough so all subsequent fingers placed on the screen will be +// passed through. Once the finger in the corner has been released, the state +// will switch to wait for no fingers. +// +// The caller is expected to retain ownership of instances of this class and +// destroy them before |root_window| is destroyed. +class TouchExplorationController : public ui::EventRewriter, + public ui::GestureProviderAuraClient, + public ui::GestureConsumer { + public: + TouchExplorationController( + aura::Window* root_window, + TouchExplorationControllerDelegate* delegate); + ~TouchExplorationController() override; + + // Make synthesized touch events are anchored at this point. This is + // called when the object with accessibility focus is updated via something + // other than touch exploration. + void SetTouchAccessibilityAnchorPoint(const gfx::Point& anchor_point); + + // Events within the exclude bounds will not be rewritten. + // |bounds| are in root window coordinates. + void SetExcludeBounds(const gfx::Rect& bounds); + + // Updates |lift_activation_bounds_|. See |lift_activation_bounds_| for more + // information. + void SetLiftActivationBounds(const gfx::Rect& bounds); + + private: + friend class TouchExplorationControllerTestApi; + + // Overridden from ui::EventRewriter + ui::EventRewriteStatus RewriteEvent( + const ui::Event& event, + std::unique_ptr<ui::Event>* rewritten_event) override; + ui::EventRewriteStatus NextDispatchEvent( + const ui::Event& last_event, + std::unique_ptr<ui::Event>* new_event) override; + + // Event handlers based on the current state - see State, below. + ui::EventRewriteStatus InNoFingersDown( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InSingleTapPressed( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InSingleTapOrTouchExploreReleased( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InDoubleTapPending( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InTouchReleasePending( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InTouchExploration( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InCornerPassthrough( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InOneFingerPassthrough( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InGestureInProgress( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InTouchExploreSecondPress( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InWaitForNoFingers( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InTwoFingerTap( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + ui::EventRewriteStatus InEdgePassthrough( + const ui::TouchEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); + + // Returns the current time of the tick clock. + base::TimeTicks Now(); + + // This timer is started every time we get the first press event, and + // it fires after the double-click timeout elapses (300 ms by default). + // If the user taps and releases within 300 ms and doesn't press again, + // we treat that as a single mouse move (touch exploration) event. + void StartTapTimer(); + void OnTapTimerFired(); + + // This timer is started every timer we get the first press event and the + // finger is in the corner of the screen. + // It fires after the corner passthrough delay elapses. If the + // user is still in the corner by the time this timer fires, all subsequent + // fingers added on the screen will be passed through. + void OnPassthroughTimerFired(); + + // Dispatch a new event outside of the event rewriting flow. + void DispatchEvent(ui::Event* event); + + // Overridden from GestureProviderAuraClient. + // + // The gesture provider keeps track of all the touch events after + // the user moves fast enough to trigger a gesture. After the user + // completes their gesture, this method will decide what keyboard + // input their gesture corresponded to. + void OnGestureEvent(ui::GestureConsumer* raw_input_consumer, + ui::GestureEvent* gesture) override; + + // Process the gesture events that have been created. + void ProcessGestureEvents(); + + void OnSwipeEvent(ui::GestureEvent* swipe_gesture); + + // Dispatches a single key with the given flags. + void DispatchKeyWithFlags(const ui::KeyboardCode key, int flags); + + // Binds DispatchKeyWithFlags to a specific key and flags. + base::OnceClosure BindKeyEventWithFlags(const ui::KeyboardCode key, + int flags); + + std::unique_ptr<ui::MouseEvent> CreateMouseMoveEvent( + const gfx::PointF& location, + int flags); + + void EnterTouchToMouseMode(); + + void PlaySoundForTimer(); + + // Sends a simulated click, if an anchor point was set explicitly. Otherwise, + // sends a simulated tap at anchor point. + void SendSimulatedClickOrTap(); + + // Sends a simulated tap at anchor point. + void SendSimulatedTap(); + + // Sends a simulated tap, if the anchor point falls within lift activation + // bounds. + void MaybeSendSimulatedTapInLiftActivationBounds(const ui::TouchEvent& event); + + // Some constants used in touch_exploration_controller: + + // Within this many dips of the screen edge, the release event generated will + // reset the state to NoFingersDown. + const float kLeavingScreenEdge = 12; + + // Swipe/scroll gestures within these bounds (in DIPs) will change preset + // settings. + const float kMaxDistanceFromEdge = 75; + + // After a slide gesture has been triggered, if the finger is still within + // these bounds (in DIPs), the preset settings will still change. + const float kSlopDistanceFromEdge = kMaxDistanceFromEdge + 40; + + // The split tap slop is a bit more generous since keeping two + // fingers in place is a bit harder. + float GetSplitTapTouchSlop(); + + enum State { + // No fingers are down and no events are pending. + NO_FINGERS_DOWN, + + // A single finger is down, but we're not yet sure if this is going + // to be touch exploration or something else. + SINGLE_TAP_PRESSED, + + // The user pressed and released a single finger - a tap - but we have + // to wait until the end of the grace period to allow the user to tap the + // second time. If the second tap doesn't occurs within the grace period, + // we dispatch a mouse move at the location of the first tap. + SINGLE_TAP_RELEASED, + + // The user was in touch explore mode and released the finger. + // If another touch press occurs within the grace period, a single + // tap click occurs. This state differs from SINGLE_TAP_RELEASED + // in that if a second tap doesn't occur within the grace period, + // there is no mouse move dispatched. + TOUCH_EXPLORE_RELEASED, + + // The user tapped once, and before the grace period expired, pressed + // one finger down to begin a double-tap, but has not released it yet. + // This could become passthrough, so no touch press is dispatched yet. + DOUBLE_TAP_PENDING, + + // The user was doing touch exploration, started split tap, but lifted the + // touch exploration finger. Once they remove all fingers, a touch release + // will go through. + TOUCH_RELEASE_PENDING, + + // We're in touch exploration mode. Anything other than the first finger + // is ignored, and movements of the first finger are rewritten as mouse + // move events. This mode is entered if a single finger is pressed and + // after the grace period the user hasn't added a second finger or + // moved the finger outside of the slop region. We'll stay in this + // mode until all fingers are lifted. + TOUCH_EXPLORATION, + + // If the user moves their finger faster than the threshold velocity after a + // single tap, the touch events that follow will be translated into gesture + // events. If the user successfully completes a gesture within the grace + // period, the gesture will be interpreted and used to control the UI via + // discrete actions - currently by synthesizing key events corresponding to + // each gesture Otherwise, the collected gestures are discarded and the + // state changes to touch_exploration. + GESTURE_IN_PROGRESS, + + // The user was in touch exploration, but has placed down another finger. + // If the user releases the second finger, a touch press and release + // will go through at the last touch explore location. If the user + // releases the touch explore finger, the touch press and release will + // still go through once the split tap finger is also lifted. If any + // fingers pressed past the first two, the touch press is cancelled and + // the user enters the wait state for the fingers to be removed. + TOUCH_EXPLORE_SECOND_PRESS, + + // After the user double taps and holds with a single finger, all events + // for that finger are passed through, displaced by an offset. Adding + // extra fingers has no effect. This state is left when the user removes + // all fingers. + ONE_FINGER_PASSTHROUGH, + + // If the user has pressed and held down the left corner past long press, + // then as long as they are holding the corner, all subsequent fingers + // registered will be in passthrough. + CORNER_PASSTHROUGH, + + // If the user added another finger in SINGLE_TAP_PRESSED, or if the user + // has multiple fingers fingers down in any other state between + // passthrough, touch exploration, and gestures, they must release + // all fingers before completing any more actions. This state is + // generally useful for developing new features, because it creates a + // simple way to handle a dead end in user flow. + WAIT_FOR_NO_FINGERS, + + // If the user taps the screen with two fingers and releases both fingers + // before the grace period has passed, spoken feedback will be silenced. + TWO_FINGER_TAP, + + // If the user enters the screen from the edge, pass events through, + // so that they are available to the system gesture handler. + EDGE_PASSTHROUGH, + }; + + enum AnchorPointState { + ANCHOR_POINT_NONE, + ANCHOR_POINT_FROM_TOUCH_EXPLORATION, + ANCHOR_POINT_EXPLICITLY_SET + }; + + enum ScreenLocation { + // Hot "edges" of the screen are each represented by a respective bit. + NO_EDGE = 0, + RIGHT_EDGE = 1 << 0, + TOP_EDGE = 1 << 1, + LEFT_EDGE = 1 << 2, + BOTTOM_EDGE = 1 << 3, + BOTTOM_LEFT_CORNER = LEFT_EDGE | BOTTOM_EDGE, + BOTTOM_RIGHT_CORNER = RIGHT_EDGE | BOTTOM_EDGE, + }; + + // Given a point, if it is within the given inset of an edge, returns the + // edge. If it is within the given inset of two edges, returns an int with + // both bits that represent the respective edges turned on. Otherwise returns + // SCREEN_CENTER. + int FindEdgesWithinInset(gfx::Point point, float inset); + + // Set the state and modifies any variables related to the state change. + // (e.g. resetting the gesture provider). + void SetState(State new_state, const char* function_name); + + void VlogState(const char* function_name); + + void VlogEvent(const ui::TouchEvent& event, const char* function_name); + + // Gets enum name from integer value. + const char* EnumStateToString(State state); + + aura::Window* root_window_; + + // Handles volume control. Not owned. + TouchExplorationControllerDelegate* delegate_; + + // A set of touch ids for fingers currently touching the screen. + std::vector<int> current_touch_ids_; + + // Map of touch ids to their last known location. + std::map<int, gfx::PointF> touch_locations_; + + // The current state. + State state_; + + // A copy of the event from the initial touch press. + std::unique_ptr<ui::TouchEvent> initial_press_; + + // The timestamp of the most recent press event for the main touch id. + // The difference between this and |initial_press_->time_stamp| is that + // |most_recent_press_timestamp_| is reset in a double-tap. + base::TimeTicks most_recent_press_timestamp_; + + // Map of touch ids to where its initial press occurred relative to the + // screen. + std::map<int, gfx::Point> initial_presses_; + + // In one finger passthrough, the touch is displaced relative to the + // last touch exploration location. + gfx::Vector2dF passthrough_offset_; + + // Stores the most recent event from a finger that is currently not + // sending events through, but might in the future (e.g. before a finger + // enters double-tap-hold passthrough, we need to update its location.) + std::unique_ptr<ui::TouchEvent> last_unused_finger_event_; + + // The anchor point used as the location of a synthesized tap when the + // user double-taps anywhere on the screen, and similarly the initial + // point used when the user double-taps, holds, and drags. This can be + // set either via touch exploration, or by a call to + // SetTouchAccessibilityAnchorPoint when focus moves due to something other + // than touch exploration. + gfx::PointF anchor_point_dip_; + + // The current state of the anchor point. + AnchorPointState anchor_point_state_; + + // The last touch exploration event. + std::unique_ptr<ui::TouchEvent> last_touch_exploration_; + + // A timer that fires after the double-tap delay. + base::OneShotTimer tap_timer_; + + // A timer that fires to enter passthrough. + base::OneShotTimer passthrough_timer_; + + // A timer to fire an indicating sound when sliding to change volume. + base::RepeatingTimer sound_timer_; + + // A default gesture detector config, so we can share the same + // timeout and pixel slop constants. + ui::GestureDetector::Config gesture_detector_config_; + + // Gesture Handler to interpret the touch events. + std::unique_ptr<ui::GestureProviderAura> gesture_provider_; + + // The previous state entered. + State prev_state_; + + // A copy of the previous event passed. + std::unique_ptr<ui::TouchEvent> prev_event_; + + // This toggles whether VLOGS are turned on or not. + bool VLOG_on_; + + // LocatedEvents within this area should be left alone. + gfx::Rect exclude_bounds_; + + // Any touch exploration that both starts and ends (touch pressed, and + // released) within this rectangle, triggers a simulated single finger tap at + // the anchor point on release. + gfx::Rect lift_activation_bounds_; + + // Whether or not we've seen a touch press event yet. + bool seen_press_ = false; + + // The maximum touch points seen in the current gesture. + size_t max_gesture_touch_points_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_BROWSER_ACCESSIBILITY_TOUCH_EXPLORATION_CONTROLLER_H_
diff --git a/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc b/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc new file mode 100644 index 0000000..ebe3c181 --- /dev/null +++ b/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc
@@ -0,0 +1,2083 @@ +// 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. + +// Copied with modifications from ash/accessibility, refactored for use in +// chromecast. + +#include "chromecast/browser/accessibility/touch_exploration_controller.h" + +#include <math.h> +#include <stddef.h> + +#include <memory> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/test/simple_test_tick_clock.h" +#include "base/time/time.h" +#include "ui/aura/client/cursor_client.h" +#include "ui/aura/test/aura_test_base.h" +#include "ui/aura/test/test_cursor_client.h" +#include "ui/aura/window.h" +#include "ui/events/event.h" +#include "ui/events/event_utils.h" +#include "ui/events/gestures/gesture_provider_aura.h" +#include "ui/events/test/event_generator.h" +#include "ui/events/test/events_test_utils.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gl/test/gl_surface_test_support.h" + +using EventList = std::vector<std::unique_ptr<ui::Event>>; + +namespace chromecast { +namespace shell { + +namespace { + +// Records all mouse, touch, gesture, and key events. +class EventCapturer : public ui::EventHandler { + public: + EventCapturer() {} + ~EventCapturer() override {} + + void Reset() { events_.clear(); } + + void OnEvent(ui::Event* event) override { + if (event->IsMouseEvent() || event->IsTouchEvent() || + event->IsGestureEvent() || event->IsKeyEvent()) { + events_.push_back(ui::Event::Clone(*event)); + } else { + return; + } + // Stop event propagation so we don't click on random stuff that + // might break test assumptions. + event->StopPropagation(); + // If there is a possibility that we're in an infinite loop, we should + // exit early with a sensible error rather than letting the test time out. + ASSERT_LT(events_.size(), 100u); + } + + const EventList& captured_events() const { return events_; } + + private: + EventList events_; + + DISALLOW_COPY_AND_ASSIGN(EventCapturer); +}; + +int Factorial(int n) { + if (n <= 0) + return 0; + if (n == 1) + return 1; + return n * Factorial(n - 1); +} + +class MockTouchExplorationControllerDelegate + : public TouchExplorationControllerDelegate { + public: + void PlayPassthroughEarcon() override { ++num_times_passthrough_played_; } + void PlayExitScreenEarcon() override { ++num_times_exit_screen_played_; } + void PlayEnterScreenEarcon() override { ++num_times_enter_screen_played_; } + void PlayTouchTypeEarcon() override { ++num_times_touch_type_sound_played_; } + void HandleAccessibilityGesture(ax::mojom::Gesture gesture) override { + last_gesture_ = gesture; + } + + const std::vector<float> VolumeChanges() const { return volume_changes_; } + size_t NumAdjustSounds() const { return num_times_adjust_sound_played_; } + size_t NumPassthroughSounds() const { return num_times_passthrough_played_; } + size_t NumExitScreenSounds() const { return num_times_exit_screen_played_; } + size_t NumEnterScreenSounds() const { return num_times_enter_screen_played_; } + size_t NumTouchTypeSounds() const { + return num_times_touch_type_sound_played_; + } + ax::mojom::Gesture GetLastGesture() const { return last_gesture_; } + void ResetLastGesture() { last_gesture_ = ax::mojom::Gesture::kNone; } + + void ResetCountersToZero() { + num_times_adjust_sound_played_ = 0; + num_times_passthrough_played_ = 0; + num_times_exit_screen_played_ = 0; + num_times_enter_screen_played_ = 0; + num_times_touch_type_sound_played_ = 0; + } + + private: + std::vector<float> volume_changes_; + size_t num_times_adjust_sound_played_ = 0; + size_t num_times_passthrough_played_ = 0; + size_t num_times_exit_screen_played_ = 0; + size_t num_times_enter_screen_played_ = 0; + size_t num_times_touch_type_sound_played_ = 0; + ax::mojom::Gesture last_gesture_ = ax::mojom::Gesture::kNone; +}; + +} // namespace + +class TouchExplorationControllerTestApi { + public: + TouchExplorationControllerTestApi( + TouchExplorationController* touch_exploration_controller) { + touch_exploration_controller_.reset(touch_exploration_controller); + } + + void CallTapTimerNowForTesting() { + DCHECK(touch_exploration_controller_->tap_timer_.IsRunning()); + touch_exploration_controller_->tap_timer_.Stop(); + touch_exploration_controller_->OnTapTimerFired(); + } + + void CallPassthroughTimerNowForTesting() { + DCHECK(touch_exploration_controller_->passthrough_timer_.IsRunning()); + touch_exploration_controller_->passthrough_timer_.Stop(); + touch_exploration_controller_->OnPassthroughTimerFired(); + } + + void CallTapTimerNowIfRunningForTesting() { + if (touch_exploration_controller_->tap_timer_.IsRunning()) { + touch_exploration_controller_->tap_timer_.Stop(); + touch_exploration_controller_->OnTapTimerFired(); + } + } + + bool IsInNoFingersDownStateForTesting() const { + return touch_exploration_controller_->state_ == + touch_exploration_controller_->NO_FINGERS_DOWN; + } + + bool IsInGestureInProgressStateForTesting() const { + return touch_exploration_controller_->state_ == + touch_exploration_controller_->GESTURE_IN_PROGRESS; + } + + bool IsInTwoFingerTapStateForTesting() const { + return touch_exploration_controller_->state_ == + touch_exploration_controller_->TWO_FINGER_TAP; + } + bool IsInCornerPassthroughStateForTesting() const { + return touch_exploration_controller_->state_ == + touch_exploration_controller_->CORNER_PASSTHROUGH; + } + + gfx::Rect BoundsOfRootWindowInDIPForTesting() const { + return touch_exploration_controller_->root_window_->GetBoundsInScreen(); + } + + // VLOGs should be suppressed in tests that generate a lot of logs, + // for example permutations of nine touch events. + void SuppressVLOGsForTesting(bool suppress) { + touch_exploration_controller_->VLOG_on_ = !suppress; + } + + float GetMaxDistanceFromEdge() const { + return touch_exploration_controller_->kMaxDistanceFromEdge; + } + + float GetSlopDistanceFromEdge() const { + return touch_exploration_controller_->kSlopDistanceFromEdge; + } + + float GetLeavingDistanceFromEdge() const { + return touch_exploration_controller_->kLeavingScreenEdge; + } + + void SetTouchAccessibilityAnchorPoint(const gfx::Point& location) { + touch_exploration_controller_->SetTouchAccessibilityAnchorPoint(location); + } + + void SetExcludeBounds(const gfx::Rect& bounds) { + touch_exploration_controller_->SetExcludeBounds(bounds); + } + + void SetLiftActivationBounds(const gfx::Rect& bounds) { + touch_exploration_controller_->SetLiftActivationBounds(bounds); + } + + private: + std::unique_ptr<TouchExplorationController> touch_exploration_controller_; + + DISALLOW_COPY_AND_ASSIGN(TouchExplorationControllerTestApi); +}; + +class TouchExplorationTest : public aura::test::AuraTestBase { + public: + TouchExplorationTest() {} + ~TouchExplorationTest() override {} + + void SetUp() override { + if (gl::GetGLImplementation() == gl::kGLImplementationNone) + gl::GLSurfaceTestSupport::InitializeOneOff(); + aura::test::AuraTestBase::SetUp(); + cursor_client_.reset(new aura::test::TestCursorClient(root_window())); + root_window()->AddPreTargetHandler(&event_capturer_); + generator_.reset(new ui::test::EventGenerator(root_window())); + + // Tests fail if time is ever 0. + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); + // ui takes ownership of the tick clock. + ui::SetEventTickClockForTesting(&simulated_clock_); + + cursor_client()->ShowCursor(); + cursor_client()->DisableMouseEvents(); + } + + void TearDown() override { + ui::SetEventTickClockForTesting(nullptr); + root_window()->RemovePreTargetHandler(&event_capturer_); + SwitchTouchExplorationMode(false); + cursor_client_.reset(); + aura::test::AuraTestBase::TearDown(); + } + + protected: + aura::client::CursorClient* cursor_client() { return cursor_client_.get(); } + + const EventList& GetCapturedEvents() { + return event_capturer_.captured_events(); + } + + std::vector<ui::LocatedEvent*> GetCapturedLocatedEvents() { + const EventList& all_events = GetCapturedEvents(); + std::vector<ui::LocatedEvent*> located_events; + for (size_t i = 0; i < all_events.size(); ++i) { + if (all_events[i]->IsMouseEvent() || all_events[i]->IsTouchEvent() || + all_events[i]->IsGestureEvent()) { + located_events.push_back( + static_cast<ui::LocatedEvent*>(all_events[i].get())); + } + } + return located_events; + } + + std::vector<ui::Event*> GetCapturedEventsOfType(int type) { + const EventList& all_events = GetCapturedEvents(); + std::vector<ui::Event*> events; + for (size_t i = 0; i < all_events.size(); ++i) { + if (type == all_events[i]->type()) + events.push_back(all_events[i].get()); + } + return events; + } + + std::vector<ui::LocatedEvent*> GetCapturedLocatedEventsOfType(int type) { + std::vector<ui::LocatedEvent*> located_events = GetCapturedLocatedEvents(); + std::vector<ui::LocatedEvent*> events; + for (size_t i = 0; i < located_events.size(); ++i) { + if (type == located_events[i]->type()) + events.push_back(located_events[i]); + } + return events; + } + + void ClearCapturedEvents() { event_capturer_.Reset(); } + + void AdvanceSimulatedTimePastTapDelay() { + simulated_clock_.Advance(gesture_detector_config_.double_tap_timeout); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); + touch_exploration_controller_->CallTapTimerNowForTesting(); + } + + void AdvanceSimulatedTimePastPassthroughDelay() { + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(1000)); + touch_exploration_controller_->CallPassthroughTimerNowForTesting(); + } + + void AdvanceSimulatedTimePastPotentialTapDelay() { + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(1000)); + touch_exploration_controller_->CallTapTimerNowIfRunningForTesting(); + } + + void SuppressVLOGs(bool suppress) { + touch_exploration_controller_->SuppressVLOGsForTesting(suppress); + } + + void SwitchTouchExplorationMode(bool on) { + if (!on && touch_exploration_controller_.get()) { + touch_exploration_controller_.reset(); + } else if (on && !touch_exploration_controller_.get()) { + touch_exploration_controller_.reset(new TouchExplorationControllerTestApi( + new TouchExplorationController(root_window(), &delegate_))); + cursor_client()->ShowCursor(); + cursor_client()->DisableMouseEvents(); + } + } + + void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) { + ui::TouchEvent touch_press( + ui::ET_TOUCH_PRESSED, tap_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&touch_press); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_TRUE(IsInTouchToMouseMode()); + } + + // Checks that Corner Passthrough is working. Assumes that corner is the + // bottom left corner or the bottom right corner. + void AssertCornerPassthroughWorking(gfx::Point corner) { + ASSERT_EQ(0U, delegate_.NumPassthroughSounds()); + + ui::TouchEvent first_press( + ui::ET_TOUCH_PRESSED, corner, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&first_press); + + AdvanceSimulatedTimePastPassthroughDelay(); + EXPECT_FALSE(IsInGestureInProgressState()); + EXPECT_FALSE(IsInTouchToMouseMode()); + EXPECT_TRUE(IsInCornerPassthroughState()); + + gfx::Rect window = BoundsOfRootWindowInDIP(); + // The following events should be passed through. + gfx::Point passthrough(window.right() / 2, window.bottom() / 2); + ui::TouchEvent passthrough_press( + ui::ET_TOUCH_PRESSED, passthrough, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + ASSERT_EQ(1U, delegate_.NumPassthroughSounds()); + generator_->Dispatch(&passthrough_press); + generator_->ReleaseTouchId(1); + generator_->PressTouchId(1); + EXPECT_FALSE(IsInGestureInProgressState()); + EXPECT_TRUE(IsInCornerPassthroughState()); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(3U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type()); + generator_->ReleaseTouchId(1); + ClearCapturedEvents(); + + generator_->ReleaseTouchId(0); + captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); + EXPECT_FALSE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInCornerPassthroughState()); + ClearCapturedEvents(); + } + + bool IsInTouchToMouseMode() { + aura::client::CursorClient* cursor_client = + aura::client::GetCursorClient(root_window()); + return cursor_client && cursor_client->IsMouseEventsEnabled() && + !cursor_client->IsCursorVisible(); + } + + bool IsInNoFingersDownState() { + return touch_exploration_controller_->IsInNoFingersDownStateForTesting(); + } + + bool IsInGestureInProgressState() { + return touch_exploration_controller_ + ->IsInGestureInProgressStateForTesting(); + } + + bool IsInTwoFingerTapState() { + return touch_exploration_controller_->IsInTwoFingerTapStateForTesting(); + } + + bool IsInCornerPassthroughState() { + return touch_exploration_controller_ + ->IsInCornerPassthroughStateForTesting(); + } + + gfx::Rect BoundsOfRootWindowInDIP() { + return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting(); + } + + float GetMaxDistanceFromEdge() const { + return touch_exploration_controller_->GetMaxDistanceFromEdge(); + } + + float GetSlopDistanceFromEdge() const { + return touch_exploration_controller_->GetSlopDistanceFromEdge(); + } + + float GetLeavingDistanceFromEdge() const { + return touch_exploration_controller_->GetLeavingDistanceFromEdge(); + } + + base::TimeTicks Now() { return ui::EventTimeForNow(); } + + void SetTouchAccessibilityAnchorPoint(const gfx::Point& location) { + touch_exploration_controller_->SetTouchAccessibilityAnchorPoint(location); + } + + void SetExcludeBounds(const gfx::Rect& bounds) { + touch_exploration_controller_->SetExcludeBounds(bounds); + } + + void SetLiftActivationBounds(const gfx::Rect& bounds) { + touch_exploration_controller_->SetLiftActivationBounds(bounds); + } + + std::unique_ptr<ui::test::EventGenerator> generator_; + ui::GestureDetector::Config gesture_detector_config_; + base::SimpleTestTickClock simulated_clock_; + MockTouchExplorationControllerDelegate delegate_; + + private: + EventCapturer event_capturer_; + std::unique_ptr<TouchExplorationControllerTestApi> + touch_exploration_controller_; + std::unique_ptr<aura::test::TestCursorClient> cursor_client_; + + DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest); +}; + +// Executes a number of assertions to confirm that |e1| and |e2| are touch +// events and are equal to each other. +void ConfirmEventsAreTouchAndEqual(ui::Event* e1, ui::Event* e2) { + ASSERT_TRUE(e1->IsTouchEvent()); + ASSERT_TRUE(e2->IsTouchEvent()); + ui::TouchEvent* touch_event1 = e1->AsTouchEvent(); + ui::TouchEvent* touch_event2 = e2->AsTouchEvent(); + EXPECT_EQ(touch_event1->type(), touch_event2->type()); + EXPECT_EQ(touch_event1->location(), touch_event2->location()); + EXPECT_EQ(touch_event1->pointer_details().id, + touch_event2->pointer_details().id); + EXPECT_EQ(touch_event1->flags(), touch_event2->flags()); + EXPECT_EQ(touch_event1->time_stamp(), touch_event2->time_stamp()); +} + +// Executes a number of assertions to confirm that |e1| and |e2| are mouse +// events and are equal to each other. +void ConfirmEventsAreMouseAndEqual(ui::Event* e1, ui::Event* e2) { + ASSERT_TRUE(e1->IsMouseEvent()); + ASSERT_TRUE(e2->IsMouseEvent()); + ui::MouseEvent* mouse_event1 = e1->AsMouseEvent(); + ui::MouseEvent* mouse_event2 = e2->AsMouseEvent(); + EXPECT_EQ(mouse_event1->type(), mouse_event2->type()); + EXPECT_EQ(mouse_event1->location(), mouse_event2->location()); + EXPECT_EQ(mouse_event1->root_location(), mouse_event2->root_location()); + EXPECT_EQ(mouse_event1->flags(), mouse_event2->flags()); +} + +// Executes a number of assertions to confirm that |e1| and |e2| are key events +// and are equal to each other. +void ConfirmEventsAreKeyAndEqual(ui::Event* e1, ui::Event* e2) { + ASSERT_TRUE(e1->IsKeyEvent()); + ASSERT_TRUE(e2->IsKeyEvent()); + ui::KeyEvent* key_event1 = e1->AsKeyEvent(); + ui::KeyEvent* key_event2 = e2->AsKeyEvent(); + EXPECT_EQ(key_event1->type(), key_event2->type()); + EXPECT_EQ(key_event1->key_code(), key_event2->key_code()); + EXPECT_EQ(key_event1->code(), key_event2->code()); + EXPECT_EQ(key_event1->flags(), key_event2->flags()); +} + +#define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \ + ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2)) + +#define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \ + ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2)) + +#define CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(e1, e2) \ + ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreKeyAndEqual(e1, e2)) + +// TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit +// events when running these tests as part of ui_base_unittests. We do get them +// when the tests are run as part of ash unit tests. + +TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) { + SwitchTouchExplorationMode(true); + EXPECT_FALSE(IsInTouchToMouseMode()); + generator_->set_current_location(gfx::Point(111, 112)); + generator_->PressTouch(); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_TRUE(IsInTouchToMouseMode()); +} + +TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) { + int slop = gesture_detector_config_.touch_slop; + int half_slop = slop / 2; + + SwitchTouchExplorationMode(true); + EXPECT_FALSE(IsInTouchToMouseMode()); + generator_->set_current_location(gfx::Point(111, 112)); + generator_->PressTouch(); + generator_->MoveTouch(gfx::Point(111 + half_slop, 112)); + EXPECT_FALSE(IsInTouchToMouseMode()); + generator_->MoveTouch(gfx::Point(111, 112 + half_slop)); + EXPECT_FALSE(IsInTouchToMouseMode()); + AdvanceSimulatedTimePastTapDelay(); + generator_->MoveTouch(gfx::Point(111 + slop + 1, 112)); + EXPECT_TRUE(IsInTouchToMouseMode()); +} + +TEST_F(TouchExplorationTest, OneFingerTap) { + SwitchTouchExplorationMode(true); + gfx::Point location(111, 112); + generator_->set_current_location(location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + AdvanceSimulatedTimePastTapDelay(); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + + EXPECT_EQ(location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +TEST_F(TouchExplorationTest, ActualMouseMovesUnaffected) { + SwitchTouchExplorationMode(true); + + gfx::Point location_start(111, 112); + gfx::Point location_end(13, 14); + generator_->set_current_location(location_start); + generator_->PressTouch(); + AdvanceSimulatedTimePastTapDelay(); + generator_->MoveTouch(location_end); + + gfx::Point location_real_mouse_move(15, 16); + ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, location_real_mouse_move, + location_real_mouse_move, ui::EventTimeForNow(), 0, + 0); + generator_->Dispatch(&mouse_move); + generator_->ReleaseTouch(); + AdvanceSimulatedTimePastTapDelay(); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(4U, events.size()); + + EXPECT_EQ(location_start, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + + EXPECT_EQ(location_end, events[1]->location()); + EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + + // The real mouse move goes through. + EXPECT_EQ(location_real_mouse_move, events[2]->location()); + CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(events[2], &mouse_move); + EXPECT_FALSE(events[2]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_FALSE(events[2]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + + // The touch release gets written as a mouse move. + EXPECT_EQ(location_end, events[3]->location()); + EXPECT_TRUE(events[3]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[3]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// Turn the touch exploration mode on in the middle of the touch gesture. +// Confirm that events from the finger which was touching when the mode was +// turned on don't get rewritten. +TEST_F(TouchExplorationTest, TurnOnMidTouch) { + SwitchTouchExplorationMode(false); + generator_->set_current_location(gfx::Point(211, 212)); + generator_->PressTouchId(1); + EXPECT_TRUE(cursor_client()->IsCursorVisible()); + ClearCapturedEvents(); + + // Enable touch exploration mode while the first finger is touching the + // screen. Ensure that subsequent events from that first finger are not + // affected by the touch exploration mode, while the touch events from another + // finger get rewritten. + SwitchTouchExplorationMode(true); + ui::TouchEvent touch_move( + ui::ET_TOUCH_MOVED, gfx::Point(111, 112), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&touch_move); + EXPECT_TRUE(cursor_client()->IsCursorVisible()); + EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(1u, captured_events.size()); + CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move); + ClearCapturedEvents(); + + // The press from the second finger should get rewritten. + generator_->PressTouchId(2); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_TRUE(IsInTouchToMouseMode()); + captured_events = GetCapturedLocatedEvents(); + std::vector<ui::LocatedEvent*>::const_iterator it; + for (it = captured_events.begin(); it != captured_events.end(); ++it) { + if ((*it)->type() == ui::ET_MOUSE_MOVED) { + EXPECT_TRUE((*it)->flags() & ui::EF_TOUCH_ACCESSIBILITY); + break; + } + } + EXPECT_NE(captured_events.end(), it); + ClearCapturedEvents(); + + // The release of the first finger shouldn't be affected. + ui::TouchEvent touch_release( + ui::ET_TOUCH_RELEASED, gfx::Point(111, 112), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&touch_release); + captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(1u, captured_events.size()); + CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release); + ClearCapturedEvents(); + + // The move and release from the second finger should get rewritten. + generator_->MoveTouchId(gfx::Point(13, 14), 2); + generator_->ReleaseTouchId(2); + AdvanceSimulatedTimePastTapDelay(); + captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(2u, captured_events.size()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// If an event is received after the double-tap timeout has elapsed, but +// before the timer has fired, a mouse move should still be generated. +TEST_F(TouchExplorationTest, TimerFiresLateDuringTouchExploration) { + SwitchTouchExplorationMode(true); + + // Make sure the touch is not in a corner of the screen. + generator_->MoveTouch(gfx::Point(100, 200)); + + // Send a press, then add another finger after the double-tap timeout. + generator_->PressTouchId(1); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(1000)); + generator_->PressTouchId(2); + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + + generator_->ReleaseTouchId(2); + generator_->ReleaseTouchId(1); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// If a new tap is received after the double-tap timeout has elapsed from +// a previous tap, but before the timer has fired, a mouse move should +// still be generated from the old tap. +TEST_F(TouchExplorationTest, TimerFiresLateAfterTap) { + SwitchTouchExplorationMode(true); + + // Send a tap at location1. + gfx::Point location0(111, 112); + generator_->set_current_location(location0); + generator_->PressTouch(); + generator_->ReleaseTouch(); + + // Send a tap at location2, after the double-tap timeout, but before the + // timer fires. + gfx::Point location1(233, 234); + generator_->set_current_location(location1); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(301)); + generator_->PressTouch(); + generator_->ReleaseTouch(); + AdvanceSimulatedTimePastTapDelay(); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(2U, events.size()); + EXPECT_EQ(location0, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(location1, events[1]->location()); + EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// Double-tapping should send a touch press and release through to the location +// of the last successful touch exploration. +TEST_F(TouchExplorationTest, DoubleTap) { + SwitchTouchExplorationMode(true); + + // Tap at one location, and get a mouse move event. + gfx::Point tap_location(51, 52); + generator_->set_current_location(tap_location); + generator_->PressTouchId(1); + generator_->ReleaseTouchId(1); + AdvanceSimulatedTimePastTapDelay(); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + + EXPECT_EQ(tap_location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + // Now double-tap at a different location. This should result in + // a single touch press and release at the location of the tap, + // not at the location of the double-tap. + gfx::Point double_tap_location(33, 34); + generator_->set_current_location(double_tap_location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + generator_->PressTouch(); + generator_->ReleaseTouch(); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(2U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(tap_location, captured_events[0]->location()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); + EXPECT_EQ(tap_location, captured_events[1]->location()); + EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// The press of the second tap in a double-tap must come within the double-tap +// timeout, but the release of the second tap can come later. +TEST_F(TouchExplorationTest, DoubleTapTiming) { + SwitchTouchExplorationMode(true); + + // Tap at one location, and get a mouse move event. + gfx::Point tap_location(51, 52); + generator_->set_current_location(tap_location); + generator_->PressTouchId(1); + generator_->ReleaseTouchId(1); + AdvanceSimulatedTimePastTapDelay(); + SetTouchAccessibilityAnchorPoint(tap_location); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + + EXPECT_EQ(tap_location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + // The press of the second tap happens in time, but the release does not. + gfx::Point double_tap_location(33, 34); + generator_->set_current_location(double_tap_location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + simulated_clock_.Advance(gesture_detector_config_.double_tap_timeout - + base::TimeDelta::FromMilliseconds(25)); + generator_->PressTouch(); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(50)); + generator_->ReleaseTouch(); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); + EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture()); +} + +// If an explicit anchor point is set during touch exploration, double-tapping +// should send a 'click' gesture rather than a simulated touch press and +// release. +TEST_F(TouchExplorationTest, DoubleTapWithExplicitAnchorPoint) { + SwitchTouchExplorationMode(true); + + // Tap at one location, and get a mouse move event. + gfx::Point tap_location(51, 52); + generator_->set_current_location(tap_location); + generator_->PressTouchId(1); + generator_->ReleaseTouchId(1); + AdvanceSimulatedTimePastTapDelay(); + + SetTouchAccessibilityAnchorPoint(tap_location); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + + EXPECT_EQ(tap_location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + // Now double-tap at a different location. This should result in + // a click gesture. + gfx::Point double_tap_location(33, 34); + generator_->set_current_location(double_tap_location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + generator_->PressTouch(); + generator_->ReleaseTouch(); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); + EXPECT_TRUE(IsInNoFingersDownState()); + EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture()); +} + +// Double-tapping where the user holds their finger down for the second time +// for a longer press should send a touch press and passthrough all further +// events from that finger. Other finger presses should be ignored. +TEST_F(TouchExplorationTest, DoubleTapPassthrough) { + SwitchTouchExplorationMode(true); + + // Tap at one location, and get a mouse move event. + gfx::Point tap_location(111, 112); + generator_->set_current_location(tap_location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + AdvanceSimulatedTimePastTapDelay(); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + + EXPECT_EQ(tap_location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + // Now double-tap and hold at a different location. + // This should result in a single touch press at the location of the tap, + // not at the location of the double-tap. + gfx::Point first_tap_location(13, 14); + generator_->set_current_location(first_tap_location); + generator_->PressTouchId(1); + generator_->ReleaseTouchId(1); + gfx::Point second_tap_location(15, 16); + generator_->set_current_location(second_tap_location); + generator_->PressTouchId(1); + // Advance to the finger passing through. + AdvanceSimulatedTimePastTapDelay(); + + gfx::Vector2d passthrough_offset = second_tap_location - tap_location; + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(1U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(second_tap_location - passthrough_offset, + captured_events[0]->location()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + + ClearCapturedEvents(); + + // All events for the first finger should pass through now, displaced + // relative to the last touch exploration location. + gfx::Point first_move_location(117, 118); + generator_->MoveTouchId(first_move_location, 1); + gfx::Point second_move_location(112, 113); + generator_->MoveTouchId(second_move_location, 1); + + captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(2U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type()); + EXPECT_EQ(first_move_location - passthrough_offset, + captured_events[0]->location()); + EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[1]->type()); + EXPECT_EQ(second_move_location - passthrough_offset, + captured_events[1]->location()); + EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + + ClearCapturedEvents(); + + // Events for other fingers should do nothing. + generator_->PressTouchId(2); + generator_->PressTouchId(3); + generator_->MoveTouchId(gfx::Point(34, 36), 2); + generator_->ReleaseTouchId(2); + captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); + + // Even with finger 3 still down, events for the first finger should still + // pass through. + gfx::Point third_move_location(114, 115); + generator_->MoveTouchId(third_move_location, 1); + captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(1U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type()); + EXPECT_EQ(third_move_location - passthrough_offset, + captured_events[0]->location()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + + // No fingers down state is only reached when every finger is lifted. + generator_->ReleaseTouchId(1); + EXPECT_FALSE(IsInNoFingersDownState()); + generator_->ReleaseTouchId(3); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// Double-tapping, going into passthrough, and holding for the longpress +// time should send a touch press and released (right click) +// to the location of the last successful touch exploration. +TEST_F(TouchExplorationTest, DoubleTapLongPress) { + SwitchTouchExplorationMode(true); + // Tap at one location, and get a mouse move event. + gfx::Point tap_location(111, 112); + generator_->set_current_location(tap_location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + AdvanceSimulatedTimePastTapDelay(); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + EXPECT_EQ(tap_location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + // Now double-tap and hold at a different location. + // This should result in a single touch long press and release + // at the location of the tap, not at the location of the double-tap. + // There should be a time delay between the touch press and release. + gfx::Point first_tap_location(33, 34); + generator_->set_current_location(first_tap_location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + gfx::Point second_tap_location(23, 24); + generator_->set_current_location(second_tap_location); + generator_->PressTouch(); + // Advance to the finger passing through, and then to the longpress timeout. + AdvanceSimulatedTimePastTapDelay(); + simulated_clock_.Advance(gesture_detector_config_.longpress_timeout); + generator_->ReleaseTouch(); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(2U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(tap_location, captured_events[0]->location()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + base::TimeTicks pressed_time = captured_events[0]->time_stamp(); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); + EXPECT_EQ(tap_location, captured_events[1]->location()); + EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + base::TimeTicks released_time = captured_events[1]->time_stamp(); + EXPECT_EQ(released_time - pressed_time, + gesture_detector_config_.longpress_timeout); +} + +// Single-tapping should send a touch press and release through to the location +// of the last successful touch exploration if the grace period has not +// elapsed. +TEST_F(TouchExplorationTest, SingleTap) { + SwitchTouchExplorationMode(true); + + // Tap once to simulate a mouse moved event. + gfx::Point initial_location(111, 112); + generator_->set_current_location(initial_location); + generator_->PressTouch(); + AdvanceSimulatedTimePastTapDelay(); + ClearCapturedEvents(); + + // Move to another location for single tap + gfx::Point tap_location(22, 23); + generator_->MoveTouch(tap_location); + generator_->ReleaseTouch(); + + // Allow time to pass within the grace period of releasing before + // tapping again. + gfx::Point final_location(33, 34); + generator_->set_current_location(final_location); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(250)); + generator_->PressTouch(); + generator_->ReleaseTouch(); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(4U, captured_events.size()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type()); + EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[2]->type()); + EXPECT_EQ(tap_location, captured_events[2]->location()); + EXPECT_TRUE(captured_events[2]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[3]->type()); + EXPECT_EQ(tap_location, captured_events[3]->location()); + EXPECT_TRUE(captured_events[3]->flags() & ui::EF_TOUCH_ACCESSIBILITY); +} + +// Double-tapping without coming from touch exploration (no previous touch +// exploration event) should not generate any events. +TEST_F(TouchExplorationTest, DoubleTapNoTouchExplore) { + SwitchTouchExplorationMode(true); + + // Double-tap without any previous touch. + // Touch exploration mode has not been entered, so there is no previous + // touch exploration event. The double-tap should be discarded, and no events + // should be generated at all. + gfx::Point double_tap_location(33, 34); + generator_->set_current_location(double_tap_location); + generator_->PressTouch(); + generator_->ReleaseTouch(); + generator_->PressTouch(); + // Since the state stays in single_tap_released, we need to make sure the + // tap timer doesn't fire and set the state to no fingers down (since there + // is still a finger down). + AdvanceSimulatedTimePastPotentialTapDelay(); + EXPECT_FALSE(IsInNoFingersDownState()); + generator_->ReleaseTouch(); + EXPECT_TRUE(IsInNoFingersDownState()); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); +} + +// Tapping and releasing with a second finger when in touch exploration mode +// should send a touch press and released to the location of the last +// successful touch exploration and return to touch explore. +TEST_F(TouchExplorationTest, SplitTap) { + SwitchTouchExplorationMode(true); + gfx::Point initial_touch_location(111, 112); + gfx::Point second_touch_location(33, 34); + + // Tap and hold at one location, and get a mouse move event in touch explore. + EnterTouchExplorationModeAtLocation(initial_touch_location); + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + + EXPECT_EQ(initial_touch_location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + EXPECT_TRUE(IsInTouchToMouseMode()); + + // Now tap and release at a different location. This should result in a + // single touch and release at the location of the first (held) tap, + // not at the location of the second tap and release. + // After the release, there is still a finger in touch explore mode. + ui::TouchEvent split_tap_press( + ui::ET_TOUCH_PRESSED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_press); + // To simulate the behavior of the real device, we manually disable + // mouse events. To not rely on manually setting the state, this is also + // tested in touch_exploration_controller_browsertest. + cursor_client()->DisableMouseEvents(); + EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); + EXPECT_FALSE(cursor_client()->IsCursorVisible()); + EXPECT_FALSE(IsInGestureInProgressState()); + ui::TouchEvent split_tap_release( + ui::ET_TOUCH_RELEASED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_release); + // Releasing the second finger should re-enable mouse events putting us + // back into the touch exploration mode. + EXPECT_TRUE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInNoFingersDownState()); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(2U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(initial_touch_location, captured_events[0]->location()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); + EXPECT_EQ(initial_touch_location, captured_events[1]->location()); + EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + ui::TouchEvent touch_explore_release( + ui::ET_TOUCH_RELEASED, initial_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&touch_explore_release); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// If split tap is started but the touch explore finger is released first, +// there should still be a touch press and release sent to the location of +// the last successful touch exploration. +// Both fingers should be released after the click goes through. +TEST_F(TouchExplorationTest, SplitTapRelease) { + SwitchTouchExplorationMode(true); + + gfx::Point initial_touch_location(111, 112); + gfx::Point second_touch_location(133, 134); + + // Tap and hold at one location, and get a mouse move event in touch explore. + EnterTouchExplorationModeAtLocation(initial_touch_location); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + // Now tap at a different location. Release at the first location, + // then release at the second. This should result in a + // single touch and release at the location of the first (held) tap, + // not at the location of the second tap and release. + ui::TouchEvent split_tap_press( + ui::ET_TOUCH_PRESSED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_press); + ui::TouchEvent touch_explore_release( + ui::ET_TOUCH_RELEASED, initial_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&touch_explore_release); + ui::TouchEvent split_tap_release( + ui::ET_TOUCH_RELEASED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_release); + EXPECT_TRUE(IsInNoFingersDownState()); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(2U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(initial_touch_location, captured_events[0]->location()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); + EXPECT_EQ(initial_touch_location, captured_events[1]->location()); + EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); +} + +TEST_F(TouchExplorationTest, SplitTapMultiFinger) { + SwitchTouchExplorationMode(true); + gfx::Point initial_touch_location(111, 112); + gfx::Point second_touch_location(133, 134); + gfx::Point third_touch_location(116, 117); + + // Tap and hold at one location, and get a mouse move event in touch explore. + EnterTouchExplorationModeAtLocation(initial_touch_location); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED); + ASSERT_EQ(1U, events.size()); + + EXPECT_EQ(initial_touch_location, events[0]->location()); + EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED); + EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + ClearCapturedEvents(); + + // Now tap at a different location + ui::TouchEvent split_tap_press( + ui::ET_TOUCH_PRESSED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_press); + simulated_clock_.Advance(gesture_detector_config_.longpress_timeout); + + // Placing a third finger on the screen should cancel the split tap and + // enter the wait state. + ui::TouchEvent third_press( + ui::ET_TOUCH_PRESSED, third_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2)); + generator_->Dispatch(&third_press); + + // When all three fingers are released, no events should be captured. + // All fingers should then be up. + ui::TouchEvent touch_explore_release( + ui::ET_TOUCH_RELEASED, initial_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&touch_explore_release); + ui::TouchEvent split_tap_release( + ui::ET_TOUCH_RELEASED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_release); + ui::TouchEvent third_tap_release( + ui::ET_TOUCH_RELEASED, third_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2)); + generator_->Dispatch(&third_tap_release); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +TEST_F(TouchExplorationTest, SplitTapLeaveSlop) { + SwitchTouchExplorationMode(true); + gfx::Point first_touch_location(111, 112); + gfx::Point second_touch_location(133, 134); + gfx::Point first_move_location( + first_touch_location.x() + gesture_detector_config_.touch_slop * 3 + 1, + first_touch_location.y()); + gfx::Point second_move_location( + second_touch_location.x() + gesture_detector_config_.touch_slop * 3 + 1, + second_touch_location.y()); + + // Tap and hold at one location, and get a mouse move event in touch explore. + EnterTouchExplorationModeAtLocation(first_touch_location); + ClearCapturedEvents(); + + // Now tap at a different location for split tap. + ui::TouchEvent split_tap_press( + ui::ET_TOUCH_PRESSED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_press); + + // Move the first finger out of slop and release both fingers. The split + // tap should have been cancelled. + ui::TouchEvent first_touch_move( + ui::ET_TOUCH_MOVED, first_move_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&first_touch_move); + ui::TouchEvent first_touch_release( + ui::ET_TOUCH_RELEASED, first_move_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&first_touch_release); + ui::TouchEvent second_touch_release( + ui::ET_TOUCH_RELEASED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&second_touch_release); + + std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); + EXPECT_TRUE(IsInNoFingersDownState()); + + // Now do the same, but moving the split tap finger out of slop + EnterTouchExplorationModeAtLocation(first_touch_location); + ClearCapturedEvents(); + ui::TouchEvent split_tap_press2( + ui::ET_TOUCH_PRESSED, second_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&split_tap_press2); + + // Move the second finger out of slop and release both fingers. The split + // tap should have been cancelled. + ui::TouchEvent second_touch_move2( + ui::ET_TOUCH_MOVED, second_move_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&second_touch_move2); + ui::TouchEvent first_touch_release2( + ui::ET_TOUCH_RELEASED, first_touch_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&first_touch_release2); + ui::TouchEvent second_touch_release2( + ui::ET_TOUCH_RELEASED, second_move_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&second_touch_release2); + + captured_events = GetCapturedLocatedEvents(); + ASSERT_EQ(0U, captured_events.size()); + EXPECT_TRUE(IsInNoFingersDownState()); +} + +// Finger must have moved more than slop, faster than the minimum swipe +// velocity, and before the tap timer fires in order to enter +// GestureInProgress state. Otherwise, if the tap timer fires before the a +// gesture is completed, enter touch exploration. +TEST_F(TouchExplorationTest, EnterGestureInProgressState) { + SwitchTouchExplorationMode(true); + EXPECT_FALSE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInGestureInProgressState()); + + float distance = gesture_detector_config_.touch_slop + 1; + ui::TouchEvent first_press( + ui::ET_TOUCH_PRESSED, gfx::Point(100, 101), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + gfx::Point second_location(100 + distance / 2, 101); + gfx::Point third_location(100 + distance, 101); + gfx::Point touch_exploration_location(120, 121); + + generator_->Dispatch(&first_press); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); + // Since we are not out of the touch slop yet, we should not be in gesture in + // progress. + generator_->MoveTouch(second_location); + EXPECT_FALSE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInGestureInProgressState()); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); + + // Once we are out of slop, we should be in GestureInProgress. + generator_->MoveTouch(third_location); + EXPECT_TRUE(IsInGestureInProgressState()); + EXPECT_FALSE(IsInTouchToMouseMode()); + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(0U, captured_events.size()); + + // Exit out of gesture mode once grace period is over and enter touch + // exploration. There should be a move when entering touch exploration and + // also for the touch move. + AdvanceSimulatedTimePastTapDelay(); + generator_->MoveTouch(touch_exploration_location); + ASSERT_EQ(2U, captured_events.size()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type()); + EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type()); + EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY); + EXPECT_TRUE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInGestureInProgressState()); +} + +// A swipe+direction gesture should trigger a Shift+Search+Direction +// keyboard event. +TEST_F(TouchExplorationTest, GestureSwipe) { + SwitchTouchExplorationMode(true); + + // Test all four swipe directions with 1 to 4 fingers. + struct GestureInfo { + int move_x; + int move_y; + int num_fingers; + ax::mojom::Gesture expected_gesture; + } gestures_to_test[] = { + {-1, 0, 1, ax::mojom::Gesture::kSwipeLeft1}, + {0, -1, 1, ax::mojom::Gesture::kSwipeUp1}, + {1, 0, 1, ax::mojom::Gesture::kSwipeRight1}, + {0, 1, 1, ax::mojom::Gesture::kSwipeDown1}, + {-1, 0, 2, ax::mojom::Gesture::kSwipeLeft2}, + {0, -1, 2, ax::mojom::Gesture::kSwipeUp2}, + {1, 0, 2, ax::mojom::Gesture::kSwipeRight2}, + {0, 1, 2, ax::mojom::Gesture::kSwipeDown2}, + {-1, 0, 3, ax::mojom::Gesture::kSwipeLeft3}, + {0, -1, 3, ax::mojom::Gesture::kSwipeUp3}, + {1, 0, 3, ax::mojom::Gesture::kSwipeRight3}, + {0, 1, 3, ax::mojom::Gesture::kSwipeDown3}, + {-1, 0, 4, ax::mojom::Gesture::kSwipeLeft4}, + {0, -1, 4, ax::mojom::Gesture::kSwipeUp4}, + {1, 0, 4, ax::mojom::Gesture::kSwipeRight4}, + {0, 1, 4, ax::mojom::Gesture::kSwipeDown4}, + }; + + // This value was taken from gesture_recognizer_unittest.cc in a swipe + // detector test, since it seems to be about the right amount to get a swipe. + const int kSteps = 15; + + for (size_t i = 0; i < base::size(gestures_to_test); ++i) { + const float distance = 2 * gesture_detector_config_.touch_slop + 1; + int move_x = gestures_to_test[i].move_x * distance; + int move_y = gestures_to_test[i].move_y * distance; + int num_fingers = gestures_to_test[i].num_fingers; + ax::mojom::Gesture expected_gesture = gestures_to_test[i].expected_gesture; + + std::vector<gfx::Point> start_points; + for (int j = 0; j < num_fingers; j++) { + start_points.push_back(gfx::Point(j * 10 + 100, j * 10 + 200)); + } + gfx::Point* start_points_array = &start_points[0]; + + // A swipe is made when a fling starts + float delta_time = + distance / gesture_detector_config_.maximum_fling_velocity; + // delta_time is in seconds, so we convert to ms. + int delta_time_ms = floor(delta_time * 1000); + generator_->GestureMultiFingerScroll(num_fingers, start_points_array, + delta_time_ms, kSteps, move_x, move_y); + EXPECT_EQ(expected_gesture, delegate_.GetLastGesture()); + EXPECT_TRUE(IsInNoFingersDownState()); + EXPECT_FALSE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInGestureInProgressState()); + ClearCapturedEvents(); + } +} + +TEST_F(TouchExplorationTest, DISABLED_GestureSwipePortrit) { + // Rotate the window 90-degrees counter-clockwise. + root_window()->GetHost()->SetRootTransform( + gfx::Transform(0, 1, 0, 0, -1, 0, 0, root_window()->bounds().height(), 0, + 0, 0, 0, 0, 0, 0, 0)); + + SwitchTouchExplorationMode(true); + + // Test 2-4 finger gestures. + struct GestureInfo { + int move_x; + int move_y; + int num_fingers; + ax::mojom::Gesture expected_gesture; + } gestures_to_test[] = { + {-1, 0, 2, ax::mojom::Gesture::kSwipeDown2}, + {0, -1, 2, ax::mojom::Gesture::kSwipeLeft2}, + {1, 0, 2, ax::mojom::Gesture::kSwipeUp2}, + {0, 1, 2, ax::mojom::Gesture::kSwipeRight2}, + {-1, 0, 3, ax::mojom::Gesture::kSwipeDown3}, + {0, -1, 3, ax::mojom::Gesture::kSwipeLeft3}, + {1, 0, 3, ax::mojom::Gesture::kSwipeUp3}, + {0, 1, 3, ax::mojom::Gesture::kSwipeRight3}, + {-1, 0, 4, ax::mojom::Gesture::kSwipeDown4}, + {0, -1, 4, ax::mojom::Gesture::kSwipeLeft4}, + {1, 0, 4, ax::mojom::Gesture::kSwipeUp4}, + {0, 1, 4, ax::mojom::Gesture::kSwipeRight4}, + }; + + // This value was taken from gesture_recognizer_unittest.cc in a swipe + // detector test, since it seems to be about the right amount to get a swipe. + const int kSteps = 15; + + for (size_t i = 0; i < base::size(gestures_to_test); ++i) { + const float distance = 2 * gesture_detector_config_.touch_slop + 1; + int move_x = gestures_to_test[i].move_x * distance; + int move_y = gestures_to_test[i].move_y * distance; + int num_fingers = gestures_to_test[i].num_fingers; + ax::mojom::Gesture expected_gesture = gestures_to_test[i].expected_gesture; + + std::vector<gfx::Point> start_points; + for (int j = 0; j < num_fingers; j++) { + start_points.push_back(gfx::Point(j * 10 + 100, j * 10 + 100)); + } + gfx::Point* start_points_array = &start_points[0]; + + // A swipe is made when a fling starts + float delta_time = + distance / gesture_detector_config_.maximum_fling_velocity; + // delta_time is in seconds, so we convert to ms. + int delta_time_ms = floor(delta_time * 1000); + generator_->GestureMultiFingerScroll(num_fingers, start_points_array, + delta_time_ms, kSteps, move_x, move_y); + EXPECT_EQ(expected_gesture, delegate_.GetLastGesture()); + EXPECT_TRUE(IsInNoFingersDownState()); + EXPECT_FALSE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInGestureInProgressState()); + ClearCapturedEvents(); + } +} + +// Since there are so many permutations, this test is fairly slow. Therefore, it +// is disabled and will be turned on to check during development. + +TEST_F(TouchExplorationTest, DISABLED_AllFingerPermutations) { + SwitchTouchExplorationMode(true); + SuppressVLOGs(true); + // We will test all permutations of events from three different fingers + // to ensure that we return to NO_FINGERS_DOWN when fingers have been + // released. + std::vector<std::unique_ptr<ui::TouchEvent>> all_events; + + // A copy of all events list which can be modified without destrying events. + std::vector<ui::TouchEvent*> queued_events; + + for (int touch_id = 0; touch_id < 3; touch_id++) { + int x = 10 * touch_id + 101; + int y = 10 * touch_id + 102; + all_events.push_back(std::make_unique<ui::TouchEvent>( + ui::ET_TOUCH_PRESSED, gfx::Point(x++, y++), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, + touch_id))); + queued_events.push_back(all_events.back().get()); + all_events.push_back(std::make_unique<ui::TouchEvent>( + ui::ET_TOUCH_MOVED, gfx::Point(x++, y++), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, + touch_id))); + queued_events.push_back(all_events.back().get()); + all_events.push_back(std::make_unique<ui::TouchEvent>( + ui::ET_TOUCH_RELEASED, gfx::Point(x, y), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, + touch_id))); + queued_events.push_back(all_events.back().get()); + } + + // I'm going to explain this algorithm, and use an example in parentheses. + // The example will be all permutations of a b c d. + // There are four letters and 4! = 24 permutations. + const int num_events = all_events.size(); + const int num_permutations = Factorial(num_events); + + for (int p = 0; p < num_permutations; p++) { + std::vector<bool> fingers_pressed(3, false); + + int current_num_permutations = num_permutations; + for (int events_left = num_events; events_left > 0; events_left--) { + // |p| indexes to each permutation when there are num_permutations + // permutations. (e.g. 0 is abcd, 1 is abdc, 2 is acbd, 3 is acdb...) + // But how do we find the index for the current number of permutations? + // To find the permutation within the part of the sequence we're + // currently looking at, we need a number between 0 and + // |current_num_permutations| - 1. + // (e.g. if we already chose the first letter, there are 3! = 6 + // options left, so we do p % 6. So |current_permutation| would go + // from 0 to 5 and then reset to 0 again, for all combinations of + // whichever three letters are remaining, as we loop through the + // permutations) + int current_permutation = p % current_num_permutations; + + // Since this is is the total number of permutations starting with + // this event and including future events, there could be multiple + // values of current_permutation that will generate the same event + // in this iteration. + // (e.g. If we chose 'a' but have b c d to choose from, we choose b when + // |current_permutation| = 0, 1 and c when |current_permutation| = 2, 3. + // Note that each letter gets two numbers, which is the next + // current_num_permutations, 2! for the two letters left.) + + // Branching out from the first event, there are num_permutations + // permutations, and each value of |p| is associated with one of these + // permutations. However, once the first event is chosen, there + // are now |num_events| - 1 events left, so the number of permutations + // for the rest of the events changes, and will always be equal to + // the factorial of the events_left. + // (e.g. There are 3! = 6 permutations that start with 'a', so if we + // start with 'a' there will be 6 ways to then choose from b c d.) + // So we now set-up for the next iteration by setting + // current_num_permutations to the factorial of the next number of + // events left. + current_num_permutations /= events_left; + + // To figure out what current event we want to choose, we integer + // divide the current permutation by the next current_num_permutations. + // (e.g. If there are 4 letters a b c d and 24 permutations, we divide + // by 24/4 = 6. Values 0 to 5 when divided by 6 equals 0, so the first + // 6 permutations start with 'a', and the last 6 will start with 'd'. + // Note that there are 6 that start with 'a' because there are 6 + // permutations for the next three letters that follow 'a'.) + int index = current_permutation / current_num_permutations; + + ui::TouchEvent* next_dispatch = queued_events[index]; + ASSERT_TRUE(next_dispatch != NULL); + + // |next_dispatch| has to be put in this container so that its time + // stamp can be changed to this point in the test, when it is being + // dispatched.. + ui::EventTestApi test_dispatch(next_dispatch); + test_dispatch.set_time_stamp(Now()); + generator_->Dispatch(next_dispatch); + queued_events.erase(queued_events.begin() + index); + + // Keep track of what fingers have been pressed, to release + // only those fingers at the end, so the check for being in + // no fingers down can be accurate. + if (next_dispatch->type() == ui::ET_TOUCH_PRESSED) { + fingers_pressed[next_dispatch->pointer_details().id] = true; + } else if (next_dispatch->type() == ui::ET_TOUCH_RELEASED) { + fingers_pressed[next_dispatch->pointer_details().id] = false; + } + } + ASSERT_EQ(queued_events.size(), 0u); + + // Release fingers recorded as pressed. + for (int j = 0; j < int(fingers_pressed.size()); j++) { + if (fingers_pressed[j] == true) { + generator_->ReleaseTouchId(j); + fingers_pressed[j] = false; + } + } + AdvanceSimulatedTimePastPotentialTapDelay(); + EXPECT_TRUE(IsInNoFingersDownState()); + ClearCapturedEvents(); + } +} + +// With the simple swipe gestures, if additional fingers are added and the tap +// timer times out, then the state should change to the wait for one finger +// state. +TEST_F(TouchExplorationTest, GestureAddedFinger) { + SwitchTouchExplorationMode(true); + EXPECT_FALSE(IsInTouchToMouseMode()); + EXPECT_FALSE(IsInGestureInProgressState()); + + float distance = gesture_detector_config_.touch_slop + 1; + ui::TouchEvent first_press( + ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&first_press); + simulated_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); + gfx::Point second_location(100 + distance, 200); + generator_->MoveTouch(second_location); + EXPECT_TRUE(IsInGestureInProgressState()); + EXPECT_FALSE(IsInTouchToMouseMode()); + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(0U, captured_events.size()); + + // Generate a second press, but time out past the gesture period so that + // gestures are prevented from continuing to go through. + ui::TouchEvent second_press( + ui::ET_TOUCH_PRESSED, gfx::Point(20, 21), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + generator_->Dispatch(&second_press); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_FALSE(IsInGestureInProgressState()); + EXPECT_FALSE(IsInTouchToMouseMode()); + ASSERT_EQ(0U, captured_events.size()); +} + +// Even if the gesture starts within bounds, if it has not moved past slop +// within the grace period, it should go to touch exploration. +TEST_F(TouchExplorationTest, InBoundariesTouchExploration) { + SwitchTouchExplorationMode(true); + + gfx::Rect window = BoundsOfRootWindowInDIP(); + gfx::Point initial_press(window.right() - (GetMaxDistanceFromEdge() + GetLeavingDistanceFromEdge()) / 2, GetLeavingDistanceFromEdge() + 1); + ui::TouchEvent first_press( + ui::ET_TOUCH_PRESSED, initial_press, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&first_press); + EXPECT_FALSE(IsInGestureInProgressState()); + EXPECT_FALSE(IsInTouchToMouseMode()); + + AdvanceSimulatedTimePastTapDelay(); + EXPECT_FALSE(IsInGestureInProgressState()); + EXPECT_TRUE(IsInTouchToMouseMode()); +} + +// If two fingers tap the screen at the same time and release before the tap +// timer runs out, a control key event should be sent to silence chromevox. +TEST_F(TouchExplorationTest, TwoFingerTap) { + SwitchTouchExplorationMode(true); + + generator_->set_current_location(gfx::Point(101, 102)); + generator_->PressTouchId(1); + EXPECT_FALSE(IsInTwoFingerTapState()); + + generator_->PressTouchId(2); + EXPECT_TRUE(IsInTwoFingerTapState()); + + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(0U, captured_events.size()); + + generator_->ReleaseTouchId(1); + EXPECT_TRUE(IsInTwoFingerTapState()); + generator_->ReleaseTouchId(2); + + EXPECT_EQ(0U, captured_events.size()); + ASSERT_EQ(ax::mojom::Gesture::kTap2, delegate_.GetLastGesture()); +} + +// If the fingers are not released before the tap timer runs out, a control +// keyevent is not sent and the state will no longer be in two finger tap. +TEST_F(TouchExplorationTest, TwoFingerTapAndHold) { + SwitchTouchExplorationMode(true); + + generator_->set_current_location(gfx::Point(101, 102)); + generator_->PressTouchId(1); + EXPECT_FALSE(IsInTwoFingerTapState()); + + generator_->PressTouchId(2); + EXPECT_TRUE(IsInTwoFingerTapState()); + + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(0U, captured_events.size()); + + AdvanceSimulatedTimePastTapDelay(); + // Since the tap delay has elapsed, it should no longer be in two finger tap. + EXPECT_FALSE(IsInTwoFingerTapState()); +} + +// The next two tests set up two finger swipes to happen. If one of the fingers +// moves out of slop before the tap timer fires, a two finger tap is not made. +// In this first test, the first finger placed will move out of slop. +TEST_F(TouchExplorationTest, TwoFingerTapAndMoveFirstFinger) { + SwitchTouchExplorationMode(true); + + // Once one of the fingers leaves slop, it should no longer be in two finger + // tap. + ui::TouchEvent first_press_id_1( + ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + ui::TouchEvent first_press_id_2( + ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2)); + + ui::TouchEvent slop_move_id_1( + ui::ET_TOUCH_MOVED, + gfx::Point(100 + gesture_detector_config_.touch_slop, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + ui::TouchEvent slop_move_id_2( + ui::ET_TOUCH_MOVED, + gfx::Point(110 + gesture_detector_config_.touch_slop, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2)); + + ui::TouchEvent out_slop_id_1( + ui::ET_TOUCH_MOVED, + gfx::Point(100 + gesture_detector_config_.touch_slop + 1, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + + // Dispatch the inital presses. + generator_->Dispatch(&first_press_id_1); + EXPECT_FALSE(IsInTwoFingerTapState()); + generator_->Dispatch(&first_press_id_2); + EXPECT_TRUE(IsInTwoFingerTapState()); + + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(0U, captured_events.size()); + + // The presses have not moved out of slop yet so it should still be in + // TwoFingerTap. + generator_->Dispatch(&slop_move_id_1); + EXPECT_TRUE(IsInTwoFingerTapState()); + generator_->Dispatch(&slop_move_id_2); + EXPECT_TRUE(IsInTwoFingerTapState()); + + // Once one of the fingers moves out of slop, we are no longer in + // TwoFingerTap. + generator_->Dispatch(&out_slop_id_1); + EXPECT_FALSE(IsInTwoFingerTapState()); +} + +// Similar test to the previous test except the second finger placed will be the +// one to move out of slop. +TEST_F(TouchExplorationTest, TwoFingerTapAndMoveSecondFinger) { + SwitchTouchExplorationMode(true); + + // Once one of the fingers leaves slop, it should no longer be in two finger + // tap. + ui::TouchEvent first_press_id_1( + ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + ui::TouchEvent first_press_id_2( + ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2)); + + ui::TouchEvent out_slop_id_2( + ui::ET_TOUCH_MOVED, + gfx::Point(100 + gesture_detector_config_.touch_slop + 1, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + + generator_->Dispatch(&first_press_id_1); + EXPECT_FALSE(IsInTwoFingerTapState()); + + generator_->Dispatch(&first_press_id_2); + EXPECT_TRUE(IsInTwoFingerTapState()); + + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(0U, captured_events.size()); + + generator_->Dispatch(&out_slop_id_2); + EXPECT_FALSE(IsInTwoFingerTapState()); +} + +// Corner passthrough should turn on if the user first holds down on either the +// right or left corner past a delay and then places a finger anywhere else on +// the screen. +TEST_F(TouchExplorationTest, ActivateLeftCornerPassthrough) { + SwitchTouchExplorationMode(true); + + gfx::Rect window = BoundsOfRootWindowInDIP(); + gfx::Point left_corner( + (GetLeavingDistanceFromEdge() + GetMaxDistanceFromEdge()) / 2, + window.bottom() - + (GetLeavingDistanceFromEdge() + GetMaxDistanceFromEdge()) / 2); + AssertCornerPassthroughWorking(left_corner); +} + +TEST_F(TouchExplorationTest, ActivateRightCornerPassthrough) { + SwitchTouchExplorationMode(true); + + gfx::Rect window = BoundsOfRootWindowInDIP(); + gfx::Point right_corner( + window.right() - + (GetLeavingDistanceFromEdge() + GetMaxDistanceFromEdge()) / 2, + window.bottom() - + (GetLeavingDistanceFromEdge() + GetMaxDistanceFromEdge()) / 2); + AssertCornerPassthroughWorking(right_corner); +} + +// Earcons should play if the user slides off the screen or enters the screen +// from the edge. +TEST_F(TouchExplorationTest, EnterEarconPlays) { + SwitchTouchExplorationMode(true); + + gfx::Rect window = BoundsOfRootWindowInDIP(); + + gfx::Point upper_left_corner(0, 0); + gfx::Point upper_right_corner(window.right(), 0); + gfx::Point lower_left_corner(0, window.bottom()); + gfx::Point lower_right_corner(window.right(), window.bottom()); + gfx::Point left_edge(0, 30); + gfx::Point right_edge(window.right(), 30); + gfx::Point top_edge(30, 0); + gfx::Point bottom_edge(30, window.bottom()); + + std::vector<gfx::Point> locations; + locations.push_back(upper_left_corner); + locations.push_back(upper_right_corner); + locations.push_back(lower_left_corner); + locations.push_back(lower_right_corner); + locations.push_back(left_edge); + locations.push_back(right_edge); + locations.push_back(top_edge); + locations.push_back(bottom_edge); + + for (std::vector<gfx::Point>::const_iterator point = locations.begin(); + point != locations.end(); ++point) { + ui::TouchEvent touch_event( + ui::ET_TOUCH_PRESSED, *point, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + + generator_->Dispatch(&touch_event); + ASSERT_EQ(1U, delegate_.NumEnterScreenSounds()); + generator_->ReleaseTouchId(1); + delegate_.ResetCountersToZero(); + } +} + +TEST_F(TouchExplorationTest, ExitEarconPlays) { + SwitchTouchExplorationMode(true); + + // On the device, it cannot actually tell if the finger has left the screen or + // not. If the finger has left the screen, it reads it as a release that + // occurred very close to the edge of the screen even if the finger is still + // technically touching the moniter. To simulate this, a release that occurs + // close to the edge is dispatched. + gfx::Point initial_press(100, 200); + gfx::Rect window = BoundsOfRootWindowInDIP(); + + gfx::Point upper_left_corner(0, 0); + gfx::Point upper_right_corner(window.right(), 0); + gfx::Point lower_left_corner(0, window.bottom()); + gfx::Point lower_right_corner(window.right(), window.bottom()); + gfx::Point left_edge(0, 30); + gfx::Point right_edge(window.right(), 30); + gfx::Point top_edge(30, 0); + gfx::Point bottom_edge(30, window.bottom()); + + std::vector<gfx::Point> locations; + locations.push_back(upper_left_corner); + locations.push_back(upper_right_corner); + locations.push_back(lower_left_corner); + locations.push_back(lower_right_corner); + locations.push_back(left_edge); + locations.push_back(right_edge); + locations.push_back(top_edge); + locations.push_back(bottom_edge); + + for (std::vector<gfx::Point>::const_iterator point = locations.begin(); + point != locations.end(); ++point) { + generator_->PressTouch(); + generator_->MoveTouch(initial_press); + generator_->MoveTouch(*point); + generator_->ReleaseTouch(); + ASSERT_EQ(1U, delegate_.NumExitScreenSounds()); + delegate_.ResetCountersToZero(); + } +} + +TEST_F(TouchExplorationTest, ExclusionArea) { + SwitchTouchExplorationMode(true); + + gfx::Rect window = BoundsOfRootWindowInDIP(); + gfx::Rect exclude = window; + exclude.Inset(0, 0, 0, window.CenterPoint().y()); + SetExcludeBounds(exclude); + + gfx::Point in_pt = exclude.CenterPoint(); + gfx::Point in_mv_pt(in_pt.x(), (in_pt.y() + exclude.bottom()) / 2); + gfx::Point out_pt(in_pt.x(), exclude.bottom() + 20); + gfx::Point out_mv_pt(in_pt.x(), exclude.bottom() + 10); + fprintf(stderr, "exclude: (%d, %d)-(%d, %d)\n", exclude.x(), exclude.y(), exclude.right(), exclude.bottom()); + fprintf(stderr, "in_pt: (%d, %d)\n", in_pt.x(), in_pt.y()); + fprintf(stderr, "in_mv_pt: (%d, %d)\n", in_mv_pt.x(), in_mv_pt.y()); + fprintf(stderr, "out_pt: (%d, %d)\n", out_pt.x(), out_pt.y()); + fprintf(stderr, "out_mv_pt: (%d, %d)\n", out_mv_pt.x(), out_mv_pt.y()); + + // Motion starting in exclusion bounds is passed-through unchanged. + { + generator_->set_current_location(in_pt); + generator_->PressTouchId(0); + AdvanceSimulatedTimePastPotentialTapDelay(); + generator_->MoveTouchId(out_mv_pt, 0); + generator_->ReleaseTouchId(0); + EXPECT_TRUE(IsInNoFingersDownState()); + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(3U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[1]->type()); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[2]->type()); + ClearCapturedEvents(); + } + + // Complete motion outside exclusion is rewritten. + { + generator_->set_current_location(out_pt); + generator_->PressTouchId(0); + AdvanceSimulatedTimePastTapDelay(); + generator_->MoveTouchId(out_mv_pt, 0); + generator_->ReleaseTouchId(0); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_TRUE(IsInNoFingersDownState()); + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(3U, captured_events.size()); + for (const std::unique_ptr<ui::Event>& e : captured_events) { + EXPECT_EQ(ui::ET_MOUSE_MOVED, e->type()); + } + ClearCapturedEvents(); + } + + // For a motion starting outside: outside events are rewritten, inside + // events are discarded unless they end the motion. + { + // finger 0 down outside, moves inside. + generator_->set_current_location(out_pt); + generator_->PressTouchId(0); + AdvanceSimulatedTimePastTapDelay(); + generator_->MoveTouchId(out_mv_pt, 0); + generator_->MoveTouchId(in_mv_pt, 0); + ASSERT_EQ(2U, GetCapturedEvents().size()); + for (const std::unique_ptr<ui::Event>& e : GetCapturedEvents()) { + EXPECT_EQ(ui::ET_MOUSE_MOVED, e->type()); + } + ClearCapturedEvents(); + + // finger 1 down inside, moves outside + generator_->set_current_location(in_pt); + generator_->PressTouchId(1); + generator_->MoveTouchId(out_mv_pt, 1); + generator_->ReleaseTouchId(1); + ASSERT_EQ(0U, GetCapturedEvents().size()); + EXPECT_FALSE(IsInNoFingersDownState()); + + generator_->ReleaseTouchId(0); + AdvanceSimulatedTimePastTapDelay(); + EXPECT_TRUE(IsInNoFingersDownState()); + + ASSERT_EQ(1U, GetCapturedEvents().size()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, GetCapturedEvents()[0]->type()); + ClearCapturedEvents(); + } +} + +TEST_F(TouchExplorationTest, SingleTapInLiftActivationArea) { + SwitchTouchExplorationMode(true); + + gfx::Rect lift_activation = BoundsOfRootWindowInDIP(); + lift_activation.Inset(0, 0, 0, lift_activation.CenterPoint().y()); + SetLiftActivationBounds(lift_activation); + + // Tap at one location, and get tap and mouse move events. + gfx::Point tap_location = lift_activation.CenterPoint(); + + // The user has to have previously selected something. + SetTouchAccessibilityAnchorPoint(tap_location); + + generator_->set_current_location(tap_location); + generator_->PressTouchId(1); + generator_->ReleaseTouchId(1); + AdvanceSimulatedTimePastTapDelay(); + + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(3U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[2]->type()); + ClearCapturedEvents(); + + gfx::Point out_tap_location(tap_location.x(), lift_activation.bottom() + 20); + SetTouchAccessibilityAnchorPoint(out_tap_location); + generator_->set_current_location(out_tap_location); + generator_->PressTouchId(1); + generator_->ReleaseTouchId(1); + AdvanceSimulatedTimePastTapDelay(); + + const EventList& out_captured_events = GetCapturedEvents(); + ASSERT_EQ(1U, out_captured_events.size()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, out_captured_events[0]->type()); +} + +TEST_F(TouchExplorationTest, TouchExploreLiftInLiftActivationArea) { + SwitchTouchExplorationMode(true); + + gfx::Rect lift_activation = BoundsOfRootWindowInDIP(); + lift_activation.Inset(0, 0, 0, lift_activation.CenterPoint().y()); + SetLiftActivationBounds(lift_activation); + + // Explore at one location, and get tap and mouse move events. + gfx::Point tap_location = lift_activation.CenterPoint(); + EnterTouchExplorationModeAtLocation(tap_location); + ClearCapturedEvents(); + ASSERT_EQ(0U, delegate_.NumTouchTypeSounds()); + + // A touch release should trigger a tap. + ui::TouchEvent touch_explore_release( + ui::ET_TOUCH_RELEASED, tap_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&touch_explore_release); + AdvanceSimulatedTimePastTapDelay(); + + const EventList& captured_events = GetCapturedEvents(); + ASSERT_EQ(3U, captured_events.size()); + EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type()); + EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[2]->type()); + ASSERT_EQ(1U, delegate_.NumTouchTypeSounds()); + ClearCapturedEvents(); + delegate_.ResetCountersToZero(); + + // Touch explore inside the activation bounds, but lift outside. + gfx::Point out_tap_location(tap_location.x(), lift_activation.bottom() + 20); + SetTouchAccessibilityAnchorPoint(out_tap_location); + EnterTouchExplorationModeAtLocation(tap_location); + ClearCapturedEvents(); + ui::TouchEvent out_touch_explore_release( + ui::ET_TOUCH_RELEASED, out_tap_location, Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); + generator_->Dispatch(&out_touch_explore_release); + AdvanceSimulatedTimePastTapDelay(); + + const EventList& out_captured_events = GetCapturedEvents(); + ASSERT_EQ(1U, out_captured_events.size()); + EXPECT_EQ(ui::ET_MOUSE_MOVED, out_captured_events[0]->type()); + ASSERT_EQ(0U, delegate_.NumTouchTypeSounds()); +} + +// Ensure that any touch release events received after +// TouchExplorationController starts up are canceled, if we haven't +// seen any touch press events yet. http://crbug.com/751348 +TEST_F(TouchExplorationTest, AlreadyHeldFingersGetCanceled) { + generator_->PressTouch(); + SwitchTouchExplorationMode(true); + generator_->ReleaseTouch(); + + std::vector<ui::LocatedEvent*> events = + GetCapturedLocatedEventsOfType(ui::ET_TOUCH_CANCELLED); + ASSERT_EQ(1U, events.size()); +} + +// Ensure 3 or 4 finger tap gets recognized correctly. +TEST_F(TouchExplorationTest, ThreeOrFourFingerTap) { + SwitchTouchExplorationMode(true); + + ui::TouchEvent press_id_1( + ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + ui::TouchEvent release_id_1( + ui::ET_TOUCH_RELEASED, gfx::Point(100, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1)); + ui::TouchEvent press_id_2( + ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2)); + ui::TouchEvent release_id_2( + ui::ET_TOUCH_RELEASED, gfx::Point(110, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 2)); + ui::TouchEvent press_id_3( + ui::ET_TOUCH_PRESSED, gfx::Point(120, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 3)); + ui::TouchEvent release_id_3( + ui::ET_TOUCH_RELEASED, gfx::Point(120, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 3)); + ui::TouchEvent press_id_4( + ui::ET_TOUCH_PRESSED, gfx::Point(130, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 4)); + ui::TouchEvent release_id_4( + ui::ET_TOUCH_RELEASED, gfx::Point(120, 200), Now(), + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 4)); + + // Three fingers down. + generator_->Dispatch(&press_id_1); + EXPECT_FALSE(IsInTwoFingerTapState()); + generator_->Dispatch(&press_id_2); + EXPECT_TRUE(IsInTwoFingerTapState()); + generator_->Dispatch(&press_id_3); + EXPECT_TRUE(IsInGestureInProgressState()); + + // Three fingers up. + generator_->Dispatch(&release_id_1); + EXPECT_TRUE(IsInGestureInProgressState()); + generator_->Dispatch(&release_id_2); + EXPECT_TRUE(IsInGestureInProgressState()); + + ASSERT_EQ(ax::mojom::Gesture::kNone, delegate_.GetLastGesture()); + + generator_->Dispatch(&release_id_3); + EXPECT_TRUE(IsInNoFingersDownState()); + + ASSERT_EQ(ax::mojom::Gesture::kTap3, delegate_.GetLastGesture()); + delegate_.ResetLastGesture(); + + // Four fingers down. + generator_->Dispatch(&press_id_1); + EXPECT_FALSE(IsInTwoFingerTapState()); + generator_->Dispatch(&press_id_2); + EXPECT_TRUE(IsInTwoFingerTapState()); + generator_->Dispatch(&press_id_3); + EXPECT_TRUE(IsInGestureInProgressState()); + generator_->Dispatch(&press_id_4); + EXPECT_TRUE(IsInGestureInProgressState()); + + // Four fingers up. + generator_->Dispatch(&release_id_1); + EXPECT_TRUE(IsInGestureInProgressState()); + generator_->Dispatch(&release_id_2); + EXPECT_TRUE(IsInGestureInProgressState()); + generator_->Dispatch(&release_id_3); + EXPECT_TRUE(IsInGestureInProgressState()); + + ASSERT_EQ(ax::mojom::Gesture::kNone, delegate_.GetLastGesture()); + + generator_->Dispatch(&release_id_4); + EXPECT_TRUE(IsInNoFingersDownState()); + + ASSERT_EQ(ax::mojom::Gesture::kTap4, delegate_.GetLastGesture()); +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/browser/accessibility/touch_exploration_manager.cc b/chromecast/browser/accessibility/touch_exploration_manager.cc new file mode 100644 index 0000000..85035c0 --- /dev/null +++ b/chromecast/browser/accessibility/touch_exploration_manager.cc
@@ -0,0 +1,123 @@ +// 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. + +// Copied with modifications from ash/accessibility, refactored for use in +// chromecast. + +#include "chromecast/browser/accessibility/touch_exploration_manager.h" + +#include "chromecast/browser/cast_browser_context.h" +#include "chromecast/browser/cast_browser_process.h" +#include "chromecast/common/extensions_api/accessibility_private.h" +#include "chromecast/graphics/cast_focus_client_aura.h" +#include "extensions/browser/event_router.h" +#include "ui/accessibility/ax_enum_util.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/display/screen.h" + +namespace chromecast { +namespace shell { + +TouchExplorationManager::TouchExplorationManager( + aura::Window* root_window, + wm::ActivationClient* activation_client, + AccessibilityFocusRingController* accessibility_focus_ring_controller) + : touch_exploration_enabled_(false), + root_window_(root_window), + activation_client_(activation_client), + accessibility_focus_ring_controller_( + accessibility_focus_ring_controller) { + UpdateTouchExplorationState(); +} + +TouchExplorationManager::~TouchExplorationManager() { +} + +void TouchExplorationManager::Enable(bool enabled) { + touch_exploration_enabled_ = enabled; + UpdateTouchExplorationState(); +} + +void TouchExplorationManager::PlayPassthroughEarcon() { + LOG(INFO) << "stub PlayPassthroughEarcon"; +} + +void TouchExplorationManager::PlayEnterScreenEarcon() { + LOG(INFO) << "stub PlayEnterScreenEarcon"; +} + +void TouchExplorationManager::PlayExitScreenEarcon() { + LOG(INFO) << "stub PlayExitScreenEarcon"; +} + +void TouchExplorationManager::PlayTouchTypeEarcon() { + LOG(INFO) << "stub PlayTouchTypeEarcon"; +} + +void TouchExplorationManager::HandleAccessibilityGesture( + ax::mojom::Gesture gesture) { + // (Code copied from Chrome's + // AccessibilityController::HandleAccessibilityGestore.) + extensions::EventRouter* event_router = extensions::EventRouter::Get( + shell::CastBrowserProcess::GetInstance()->browser_context()); + std::unique_ptr<base::ListValue> event_args = + std::make_unique<base::ListValue>(); + event_args->AppendString(ui::ToString(gesture)); + std::unique_ptr<extensions::Event> event(new extensions::Event( + extensions::events::ACCESSIBILITY_PRIVATE_ON_ACCESSIBILITY_GESTURE, + extensions::cast::api::accessibility_private::OnAccessibilityGesture:: + kEventName, + std::move(event_args))); + event_router->DispatchEventWithLazyListener( + extension_misc::kChromeVoxExtensionId, std::move(event)); +} + +void TouchExplorationManager::OnWindowActivated( + ::wm::ActivationChangeObserver::ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) { + UpdateTouchExplorationState(); +} + +void TouchExplorationManager::SetTouchAccessibilityAnchorPoint( + const gfx::Point& anchor_point) { + if (touch_exploration_controller_) { + touch_exploration_controller_->SetTouchAccessibilityAnchorPoint( + anchor_point); + } +} + +void TouchExplorationManager::UpdateTouchExplorationState() { + // See https://crbug.com/603745 for more details. + aura::Window* active_window = activation_client_->GetActiveWindow(); + const bool pass_through_surface = + active_window && + active_window->GetProperty( + aura::client::kAccessibilityTouchExplorationPassThrough); + + if (touch_exploration_enabled_) { + if (!touch_exploration_controller_.get()) { + touch_exploration_controller_ = + std::make_unique<TouchExplorationController>(root_window_, this); + } + if (pass_through_surface) { + const display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow( + root_window_); + const gfx::Rect work_area = display.work_area(); + touch_exploration_controller_->SetExcludeBounds(work_area); + // Clear the focus highlight. + accessibility_focus_ring_controller_->SetFocusRing( + std::vector<gfx::Rect>(), + FocusRingBehavior::PERSIST_FOCUS_RING); + } else { + touch_exploration_controller_->SetExcludeBounds(gfx::Rect()); + } + } else { + touch_exploration_controller_.reset(); + } +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/browser/accessibility/touch_exploration_manager.h b/chromecast/browser/accessibility/touch_exploration_manager.h new file mode 100644 index 0000000..f109d0a --- /dev/null +++ b/chromecast/browser/accessibility/touch_exploration_manager.h
@@ -0,0 +1,69 @@ +// 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. + +// Copied with modifications from ash/accessibility, refactored for use in +// chromecast. + +#ifndef CHROMECAST_BROWSER_ACCESSIBILITY_TOUCH_EXPLORATION_MANAGER_H_ +#define CHROMECAST_BROWSER_ACCESSIBILITY_TOUCH_EXPLORATION_MANAGER_H_ + +#include "chromecast/graphics/accessibility/accessibility_focus_ring_controller.h" +#include "chromecast/browser/accessibility/touch_exploration_controller.h" +#include "ui/wm/public/activation_change_observer.h" +#include "ui/wm/public/activation_client.h" + +namespace chromecast { +namespace shell { + +// Responsible for initializing TouchExplorationController when spoken feedback +// is on. Implements TouchExplorationControllerDelegate which allows touch +// gestures to manipulate the system. +class TouchExplorationManager : public TouchExplorationControllerDelegate, + public ::wm::ActivationChangeObserver { + public: + TouchExplorationManager( + aura::Window* root_window, + wm::ActivationClient* activation_client, + AccessibilityFocusRingController* accessibility_focus_ring_controller); + ~TouchExplorationManager() override; + + // Enable or disable touch exploration. + // (In the Chrome version this is handled as an AccessibilityObserver.) + void Enable(bool enabled); + + // TouchExplorationControllerDelegate overrides: + void PlayPassthroughEarcon() override; + void PlayExitScreenEarcon() override; + void PlayEnterScreenEarcon() override; + void PlayTouchTypeEarcon() override; + void HandleAccessibilityGesture(ax::mojom::Gesture gesture) override; + + // wm::ActivationChangeObserver overrides: + void OnWindowActivated( + ::wm::ActivationChangeObserver::ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override; + + // Update the touch exploration controller so that synthesized touch + // events are anchored at this point. + void SetTouchAccessibilityAnchorPoint(const gfx::Point& anchor_point); + + private: + void UpdateTouchExplorationState(); + + std::unique_ptr<TouchExplorationController> touch_exploration_controller_; + bool touch_exploration_enabled_; + + // Not owned; must outlive TouchExplorationManager. + aura::Window* root_window_; + wm::ActivationClient* activation_client_; + AccessibilityFocusRingController* accessibility_focus_ring_controller_; + + DISALLOW_COPY_AND_ASSIGN(TouchExplorationManager); +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_BROWSER_ACCESSIBILITY_TOUCH_EXPLORATION_MANAGER_H_
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 43aae20..8f9502c 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -29,6 +29,10 @@ class BluetoothAdapterCast; } +namespace media { +class CdmFactory; +} + namespace metrics { class MetricsService; } @@ -97,7 +101,6 @@ std::unique_ptr<::media::AudioManager> CreateAudioManager( ::media::AudioLogFactory* audio_log_factory) override; bool OverridesAudioManager() override; - std::unique_ptr<::media::CdmFactory> CreateCdmFactory() override; #endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) media::MediaCapsImpl* media_caps(); @@ -196,6 +199,10 @@ return renderer_config_manager_.get(); } +#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) + std::unique_ptr<::media::CdmFactory> CreateCdmFactory(); +#endif // BUILDFLAG(IS_CAST_USING_CMA_BACKEND) + protected: CastContentBrowserClient(); @@ -219,6 +226,7 @@ const base::Callback<void(scoped_refptr<net::X509Certificate>, scoped_refptr<net::SSLPrivateKey>)>& continue_callback); + #if !defined(OS_ANDROID) // Returns the crash signal FD corresponding to the current process type. int GetCrashSignalFD(const base::CommandLine& command_line);
diff --git a/chromecast/browser/cast_gesture_dispatcher.cc b/chromecast/browser/cast_gesture_dispatcher.cc index 2224f13..e0a0cbf 100644 --- a/chromecast/browser/cast_gesture_dispatcher.cc +++ b/chromecast/browser/cast_gesture_dispatcher.cc
@@ -32,6 +32,8 @@ const gfx::Point& touch_location) { if (swipe_origin == CastSideSwipeOrigin::LEFT) { dispatched_back_ = false; + VLOG(1) << "swipe gesture begin"; + current_swipe_time_ = base::ElapsedTimer(); } } @@ -47,9 +49,14 @@ } delegate_->GestureProgress(GestureType::GO_BACK, touch_location); + VLOG(1) << "swipe gesture continue, elapsed time: " + << current_swipe_time_.Elapsed().InMilliseconds() << "ms"; + if (!dispatched_back_ && touch_location.x() >= horizontal_threshold_) { dispatched_back_ = true; delegate_->ConsumeGesture(GestureType::GO_BACK); + VLOG(1) << "swipe gesture complete, elapsed time: " + << current_swipe_time_.Elapsed().InMilliseconds() << "ms"; } } @@ -59,10 +66,13 @@ if (swipe_origin != CastSideSwipeOrigin::LEFT) { return; } + VLOG(1) << "swipe end, elapsed time: " + << current_swipe_time_.Elapsed().InMilliseconds() << "ms"; if (!delegate_->CanHandleGesture(GestureType::GO_BACK)) { return; } if (!dispatched_back_ && touch_location.x() < horizontal_threshold_) { + VLOG(1) << "swipe gesture cancelled"; delegate_->CancelGesture(GestureType::GO_BACK, touch_location); } }
diff --git a/chromecast/browser/cast_gesture_dispatcher.h b/chromecast/browser/cast_gesture_dispatcher.h index 83b5117..16a82f37 100644 --- a/chromecast/browser/cast_gesture_dispatcher.h +++ b/chromecast/browser/cast_gesture_dispatcher.h
@@ -6,6 +6,7 @@ #define CHROMECAST_BROWSER_CAST_GESTURE_DISPATCHER_H_ #include "base/macros.h" +#include "base/timer/elapsed_timer.h" #include "chromecast/browser/cast_content_window.h" #include "chromecast/graphics/cast_gesture_handler.h" @@ -34,6 +35,7 @@ const int horizontal_threshold_; CastContentWindow::Delegate* const delegate_; bool dispatched_back_; + base::ElapsedTimer current_swipe_time_; }; } // namespace shell
diff --git a/chromecast/graphics/BUILD.gn b/chromecast/graphics/BUILD.gn index f62a9183..f14f777e 100644 --- a/chromecast/graphics/BUILD.gn +++ b/chromecast/graphics/BUILD.gn
@@ -73,6 +73,7 @@ "//ui/compositor", "//ui/display", "//ui/gfx/geometry", + "//ui/platform_window", ] } } @@ -116,6 +117,7 @@ "//ui/events:test_support", "//ui/gfx", "//ui/gl:test_support", + "//ui/platform_window", "//ui/views", "//ui/wm", ]
diff --git a/chromecast/graphics/DEPS b/chromecast/graphics/DEPS index 1ef86f00..efb3e33 100644 --- a/chromecast/graphics/DEPS +++ b/chromecast/graphics/DEPS
@@ -8,6 +8,7 @@ "+ui/events/test", "+ui/gfx", "+ui/gl/test", + "+ui/platform_window", "+ui/views", "+ui/wm/core", "+ui/wm/public",
diff --git a/chromecast/graphics/cast_focus_client_aura_test.cc b/chromecast/graphics/cast_focus_client_aura_test.cc index b40e093..dcb9639 100644 --- a/chromecast/graphics/cast_focus_client_aura_test.cc +++ b/chromecast/graphics/cast_focus_client_aura_test.cc
@@ -9,6 +9,7 @@ #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace chromecast { namespace test { @@ -33,8 +34,9 @@ }; TEST_F(CastFocusClientAuraTest, FocusableWindows) { - std::unique_ptr<aura::WindowTreeHost> window_tree_host( - aura::WindowTreeHost::Create(gfx::Rect(0, 0, 1280, 720))); + std::unique_ptr<aura::WindowTreeHost> window_tree_host = + aura::WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(0, 0, 1280, 720)}); window_tree_host->InitHost(); window_tree_host->Show(); @@ -67,8 +69,9 @@ } TEST_F(CastFocusClientAuraTest, ChildFocus) { - std::unique_ptr<aura::WindowTreeHost> window_tree_host( - aura::WindowTreeHost::Create(gfx::Rect(0, 0, 1280, 720))); + std::unique_ptr<aura::WindowTreeHost> window_tree_host = + aura::WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(0, 0, 1280, 720)}); window_tree_host->InitHost(); window_tree_host->Show(); @@ -103,8 +106,9 @@ } TEST_F(CastFocusClientAuraTest, ZOrder) { - std::unique_ptr<aura::WindowTreeHost> window_tree_host( - aura::WindowTreeHost::Create(gfx::Rect(0, 0, 1280, 720))); + std::unique_ptr<aura::WindowTreeHost> window_tree_host = + aura::WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(0, 0, 1280, 720)}); window_tree_host->InitHost(); window_tree_host->Show(); @@ -156,8 +160,9 @@ } TEST_F(CastFocusClientAuraTest, ZOrderWithChildWindows) { - std::unique_ptr<aura::WindowTreeHost> window_tree_host( - aura::WindowTreeHost::Create(gfx::Rect(0, 0, 1280, 720))); + std::unique_ptr<aura::WindowTreeHost> window_tree_host = + aura::WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(0, 0, 1280, 720)}); window_tree_host->InitHost(); window_tree_host->Show();
diff --git a/chromecast/graphics/cast_system_gesture_event_handler.cc b/chromecast/graphics/cast_system_gesture_event_handler.cc index c781391..bbdd323 100644 --- a/chromecast/graphics/cast_system_gesture_event_handler.cc +++ b/chromecast/graphics/cast_system_gesture_event_handler.cc
@@ -108,6 +108,8 @@ // Let the subscriber know about the gesture begin. gesture_handler->HandleSideSwipeBegin(side_swipe_origin, touch_location); + VLOG(1) << "side swipe gesture begin @ " << touch_location.ToString(); + current_swipe_time_ = base::ElapsedTimer(); } } @@ -124,6 +126,9 @@ // The system gesture has ended. if (event->type() == ui::ET_TOUCH_RELEASED) { + VLOG(1) << "gesture release; time since press: " + << current_swipe_time_.Elapsed().InMilliseconds() << "ms @ " + << touch_location.ToString(); for (auto* gesture_handler : gesture_handlers_) { gesture_handler->HandleSideSwipeEnd(current_swipe_, touch_location); } @@ -136,6 +141,9 @@ for (auto* gesture_handler : gesture_handlers_) { // Let the subscriber know about the gesture begin. gesture_handler->HandleSideSwipeContinue(current_swipe_, touch_location); + VLOG(1) << "gesture continue; time since press: " + << current_swipe_time_.Elapsed().InMilliseconds() << "ms @ " + << touch_location.ToString(); } }
diff --git a/chromecast/graphics/cast_system_gesture_event_handler.h b/chromecast/graphics/cast_system_gesture_event_handler.h index 1214f60..65f6de2b 100644 --- a/chromecast/graphics/cast_system_gesture_event_handler.h +++ b/chromecast/graphics/cast_system_gesture_event_handler.h
@@ -7,6 +7,7 @@ #include "base/containers/flat_set.h" #include "base/macros.h" +#include "base/timer/elapsed_timer.h" #include "chromecast/graphics/cast_gesture_handler.h" #include "ui/events/event_handler.h" @@ -50,6 +51,7 @@ aura::Window* root_window_; CastSideSwipeOrigin current_swipe_; + base::ElapsedTimer current_swipe_time_; base::flat_set<CastGestureHandler*> gesture_handlers_;
diff --git a/chromecast/graphics/cast_window_manager_aura.cc b/chromecast/graphics/cast_window_manager_aura.cc index 9e216eb..a7387cd 100644 --- a/chromecast/graphics/cast_window_manager_aura.cc +++ b/chromecast/graphics/cast_window_manager_aura.cc
@@ -18,6 +18,7 @@ #include "ui/base/ime/input_method_factory.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/platform_window/platform_window_init_properties.h" #include "ui/wm/core/default_screen_position_client.h" namespace chromecast { @@ -98,7 +99,8 @@ CastWindowTreeHost::CastWindowTreeHost(bool enable_input, const gfx::Rect& bounds) - : WindowTreeHostPlatform(bounds), enable_input_(enable_input) { + : WindowTreeHostPlatform(ui::PlatformWindowInitProperties{bounds}), + enable_input_(enable_input) { if (!enable_input) { window()->SetEventTargeter( std::unique_ptr<ui::EventTargeter>(new CastEventIgnorer));
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index 1476c6d..7ff4fdf 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -829,17 +829,6 @@ "//:chromiumos_preflight", # Builds the browser. ":cros_vm_sanity_test_wrapper", # Builds the test wrapper. ] - - # The following dependencies are needed to deploy chrome to the VM. See the - # link for the full list: - # https://codesearch.chromium.org/chromium/src/third_party/chromite/lib/chrome_util.py?l=341 - data_deps += [ "//chrome:xdg_mime" ] - - # TODO(bpastene): Figure out what's generating resources/chromeos/ and - # declare it as a dep instead of adding the dir directly. - data = [ - "$root_out_dir/resources/chromeos/", - ] } }
diff --git a/chromeos/account_manager/account_manager.cc b/chromeos/account_manager/account_manager.cc index 1f5094c6..1fb4eec 100644 --- a/chromeos/account_manager/account_manager.cc +++ b/chromeos/account_manager/account_manager.cc
@@ -276,21 +276,10 @@ return; } - const std::string token = std::move(it->second); + MaybeRevokeTokenOnServer(account_key); tokens_.erase(it); PersistTokensAsync(); NotifyAccountRemovalObservers(account_key); - - // Revoke the token iff it is a GAIA account and the token is not empty. - // Stored tokens can be empty for accounts recently migrated to - // AccountManager, for which we do not have LSTs yet. These accounts require - // re-authentication from the user, but are in a valid state (and hence don't - // do a DCHECK here for |!token.empty()|). - if (account_key.account_type == - account_manager::AccountType::ACCOUNT_TYPE_GAIA && - !token.empty()) { - RevokeGaiaTokenOnServer(token); - } } void AccountManager::UpsertToken(const AccountKey& account_key, @@ -312,6 +301,7 @@ auto it = tokens_.find(account_key); if ((it == tokens_.end()) || (it->second != token)) { + MaybeRevokeTokenOnServer(account_key); tokens_[account_key] = token; PersistTokensAsync(); NotifyTokenObservers(account_key); @@ -385,7 +375,28 @@ return it != tokens_.end() && !it->second.empty(); } +void AccountManager::MaybeRevokeTokenOnServer(const AccountKey& account_key) { + auto it = tokens_.find(account_key); + if (it == tokens_.end()) { + return; + } + + const std::string& token = it->second; + + // Stored tokens can be empty for accounts recently migrated to + // AccountManager, for which we do not have LSTs yet. These accounts require + // re-authentication from the user, but are in a valid state (and hence don't + // do a DCHECK here for |!token.empty()|). + if (account_key.account_type == + account_manager::AccountType::ACCOUNT_TYPE_GAIA && + !token.empty()) { + RevokeGaiaTokenOnServer(token); + } +} + void AccountManager::RevokeGaiaTokenOnServer(const std::string& refresh_token) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + pending_token_revocation_requests_.emplace_back( std::make_unique<GaiaTokenRevocationRequest>( GetUrlRequestContext(), delay_network_call_runner_, refresh_token,
diff --git a/chromeos/account_manager/account_manager.h b/chromeos/account_manager/account_manager.h index a13c048..d5fcf4c 100644 --- a/chromeos/account_manager/account_manager.h +++ b/chromeos/account_manager/account_manager.h
@@ -194,6 +194,14 @@ // Notify |Observer|s about an account removal. void NotifyAccountRemovalObservers(const AccountKey& account_key); + // Revokes |account_key|'s token on the relevant backend. + // Note: Does not do anything if the |account_manager::AccountType| + // of |account_key| does not support server token revocation. + // Note: Does not do anything if |account_key| is not present in |tokens_|. + // Hence, call this method before actually modifying or deleting old tokens + // from |tokens_|. + void MaybeRevokeTokenOnServer(const AccountKey& account_key); + // Revokes |refresh_token| with GAIA. Virtual for testing. virtual void RevokeGaiaTokenOnServer(const std::string& refresh_token);
diff --git a/chromeos/account_manager/account_manager_unittest.cc b/chromeos/account_manager/account_manager_unittest.cc index 3d8d4a3..308938d4 100644 --- a/chromeos/account_manager/account_manager_unittest.cc +++ b/chromeos/account_manager/account_manager_unittest.cc
@@ -198,16 +198,16 @@ TEST_F(AccountManagerTest, ObserversAreNotNotifiedIfTokenIsNotUpdated) { auto observer = std::make_unique<AccountManagerObserver>(); - const std::string& kToken = "123"; + const std::string token = "123"; EXPECT_FALSE(observer->is_token_upserted_callback_called_); account_manager_->AddObserver(observer.get()); - account_manager_->UpsertToken(kAccountKey_, kToken); + account_manager_->UpsertToken(kAccountKey_, token); scoped_task_environment_.RunUntilIdle(); // Observers should not be called when token is not updated. observer->is_token_upserted_callback_called_ = false; - account_manager_->UpsertToken(kAccountKey_, kToken); + account_manager_->UpsertToken(kAccountKey_, token); scoped_task_environment_.RunUntilIdle(); EXPECT_FALSE(observer->is_token_upserted_callback_called_); @@ -249,18 +249,19 @@ account_manager_->RemoveObserver(observer.get()); } -TEST_F(AccountManagerTest, TokenRevocationIsAttemptedForGaiaAccounts) { - const std::string kToken = "123"; +TEST_F(AccountManagerTest, TokenRevocationIsAttemptedForGaiaAccountRemovals) { + const std::string token = "123"; ResetAndInitializeAccountManager(); - EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(kToken)); + EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(token)); - account_manager_->UpsertToken(kAccountKey_, kToken); + account_manager_->UpsertToken(kAccountKey_, token); scoped_task_environment_.RunUntilIdle(); account_manager_->RemoveAccount(kAccountKey_); } -TEST_F(AccountManagerTest, TokenRevocationIsNotAttemptedForNonGaiaAccounts) { +TEST_F(AccountManagerTest, + TokenRevocationIsNotAttemptedForNonGaiaAccountRemovals) { ResetAndInitializeAccountManager(); EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(_)).Times(0); @@ -272,7 +273,7 @@ account_manager_->RemoveAccount(adAccountKey); } -TEST_F(AccountManagerTest, TokenRevocationIsNotAttemptedForEmptyTokens) { +TEST_F(AccountManagerTest, TokenRevocationIsNotAttemptedForEmptyTokenRemovals) { ResetAndInitializeAccountManager(); EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(_)).Times(0); @@ -282,4 +283,18 @@ account_manager_->RemoveAccount(kAccountKey_); } +TEST_F(AccountManagerTest, OldTokenIsRevokedOnTokenUpdate) { + const std::string old_token = "123"; + const std::string new_token = "456"; + ResetAndInitializeAccountManager(); + // Only 1 token should be revoked. + EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(old_token)) + .Times(1); + account_manager_->UpsertToken(kAccountKey_, old_token); + + // Update the token. + account_manager_->UpsertToken(kAccountKey_, new_token); + scoped_task_environment_.RunUntilIdle(); +} + } // namespace chromeos
diff --git a/chromeos/components/drivefs/fake_drivefs.cc b/chromeos/components/drivefs/fake_drivefs.cc index 5daec56..270bb8f7 100644 --- a/chromeos/components/drivefs/fake_drivefs.cc +++ b/chromeos/components/drivefs/fake_drivefs.cc
@@ -153,10 +153,14 @@ metadata->pinned = stored_metadata.pinned; metadata->content_mime_type = stored_metadata.mime_type; - metadata->hosted = stored_metadata.hosted; + metadata->type = stored_metadata.hosted + ? mojom::FileMetadata::Type::kHosted + : info.is_directory + ? mojom::FileMetadata::Type::kDirectory + : mojom::FileMetadata::Type::kFile; base::StringPiece prefix; - if (metadata->hosted) { + if (stored_metadata.hosted) { prefix = "https://document_alternate_link/"; } else if (info.is_directory) { prefix = "https://folder_alternate_link/"; @@ -167,6 +171,7 @@ ? path.BaseName().value() : stored_metadata.original_name; metadata->alternate_url = GURL(base::StrCat({prefix, suffix})).spec(); + metadata->capabilities = mojom::Capabilities::New(); std::move(callback).Run(drive::FILE_ERROR_OK, std::move(metadata)); }
diff --git a/chromeos/components/drivefs/mojom/drivefs.mojom b/chromeos/components/drivefs/mojom/drivefs.mojom index 886d6af..ca400b8 100644 --- a/chromeos/components/drivefs/mojom/drivefs.mojom +++ b/chromeos/components/drivefs/mojom/drivefs.mojom
@@ -85,6 +85,18 @@ }; struct FileMetadata { + enum Type { + // A regular file. + kFile, + + // A hosted document (e.g. a gdoc). + kHosted, + + // A directory. + kDirectory, + }; + Type type; + int64 size; string content_mime_type; @@ -102,7 +114,6 @@ bool available_offline; bool dirty; - bool hosted; bool pinned; bool shared; bool starred; @@ -113,6 +124,8 @@ // The thumbnail as a PNG. It is only set if |want_thumbnail| is true in the // request and the file has a thumbnail available. array<uint8>? thumbnail; + + Capabilities capabilities; }; struct ImageMetadata { @@ -124,6 +137,15 @@ int32 rotation = 0; }; +// Drive capabilities: +struct Capabilities { + bool can_share = true; + bool can_copy = true; + bool can_delete = true; + bool can_rename = true; + bool can_add_children = true; +}; + struct ItemEvent { enum State { kQueued,
diff --git a/chromeos/login/auth/authpolicy_login_helper.cc b/chromeos/login/auth/authpolicy_login_helper.cc index 5e93bf0..c16240b 100644 --- a/chromeos/login/auth/authpolicy_login_helper.cc +++ b/chromeos/login/auth/authpolicy_login_helper.cc
@@ -13,6 +13,9 @@ #include "chromeos/dbus/auth_policy_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/upstart_client.h" +#include "crypto/encryptor.h" +#include "crypto/hmac.h" +#include "crypto/symmetric_key.h" namespace chromeos { @@ -65,6 +68,75 @@ return true; } +std::string DoDecrypt(const std::string& encrypted_data, + const std::string& password) { + constexpr char error_msg[] = "Failed to decrypt data"; + const size_t kSaltSize = 32; + const size_t kSignatureSize = 32; + if (encrypted_data.size() <= kSaltSize + kSignatureSize) { + LOG(ERROR) << error_msg; + return std::string(); + } + + const std::string salt = encrypted_data.substr(0, kSaltSize); + const std::string signature = + encrypted_data.substr(kSaltSize, kSignatureSize); + const std::string ciphertext = + encrypted_data.substr(kSaltSize + kSignatureSize); + + // Derive AES key, AES IV and HMAC key from password. + const size_t kAesKeySize = 32; + const size_t kAesIvSize = 16; + const size_t kHmacKeySize = 32; + const size_t kKeySize = kAesKeySize + kAesIvSize + kHmacKeySize; + std::unique_ptr<crypto::SymmetricKey> key = + crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::HMAC_SHA1, password, salt, 10000, kKeySize * 8); + if (!key) { + LOG(ERROR) << error_msg; + return std::string(); + } + DCHECK(kAesKeySize + kAesIvSize + kHmacKeySize == key->key().size()); + const char* key_data_chars = key->key().data(); + std::string aes_key(key_data_chars, kAesKeySize); + std::string aes_iv(key_data_chars + kAesKeySize, kAesIvSize); + std::string hmac_key(key_data_chars + kAesKeySize + kAesIvSize, kHmacKeySize); + + // Check signature. + crypto::HMAC hmac(crypto::HMAC::SHA256); + if (kSignatureSize != hmac.DigestLength()) { + LOG(ERROR) << error_msg; + return std::string(); + } + uint8_t recomputed_signature[kSignatureSize]; + if (!hmac.Init(hmac_key) || + !hmac.Sign(ciphertext, recomputed_signature, kSignatureSize)) { + LOG(ERROR) << error_msg; + return std::string(); + } + std::string recomputed_signature_str( + reinterpret_cast<char*>(recomputed_signature), kSignatureSize); + if (signature != recomputed_signature_str) { + LOG(ERROR) << error_msg; + return std::string(); + } + + // Decrypt. + std::unique_ptr<crypto::SymmetricKey> aes_key_obj( + crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, aes_key)); + crypto::Encryptor encryptor; + if (!encryptor.Init(aes_key_obj.get(), crypto::Encryptor::CBC, aes_iv)) { + LOG(ERROR) << error_msg; + return std::string(); + } + std::string decrypted_data; + if (!encryptor.Decrypt(ciphertext, &decrypted_data)) { + LOG(ERROR) << error_msg; + return std::string(); + } + return decrypted_data; +} + } // namespace AuthPolicyLoginHelper::AuthPolicyLoginHelper() : weak_factory_(this) {} @@ -88,6 +160,15 @@ } // static +void AuthPolicyLoginHelper::DecryptConfiguration(const std::string& blob, + const std::string& password, + OnDecryptedCallback callback) { + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + base::BindOnce(&DoDecrypt, blob, password), std::move(callback)); +} + +// static bool AuthPolicyLoginHelper::IsAdLocked() { std::string mode; return chromeos::tpm_util::InstallAttributesGet(kAttrMode, &mode) &&
diff --git a/chromeos/login/auth/authpolicy_login_helper.h b/chromeos/login/auth/authpolicy_login_helper.h index 0fb983af..27cfd81 100644 --- a/chromeos/login/auth/authpolicy_login_helper.h +++ b/chromeos/login/auth/authpolicy_login_helper.h
@@ -23,6 +23,8 @@ public: using AuthCallback = AuthPolicyClient::AuthCallback; using JoinCallback = AuthPolicyClient::JoinCallback; + using OnDecryptedCallback = + base::OnceCallback<void(std::string decrypted_data)>; AuthPolicyLoginHelper(); ~AuthPolicyLoginHelper(); @@ -37,6 +39,13 @@ // Restarts AuthPolicy service. static void Restart(); + // Decrypts |blob| with |password| on a separate thread. Calls |callback| on + // the orginal thread. If decryption failed |callback| called with an empty + // string. + static void DecryptConfiguration(const std::string& blob, + const std::string& password, + OnDecryptedCallback callback); + // Checks if device is locked for Active Directory management. static bool IsAdLocked();
diff --git a/chromeos/network/auto_connect_handler.cc b/chromeos/network/auto_connect_handler.cc index 41fa0f3a..5cb72b3 100644 --- a/chromeos/network/auto_connect_handler.cc +++ b/chromeos/network/auto_connect_handler.cc
@@ -283,14 +283,24 @@ } void AutoConnectHandler::DisconnectIfPolicyRequires() { - if (!LoginState::Get()->IsUserLoggedIn() || !user_policy_applied_) + // Only block networks in a user session. + if (!LoginState::Get()->IsUserLoggedIn()) + return; + + // Wait for both user and device policy to be applied before disconnecting. + // The device policy holds the policies, which might cause the network to get + // disconnected. The user policy might hold a valid network configuration, + // which prevents the network from being disconnected. + if (!user_policy_applied_ || !device_policy_applied_) return; const base::DictionaryValue* global_network_config = managed_configuration_handler_->GetGlobalConfigFromPolicy( std::string() /* no username hash, device policy */); if (!global_network_config) - return; // Device policy is not set, yet. + return; + + DisconnectAndRemoveBlacklistedNetworks(); const base::Value* connect_value = global_network_config->FindKeyOfType( ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, @@ -317,6 +327,45 @@ } } +void AutoConnectHandler::DisconnectAndRemoveBlacklistedNetworks() { + NET_LOG_DEBUG("DisconnectAndRemoveBlacklistedNetworks", ""); + + const base::DictionaryValue* global_network_config = + managed_configuration_handler_->GetGlobalConfigFromPolicy( + std::string() /* no username hash, device policy */); + + const base::Value* blacklist_value = global_network_config->FindKeyOfType( + ::onc::global_network_config::kBlacklistedHexSSIDs, + base::Value::Type::LIST); + if (!blacklist_value || blacklist_value->GetList().empty()) + return; // No blacklisted WiFi networks set. + + std::set<std::string> blacklist; + for (const base::Value& hex_ssid_value : blacklist_value->GetList()) + blacklist.insert(hex_ssid_value.GetString()); + + NetworkStateHandler::NetworkStateList networks; + network_state_handler_->GetNetworkListByType(NetworkTypePattern::WiFi(), + false, false, 0, &networks); + for (const NetworkState* network : networks) { + if (blacklist.find(network->GetHexSsid()) == blacklist.end()) + continue; + + const bool is_managed = + !network->profile_path().empty() && !network->guid().empty() && + managed_configuration_handler_->FindPolicyByGuidAndProfile( + network->guid(), network->profile_path(), nullptr /* onc_source */); + if (is_managed) + continue; + + if (network->IsConnectingOrConnected()) + DisconnectNetwork(network->path()); + + if (network->IsInProfile()) + RemoveNetworkConfigurationForNetwork(network->path()); + } +} + void AutoConnectHandler::DisconnectFromAllUnmanagedWiFiNetworks( bool remove_configuration, bool disable_auto_connect) { @@ -330,7 +379,6 @@ !network->profile_path().empty() && !network->guid().empty() && managed_configuration_handler_->FindPolicyByGuidAndProfile( network->guid(), network->profile_path(), nullptr /* onc_source */); - if (is_managed) continue; @@ -356,7 +404,7 @@ void AutoConnectHandler::RemoveNetworkConfigurationForNetwork( const std::string& service_path) { - NET_LOG_EVENT("Disconnect forced by policy", service_path); + NET_LOG_EVENT("Remove configuration forced by policy", service_path); managed_configuration_handler_->RemoveConfiguration( service_path, base::DoNothing(),
diff --git a/chromeos/network/auto_connect_handler.h b/chromeos/network/auto_connect_handler.h index 50dfd4b..3131a0c 100644 --- a/chromeos/network/auto_connect_handler.h +++ b/chromeos/network/auto_connect_handler.h
@@ -88,6 +88,12 @@ // manually connected unmanaged networks on every policy update. void DisconnectIfPolicyRequires(); + // Disconnects from all currently connected/connecting blacklisted WiFis. Also + // removes the corresponding network configuration for all blacklisted + // networks to prevent Shill from re-connecting to them (e.g. during + // ConnectToBestService). + void DisconnectAndRemoveBlacklistedNetworks(); + // Disconnects from all currently connected/connecting unmanaged WiFis. // When |remove_configuration|==true, we also remove the corresponding network // configuration for all unmanaged networks from Shill.
diff --git a/chromeos/network/auto_connect_handler_unittest.cc b/chromeos/network/auto_connect_handler_unittest.cc index 0c635e1..fe958a8 100644 --- a/chromeos/network/auto_connect_handler_unittest.cc +++ b/chromeos/network/auto_connect_handler_unittest.cc
@@ -17,11 +17,13 @@ #include "base/test/scoped_task_environment.h" #include "chromeos/cert_loader.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/shill_profile_client.h" #include "chromeos/network/client_cert_resolver.h" #include "chromeos/network/managed_network_configuration_handler_impl.h" #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_profile_handler.h" +#include "chromeos/network/network_state.h" #include "chromeos/network/network_state_test.h" #include "components/onc/onc_constants.h" #include "crypto/scoped_nss_types.h" @@ -282,10 +284,11 @@ const char* kConfigUnmanagedSharedConnected = "{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"online\", " - " \"Security\": \"wpa\" }"; + " \"Security\": \"wpa\", \"Profile\": \"/profile/default\" }"; const char* kConfigManagedSharedConnectable = "{ \"GUID\": \"wifi1\", \"Type\": \"wifi\", \"State\": \"idle\", " - " \"Connectable\": true, \"Security\": \"wpa\" }"; + " \"Connectable\": true, \"Security\": \"wpa\", \"Profile\": " + "\"/profile/default\" }"; const char* kPolicy = "[ { \"GUID\": \"wifi1\"," @@ -556,4 +559,46 @@ EXPECT_EQ(0, test_observer_->num_auto_connect_events()); } +TEST_F(AutoConnectHandlerTest, DisconnectFromBlacklistedNetwork) { + EXPECT_FALSE(ConfigureService(kConfigUnmanagedSharedConnected).empty()); + EXPECT_FALSE(ConfigureService(kConfigManagedSharedConnectable).empty()); + + LoginToRegularUser(); + StartCertLoader(); + EXPECT_EQ(shill::kStateOnline, GetServiceState("wifi0")); + EXPECT_EQ(shill::kStateIdle, GetServiceState("wifi1")); + EXPECT_TRUE(DBusThreadManager::Get() + ->GetShillProfileClient() + ->GetTestInterface() + ->HasService("wifi0")); + + // Apply a device policy, which blocks wifi0. No disconnects should occur + // since we wait for both device & user policy before possibly disconnecting. + base::Value::ListStorage blacklist; + blacklist.push_back(base::Value("7769666930")); // hex(wifi0) = 7769666930 + base::DictionaryValue global_config; + global_config.SetKey(::onc::global_network_config::kBlacklistedHexSSIDs, + base::Value(blacklist)); + SetupPolicy(std::string(), global_config, false /* load as device policy */); + EXPECT_EQ(shill::kStateOnline, GetServiceState("wifi0")); + EXPECT_EQ(shill::kStateIdle, GetServiceState("wifi1")); + EXPECT_TRUE(DBusThreadManager::Get() + ->GetShillProfileClient() + ->GetTestInterface() + ->HasService("wifi0")); + + // Apply an empty user policy (no whitelist for wifi0). Connection to wifi0 + // should be disconnected due to being blacklisted. + SetupPolicy(std::string(), base::DictionaryValue(), + true /* load as user policy */); + EXPECT_EQ(shill::kStateIdle, GetServiceState("wifi0")); + EXPECT_EQ(shill::kStateIdle, GetServiceState("wifi1")); + EXPECT_FALSE(DBusThreadManager::Get() + ->GetShillProfileClient() + ->GetTestInterface() + ->HasService("wifi0")); + + EXPECT_EQ(0, test_observer_->num_auto_connect_events()); +} + } // namespace chromeos
diff --git a/chromeos/network/managed_network_configuration_handler.h b/chromeos/network/managed_network_configuration_handler.h index 9844199..022cb2df 100644 --- a/chromeos/network/managed_network_configuration_handler.h +++ b/chromeos/network/managed_network_configuration_handler.h
@@ -158,6 +158,16 @@ const std::string& profile_path, ::onc::ONCSource* onc_source) const = 0; + // Returns true if the provided network is blocked by policy. This can occur, + // by either 'BlacklistedHexSSIDs' or 'AllowOnlyPolicyNetworksToConnect', + // which are both specified in ONC's global configuration. Both policies only + // apply to WiFi networks and can be bypassed by providing a network + // configuration with an ONC policy. + virtual bool IsNetworkBlockedByPolicy(const std::string& type, + const std::string& guid, + const std::string& profile_path, + const std::string& hex_ssid) const = 0; + private: DISALLOW_ASSIGN(ManagedNetworkConfigurationHandler); };
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc index 2ab7f8c..734ae00 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.cc +++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -798,6 +798,47 @@ return policy; } +bool ManagedNetworkConfigurationHandlerImpl::IsNetworkBlockedByPolicy( + const std::string& type, + const std::string& guid, + const std::string& profile_path, + const std::string& hex_ssid) const { + // Only apply blocking to WiFi networks. + if (!NetworkTypePattern::WiFi().MatchesType(type)) + return false; + + // Policies to block WiFis are located in the |global_network_config|. + const base::DictionaryValue* global_network_config = + GetGlobalConfigFromPolicy( + std::string() /* no username hash, device policy */); + if (!global_network_config) + return false; + + // Check if the network is managed. Managed networks are always allowed. + bool is_managed = + !profile_path.empty() && + FindPolicyByGuidAndProfile(guid, profile_path, nullptr /* onc_source */); + if (is_managed) + return false; + + // Check if the network is blacklisted. + const base::Value* blacklist_value = global_network_config->FindKeyOfType( + ::onc::global_network_config::kBlacklistedHexSSIDs, + base::Value::Type::LIST); + if (blacklist_value && !blacklist_value->GetList().empty() && + base::ContainsValue(blacklist_value->GetList(), base::Value(hex_ssid))) + return true; + + // Check if only managed networks are allowed. + const base::Value* managed_only_value = global_network_config->FindKeyOfType( + ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, + base::Value::Type::BOOLEAN); + if (managed_only_value && managed_only_value->GetBool()) + return true; + + return false; +} + const ManagedNetworkConfigurationHandlerImpl::Policies* ManagedNetworkConfigurationHandlerImpl::GetPoliciesForUser( const std::string& userhash) const {
diff --git a/chromeos/network/managed_network_configuration_handler_impl.h b/chromeos/network/managed_network_configuration_handler_impl.h index 737ac96..e9c985a 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.h +++ b/chromeos/network/managed_network_configuration_handler_impl.h
@@ -98,6 +98,11 @@ const std::string& profile_path, onc::ONCSource* onc_source) const override; + bool IsNetworkBlockedByPolicy(const std::string& type, + const std::string& guid, + const std::string& profile_path, + const std::string& hex_ssid) const override; + // NetworkProfileObserver overrides void OnProfileAdded(const NetworkProfile& profile) override; void OnProfileRemoved(const NetworkProfile& profile) override;
diff --git a/chromeos/network/mock_managed_network_configuration_handler.h b/chromeos/network/mock_managed_network_configuration_handler.h index 038509f6..eda3ba7 100644 --- a/chromeos/network/mock_managed_network_configuration_handler.h +++ b/chromeos/network/mock_managed_network_configuration_handler.h
@@ -75,6 +75,11 @@ const base::DictionaryValue*(const std::string& guid, const std::string& profile_path, ::onc::ONCSource* onc_source)); + MOCK_CONST_METHOD4(IsNetworkBlockedByPolicy, + bool(const std::string& type, + const std::string& guid, + const std::string& profile_path, + const std::string& hex_ssid)); private: DISALLOW_COPY_AND_ASSIGN(MockManagedNetworkConfigurationHandler);
diff --git a/chromeos/network/network_connection_handler.cc b/chromeos/network/network_connection_handler.cc index 59b0d47..af603f1 100644 --- a/chromeos/network/network_connection_handler.cc +++ b/chromeos/network/network_connection_handler.cc
@@ -53,8 +53,8 @@ "connect-canceled"; const char NetworkConnectionHandler::kErrorCertLoadTimeout[] = "cert-load-timeout"; -const char NetworkConnectionHandler::kErrorUnmanagedNetwork[] = - "unmanaged-network"; +const char NetworkConnectionHandler::kErrorBlockedByPolicy[] = + "blocked-by-policy"; const char NetworkConnectionHandler::kErrorActivateFailed[] = "activate-failed"; const char NetworkConnectionHandler::kErrorEnabledOrDisabledWhenNotAvailable[] = "not-available";
diff --git a/chromeos/network/network_connection_handler.h b/chromeos/network/network_connection_handler.h index f6fd03d..3519c44 100644 --- a/chromeos/network/network_connection_handler.h +++ b/chromeos/network/network_connection_handler.h
@@ -88,8 +88,8 @@ // Certificate load timed out. static const char kErrorCertLoadTimeout[]; - // Trying to configure an unmanaged network but policy prohibits that - static const char kErrorUnmanagedNetwork[]; + // Trying to configure a network that is blocked by policy. + static const char kErrorBlockedByPolicy[]; // Network activation failed. static const char kErrorActivateFailed[];
diff --git a/chromeos/network/network_connection_handler_impl.cc b/chromeos/network/network_connection_handler_impl.cc index 2c8ea86..3218b39 100644 --- a/chromeos/network/network_connection_handler_impl.cc +++ b/chromeos/network/network_connection_handler_impl.cc
@@ -24,6 +24,7 @@ #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_util.h" #include "chromeos/network/shill_property_util.h" #include "dbus/object_path.h" #include "net/cert/x509_certificate.h" @@ -299,12 +300,14 @@ // Connect immediately to 'connectable' networks. // TODO(stevenjb): Shill needs to properly set Connectable for VPN. if (network && network->connectable() && network->type() != shill::kTypeVPN) { - if (IsNetworkProhibitedByPolicy(network->type(), network->guid(), - network->profile_path())) { + if (logged_in_ && managed_configuration_handler_->IsNetworkBlockedByPolicy( + network->type(), network->guid(), + network->profile_path(), network->GetHexSsid())) { InvokeConnectErrorCallback(service_path, error_callback, - kErrorUnmanagedNetwork); + kErrorBlockedByPolicy); return; } + call_connect = true; } @@ -464,9 +467,15 @@ guid, profile, &onc_source); } - if (IsNetworkProhibitedByPolicy(type, guid, profile)) { - ErrorCallbackForPendingRequest(service_path, kErrorUnmanagedNetwork); - return; + if (type == shill::kTypeWifi) { + const base::Value* hex_ssid_value = service_properties.FindKeyOfType( + shill::kWifiHexSsid, base::Value::Type::STRING); + if (hex_ssid_value && logged_in_ && + managed_configuration_handler_->IsNetworkBlockedByPolicy( + type, guid, profile, hex_ssid_value->GetString())) { + ErrorCallbackForPendingRequest(service_path, kErrorBlockedByPolicy); + return; + } } client_cert::ClientCertConfig cert_config_from_policy; @@ -581,31 +590,6 @@ CallShillConnect(service_path); } -bool NetworkConnectionHandlerImpl::IsNetworkProhibitedByPolicy( - const std::string& type, - const std::string& guid, - const std::string& profile_path) { - if (!logged_in_ || type != shill::kTypeWifi) - return false; - const base::DictionaryValue* global_network_config = - managed_configuration_handler_->GetGlobalConfigFromPolicy( - std::string() /* no username hash, device policy */); - if (!global_network_config) - return false; - bool policy_prohibites = false; - if (!global_network_config->GetBooleanWithoutPathExpansion( - ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, - &policy_prohibites) || - !policy_prohibites) { - return false; - } - // If |profile_path| is empty, this is not a policy network. - if (profile_path.empty()) - return true; - return !managed_configuration_handler_->FindPolicyByGuidAndProfile( - guid, profile_path, nullptr /* onc_source */); -} - void NetworkConnectionHandlerImpl::QueueConnectRequest( const std::string& service_path) { ConnectRequest* request = GetPendingRequest(service_path);
diff --git a/chromeos/network/network_connection_handler_impl.h b/chromeos/network/network_connection_handler_impl.h index a348b82c..6c94bf0d 100644 --- a/chromeos/network/network_connection_handler_impl.h +++ b/chromeos/network/network_connection_handler_impl.h
@@ -90,10 +90,6 @@ const std::string& service_path, const base::DictionaryValue& properties); - bool IsNetworkProhibitedByPolicy(const std::string& type, - const std::string& guid, - const std::string& profile_path); - // Queues a connect request until certificates have loaded. void QueueConnectRequest(const std::string& service_path);
diff --git a/chromeos/network/network_connection_handler_impl_unittest.cc b/chromeos/network/network_connection_handler_impl_unittest.cc index be14b28e..b062283 100644 --- a/chromeos/network/network_connection_handler_impl_unittest.cc +++ b/chromeos/network/network_connection_handler_impl_unittest.cc
@@ -355,7 +355,7 @@ } TEST_F(NetworkConnectionHandlerImplTest, - NetworkConnectionHandlerConnectProhibited) { + NetworkConnectionHandlerConnectBlockedByManagedOnly) { EXPECT_FALSE(ConfigureService(kConfigConnectable).empty()); base::DictionaryValue global_config; global_config.SetKey( @@ -364,7 +364,7 @@ SetupPolicy("[]", global_config, false /* load as device policy */); LoginToRegularUser(); Connect(kWifi0); - EXPECT_EQ(NetworkConnectionHandler::kErrorUnmanagedNetwork, + EXPECT_EQ(NetworkConnectionHandler::kErrorBlockedByPolicy, GetResultAndReset()); SetupPolicy(kPolicyWifi0, global_config, false /* load as device policy */); @@ -372,6 +372,31 @@ EXPECT_EQ(kSuccessResult, GetResultAndReset()); } +TEST_F(NetworkConnectionHandlerImplTest, + NetworkConnectionHandlerConnectBlockedByBlacklist) { + EXPECT_FALSE(ConfigureService(kConfigConnectable).empty()); + + // Set a device policy which blocks wifi0. + base::Value::ListStorage blacklist; + blacklist.push_back(base::Value("7769666930")); // hex(wifi0) = 7769666930 + base::DictionaryValue global_config; + global_config.SetKey(::onc::global_network_config::kBlacklistedHexSSIDs, + base::Value(blacklist)); + SetupPolicy("[]", global_config, false /* load as device policy */); + + LoginToRegularUser(); + + Connect(kWifi0); + EXPECT_EQ(NetworkConnectionHandler::kErrorBlockedByPolicy, + GetResultAndReset()); + + // Set a user policy, which configures wifi0 (==whitelisted). + SetupPolicy(kPolicyWifi0, base::DictionaryValue(), + true /* load as user policy */); + Connect(kWifi0); + EXPECT_EQ(kSuccessResult, GetResultAndReset()); +} + // Handles basic failure cases. TEST_F(NetworkConnectionHandlerImplTest, NetworkConnectionHandlerConnectFailure) {
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc index 2e1238b4..0bef494d 100644 --- a/chromeos/network/onc/onc_signature.cc +++ b/chromeos/network/onc/onc_signature.cc
@@ -366,6 +366,7 @@ &kBoolSignature}, {::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, &kBoolSignature}, + {::onc::global_network_config::kBlacklistedHexSSIDs, &kStringListSignature}, {::onc::global_network_config::kDisableNetworkTypes, &kStringListSignature}, {NULL}};
diff --git a/chromeos/network/onc/onc_validator.cc b/chromeos/network/onc/onc_validator.cc index 02993a99..ebb7bf8 100644 --- a/chromeos/network/onc/onc_validator.cc +++ b/chromeos/network/onc/onc_validator.cc
@@ -336,6 +336,18 @@ } // namespace +bool Validator::IsInDevicePolicy(base::DictionaryValue* result, + const std::string& field_name) { + if (result->HasKey(field_name)) { + if (onc_source_ != ::onc::ONC_SOURCE_DEVICE_POLICY) { + error_or_warning_found_ = true; + LOG(ERROR) << field_name << " only allowed in device policy."; + return false; + } + } + return true; +} + bool Validator::IsValidValue(const std::string& field_value, const std::vector<const char*>& valid_values) { for (const char* it : valid_values) { @@ -910,28 +922,12 @@ using namespace ::onc::global_network_config; using namespace ::onc::network_config; - // Validate kDisableNetworkTypes field. - const base::ListValue* disabled_network_types = NULL; - if (result->GetListWithoutPathExpansion(kDisableNetworkTypes, - &disabled_network_types)) { - // The kDisableNetworkTypes field is only allowed in device policy. - if (!disabled_network_types->empty() && - onc_source_ != ::onc::ONC_SOURCE_DEVICE_POLICY) { - error_or_warning_found_ = true; - LOG(ERROR) << "Disabled network types only allowed in device policy."; - return false; - } - } - - if (result->HasKey(kAllowOnlyPolicyNetworksToConnect)) { - // The kAllowOnlyPolicyNetworksToConnect field is only allowed in device - // policy. - if (onc_source_ != ::onc::ONC_SOURCE_DEVICE_POLICY) { - error_or_warning_found_ = true; - LOG(ERROR) - << "AllowOnlyPolicyNetworksToConnect only allowed in device policy."; - return false; - } + // Validate that kDisableNetworkTypes, kAllowOnlyPolicyNetworksToConnect and + // kBlacklistedHexSSIDs are only allowed in device policy. + if (!IsInDevicePolicy(result, kDisableNetworkTypes) || + !IsInDevicePolicy(result, kAllowOnlyPolicyNetworksToConnect) || + !IsInDevicePolicy(result, kBlacklistedHexSSIDs)) { + return false; } // Ensure the list contains only legitimate network type identifiers.
diff --git a/chromeos/network/onc/onc_validator.h b/chromeos/network/onc/onc_validator.h index 3317006..cb457e1b 100644 --- a/chromeos/network/onc/onc_validator.h +++ b/chromeos/network/onc/onc_validator.h
@@ -176,6 +176,10 @@ bool IsValidValue(const std::string& field_value, const std::vector<const char*>& valid_values); + + bool IsInDevicePolicy(base::DictionaryValue* result, + const std::string& field_name); + bool FieldExistsAndHasNoValidValue( const base::DictionaryValue& object, const std::string& field_name,
diff --git a/chromeos/services/assistant/BUILD.gn b/chromeos/services/assistant/BUILD.gn index c77559e..91cb94d 100644 --- a/chromeos/services/assistant/BUILD.gn +++ b/chromeos/services/assistant/BUILD.gn
@@ -36,6 +36,7 @@ public_deps = [ "//ash/public/cpp:cpp", "//mojo/public/cpp/bindings:bindings", + "//services/audio/public/cpp:cpp", "//services/service_manager/public/cpp:cpp", ] @@ -65,10 +66,7 @@ "//chromeos/assistant/internal/action", "//libassistant/contrib/core", "//libassistant/contrib/platform/audio", - "//libassistant/contrib/platform/net", - "//libassistant/contrib/platform/resources", "//libassistant/shared/internal_api/c:api_wrappers_for_caller_no_chromium", - "//libassistant/shared/proto:assistant_proto", "//libassistant/shared/public", "//libassistant/shared/public:export", "//ui/base",
diff --git a/chromeos/services/assistant/DEPS b/chromeos/services/assistant/DEPS index 2a44cee..f724f4f 100644 --- a/chromeos/services/assistant/DEPS +++ b/chromeos/services/assistant/DEPS
@@ -3,9 +3,12 @@ "+chromeos/assistant", "+google_apis/gaia", "+libassistant", + "+media/base", + "+media/audio", "+mojo/public", "+services/device/public", "+services/identity/public", "+services/service_manager/public", "+ui/base", + "+services/audio/public", ]
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 8d287b5..210076f 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -32,10 +32,10 @@ const char kBluetoothDeviceSettingId[] = "BLUETOOTH"; AssistantManagerServiceImpl::AssistantManagerServiceImpl( - mojom::AudioInputPtr audio_input, + service_manager::Connector* connector, device::mojom::BatteryMonitorPtr battery_monitor) : platform_api_(CreateLibAssistantConfig(), - std::move(audio_input), + connector, std::move(battery_monitor)), action_module_(std::make_unique<action::CrosActionModule>(this)), display_connection_(std::make_unique<CrosDisplayConnection>(this)),
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index a3e5416..3ec12fa1 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -28,6 +28,10 @@ class AssistantManagerInternal; } // namespace assistant_client +namespace service_manager { +class Connector; +} // namespace service_manager + namespace chromeos { namespace assistant { @@ -43,9 +47,8 @@ public assistant_client::ConversationStateListener, public assistant_client::AssistantManagerDelegate { public: - explicit AssistantManagerServiceImpl( - mojom::AudioInputPtr audio_input, - device::mojom::BatteryMonitorPtr battery_monitor); + AssistantManagerServiceImpl(service_manager::Connector* connector, + device::mojom::BatteryMonitorPtr battery_monitor); ~AssistantManagerServiceImpl() override; // assistant::AssistantManagerService overrides
diff --git a/chromeos/services/assistant/manifest.json b/chromeos/services/assistant/manifest.json index 8a2db6b..702c7d9 100644 --- a/chromeos/services/assistant/manifest.json +++ b/chromeos/services/assistant/manifest.json
@@ -6,7 +6,8 @@ "requires": { "ash": [ "system_ui" ], "identity": [ "identity_manager" ], - "device": [ "device:battery_monitor" ] + "device": [ "device:battery_monitor" ], + "audio": [ "stream_factory" ] }, "provides": { "assistant": [
diff --git a/chromeos/services/assistant/platform/audio_input_provider_impl.cc b/chromeos/services/assistant/platform/audio_input_provider_impl.cc index 565dea1f..6c80769 100644 --- a/chromeos/services/assistant/platform/audio_input_provider_impl.cc +++ b/chromeos/services/assistant/platform/audio_input_provider_impl.cc
@@ -7,6 +7,12 @@ #include "base/logging.h" #include "base/stl_util.h" #include "libassistant/shared/public/platform_audio_buffer.h" +#include "media/audio/audio_device_description.h" +#include "media/base/audio_parameters.h" +#include "media/base/audio_sample_types.h" +#include "media/base/channel_layout.h" +#include "services/audio/public/cpp/device_factory.h" +#include "services/service_manager/public/cpp/connector.h" namespace chromeos { namespace assistant { @@ -15,78 +21,136 @@ // This format should match //c/b/c/assistant/platform_audio_input_host.cc. constexpr assistant_client::BufferFormat kFormat{ - 16000 /* sample_rate */, assistant_client::INTERLEAVED_S32, 2 /* channels */ + 16000 /* sample_rate */, assistant_client::INTERLEAVED_S32, 1 /* channels */ }; } // namespace -class AudioInputBufferImpl : public assistant_client::AudioBuffer { - public: - AudioInputBufferImpl(const void* data, uint32_t frame_count) - : data_(data), frame_count_(frame_count) {} - ~AudioInputBufferImpl() override = default; +AudioInputBufferImpl::AudioInputBufferImpl(const void* data, + uint32_t frame_count) + : data_(data), frame_count_(frame_count) {} - // assistant_client::AudioBuffer overrides: - assistant_client::BufferFormat GetFormat() const override { return kFormat; } - const void* GetData() const override { return data_; } - void* GetWritableData() override { - NOTREACHED(); - return nullptr; - } - int GetFrameCount() const override { return frame_count_; } +AudioInputBufferImpl::~AudioInputBufferImpl() = default; - private: - const void* data_; - int frame_count_; - DISALLOW_COPY_AND_ASSIGN(AudioInputBufferImpl); -}; - -AudioInputImpl::AudioInputImpl(mojom::AudioInputPtr audio_input) - : binding_(this) { - mojom::AudioInputObserverPtr observer; - binding_.Bind(mojo::MakeRequest(&observer)); - audio_input->AddObserver(std::move(observer)); +assistant_client::BufferFormat AudioInputBufferImpl::GetFormat() const { + return kFormat; } -AudioInputImpl::~AudioInputImpl() = default; +const void* AudioInputBufferImpl::GetData() const { + return data_; +} -void AudioInputImpl::OnAudioInputFramesAvailable( - const std::vector<int32_t>& buffer, - uint32_t frame_count, - base::TimeTicks timestamp) { - AudioInputBufferImpl input_buffer(buffer.data(), frame_count); - int64_t time = timestamp.since_origin().InMilliseconds(); +void* AudioInputBufferImpl::GetWritableData() { + NOTREACHED(); + return nullptr; +} + +int AudioInputBufferImpl::GetFrameCount() const { + return frame_count_; +} + +AudioInputImpl::AudioInputImpl( + std::unique_ptr<service_manager::Connector> connector) + : source_(audio::CreateInputDevice( + std::move(connector), + media::AudioDeviceDescription::kDefaultDeviceId)), + task_runner_(base::ThreadTaskRunnerHandle::Get()), + weak_factory_(this) { + DETACH_FROM_SEQUENCE(observer_sequence_checker_); + // AUDIO_PCM_LINEAR and AUDIO_PCM_LOW_LATENCY are the same on CRAS. + source_->Initialize( + media::AudioParameters( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::CHANNEL_LAYOUT_MONO, kFormat.sample_rate, + kFormat.sample_rate / 10 /* buffer size for 100 ms */), + this); +} + +AudioInputImpl::~AudioInputImpl() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + source_->Stop(); +} + +void AudioInputImpl::Capture(const media::AudioBus* audio_source, + int audio_delay_milliseconds, + double volume, + bool key_pressed) { + DCHECK_EQ(kFormat.num_channels, audio_source->channels()); + std::vector<int32_t> buffer(kFormat.num_channels * audio_source->frames()); + audio_source->ToInterleaved<media::SignedInt32SampleTypeTraits>( + audio_source->frames(), buffer.data()); + int64_t time = base::TimeTicks::Now().since_origin().InMilliseconds() - + audio_delay_milliseconds; + AudioInputBufferImpl input_buffer(buffer.data(), audio_source->frames()); { - base::AutoLock auto_lock(lock_); + base::AutoLock lock(lock_); for (auto* observer : observers_) observer->OnBufferAvailable(input_buffer, time); } } -void AudioInputImpl::OnAudioInputClosed() { - base::AutoLock auto_lock(lock_); +void AudioInputImpl::OnCaptureError(const std::string& message) { + DLOG(ERROR) << "Capture error " << message; + base::AutoLock lock(lock_); for (auto* observer : observers_) - observer->OnStopped(); + observer->OnError(AudioInput::Error::FATAL_ERROR); } +void AudioInputImpl::OnCaptureMuted(bool is_muted) {} + assistant_client::BufferFormat AudioInputImpl::GetFormat() const { return kFormat; } void AudioInputImpl::AddObserver( assistant_client::AudioInput::Observer* observer) { - base::AutoLock auto_lock(lock_); - observers_.push_back(observer); + DCHECK_CALLED_ON_VALID_SEQUENCE(observer_sequence_checker_); + bool should_start = false; + { + base::AutoLock lock(lock_); + observers_.push_back(observer); + should_start = observers_.size() == 1; + } + + if (should_start) { + // Post to main thread runner to start audio recording. Assistant thread + // does not have thread context defined in //base and will fail sequence + // check in AudioCapturerSource::Start(). + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&AudioInputImpl::StartRecording, + weak_factory_.GetWeakPtr())); + } } void AudioInputImpl::RemoveObserver( assistant_client::AudioInput::Observer* observer) { - base::AutoLock auto_lock(lock_); - base::Erase(observers_, observer); + DCHECK_CALLED_ON_VALID_SEQUENCE(observer_sequence_checker_); + bool should_stop = false; + { + base::AutoLock lock(lock_); + base::Erase(observers_, observer); + should_stop = observers_.empty(); + } + if (should_stop) { + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&AudioInputImpl::StopRecording, + weak_factory_.GetWeakPtr())); + } } -AudioInputProviderImpl::AudioInputProviderImpl(mojom::AudioInputPtr audio_input) - : audio_input_(std::move(audio_input)) {} +void AudioInputImpl::StartRecording() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + source_->Start(); +} + +void AudioInputImpl::StopRecording() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + source_->Stop(); +} + +AudioInputProviderImpl::AudioInputProviderImpl( + service_manager::Connector* connector) + : audio_input_(connector->Clone()) {} AudioInputProviderImpl::~AudioInputProviderImpl() = default;
diff --git a/chromeos/services/assistant/platform/audio_input_provider_impl.h b/chromeos/services/assistant/platform/audio_input_provider_impl.h index 55c65ac..fdbf6d1d 100644 --- a/chromeos/services/assistant/platform/audio_input_provider_impl.h +++ b/chromeos/services/assistant/platform/audio_input_provider_impl.h
@@ -9,45 +9,90 @@ #include <vector> #include "base/macros.h" +#include "base/observer_list.h" +#include "base/sequence_checker.h" #include "base/synchronization/lock.h" #include "base/time/time.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "libassistant/shared/public/platform_audio_input.h" +#include "media/base/audio_capturer_source.h" #include "mojo/public/cpp/bindings/binding.h" +namespace service_manager { +class Connector; +} // namespace service_manager + +namespace media { +class AudioBus; +} // namespace media + namespace chromeos { namespace assistant { -class AudioInputImpl : public assistant_client::AudioInput, - public mojom::AudioInputObserver { +class AudioInputBufferImpl : public assistant_client::AudioBuffer { public: - explicit AudioInputImpl(mojom::AudioInputPtr audio_input); + AudioInputBufferImpl(const void* data, uint32_t frame_count); + ~AudioInputBufferImpl() override; + + // assistant_client::AudioBuffer overrides: + assistant_client::BufferFormat GetFormat() const override; + const void* GetData() const override; + void* GetWritableData() override; + int GetFrameCount() const override; + + private: + const void* data_; + int frame_count_; + DISALLOW_COPY_AND_ASSIGN(AudioInputBufferImpl); +}; + +class AudioInputImpl : public assistant_client::AudioInput, + public media::AudioCapturerSource::CaptureCallback { + public: + explicit AudioInputImpl( + std::unique_ptr<service_manager::Connector> connector); ~AudioInputImpl() override; - // mojom::AudioInputObserver overrides: - void OnAudioInputFramesAvailable(const std::vector<int32_t>& buffer, - uint32_t frame_count, - base::TimeTicks timestamp) override; - void OnAudioInputClosed() override; + // media::AudioCapturerSource::CaptureCallback overrides: + void Capture(const media::AudioBus* audio_source, + int audio_delay_milliseconds, + double volume, + bool key_pressed) override; + void OnCaptureError(const std::string& message) override; + void OnCaptureMuted(bool is_muted) override; - // assistant_client::AudioInput overrides: + // assistant_client::AudioInput overrides. These function are called by + // assistant from assistant thread, for which we should not assume any + // //base related thread context to be in place. assistant_client::BufferFormat GetFormat() const override; void AddObserver(assistant_client::AudioInput::Observer* observer) override; void RemoveObserver( assistant_client::AudioInput::Observer* observer) override; private: - // Protects |observers_| access becase AssistantManager calls - // Add/RemoveObserver on its own thread. + void StartRecording(); + void StopRecording(); + + scoped_refptr<media::AudioCapturerSource> source_; + + // Guards observers_; base::Lock lock_; std::vector<assistant_client::AudioInput::Observer*> observers_; - mojo::Binding<mojom::AudioInputObserver> binding_; + + // To be initialized on assistant thread the first call to AddObserver. + // It ensures that AddObserver / RemoveObserver are called on the same + // sequence. + SEQUENCE_CHECKER(observer_sequence_checker_); + + scoped_refptr<base::SequencedTaskRunner> task_runner_; + + base::WeakPtrFactory<AudioInputImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(AudioInputImpl); }; class AudioInputProviderImpl : public assistant_client::AudioInputProvider { public: - explicit AudioInputProviderImpl(mojom::AudioInputPtr audio_input); + explicit AudioInputProviderImpl(service_manager::Connector* connector); ~AudioInputProviderImpl() override; // assistant_client::AudioInputProvider overrides:
diff --git a/chromeos/services/assistant/platform_api_impl.cc b/chromeos/services/assistant/platform_api_impl.cc index 373e3d3..b68d43e 100644 --- a/chromeos/services/assistant/platform_api_impl.cc +++ b/chromeos/services/assistant/platform_api_impl.cc
@@ -74,9 +74,9 @@ PlatformApiImpl::PlatformApiImpl( const std::string& config, - mojom::AudioInputPtr audio_input, + service_manager::Connector* connector, device::mojom::BatteryMonitorPtr battery_monitor) - : audio_input_provider_(std::move(audio_input)), + : audio_input_provider_(connector), audio_output_provider_(config, this), system_provider_(std::move(battery_monitor)) {}
diff --git a/chromeos/services/assistant/platform_api_impl.h b/chromeos/services/assistant/platform_api_impl.h index db0cd41..b0a110b8 100644 --- a/chromeos/services/assistant/platform_api_impl.h +++ b/chromeos/services/assistant/platform_api_impl.h
@@ -24,6 +24,10 @@ #include "libassistant/shared/public/platform_auth.h" #include "services/device/public/mojom/battery_monitor.mojom.h" +namespace service_manager { +class Connector; +} // namespace service_manager + namespace chromeos { namespace assistant { @@ -31,7 +35,7 @@ class PlatformApiImpl : public assistant_client::PlatformApi { public: PlatformApiImpl(const std::string& config, - mojom::AudioInputPtr audio_input, + service_manager::Connector* connector, device::mojom::BatteryMonitorPtr battery_monitor); ~PlatformApiImpl() override;
diff --git a/chromeos/services/assistant/public/mojom/assistant.mojom b/chromeos/services/assistant/public/mojom/assistant.mojom index 9e53cc86..928499a 100644 --- a/chromeos/services/assistant/public/mojom/assistant.mojom +++ b/chromeos/services/assistant/public/mojom/assistant.mojom
@@ -67,22 +67,18 @@ OnSpeechLevelUpdated(float speech_level); }; -// Platform connection to assistant. +// Interface for browser to bind and start assistant. interface AssistantPlatform { // Initiates assistant and provides interfaces for assistant to call into the // browser. - Init(Client assistant_client_interface, Context context_interface, - AudioInput audio_input_interface); + Init(Client assistant_client_interface); }; // Interface for assistant to call into client. interface Client { // Notifies assistant client that assistant running status has changed. OnAssistantStatusChanged(bool running); -}; -// Interface for assistant to request view hierarchy for current focused window. -interface Context { // Request context of current window from browser. RequestAssistantStructure() => ( ax.mojom.AssistantExtra? extra,
diff --git a/chromeos/services/assistant/service.cc b/chromeos/services/assistant/service.cc index cc01c1b..a3d0e42 100644 --- a/chromeos/services/assistant/service.cc +++ b/chromeos/services/assistant/service.cc
@@ -117,31 +117,6 @@ } } -void Service::Init(mojom::ClientPtr client, - mojom::ContextPtr assistant_context, - mojom::AudioInputPtr audio_input) { - client_ = std::move(client); - - // unit tests may set it early, so we don't need to create one. - if (!assistant_manager_service_) { -#if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) - device::mojom::BatteryMonitorPtr battery_monitor; - context()->connector()->BindInterface(device::mojom::kServiceName, - mojo::MakeRequest(&battery_monitor)); - - assistant_manager_service_ = std::make_unique<AssistantManagerServiceImpl>( - std::move(audio_input), std::move(battery_monitor)); -#else - assistant_manager_service_ = - std::make_unique<FakeAssistantManagerServiceImpl>(); -#endif - } - - // This will eventually trigger the actual start of assistant services because - // they all depend on it. - RequestAccessToken(); -} - void Service::OnSessionActivated(bool activated) { DCHECK(client_); session_active_ = activated; @@ -185,6 +160,24 @@ &Service::RequestAccessToken); } +void Service::Init(mojom::ClientPtr client) { + client_ = std::move(client); +#if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) + device::mojom::BatteryMonitorPtr battery_monitor; + context()->connector()->BindInterface(device::mojom::kServiceName, + mojo::MakeRequest(&battery_monitor)); + assistant_manager_service_ = std::make_unique<AssistantManagerServiceImpl>( + context()->connector(), std::move(battery_monitor)); +#else + assistant_manager_service_ = + std::make_unique<FakeAssistantManagerServiceImpl>(); +#endif + + // This will eventually trigger the actual start of assistant services because + // they all depend on it. + RequestAccessToken(); +} + void Service::GetPrimaryAccountInfoCallback( const base::Optional<AccountInfo>& account_info, const identity::AccountState& account_state) {
diff --git a/chromeos/services/assistant/service.h b/chromeos/services/assistant/service.h index c1a307a3..9d9ad63 100644 --- a/chromeos/services/assistant/service.h +++ b/chromeos/services/assistant/service.h
@@ -67,9 +67,7 @@ void SuspendDone(const base::TimeDelta& sleep_duration) override; // mojom::AssistantPlatform overrides: - void Init(mojom::ClientPtr client, - mojom::ContextPtr assistant_context, - mojom::AudioInputPtr audio_input) override; + void Init(mojom::ClientPtr client) override; // ash::mojom::SessionActivationObserver overrides: void OnSessionActivated(bool activated) override;
diff --git a/chromeos/services/assistant/service_unittest.cc b/chromeos/services/assistant/service_unittest.cc index 58916fb..d27c886 100644 --- a/chromeos/services/assistant/service_unittest.cc +++ b/chromeos/services/assistant/service_unittest.cc
@@ -115,35 +115,14 @@ private: // mojom::Client: void OnAssistantStatusChanged(bool running) override {} + void RequestAssistantStructure( + RequestAssistantStructureCallback callback) override {} mojo::Binding<mojom::Client> binding_; DISALLOW_COPY_AND_ASSIGN(FakeAssistantClient); }; -class FakeAssistantContext : mojom::Context { - public: - FakeAssistantContext() : binding_(this) {} - - mojom::ContextPtr CreateInterfacePtrAndBind() { - mojom::ContextPtr ptr; - binding_.Bind(mojo::MakeRequest(&ptr)); - return ptr; - } - - private: - // mojom::Context: - using RequestAssistantStructureCallback = - base::OnceCallback<void(::ax::mojom::AssistantExtraPtr, - std::unique_ptr<ui::AssistantTree>)>; - void RequestAssistantStructure( - RequestAssistantStructureCallback callback) override {} - - mojo::Binding<mojom::Context> binding_; - - DISALLOW_COPY_AND_ASSIGN(FakeAssistantContext); -}; - class FakeAudioInput : mojom::AudioInput { public: FakeAudioInput() : binding_(this) {} @@ -232,9 +211,7 @@ void SetUp() override { service_manager::test::ServiceTest::SetUp(); - GetService()->Init(fake_assistant_client_->CreateInterfacePtrAndBind(), - fake_assistant_context_->CreateInterfacePtrAndBind(), - fake_audio_input_->CreateInterfacePtrAndBind()); + GetService()->Init(fake_assistant_client_->CreateInterfacePtrAndBind()); platform_service_.FlushForTesting(); base::RunLoop().RunUntilIdle(); } @@ -245,7 +222,6 @@ std::unique_ptr<service_manager::Service> CreateService() override { fake_identity_manager_ = std::make_unique<FakeIdentityManager>(); fake_assistant_client_ = std::make_unique<FakeAssistantClient>(); - fake_assistant_context_ = std::make_unique<FakeAssistantContext>(); fake_audio_input_ = std::make_unique<FakeAudioInput>(); fake_assistant_manager_ptr_ = new FakeAssistantManagerServiceImpl(); @@ -294,7 +270,6 @@ std::unique_ptr<FakeIdentityManager> fake_identity_manager_; std::unique_ptr<FakeAssistantClient> fake_assistant_client_; - std::unique_ptr<FakeAssistantContext> fake_assistant_context_; std::unique_ptr<FakeAudioInput> fake_audio_input_; FakeAssistantManagerServiceImpl* fake_assistant_manager_ptr_;
diff --git a/chromeos/services/multidevice_setup/BUILD.gn b/chromeos/services/multidevice_setup/BUILD.gn index d7a3dad..6c9a6a49 100644 --- a/chromeos/services/multidevice_setup/BUILD.gn +++ b/chromeos/services/multidevice_setup/BUILD.gn
@@ -10,12 +10,14 @@ static_library("multidevice_setup") { sources = [ + "account_status_change_delegate_notifier.cc", + "account_status_change_delegate_notifier.h", + "account_status_change_delegate_notifier_impl.cc", + "account_status_change_delegate_notifier_impl.h", "multidevice_setup_impl.cc", "multidevice_setup_impl.h", "multidevice_setup_service.cc", "multidevice_setup_service.h", - "observer_notifier.cc", - "observer_notifier.h", "setup_flow_completion_recorder.h", "setup_flow_completion_recorder_impl.cc", "setup_flow_completion_recorder_impl.h", @@ -43,16 +45,13 @@ testonly = true sources = [ - "fake_multidevice_setup_observer.cc", - "fake_multidevice_setup_observer.h", + "fake_account_status_change_delegate.cc", + "fake_account_status_change_delegate.h", + "fake_account_status_change_delegate_notifier.h", "fake_setup_flow_completion_recorder.cc", "fake_setup_flow_completion_recorder.h", ] - public_deps = [ - ":multidevice_setup", - ] - deps = [ ":multidevice_setup", "//base", @@ -66,8 +65,8 @@ testonly = true sources = [ + "account_status_change_delegate_notifier_impl_unittest.cc", "multidevice_setup_service_unittest.cc", - "observer_notifier_unittest.cc", "setup_flow_completion_recorder_impl_unittest.cc", ]
diff --git a/chromeos/services/multidevice_setup/account_status_change_delegate_notifier.cc b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier.cc new file mode 100644 index 0000000..1b9f520 --- /dev/null +++ b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier.cc
@@ -0,0 +1,43 @@ +// 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 "chromeos/services/multidevice_setup/account_status_change_delegate_notifier.h" + +#include "base/logging.h" +#include "chromeos/components/proximity_auth/logging/logging.h" + +namespace chromeos { + +namespace multidevice_setup { + +AccountStatusChangeDelegateNotifier::AccountStatusChangeDelegateNotifier() = + default; + +AccountStatusChangeDelegateNotifier::~AccountStatusChangeDelegateNotifier() = + default; + +void AccountStatusChangeDelegateNotifier::SetAccountStatusChangeDelegatePtr( + mojom::AccountStatusChangeDelegatePtr delegate_ptr) { + if (delegate_ptr_.is_bound()) { + PA_LOG(ERROR) << "AccountStatusChangeDelegateNotifier::" + << "SetAccountStatusChangeDelegatePtr(): Tried to set " + << "delegate, but one already existed."; + NOTREACHED(); + } + + delegate_ptr_ = std::move(delegate_ptr); + OnDelegateSet(); +} + +// No default implementation. +void AccountStatusChangeDelegateNotifier::OnDelegateSet() {} + +void AccountStatusChangeDelegateNotifier::FlushForTesting() { + if (delegate_ptr_) + delegate_ptr_.FlushForTesting(); +} + +} // namespace multidevice_setup + +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/account_status_change_delegate_notifier.h b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier.h new file mode 100644 index 0000000..f72d714 --- /dev/null +++ b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier.h
@@ -0,0 +1,50 @@ +// 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 CHROMEOS_SERVICES_MULTIDEVICE_SETUP_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_H_ + +#include "base/macros.h" +#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" + +namespace chromeos { + +namespace multidevice_setup { + +// Notifies the delegate of MultiDeviceSetup for each of the following changes: +// (1) a potential host is found for someone who has not gone through the setup +// flow before, +// (2) the host has switched for someone who has, or +// (3) a new Chromebook has been added to an account for someone who has. +class AccountStatusChangeDelegateNotifier { + public: + virtual ~AccountStatusChangeDelegateNotifier(); + + void SetAccountStatusChangeDelegatePtr( + mojom::AccountStatusChangeDelegatePtr delegate_ptr); + + protected: + AccountStatusChangeDelegateNotifier(); + + // Derived classes should override this function to be alerted when + // SetAccountStatusChangeDelegatePtr() is called. + virtual void OnDelegateSet(); + + mojom::AccountStatusChangeDelegate* delegate() { return delegate_ptr_.get(); } + + private: + friend class MultiDeviceSetupAccountStatusChangeDelegateNotifierTest; + + void FlushForTesting(); + + mojom::AccountStatusChangeDelegatePtr delegate_ptr_; + + DISALLOW_COPY_AND_ASSIGN(AccountStatusChangeDelegateNotifier); +}; + +} // namespace multidevice_setup + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_H_
diff --git a/chromeos/services/multidevice_setup/observer_notifier.cc b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.cc similarity index 65% rename from chromeos/services/multidevice_setup/observer_notifier.cc rename to chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.cc index b7f7ccf4..43be1ddc 100644 --- a/chromeos/services/multidevice_setup/observer_notifier.cc +++ b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.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 "chromeos/services/multidevice_setup/observer_notifier.h" +#include "chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.h" #include <set> #include <utility> @@ -43,37 +43,42 @@ } // namespace // static -ObserverNotifier::Factory* ObserverNotifier::Factory::test_factory_ = nullptr; +AccountStatusChangeDelegateNotifierImpl::Factory* + AccountStatusChangeDelegateNotifierImpl::Factory::test_factory_ = nullptr; // static -ObserverNotifier::Factory* ObserverNotifier::Factory::Get() { +AccountStatusChangeDelegateNotifierImpl::Factory* +AccountStatusChangeDelegateNotifierImpl::Factory::Get() { if (test_factory_) return test_factory_; - static base::NoDestructor<ObserverNotifier::Factory> factory; + static base::NoDestructor<Factory> factory; return factory.get(); } // static -void ObserverNotifier::Factory::SetFactoryForTesting(Factory* test_factory) { +void AccountStatusChangeDelegateNotifierImpl::Factory::SetFactoryForTesting( + Factory* test_factory) { test_factory_ = test_factory; } -ObserverNotifier::Factory::~Factory() = default; +AccountStatusChangeDelegateNotifierImpl::Factory::~Factory() = default; -std::unique_ptr<ObserverNotifier> ObserverNotifier::Factory::BuildInstance( +std::unique_ptr<AccountStatusChangeDelegateNotifier> +AccountStatusChangeDelegateNotifierImpl::Factory::BuildInstance( device_sync::DeviceSyncClient* device_sync_client, PrefService* pref_service, SetupFlowCompletionRecorder* setup_flow_completion_recorder, base::Clock* clock) { - return base::WrapUnique(new ObserverNotifier( + return base::WrapUnique(new AccountStatusChangeDelegateNotifierImpl( device_sync_client, pref_service, setup_flow_completion_recorder, clock)); } // static -void ObserverNotifier::RegisterPrefs(PrefRegistrySimple* registry) { +void AccountStatusChangeDelegateNotifierImpl::RegisterPrefs( + PrefRegistrySimple* registry) { // Records the timestamps (in milliseconds since UNIX Epoch, aka JavaTime) of - // the last instance the observer was notified for each of the changes listed + // the last instance the delegate was notified for each of the changes listed // in the class description. registry->RegisterInt64Pref(kNewUserPotentialHostExistsPrefName, kTimestampNotSet); @@ -85,42 +90,41 @@ kNoHost); } -ObserverNotifier::~ObserverNotifier() { +AccountStatusChangeDelegateNotifierImpl:: + ~AccountStatusChangeDelegateNotifierImpl() { device_sync_client_->RemoveObserver(this); } -void ObserverNotifier::SetMultiDeviceSetupObserverPtr( - mojom::MultiDeviceSetupObserverPtr observer_ptr) { - if (observer_ptr_.is_bound()) { - PA_LOG(ERROR) << "There is already a mojom::MultiDeviceSetupObserverPtr " - << "set. There should only be one."; - NOTREACHED(); - } - observer_ptr_ = std::move(observer_ptr); +void AccountStatusChangeDelegateNotifierImpl::OnDelegateSet() { CheckForMultiDeviceEvents(); } // static -const char ObserverNotifier::kNewUserPotentialHostExistsPrefName[] = - "multidevice_setup.new_user_potential_host_exists"; +const char AccountStatusChangeDelegateNotifierImpl:: + kNewUserPotentialHostExistsPrefName[] = + "multidevice_setup.new_user_potential_host_exists"; // static -const char ObserverNotifier::kExistingUserHostSwitchedPrefName[] = - "multidevice_setup.existing_user_host_switched"; +const char AccountStatusChangeDelegateNotifierImpl:: + kExistingUserHostSwitchedPrefName[] = + "multidevice_setup.existing_user_host_switched"; // static -const char ObserverNotifier::kExistingUserChromebookAddedPrefName[] = - "multidevice_setup.existing_user_chromebook_added"; +const char AccountStatusChangeDelegateNotifierImpl:: + kExistingUserChromebookAddedPrefName[] = + "multidevice_setup.existing_user_chromebook_added"; // static -const char ObserverNotifier::kHostPublicKeyFromMostRecentSyncPrefName[] = - "multidevice_setup.host_public_key_from_most_recent_sync"; +const char AccountStatusChangeDelegateNotifierImpl:: + kHostPublicKeyFromMostRecentSyncPrefName[] = + "multidevice_setup.host_public_key_from_most_recent_sync"; -ObserverNotifier::ObserverNotifier( - device_sync::DeviceSyncClient* device_sync_client, - PrefService* pref_service, - SetupFlowCompletionRecorder* setup_flow_completion_recorder, - base::Clock* clock) +AccountStatusChangeDelegateNotifierImpl:: + AccountStatusChangeDelegateNotifierImpl( + device_sync::DeviceSyncClient* device_sync_client, + PrefService* pref_service, + SetupFlowCompletionRecorder* setup_flow_completion_recorder, + base::Clock* clock) : device_sync_client_(device_sync_client), pref_service_(pref_service), setup_flow_completion_recorder_(setup_flow_completion_recorder), @@ -131,8 +135,9 @@ device_sync_client_->GetSyncedDevices(); base::Optional<cryptauth::RemoteDeviceRef> local_device = device_sync_client_->GetLocalDeviceMetadata(); - // ObserverNotifier should not be constructed if DeviceSyncClient is not - // initialized. + + // AccountStatusChangeDelegateNotifierImpl should not be constructed if + // DeviceSyncClient is not initialized. DCHECK(local_device); local_device_is_enabled_client_ = local_device->GetSoftwareFeatureState( @@ -141,15 +146,15 @@ device_sync_client_->AddObserver(this); } -void ObserverNotifier::OnNewDevicesSynced() { +void AccountStatusChangeDelegateNotifierImpl::OnNewDevicesSynced() { CheckForMultiDeviceEvents(); } -void ObserverNotifier::CheckForMultiDeviceEvents() { - // Without an observer, there is nothing to do. - if (!observer_ptr_) { - PA_LOG(INFO) << "You must set a mojom::MultiDeviceSetupObserverPtr using " - << "ObserverNotifier::SetMultiDeviceSetupObserverPtr()"; +void AccountStatusChangeDelegateNotifierImpl::CheckForMultiDeviceEvents() { + if (!delegate()) { + PA_LOG(INFO) << "AccountStatusChangeDelegateNotifierImpl::" + << "CheckForMultiDeviceEvents(): Tried to check for potential " + << "events, but no delegatd was set."; return; } @@ -178,8 +183,9 @@ local_device_was_enabled_client_before_sync); } -void ObserverNotifier::CheckForNewUserPotentialHostExistsEvent( - const cryptauth::RemoteDeviceRefList& device_ref_list) { +void AccountStatusChangeDelegateNotifierImpl:: + CheckForNewUserPotentialHostExistsEvent( + const cryptauth::RemoteDeviceRefList& device_ref_list) { // We only check for new user events if there is no enabled host. if (host_public_key_from_most_recent_sync_) return; @@ -187,24 +193,27 @@ // If the observer has been notified of this event before, the user is not // new. if (pref_service_->GetInt64(kNewUserPotentialHostExistsPrefName) != - kTimestampNotSet) + kTimestampNotSet) { return; + } for (const auto& device_ref : device_ref_list) { if (device_ref.GetSoftwareFeatureState( cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST) != - cryptauth::SoftwareFeatureState::kSupported) + cryptauth::SoftwareFeatureState::kSupported) { continue; + } - observer_ptr_->OnPotentialHostExistsForNewUser(); + delegate()->OnPotentialHostExistsForNewUser(); pref_service_->SetInt64(kNewUserPotentialHostExistsPrefName, clock_->Now().ToJavaTime()); return; } } -void ObserverNotifier::CheckForExistingUserHostSwitchedEvent( - base::Optional<std::string> host_public_key_before_sync) { +void AccountStatusChangeDelegateNotifierImpl:: + CheckForExistingUserHostSwitchedEvent( + base::Optional<std::string> host_public_key_before_sync) { // If the local device is not an enabled client, the account's new host is not // yet the local device's new host. if (!local_device_is_enabled_client_) @@ -218,18 +227,20 @@ if (host_public_key_before_sync == host_public_key_from_most_recent_sync_) return; - observer_ptr_->OnConnectedHostSwitchedForExistingUser(); + delegate()->OnConnectedHostSwitchedForExistingUser(); pref_service_->SetInt64(kExistingUserHostSwitchedPrefName, clock_->Now().ToJavaTime()); } -void ObserverNotifier::CheckForExistingUserChromebookAddedEvent( - bool local_device_was_enabled_client_before_sync) { +void AccountStatusChangeDelegateNotifierImpl:: + CheckForExistingUserChromebookAddedEvent( + bool local_device_was_enabled_client_before_sync) { // The chromebook added event requires that the local device changed its // client status in the sync from not being enabled to being enabled. if (!local_device_is_enabled_client_ || - local_device_was_enabled_client_before_sync) + local_device_was_enabled_client_before_sync) { return; + } // This event only applies if the user completed the setup flow on a different // device. @@ -239,18 +250,13 @@ // Without an enabled host, the local device cannot be an enabled client. DCHECK(host_public_key_from_most_recent_sync_); - observer_ptr_->OnNewChromebookAddedForExistingUser(); + delegate()->OnNewChromebookAddedForExistingUser(); pref_service_->SetInt64(kExistingUserChromebookAddedPrefName, clock_->Now().ToJavaTime()); } -void ObserverNotifier::FlushForTesting() { - if (observer_ptr_) - observer_ptr_.FlushForTesting(); -} - -base::Optional<std::string> -ObserverNotifier::LoadHostPublicKeyFromEndOfPreviousSession() { +base::Optional<std::string> AccountStatusChangeDelegateNotifierImpl:: + LoadHostPublicKeyFromEndOfPreviousSession() { std::string host_public_key_from_most_recent_sync = pref_service_->GetString(kHostPublicKeyFromMostRecentSyncPrefName); if (host_public_key_from_most_recent_sync.empty())
diff --git a/chromeos/services/multidevice_setup/observer_notifier.h b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.h similarity index 60% rename from chromeos/services/multidevice_setup/observer_notifier.h rename to chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.h index 8c6ef423..aab3616 100644 --- a/chromeos/services/multidevice_setup/observer_notifier.h +++ b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.h
@@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_SERVICES_MULTIDEVICE_SETUP_OBSERVER_NOTIFIER_H_ -#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_OBSERVER_NOTIFIER_H_ +#ifndef CHROMEOS_SERVICES_MULTIDEVICE_SETUP_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_IMPL_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_IMPL_H_ #include <memory> #include <string> #include "base/macros.h" #include "chromeos/services/device_sync/public/cpp/device_sync_client.h" +#include "chromeos/services/multidevice_setup/account_status_change_delegate_notifier.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" class PrefRegistrySimple; @@ -17,7 +18,7 @@ namespace base { class Clock; -} +} // namespace base namespace chromeos { @@ -25,19 +26,19 @@ class SetupFlowCompletionRecorder; -// Notifies the observer of MultiDeviceSetup for each of the following changes: -// (1) a potential host is found for someone who has not gone through the setup -// flow before, -// (2) the host has switched for someone who has, or -// (3) a new Chromebook has been added to an account for someone who has. -class ObserverNotifier : public device_sync::DeviceSyncClient::Observer { +// Concrete AccountStatusChangeDelegateNotifier implementation, which uses +// DeviceSyncClient to check for account changes and PrefStore to track previous +// notifications. +class AccountStatusChangeDelegateNotifierImpl + : public AccountStatusChangeDelegateNotifier, + public device_sync::DeviceSyncClient::Observer { public: class Factory { public: static Factory* Get(); static void SetFactoryForTesting(Factory* test_factory); virtual ~Factory(); - virtual std::unique_ptr<ObserverNotifier> BuildInstance( + virtual std::unique_ptr<AccountStatusChangeDelegateNotifier> BuildInstance( device_sync::DeviceSyncClient* device_sync_client, PrefService* pref_service, SetupFlowCompletionRecorder* setup_flow_completion_recorder, @@ -49,13 +50,13 @@ static void RegisterPrefs(PrefRegistrySimple* registry); - ~ObserverNotifier() override; + ~AccountStatusChangeDelegateNotifierImpl() override; - void SetMultiDeviceSetupObserverPtr( - mojom::MultiDeviceSetupObserverPtr observer_ptr); + void SetAccountStatusChangeDelegatePtr( + mojom::AccountStatusChangeDelegatePtr delegate_ptr); private: - friend class ObserverNotifierTest; + friend class MultiDeviceSetupAccountStatusChangeDelegateNotifierTest; static const char kNewUserPotentialHostExistsPrefName[]; static const char kExistingUserHostSwitchedPrefName[]; @@ -63,10 +64,14 @@ static const char kHostPublicKeyFromMostRecentSyncPrefName[]; - ObserverNotifier(device_sync::DeviceSyncClient* device_sync_client, - PrefService* pref_service, - SetupFlowCompletionRecorder* setup_flow_completion_recorder, - base::Clock* clock); + AccountStatusChangeDelegateNotifierImpl( + device_sync::DeviceSyncClient* device_sync_client, + PrefService* pref_service, + SetupFlowCompletionRecorder* setup_flow_completion_recorder, + base::Clock* clock); + + // AccountStatusChangeDelegateNotifier: + void OnDelegateSet() override; // device_sync::DeviceSyncClient::Observer: void OnNewDevicesSynced() override; @@ -80,8 +85,6 @@ void CheckForExistingUserChromebookAddedEvent( bool local_device_was_enabled_client_before_sync); - void FlushForTesting(); - // Loads data from previous session using PrefService. base::Optional<std::string> LoadHostPublicKeyFromEndOfPreviousSession(); @@ -89,17 +92,17 @@ base::Optional<std::string> host_public_key_from_most_recent_sync_; bool local_device_is_enabled_client_; - mojom::MultiDeviceSetupObserverPtr observer_ptr_; + mojom::AccountStatusChangeDelegatePtr delegate_ptr_; device_sync::DeviceSyncClient* device_sync_client_; PrefService* pref_service_; SetupFlowCompletionRecorder* setup_flow_completion_recorder_; base::Clock* clock_; - DISALLOW_COPY_AND_ASSIGN(ObserverNotifier); + DISALLOW_COPY_AND_ASSIGN(AccountStatusChangeDelegateNotifierImpl); }; } // namespace multidevice_setup } // namespace chromeos -#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_OBSERVER_NOTIFIER_H_ +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_IMPL_H_
diff --git a/chromeos/services/multidevice_setup/observer_notifier_unittest.cc b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl_unittest.cc similarity index 67% rename from chromeos/services/multidevice_setup/observer_notifier_unittest.cc rename to chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl_unittest.cc index 8b73885..347bc3c5 100644 --- a/chromeos/services/multidevice_setup/observer_notifier_unittest.cc +++ b/chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.h" + #include <string> #include <vector> @@ -9,9 +11,8 @@ #include "base/test/simple_test_clock.h" #include "base/time/time.h" #include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h" -#include "chromeos/services/multidevice_setup/fake_multidevice_setup_observer.h" +#include "chromeos/services/multidevice_setup/fake_account_status_change_delegate.h" #include "chromeos/services/multidevice_setup/fake_setup_flow_completion_recorder.h" -#include "chromeos/services/multidevice_setup/observer_notifier.h" #include "components/cryptauth/remote_device_test_util.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,6 +22,7 @@ namespace multidevice_setup { namespace { + const int64_t kTestTimeMillis = 1500000000000; constexpr const char* const kDummyKeys[] = {"publicKey0", "publicKey1", "publicKey2"}; @@ -44,20 +46,24 @@ cryptauth::SoftwareFeatureState::kSupported) .Build(); } + } // namespace -class ObserverNotifierTest : public testing::Test { +class MultiDeviceSetupAccountStatusChangeDelegateNotifierTest + : public testing::Test { protected: - ObserverNotifierTest() : local_device_(BuildLocalDevice()) {} + MultiDeviceSetupAccountStatusChangeDelegateNotifierTest() + : local_device_(BuildLocalDevice()) {} - ~ObserverNotifierTest() override = default; + ~MultiDeviceSetupAccountStatusChangeDelegateNotifierTest() override = default; void SetUp() override { test_pref_service_ = std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); - ObserverNotifier::RegisterPrefs(test_pref_service_->registry()); + AccountStatusChangeDelegateNotifierImpl::RegisterPrefs( + test_pref_service_->registry()); - fake_observer_ = std::make_unique<FakeMultiDeviceSetupObserver>(); + fake_delegate_ = std::make_unique<FakeAccountStatusChangeDelegate>(); fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); @@ -69,42 +75,49 @@ test_clock_->SetNow(base::Time::FromJavaTime(kTestTimeMillis)); } - void BuildObserverNotifier() { - observer_notifier_ = ObserverNotifier::Factory::Get()->BuildInstance( - fake_device_sync_client_.get(), test_pref_service_.get(), - fake_setup_flow_completion_recorder_.get(), test_clock_.get()); + void BuildAccountStatusChangeDelegateNotifier() { + delegate_notifier_ = + AccountStatusChangeDelegateNotifierImpl::Factory::Get()->BuildInstance( + fake_device_sync_client_.get(), test_pref_service_.get(), + fake_setup_flow_completion_recorder_.get(), test_clock_.get()); } void SetNewUserPotentialHostExistsTimestamp(int64_t timestamp) { - test_pref_service_->SetInt64( - ObserverNotifier::kNewUserPotentialHostExistsPrefName, timestamp); + test_pref_service_->SetInt64(AccountStatusChangeDelegateNotifierImpl:: + kNewUserPotentialHostExistsPrefName, + timestamp); } void SetExistingUserChromebookAddedTimestamp(int64_t timestamp) { - test_pref_service_->SetInt64( - ObserverNotifier::kExistingUserChromebookAddedPrefName, timestamp); + test_pref_service_->SetInt64(AccountStatusChangeDelegateNotifierImpl:: + kExistingUserChromebookAddedPrefName, + timestamp); } void SetHostFromPreviousSession(std::string old_host_key) { - test_pref_service_->SetString( - ObserverNotifier::kHostPublicKeyFromMostRecentSyncPrefName, - old_host_key); + test_pref_service_->SetString(AccountStatusChangeDelegateNotifierImpl:: + kHostPublicKeyFromMostRecentSyncPrefName, + old_host_key); } - void SetMultiDeviceSetupObserverPtr() { - observer_notifier_->SetMultiDeviceSetupObserverPtr( - fake_observer_->GenerateInterfacePtr()); - observer_notifier_->FlushForTesting(); + void SetAccountStatusChangeDelegatePtr() { + delegate_notifier_->SetAccountStatusChangeDelegatePtr( + fake_delegate_->GenerateInterfacePtr()); + delegate_notifier_->FlushForTesting(); } void RecordSetupFlowCompletionAtEarlierTime(const base::Time& earlier_time) { fake_setup_flow_completion_recorder_->set_current_time(earlier_time); - observer_notifier_->setup_flow_completion_recorder_->RecordCompletion(); + + SetupFlowCompletionRecorder* derived_ptr = + static_cast<SetupFlowCompletionRecorder*>( + fake_setup_flow_completion_recorder_.get()); + derived_ptr->RecordCompletion(); } void NotifyNewDevicesSynced() { fake_device_sync_client_->NotifyNewDevicesSynced(); - observer_notifier_->FlushForTesting(); + delegate_notifier_->FlushForTesting(); } // Represents setting preexisting devices on account and therefore does not @@ -130,7 +143,7 @@ cryptauth::RemoteDeviceRefList{BuildHostCandidate( kDummyKeys[0], cryptauth::SoftwareFeatureState::kEnabled)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); } // If the account as an enabled host, the local device will enable its @@ -144,22 +157,26 @@ int64_t GetNewUserPotentialHostExistsTimestamp() { return test_pref_service_->GetInt64( - ObserverNotifier::kNewUserPotentialHostExistsPrefName); + AccountStatusChangeDelegateNotifierImpl:: + kNewUserPotentialHostExistsPrefName); } int64_t GetExistingUserChromebookAddedTimestamp() { return test_pref_service_->GetInt64( - ObserverNotifier::kExistingUserChromebookAddedPrefName); + AccountStatusChangeDelegateNotifierImpl:: + kExistingUserChromebookAddedPrefName); } - FakeMultiDeviceSetupObserver* fake_observer() { return fake_observer_.get(); } + FakeAccountStatusChangeDelegate* fake_delegate() { + return fake_delegate_.get(); + } private: const base::test::ScopedTaskEnvironment scoped_task_environment_; cryptauth::RemoteDeviceRef local_device_; - std::unique_ptr<FakeMultiDeviceSetupObserver> fake_observer_; + std::unique_ptr<FakeAccountStatusChangeDelegate> fake_delegate_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> @@ -168,12 +185,14 @@ fake_setup_flow_completion_recorder_; std::unique_ptr<base::SimpleTestClock> test_clock_; - std::unique_ptr<ObserverNotifier> observer_notifier_; + std::unique_ptr<AccountStatusChangeDelegateNotifier> delegate_notifier_; - DISALLOW_COPY_AND_ASSIGN(ObserverNotifierTest); + DISALLOW_COPY_AND_ASSIGN( + MultiDeviceSetupAccountStatusChangeDelegateNotifierTest); }; -TEST_F(ObserverNotifierTest, SetObserverWithSupportedHost) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + SetObserverWithSupportedHost) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ BuildHostCandidate(kDummyKeys[0], @@ -181,22 +200,23 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); - SetMultiDeviceSetupObserverPtr(); - EXPECT_EQ(1u, fake_observer()->num_new_user_events_handled()); + SetAccountStatusChangeDelegatePtr(); + EXPECT_EQ(1u, fake_delegate()->num_new_user_events_handled()); EXPECT_EQ(kTestTimeMillis, GetNewUserPotentialHostExistsTimestamp()); } -TEST_F(ObserverNotifierTest, SupportedHostAddedLater) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + SupportedHostAddedLater) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{BuildHostCandidate( kDummyKeys[0], cryptauth::SoftwareFeatureState::kNotSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); - SetMultiDeviceSetupObserverPtr(); - EXPECT_EQ(0u, fake_observer()->num_new_user_events_handled()); + SetAccountStatusChangeDelegatePtr(); + EXPECT_EQ(0u, fake_delegate()->num_new_user_events_handled()); EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp()); device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -205,11 +225,12 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kSupported)}; UpdateNonLocalSyncedDevices(&device_ref_list); - EXPECT_EQ(1u, fake_observer()->num_new_user_events_handled()); + EXPECT_EQ(1u, fake_delegate()->num_new_user_events_handled()); EXPECT_EQ(kTestTimeMillis, GetNewUserPotentialHostExistsTimestamp()); } -TEST_F(ObserverNotifierTest, ExistingEnabledHostPreventsNewUserEvent) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + ExistingEnabledHostPreventsNewUserEvent) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ BuildHostCandidate(kDummyKeys[0], @@ -219,13 +240,14 @@ BuildHostCandidate(kDummyKeys[2], cryptauth::SoftwareFeatureState::kEnabled)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); - SetMultiDeviceSetupObserverPtr(); - EXPECT_EQ(0u, fake_observer()->num_new_user_events_handled()); + SetAccountStatusChangeDelegatePtr(); + EXPECT_EQ(0u, fake_delegate()->num_new_user_events_handled()); } -TEST_F(ObserverNotifierTest, NoNewUserEventWithoutObserverSet) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + NoNewUserEventWithoutObserverSet) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ BuildHostCandidate(kDummyKeys[0], @@ -233,16 +255,17 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); - // All conditions for new user event are now satisfied except for setting an - // observer. + BuildAccountStatusChangeDelegateNotifier(); + // All conditions for new user event are now satisfied except for setting a + // delegate. - // No observer is set before the sync. + // No delegate is set before the sync. NotifyNewDevicesSynced(); - EXPECT_EQ(0u, fake_observer()->num_new_user_events_handled()); + EXPECT_EQ(0u, fake_delegate()->num_new_user_events_handled()); } -TEST_F(ObserverNotifierTest, OldTimestampInPreferencesPreventsNewUserFlow) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + OldTimestampInPreferencesPreventsNewUserFlow) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ BuildHostCandidate(kDummyKeys[0], @@ -250,34 +273,36 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); int64_t earlier_test_time_millis = kTestTimeMillis / 2; SetNewUserPotentialHostExistsTimestamp(earlier_test_time_millis); - SetMultiDeviceSetupObserverPtr(); - EXPECT_EQ(0u, fake_observer()->num_new_user_events_handled()); + SetAccountStatusChangeDelegatePtr(); + EXPECT_EQ(0u, fake_delegate()->num_new_user_events_handled()); // Timestamp was not overwritten by clock. EXPECT_EQ(earlier_test_time_millis, GetNewUserPotentialHostExistsTimestamp()); } -TEST_F(ObserverNotifierTest, MultipleSyncsOnlyTriggerOneNewUserEvent) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + MultipleSyncsOnlyTriggerOneNewUserEvent) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{BuildHostCandidate( kDummyKeys[0], cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); - SetMultiDeviceSetupObserverPtr(); - EXPECT_EQ(1u, fake_observer()->num_new_user_events_handled()); + SetAccountStatusChangeDelegatePtr(); + EXPECT_EQ(1u, fake_delegate()->num_new_user_events_handled()); NotifyNewDevicesSynced(); - EXPECT_EQ(1u, fake_observer()->num_new_user_events_handled()); + EXPECT_EQ(1u, fake_delegate()->num_new_user_events_handled()); NotifyNewDevicesSynced(); - EXPECT_EQ(1u, fake_observer()->num_new_user_events_handled()); + EXPECT_EQ(1u, fake_delegate()->num_new_user_events_handled()); } -TEST_F(ObserverNotifierTest, NotifiesObserverForHostSwitchEvents) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + NotifiesObserverForHostSwitchEvents) { const std::string initial_host_key = kDummyKeys[0]; const std::string alternative_host_key_1 = kDummyKeys[1]; const std::string alternative_host_key_2 = kDummyKeys[2]; @@ -288,13 +313,13 @@ BuildHostCandidate(alternative_host_key_1, cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); EnableLocalDeviceAsClient(); - SetMultiDeviceSetupObserverPtr(); - // Verify the observer initializes to 0. + SetAccountStatusChangeDelegatePtr(); + // Verify the delegate initializes to 0. EXPECT_EQ(0u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); // Switch hosts. device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -304,7 +329,7 @@ cryptauth::SoftwareFeatureState::kEnabled)}; UpdateNonLocalSyncedDevices(&device_ref_list); EXPECT_EQ(1u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); // Adding and enabling a new host device (counts as a switch). device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -316,7 +341,7 @@ cryptauth::SoftwareFeatureState::kEnabled)}; UpdateNonLocalSyncedDevices(&device_ref_list); EXPECT_EQ(2u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); // Removing new device and switching back to initial host. device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -326,10 +351,11 @@ cryptauth::SoftwareFeatureState::kSupported)}; UpdateNonLocalSyncedDevices(&device_ref_list); EXPECT_EQ(3u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); } -TEST_F(ObserverNotifierTest, HostSwitchedBetweenSessions) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + HostSwitchedBetweenSessions) { const std::string old_host_key = kDummyKeys[0]; const std::string new_host_key = kDummyKeys[1]; SetHostFromPreviousSession(old_host_key); @@ -338,15 +364,15 @@ cryptauth::RemoteDeviceRefList{BuildHostCandidate( new_host_key, cryptauth::SoftwareFeatureState::kEnabled)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); EnableLocalDeviceAsClient(); - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); EXPECT_EQ(1u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); } -TEST_F(ObserverNotifierTest, +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, NoHostSwitchedEventWithoutLocalDeviceClientEnabled) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -355,9 +381,9 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); // Switch hosts. device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -368,13 +394,14 @@ // All conditions for host switched event are now satisfied except for the // local device's Better Together client feature enabled. - // No observer is set before the update (which includes a sync). + // No delegate is set before the update (which includes a sync). UpdateNonLocalSyncedDevices(&device_ref_list); EXPECT_EQ(0u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); } -TEST_F(ObserverNotifierTest, NoHostSwitchedEventWithoutExistingHost) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + NoHostSwitchedEventWithoutExistingHost) { // No enabled host initially. cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -383,9 +410,9 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); // Enable one of the host devices. device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -396,10 +423,11 @@ EnableLocalDeviceAsClient(); UpdateNonLocalSyncedDevices(&device_ref_list); EXPECT_EQ(0u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); } -TEST_F(ObserverNotifierTest, NoHostSwitchedEventWithoutObserverSet) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + NoHostSwitchedEventWithoutObserverSet) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ BuildHostCandidate(kDummyKeys[0], @@ -407,7 +435,7 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kSupported)}; SetNonLocalSyncedDevices(&device_ref_list); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); EnableLocalDeviceAsClient(); // Switch hosts. @@ -417,33 +445,34 @@ BuildHostCandidate(kDummyKeys[1], cryptauth::SoftwareFeatureState::kEnabled)}; // All conditions for host switched event are now satisfied except for setting - // an observer. + // an delegate. - // No observer is set before the update (which includes a sync). + // No delegate is set before the update (which includes a sync). UpdateNonLocalSyncedDevices(&device_ref_list); EXPECT_EQ(0u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); } -TEST_F(ObserverNotifierTest, NotifiesObserverForChromebookAddedEvents) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + NotifiesObserverForChromebookAddedEvents) { PrepareToEnableLocalDeviceAsClient(); EnableLocalDeviceAsClient(); - // Verify the observer initializes to 0. + // Verify the delegate initializes to 0. EXPECT_EQ( - 0u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); EXPECT_EQ( - 1u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); // Another sync should not trigger an additional chromebook added event. NotifyNewDevicesSynced(); EXPECT_EQ( - 1u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); } -TEST_F(ObserverNotifierTest, +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, OldTimestampInPreferencesDoesNotPreventChromebookAddedEvent) { PrepareToEnableLocalDeviceAsClient(); EnableLocalDeviceAsClient(); @@ -451,25 +480,25 @@ int64_t earlier_test_time_millis = kTestTimeMillis / 2; SetExistingUserChromebookAddedTimestamp(earlier_test_time_millis); - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); EXPECT_EQ( - 1u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); // Timestamp was overwritten by clock. EXPECT_EQ(kTestTimeMillis, GetExistingUserChromebookAddedTimestamp()); } -TEST_F(ObserverNotifierTest, +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, ChromebookAddedEventRequiresLocalDeviceToEnableClientFeature) { PrepareToEnableLocalDeviceAsClient(); // Triggers event check. Note that if the local device enabled the client // feature, this would trigger a Chromebook added event. - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); EXPECT_EQ( - 0u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); } -TEST_F(ObserverNotifierTest, +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, NoChromebookAddedEventIfDeviceWasUsedForUnifiedSetupFlow) { PrepareToEnableLocalDeviceAsClient(); EnableLocalDeviceAsClient(); @@ -479,24 +508,25 @@ // Triggers event check. Note that if the setup flow completion had not been // recorded, this would trigger a Chromebook added event. - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); EXPECT_EQ( - 0u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); } -TEST_F(ObserverNotifierTest, NoChromebookAddedEventWithoutObserverSet) { +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, + NoChromebookAddedEventWithoutObserverSet) { PrepareToEnableLocalDeviceAsClient(); EnableLocalDeviceAsClient(); // All conditions for chromebook added event are now satisfied except for - // setting an observer. + // setting a delegate. - // No observer is set before the sync. + // No delegate is set before the sync. NotifyNewDevicesSynced(); EXPECT_EQ( - 0u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); } -TEST_F(ObserverNotifierTest, +TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest, DeviceSyncDoesNotNotifyObserverOfDisconnectedHostsAndClients) { cryptauth::RemoteDeviceRefList device_ref_list = cryptauth::RemoteDeviceRefList{ @@ -512,23 +542,23 @@ .Build()}; SetNonLocalSyncedDevices(&device_ref_list); EnableLocalDeviceAsClient(); - BuildObserverNotifier(); + BuildAccountStatusChangeDelegateNotifier(); - SetMultiDeviceSetupObserverPtr(); + SetAccountStatusChangeDelegatePtr(); NotifyNewDevicesSynced(); EXPECT_EQ( - 0u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); EXPECT_EQ(0u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); device_ref_list = cryptauth::RemoteDeviceRefList{}; UpdateNonLocalSyncedDevices(&device_ref_list); // No new events caused by removing devices. EXPECT_EQ( - 0u, fake_observer()->num_existing_user_chromebook_added_events_handled()); + 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled()); EXPECT_EQ(0u, - fake_observer()->num_existing_user_host_switched_events_handled()); + fake_delegate()->num_existing_user_host_switched_events_handled()); } } // namespace multidevice_setup
diff --git a/chromeos/services/multidevice_setup/fake_account_status_change_delegate.cc b/chromeos/services/multidevice_setup/fake_account_status_change_delegate.cc new file mode 100644 index 0000000..9f04264 --- /dev/null +++ b/chromeos/services/multidevice_setup/fake_account_status_change_delegate.cc
@@ -0,0 +1,36 @@ +// 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 "chromeos/services/multidevice_setup/fake_account_status_change_delegate.h" + +namespace chromeos { + +namespace multidevice_setup { + +FakeAccountStatusChangeDelegate::FakeAccountStatusChangeDelegate() = default; + +FakeAccountStatusChangeDelegate::~FakeAccountStatusChangeDelegate() = default; + +mojom::AccountStatusChangeDelegatePtr +FakeAccountStatusChangeDelegate::GenerateInterfacePtr() { + mojom::AccountStatusChangeDelegatePtr interface_ptr; + bindings_.AddBinding(this, mojo::MakeRequest(&interface_ptr)); + return interface_ptr; +} + +void FakeAccountStatusChangeDelegate::OnPotentialHostExistsForNewUser() { + ++num_new_user_events_handled_; +} + +void FakeAccountStatusChangeDelegate::OnConnectedHostSwitchedForExistingUser() { + ++num_existing_user_host_switched_events_handled_; +} + +void FakeAccountStatusChangeDelegate::OnNewChromebookAddedForExistingUser() { + ++num_existing_user_chromebook_added_events_handled_; +} + +} // namespace multidevice_setup + +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/fake_multidevice_setup_observer.h b/chromeos/services/multidevice_setup/fake_account_status_change_delegate.h similarity index 61% rename from chromeos/services/multidevice_setup/fake_multidevice_setup_observer.h rename to chromeos/services/multidevice_setup/fake_account_status_change_delegate.h index 1fc2cafc..a151744 100644 --- a/chromeos/services/multidevice_setup/fake_multidevice_setup_observer.h +++ b/chromeos/services/multidevice_setup/fake_account_status_change_delegate.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 CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_MULTIDEVICE_SETUP_OBSERVER_H_ -#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_MULTIDEVICE_SETUP_OBSERVER_H_ +#ifndef CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_ACCOUNT_STATUS_CHANGE_DELEGATE_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_ACCOUNT_STATUS_CHANGE_DELEGATE_H_ #include "base/macros.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" @@ -13,13 +13,14 @@ namespace multidevice_setup { -// Fake MultiDeviceSetupObserver implementation for tests. -class FakeMultiDeviceSetupObserver : public mojom::MultiDeviceSetupObserver { +// Fake mojom::AccountStatusChangeDelegate implementation for tests. +class FakeAccountStatusChangeDelegate + : public mojom::AccountStatusChangeDelegate { public: - FakeMultiDeviceSetupObserver(); - ~FakeMultiDeviceSetupObserver() override; + FakeAccountStatusChangeDelegate(); + ~FakeAccountStatusChangeDelegate() override; - mojom::MultiDeviceSetupObserverPtr GenerateInterfacePtr(); + mojom::AccountStatusChangeDelegatePtr GenerateInterfacePtr(); size_t num_new_user_events_handled() { return num_new_user_events_handled_; } @@ -31,7 +32,7 @@ return num_existing_user_chromebook_added_events_handled_; } - // mojom::MultiDeviceSetupObserver: + // mojom::AccountStatusChangeDelegate: void OnPotentialHostExistsForNewUser() override; void OnConnectedHostSwitchedForExistingUser() override; void OnNewChromebookAddedForExistingUser() override; @@ -41,13 +42,13 @@ size_t num_existing_user_host_switched_events_handled_ = 0u; size_t num_existing_user_chromebook_added_events_handled_ = 0u; - mojo::BindingSet<mojom::MultiDeviceSetupObserver> bindings_; + mojo::BindingSet<mojom::AccountStatusChangeDelegate> bindings_; - DISALLOW_COPY_AND_ASSIGN(FakeMultiDeviceSetupObserver); + DISALLOW_COPY_AND_ASSIGN(FakeAccountStatusChangeDelegate); }; } // namespace multidevice_setup } // namespace chromeos -#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_MULTIDEVICE_SETUP_OBSERVER_H_ +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_ACCOUNT_STATUS_CHANGE_DELEGATE_H_
diff --git a/chromeos/services/multidevice_setup/fake_account_status_change_delegate_notifier.h b/chromeos/services/multidevice_setup/fake_account_status_change_delegate_notifier.h new file mode 100644 index 0000000..0635e44 --- /dev/null +++ b/chromeos/services/multidevice_setup/fake_account_status_change_delegate_notifier.h
@@ -0,0 +1,33 @@ +// 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 CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_H_ + +#include "base/macros.h" +#include "chromeos/services/multidevice_setup/account_status_change_delegate_notifier.h" +#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" + +namespace chromeos { + +namespace multidevice_setup { + +// Test AccountStatusChangeDelegateNotifier implementation. +class FakeAccountStatusChangeDelegateNotifier + : public AccountStatusChangeDelegateNotifier { + public: + FakeAccountStatusChangeDelegateNotifier() = default; + ~FakeAccountStatusChangeDelegateNotifier() override = default; + + using AccountStatusChangeDelegateNotifier::delegate; + + private: + DISALLOW_COPY_AND_ASSIGN(FakeAccountStatusChangeDelegateNotifier); +}; + +} // namespace multidevice_setup + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_ACCOUNT_STATUS_CHANGE_DELEGATE_NOTIFIER_H_
diff --git a/chromeos/services/multidevice_setup/fake_multidevice_setup_observer.cc b/chromeos/services/multidevice_setup/fake_multidevice_setup_observer.cc deleted file mode 100644 index 4e5f05c1..0000000 --- a/chromeos/services/multidevice_setup/fake_multidevice_setup_observer.cc +++ /dev/null
@@ -1,36 +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. - -#include "chromeos/services/multidevice_setup/fake_multidevice_setup_observer.h" - -namespace chromeos { - -namespace multidevice_setup { - -FakeMultiDeviceSetupObserver::FakeMultiDeviceSetupObserver() = default; - -FakeMultiDeviceSetupObserver::~FakeMultiDeviceSetupObserver() = default; - -mojom::MultiDeviceSetupObserverPtr -FakeMultiDeviceSetupObserver::GenerateInterfacePtr() { - mojom::MultiDeviceSetupObserverPtr interface_ptr; - bindings_.AddBinding(this, mojo::MakeRequest(&interface_ptr)); - return interface_ptr; -} - -void FakeMultiDeviceSetupObserver::OnPotentialHostExistsForNewUser() { - ++num_new_user_events_handled_; -} - -void FakeMultiDeviceSetupObserver::OnConnectedHostSwitchedForExistingUser() { - ++num_existing_user_host_switched_events_handled_; -} - -void FakeMultiDeviceSetupObserver::OnNewChromebookAddedForExistingUser() { - ++num_existing_user_chromebook_added_events_handled_; -} - -} // namespace multidevice_setup - -} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl.cc b/chromeos/services/multidevice_setup/multidevice_setup_impl.cc index dfe79ad..f67d56a 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl.cc
@@ -10,24 +10,6 @@ namespace multidevice_setup { -namespace { - -std::string EventTypeEnumToString(mojom::EventTypeForDebugging type) { - switch (type) { - case mojom::EventTypeForDebugging::kNewUserPotentialHostExists: - return "kNewUserPotentialHostExists"; - case mojom::EventTypeForDebugging::kExistingUserConnectedHostSwitched: - return "kExistingUserConnectedHostSwitched"; - case mojom::EventTypeForDebugging::kExistingUserNewChromebookAdded: - return "kExistingUserNewChromebookAdded"; - default: - NOTREACHED(); - return "[invalid input]"; - } -} - -} // namespace - MultiDeviceSetupImpl::MultiDeviceSetupImpl() = default; MultiDeviceSetupImpl::~MultiDeviceSetupImpl() = default; @@ -36,42 +18,35 @@ bindings_.AddBinding(this, std::move(request)); } -void MultiDeviceSetupImpl::SetObserver( - mojom::MultiDeviceSetupObserverPtr observer, - SetObserverCallback callback) { - if (observer_.is_bound()) { - PA_LOG(ERROR) << "SetObserver() called when a MultiDeviceSetupObserver was " - << "already set. Replacing the previously-set " - << "MultiDeviceSetupObserver."; - } - - PA_LOG(INFO) << "MultiDeviceSetupImpl::SetObserver()"; - observer_ = std::move(observer); +void MultiDeviceSetupImpl::SetAccountStatusChangeDelegate( + mojom::AccountStatusChangeDelegatePtr delegate, + SetAccountStatusChangeDelegateCallback callback) { + delegate_ = std::move(delegate); std::move(callback).Run(); } void MultiDeviceSetupImpl::TriggerEventForDebugging( mojom::EventTypeForDebugging type, TriggerEventForDebuggingCallback callback) { - PA_LOG(INFO) << "TriggerEventForDebugging(" << EventTypeEnumToString(type) + PA_LOG(INFO) << "MultiDeviceSetupImpl::TriggerEventForDebugging(" << type << ") called."; - if (!observer_.is_bound()) { - PA_LOG(ERROR) << "No MultiDeviceSetupObserver has been set. Cannot " - << "proceed."; + if (!delegate_.is_bound()) { + PA_LOG(ERROR) << "MultiDeviceSetupImpl::TriggerEventForDebugging(): No " + << "delgate has been set; cannot proceed."; std::move(callback).Run(false /* success */); return; } switch (type) { case mojom::EventTypeForDebugging::kNewUserPotentialHostExists: - observer_->OnPotentialHostExistsForNewUser(); + delegate_->OnPotentialHostExistsForNewUser(); break; case mojom::EventTypeForDebugging::kExistingUserConnectedHostSwitched: - observer_->OnConnectedHostSwitchedForExistingUser(); + delegate_->OnConnectedHostSwitchedForExistingUser(); break; case mojom::EventTypeForDebugging::kExistingUserNewChromebookAdded: - observer_->OnNewChromebookAddedForExistingUser(); + delegate_->OnNewChromebookAddedForExistingUser(); break; default: NOTREACHED();
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl.h b/chromeos/services/multidevice_setup/multidevice_setup_impl.h index 88a8898..9521fd29 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl.h +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl.h
@@ -27,14 +27,15 @@ void BindRequest(mojom::MultiDeviceSetupRequest request); // mojom::MultiDeviceSetup: - void SetObserver(mojom::MultiDeviceSetupObserverPtr presenter, - SetObserverCallback callback) override; + void SetAccountStatusChangeDelegate( + mojom::AccountStatusChangeDelegatePtr delegate, + SetAccountStatusChangeDelegateCallback callback) override; void TriggerEventForDebugging( mojom::EventTypeForDebugging type, TriggerEventForDebuggingCallback callback) override; private: - mojom::MultiDeviceSetupObserverPtr observer_; + mojom::AccountStatusChangeDelegatePtr delegate_; mojo::BindingSet<mojom::MultiDeviceSetup> bindings_; DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupImpl);
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc b/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc index 5362976..8193b1c 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc
@@ -7,7 +7,7 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" -#include "chromeos/services/multidevice_setup/fake_multidevice_setup_observer.h" +#include "chromeos/services/multidevice_setup/fake_account_status_change_delegate.h" #include "chromeos/services/multidevice_setup/multidevice_setup_service.h" #include "chromeos/services/multidevice_setup/public/mojom/constants.mojom.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" @@ -24,8 +24,8 @@ ~MultiDeviceSetupServiceTest() override = default; void SetUp() override { - fake_multidevice_setup_observer_ = - std::make_unique<FakeMultiDeviceSetupObserver>(); + fake_account_status_change_delegate_ = + std::make_unique<FakeAccountStatusChangeDelegate>(); connector_factory_ = service_manager::TestConnectorFactory::CreateForUniqueService( std::make_unique<MultiDeviceSetupService>()); @@ -39,21 +39,21 @@ connector_ = connector_factory_->CreateConnector(); connector_->BindInterface(mojom::kServiceName, &multidevice_setup_); - // Set |fake_multidevice_setup_observer_|. - CallSetObserver(); + // Set |fake_account_status_change_delegate_|. + CallSetAccountStatusChangeDelegate(); } return multidevice_setup_.get(); } - FakeMultiDeviceSetupObserver* fake_multidevice_setup_observer() { - return fake_multidevice_setup_observer_.get(); + FakeAccountStatusChangeDelegate* fake_account_status_change_delegate() { + return fake_account_status_change_delegate_.get(); } - void CallSetObserver() { + void CallSetAccountStatusChangeDelegate() { base::RunLoop run_loop; - multidevice_setup_->SetObserver( - fake_multidevice_setup_observer_->GenerateInterfacePtr(), + multidevice_setup_->SetAccountStatusChangeDelegate( + fake_account_status_change_delegate_->GenerateInterfacePtr(), base::BindOnce( &MultiDeviceSetupServiceTest::OnNotificationPresenterRegistered, base::Unretained(this), run_loop.QuitClosure())); @@ -87,8 +87,8 @@ std::unique_ptr<service_manager::TestConnectorFactory> connector_factory_; std::unique_ptr<service_manager::Connector> connector_; - std::unique_ptr<FakeMultiDeviceSetupObserver> - fake_multidevice_setup_observer_; + std::unique_ptr<FakeAccountStatusChangeDelegate> + fake_account_status_change_delegate_; mojom::MultiDeviceSetupPtr multidevice_setup_; DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupServiceTest); @@ -99,8 +99,8 @@ CallTriggerEventForDebugging( mojom::EventTypeForDebugging::kNewUserPotentialHostExists); - EXPECT_EQ(1u, - fake_multidevice_setup_observer()->num_new_user_events_handled()); + EXPECT_EQ( + 1u, fake_account_status_change_delegate()->num_new_user_events_handled()); } TEST_F(MultiDeviceSetupServiceTest, @@ -108,7 +108,7 @@ CallTriggerEventForDebugging( mojom::EventTypeForDebugging::kExistingUserConnectedHostSwitched); - EXPECT_EQ(1u, fake_multidevice_setup_observer() + EXPECT_EQ(1u, fake_account_status_change_delegate() ->num_existing_user_host_switched_events_handled()); } @@ -117,7 +117,7 @@ CallTriggerEventForDebugging( mojom::EventTypeForDebugging::kExistingUserNewChromebookAdded); - EXPECT_EQ(1u, fake_multidevice_setup_observer() + EXPECT_EQ(1u, fake_account_status_change_delegate() ->num_existing_user_chromebook_added_events_handled()); }
diff --git a/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom b/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom index 121207e..e70c626 100644 --- a/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom +++ b/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom
@@ -4,8 +4,7 @@ module chromeos.multidevice_setup.mojom; -// Handles events dispatched by MultiDeviceSetup. -interface MultiDeviceSetupObserver { +interface AccountStatusChangeDelegate { // Callback which indicates that one or more MultiDevice host phones are // available for setup with the MultiDevice setup flow. This function is only // called if the current user has not yet set up MultiDevice features. @@ -37,12 +36,10 @@ // chrome://proximity-auth (debugging only). // TODO(khorimoto): Finish fleshing out this interface. interface MultiDeviceSetup { - // Registers the observer to be used by the service. Once this function has - // been called, the service will begin monitoring changes to synced devices - // and will notify |observer| when appropriate. Only one observer can be - // active at a time; calling this function a second time will remove the - // first observer added. - SetObserver(MultiDeviceSetupObserver observer) => (); + // Registers the "account status change" delegate to be used by the service. + // Only one delegate can be set; this function should not be called more than + // once. + SetAccountStatusChangeDelegate(AccountStatusChangeDelegate delegate) => (); // Triggers an event to be dispatched by the service. This API function is // intended to be used only for debugging in the chrome://proximity-auth page.
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index f6464d5..6435354 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -151,6 +151,8 @@ "arc_data_remover.h", "arc_features.cc", "arc_features.h", + "arc_features_parser.cc", + "arc_features_parser.h", "arc_service_manager.cc", "arc_service_manager.h", "arc_session.cc", @@ -270,6 +272,7 @@ testonly = true sources = [ "arc_data_remover_unittest.cc", + "arc_features_parser_unittest.cc", "arc_session_impl_unittest.cc", "arc_session_runner_unittest.cc", "arc_util_unittest.cc",
diff --git a/components/arc/arc_features_parser.cc b/components/arc/arc_features_parser.cc new file mode 100644 index 0000000..beea0d9 --- /dev/null +++ b/components/arc/arc_features_parser.cc
@@ -0,0 +1,139 @@ +// 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/arc/arc_features_parser.h" + +#include <memory> + +#include "base/files/file_util.h" +#include "base/json/json_reader.h" +#include "base/stl_util.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" +#include "base/values.h" + +namespace arc { + +namespace { + +constexpr const base::FilePath::CharType kArcFeaturesJsonFile[] = + FILE_PATH_LITERAL("/etc/arc/features.json"); + +base::Optional<ArcFeatures> ParseFeaturesJson(base::StringPiece input_json) { + ArcFeatures arc_features; + + int error_code; + std::string error_msg; + std::unique_ptr<base::Value> json_value = + base::JSONReader::ReadAndReturnError(input_json, base::JSON_PARSE_RFC, + &error_code, &error_msg); + if (!json_value || !json_value->is_dict()) { + LOG(ERROR) << "Error parsing feature JSON: " << error_msg; + return base::nullopt; + } + + // Parse each item under features. + const base::Value* feature_list = + json_value->FindKeyOfType("features", base::Value::Type::LIST); + if (!feature_list) { + LOG(ERROR) << "No feature list in JSON."; + return base::nullopt; + } + for (auto& feature_item : feature_list->GetList()) { + const base::Value* feature_name = + feature_item.FindKeyOfType("name", base::Value::Type::STRING); + const base::Value* feature_version = + feature_item.FindKeyOfType("version", base::Value::Type::INTEGER); + if (!feature_name || feature_name->GetString().empty()) { + LOG(ERROR) << "Missing name in the feature."; + return base::nullopt; + } + if (!feature_version) { + LOG(ERROR) << "Missing version in the feature."; + return base::nullopt; + } + arc_features.feature_map.emplace(feature_name->GetString(), + feature_version->GetInt()); + } + + // Parse each item under unavailable_features. + const base::Value* unavailable_feature_list = json_value->FindKeyOfType( + "unavailable_features", base::Value::Type::LIST); + if (!unavailable_feature_list) { + LOG(ERROR) << "No unavailable feature list in JSON."; + return base::nullopt; + } + for (auto& feature_item : unavailable_feature_list->GetList()) { + if (!feature_item.is_string()) { + LOG(ERROR) << "Item in the unavailable feature list is not a string."; + return base::nullopt; + } + + if (feature_item.GetString().empty()) { + LOG(ERROR) << "Missing name in the feature."; + return base::nullopt; + } + arc_features.unavailable_features.emplace_back(feature_item.GetString()); + } + + // Parse each item under properties. + const base::Value* properties = + json_value->FindKeyOfType("properties", base::Value::Type::DICTIONARY); + if (!properties) { + LOG(ERROR) << "No properties in JSON."; + return base::nullopt; + } + for (const auto& item : properties->DictItems()) { + if (!item.second.is_string()) { + LOG(ERROR) << "Item in the properties mapping is not a string."; + return base::nullopt; + } + + arc_features.build_props.emplace(item.first, item.second.GetString()); + } + + return arc_features; +} + +base::Optional<ArcFeatures> ReadOnFileThread(const base::FilePath& file_path) { + DCHECK(!file_path.empty()); + base::AssertBlockingAllowed(); + + std::string input_json; + if (!base::ReadFileToString(file_path, &input_json)) { + PLOG(ERROR) << "Cannot read file " << file_path.value() << " into string."; + return base::nullopt; + } + + if (input_json.empty()) { + LOG(ERROR) << "Input JSON is empty in file " << file_path.value(); + return base::nullopt; + } + + return ParseFeaturesJson(input_json); +} + +} // namespace + +ArcFeatures::ArcFeatures() = default; +ArcFeatures::ArcFeatures(ArcFeatures&& other) = default; +ArcFeatures::~ArcFeatures() = default; +ArcFeatures& ArcFeatures::operator=(ArcFeatures&& other) = default; + +void ArcFeaturesParser::GetArcFeatures( + base::OnceCallback<void(base::Optional<ArcFeatures>)> callback) { + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + base::BindOnce(&ReadOnFileThread, base::FilePath(kArcFeaturesJsonFile)), + std::move(callback)); +} + +base::Optional<ArcFeatures> ArcFeaturesParser::ParseFeaturesJsonForTesting( + base::StringPiece input_json) { + return ParseFeaturesJson(input_json); +} + +} // namespace arc
diff --git a/components/arc/arc_features_parser.h b/components/arc/arc_features_parser.h new file mode 100644 index 0000000..0b0219a --- /dev/null +++ b/components/arc/arc_features_parser.h
@@ -0,0 +1,93 @@ +// 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 COMPONENTS_ARC_ARC_FEATURES_PARSER_H_ +#define COMPONENTS_ARC_ARC_FEATURES_PARSER_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/optional.h" +#include "base/strings/string_piece.h" + +namespace arc { + +// This struct contains an ARC available feature map, unavailable feature set +// and ARC build property map. +struct ArcFeatures { + // Key is the feature name. Value is the feature version. + using FeatureVersionMapping = std::map<std::string, int>; + + // Each item in the vector is the feature name. + using FeatureList = std::vector<std::string>; + + // Key is the property key, such as "ro.build.version.sdk". Value is the + // corresponding property value. + using BuildPropsMapping = std::map<std::string, std::string>; + + ArcFeatures(); + ArcFeatures(ArcFeatures&& other); + ~ArcFeatures(); + + ArcFeatures& operator=(ArcFeatures&& other); + + // This map contains all ARC system available features. For each feature, it + // has the name and version. Unavailable features have been filtered out from + // this map. + FeatureVersionMapping feature_map; + + // This list contains all ARC unavailable feature names. + FeatureList unavailable_features; + + // This map contains all ARC build properties. + BuildPropsMapping build_props; + + private: + DISALLOW_COPY_AND_ASSIGN(ArcFeatures); +}; + +// Parses JSON files for Android system available features and build properties. +// +// A feature JSON file looks like this: +// { +// "features": [ +// { +// "name": "android.hardware.location", +// "version: 2 +// }, +// { +// "name": "android.hardware.location.network", +// "version": 0 +// } +// ], +// "unavailable_features": [ +// "android.hardware.usb.accessory", +// "android.software.live_tv" +// ], +// "properties": { +// "ro.product.cpu.abilist": "x86_64,x86,armeabi-v7a,armeabi", +// "ro.build.version.sdk": "25" +// } +// } +class ArcFeaturesParser { + public: + // Get ARC system available features. + static void GetArcFeatures( + base::OnceCallback<void(base::Optional<ArcFeatures>)> callback); + + // Given an input feature JSON, return ARC features. This method is for + // testing only. + static base::Optional<ArcFeatures> ParseFeaturesJsonForTesting( + base::StringPiece input_json); + + private: + DISALLOW_COPY_AND_ASSIGN(ArcFeaturesParser); +}; + +} // namespace arc + +#endif // COMPONENTS_ARC_ARC_FEATURES_PARSER_H_
diff --git a/components/arc/arc_features_parser_unittest.cc b/components/arc/arc_features_parser_unittest.cc new file mode 100644 index 0000000..5df03355 --- /dev/null +++ b/components/arc/arc_features_parser_unittest.cc
@@ -0,0 +1,124 @@ +// 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/arc/arc_features_parser.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace arc { +namespace { + +class ArcFeaturesParserTest : public testing::Test { + public: + ArcFeaturesParserTest() = default; + + private: + DISALLOW_COPY_AND_ASSIGN(ArcFeaturesParserTest); +}; + +constexpr const char kValidJson[] = R"json({"features": [ + { + "name": "com.google.android.feature.GOOGLE_BUILD", + "version": 0 + }, + { + "name": "com.google.android.feature.GOOGLE_EXPERIENCE", + "version": 2 + } + ], + "unavailable_features": [], + "properties": { + "ro.product.cpu.abilist": "x86_64,x86,armeabi-v7a,armeabi", + "ro.build.version.sdk": "25" + }})json"; + +constexpr const char kValidJsonWithUnavailableFeature[] = + R"json({"features": [ + { + "name": "android.software.home_screen", + "version": 0 + }, + { + "name": "com.google.android.feature.GOOGLE_EXPERIENCE", + "version": 0 + } + ], + "unavailable_features": ["android.software.location"], + "properties": {}})json"; + +constexpr const char kValidJsonFeatureEmptyName[] = + R"json({"features": [ + { + "name": "android.hardware.faketouch", + "version": 0 + }, + { + "name": "android.hardware.location", + "version": 0 + }, + { + "name": "", + "version": 0 + } + ], + "unavailable_features": ["android.software.home_screen", ""], + "properties": {}})json"; + +constexpr const char kValidJsonWithMissingFields[] = + R"json({"invalid_root": [ + { + "name": "android.hardware.location" + }, + { + "name": "android.hardware.location.network" + } + ], + "invalid_root_second": [], + "invalid_root_third": {}})json"; + +TEST_F(ArcFeaturesParserTest, ParseEmptyJson) { + base::Optional<ArcFeatures> arc_features = + ArcFeaturesParser::ParseFeaturesJsonForTesting(base::StringPiece()); + EXPECT_EQ(arc_features, base::nullopt); +} + +TEST_F(ArcFeaturesParserTest, ParseInvalidJson) { + base::Optional<ArcFeatures> arc_features = + ArcFeaturesParser::ParseFeaturesJsonForTesting( + kValidJsonWithMissingFields); + EXPECT_EQ(arc_features, base::nullopt); +} + +TEST_F(ArcFeaturesParserTest, ParseValidJson) { + base::Optional<ArcFeatures> arc_features = + ArcFeaturesParser::ParseFeaturesJsonForTesting(kValidJson); + auto feature_map = arc_features->feature_map; + auto unavailable_features = arc_features->unavailable_features; + auto build_props = arc_features->build_props; + EXPECT_EQ(feature_map.size(), 2u); + EXPECT_EQ(unavailable_features.size(), 0u); + EXPECT_EQ(build_props.size(), 2u); +} + +TEST_F(ArcFeaturesParserTest, ParseValidJsonWithUnavailableFeature) { + base::Optional<ArcFeatures> arc_features = + ArcFeaturesParser::ParseFeaturesJsonForTesting( + kValidJsonWithUnavailableFeature); + auto feature_map = arc_features->feature_map; + auto unavailable_features = arc_features->unavailable_features; + auto build_props = arc_features->build_props; + EXPECT_EQ(feature_map.size(), 2u); + EXPECT_EQ(unavailable_features.size(), 1u); + EXPECT_EQ(build_props.size(), 0u); +} + +TEST_F(ArcFeaturesParserTest, ParseValidJsonWithEmptyFeatureName) { + base::Optional<ArcFeatures> arc_features = + ArcFeaturesParser::ParseFeaturesJsonForTesting( + kValidJsonFeatureEmptyName); + EXPECT_EQ(arc_features, base::nullopt); +} + +} // namespace +} // namespace arc
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index fc9f9bf..0d138bf 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -230,6 +230,7 @@ "//components/autofill/core/browser/proto", "//components/autofill/core/common", "//components/resources", + "//components/security_state/core", "//skia", "//third_party/libaddressinput", ] @@ -242,7 +243,6 @@ "//components/os_crypt", "//components/pref_registry", "//components/prefs", - "//components/security_state/core", "//components/signin/core/browser:signin_metrics", "//components/strings", "//components/sync",
diff --git a/components/autofill/core/browser/autocomplete_history_manager.cc b/components/autofill/core/browser/autocomplete_history_manager.cc index f9f06cf..8df3e4ec 100644 --- a/components/autofill/core/browser/autocomplete_history_manager.cc +++ b/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -90,14 +90,14 @@ // - value is not a SSN // - field was not identified as a CVC field (this is handled in // AutofillManager) + // - field is focusable + // - not a presentation field std::vector<FormFieldData> values; for (const FormFieldData& field : form.fields) { - if (!field.value.empty() && - !field.name.empty() && - IsTextField(field) && - field.should_autocomplete && - !IsValidCreditCardNumber(field.value) && - !IsSSN(field.value)) { + if (!field.value.empty() && !field.name.empty() && IsTextField(field) && + field.should_autocomplete && !IsValidCreditCardNumber(field.value) && + !IsSSN(field.value) && field.is_focusable && + field.role != FormFieldData::ROLE_ATTRIBUTE_PRESENTATION) { values.push_back(field); } }
diff --git a/components/autofill/core/browser/autocomplete_history_manager_unittest.cc b/components/autofill/core/browser/autocomplete_history_manager_unittest.cc index c22cf0c4..f9db7be 100644 --- a/components/autofill/core/browser/autocomplete_history_manager_unittest.cc +++ b/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
@@ -186,6 +186,48 @@ autocomplete_manager_->OnWillSubmitForm(form); } +// Tests that text entered into fields that are not focusable is not sent to the +// WebDatabase to be saved. +TEST_F(AutocompleteHistoryManagerTest, NonFocusableField) { + FormData form; + form.name = ASCIIToUTF16("MyForm"); + form.origin = GURL("http://myform.com/form.html"); + form.action = GURL("http://myform.com/submit.html"); + + // Unfocusable field. + FormFieldData field; + field.label = ASCIIToUTF16("Something esoteric"); + field.name = ASCIIToUTF16("esoterica"); + field.value = ASCIIToUTF16("a truly esoteric value, I assure you"); + field.form_control_type = "text"; + field.is_focusable = false; + form.fields.push_back(field); + + EXPECT_CALL(*web_data_service_, AddFormFields(_)).Times(0); + autocomplete_manager_->OnWillSubmitForm(form); +} + +// Tests that text entered into presentation fields is not sent to the +// WebDatabase to be saved. +TEST_F(AutocompleteHistoryManagerTest, PresentationField) { + FormData form; + form.name = ASCIIToUTF16("MyForm"); + form.origin = GURL("http://myform.com/form.html"); + form.action = GURL("http://myform.com/submit.html"); + + // Presentation field. + FormFieldData field; + field.label = ASCIIToUTF16("Something esoteric"); + field.name = ASCIIToUTF16("esoterica"); + field.value = ASCIIToUTF16("a truly esoteric value, I assure you"); + field.form_control_type = "text"; + field.role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION; + form.fields.push_back(field); + + EXPECT_CALL(*web_data_service_, AddFormFields(_)).Times(0); + autocomplete_manager_->OnWillSubmitForm(form); +} + namespace { class MockAutofillExternalDelegate : public AutofillExternalDelegate {
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index 522952e..61d4332 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h
@@ -15,6 +15,7 @@ #include "base/strings/string16.h" #include "base/values.h" #include "components/autofill/core/browser/risk_data_loader.h" +#include "components/security_state/core/security_state.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "ui/base/window_open_disposition.h" #include "url/gurl.h" @@ -117,6 +118,10 @@ // Gets an AddressNormalizer instance (can be null). virtual AddressNormalizer* GetAddressNormalizer() = 0; + // Gets the security level used for recording histograms for the current + // context if possible, SECURITY_LEVEL_COUNT otherwise. + virtual security_state::SecurityLevel GetSecurityLevelForUmaHistograms() = 0; + // Causes the Autofill settings UI to be shown. virtual void ShowAutofillSettings() = 0;
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index be6431b..872c35b 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -506,8 +506,9 @@ if (!user_did_type_) { user_did_type_ = true; - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE, - autofill_field->Type().group()); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::USER_DID_TYPE, autofill_field->Type().group(), + client_->GetSecurityLevelForUmaHistograms()); } if (autofill_field->is_autofilled) { @@ -515,13 +516,15 @@ autofill_field->set_previously_autofilled(true); AutofillMetrics::LogUserHappinessMetric( AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD, - autofill_field->Type().group()); + autofill_field->Type().group(), + client_->GetSecurityLevelForUmaHistograms()); if (!user_did_edit_autofilled_field_) { user_did_edit_autofilled_field_ = true; AutofillMetrics::LogUserHappinessMetric( AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD_ONCE, - autofill_field->Type().group()); + autofill_field->Type().group(), + client_->GetSecurityLevelForUmaHistograms()); } } @@ -787,12 +790,14 @@ if (FindCachedForm(form, &form_structure)) { form_types = form_structure->GetFormTypes(); } - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL, - form_types); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::USER_DID_AUTOFILL, form_types, + client_->GetSecurityLevelForUmaHistograms()); if (!user_did_autofill_) { user_did_autofill_ = true; AutofillMetrics::LogUserHappinessMetric( - AutofillMetrics::USER_DID_AUTOFILL_ONCE, form_types); + AutofillMetrics::USER_DID_AUTOFILL_ONCE, form_types, + client_->GetSecurityLevelForUmaHistograms()); } UpdateInitialInteractionTimestamp(timestamp); @@ -809,14 +814,16 @@ return; if (has_autofill_suggestions) { - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::SUGGESTIONS_SHOWN, - autofill_field->Type().group()); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::SUGGESTIONS_SHOWN, autofill_field->Type().group(), + client_->GetSecurityLevelForUmaHistograms()); if (!did_show_suggestions_) { did_show_suggestions_ = true; AutofillMetrics::LogUserHappinessMetric( AutofillMetrics::SUGGESTIONS_SHOWN_ONCE, - autofill_field->Type().group()); + autofill_field->Type().group(), + client_->GetSecurityLevelForUmaHistograms()); } if (autofill_field->Type().group() == CREDIT_CARD) { @@ -1626,8 +1633,9 @@ } if (!queryable_forms.empty() || !non_queryable_forms.empty()) { - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED, - form_types); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::FORMS_LOADED, form_types, + client_->GetSecurityLevelForUmaHistograms()); #if defined(OS_IOS) // Log this from same location as AutofillMetrics::FORMS_LOADED to ensure @@ -1929,7 +1937,8 @@ // fields with non-empty values, such as select-one fields. field_data->is_autofilled = true; AutofillMetrics::LogUserHappinessMetric( - AutofillMetrics::FIELD_WAS_AUTOFILLED, autofill_field->Type().group()); + AutofillMetrics::FIELD_WAS_AUTOFILLED, autofill_field->Type().group(), + client_->GetSecurityLevelForUmaHistograms()); if (should_notify) { client_->DidFillOrPreviewField(
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc index a0af20f..6923a50 100644 --- a/components/autofill/core/browser/autofill_metrics.cc +++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -89,6 +89,31 @@ return static_cast<uint64_t>(field_signature) % 1021; } +std::string GetHistogramSuffixForSecurityLevel( + security_state::SecurityLevel level) { + switch (level) { + case security_state::EV_SECURE: + return "EV_SECURE"; + case security_state::SECURE: + return "SECURE"; + case security_state::NONE: + return "NONE"; + case security_state::HTTP_SHOW_WARNING: + return "HTTP_SHOW_WARNING"; + case security_state::SECURE_WITH_POLICY_INSTALLED_CERT: + return "SECURE_WITH_POLICY_INSTALLED_CERT"; + case security_state::DANGEROUS: + return "DANGEROUS"; + default: + return "OTHER"; + } +} + +std::string GetSecurityLevelHistogramName(const std::string prefix, + security_state::SecurityLevel level) { + return prefix + "." + GetHistogramSuffixForSecurityLevel(level); +} + } // namespace // First, translates |field_type| to the corresponding logical |group| from @@ -691,7 +716,8 @@ SaveCardPromptMetric metric, bool is_uploading, bool is_reshow, - int previous_save_credit_card_prompt_user_decision) { + int previous_save_credit_card_prompt_user_decision, + security_state::SecurityLevel security_level) { DCHECK_LT(metric, NUM_SAVE_CARD_PROMPT_METRICS); std::string destination = is_uploading ? ".Upload" : ".Local"; std::string show = is_reshow ? ".Reshows" : ".FirstShow"; @@ -703,6 +729,31 @@ PreviousSaveCreditCardPromptUserDecisionToString( previous_save_credit_card_prompt_user_decision), metric, NUM_SAVE_CARD_PROMPT_METRICS); + + LogSaveCardPromptMetricBySecurityLevel(metric, is_uploading, security_level); +} + +// static +void AutofillMetrics::LogSaveCardPromptMetricBySecurityLevel( + SaveCardPromptMetric metric, + bool is_uploading, + security_state::SecurityLevel security_level) { + // Getting a SECURITY_LEVEL_COUNT security level means that it was not + // possible to get the real security level. Don't log. + if (security_level == security_state::SecurityLevel::SECURITY_LEVEL_COUNT) { + return; + } + + std::string histogram_name = "Security.SaveCardPromptMetric."; + if (is_uploading) { + histogram_name += "Upload"; + } else { + histogram_name += "Local"; + } + + base::UmaHistogramEnumeration( + GetSecurityLevelHistogramName(histogram_name, security_level), metric, + NUM_SAVE_CARD_PROMPT_METRICS); } // static @@ -907,38 +958,83 @@ } // static -void AutofillMetrics::LogUserHappinessMetric(UserHappinessMetric metric, - FieldTypeGroup field_type_group) { +void AutofillMetrics::LogUserHappinessMetric( + UserHappinessMetric metric, + FieldTypeGroup field_type_group, + security_state::SecurityLevel security_level) { LogUserHappinessMetric( - metric, {FormTypes::FieldTypeGroupToFormType(field_type_group)}); + metric, {FormTypes::FieldTypeGroupToFormType(field_type_group)}, + security_level); } // static void AutofillMetrics::LogUserHappinessMetric( UserHappinessMetric metric, - const std::set<FormType>& form_types) { + const std::set<FormType>& form_types, + security_state::SecurityLevel security_level) { DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS); UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric, NUM_USER_HAPPINESS_METRICS); if (base::ContainsKey(form_types, CREDIT_CARD_FORM)) { UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.CreditCard", metric, NUM_USER_HAPPINESS_METRICS); + LogUserHappinessBySecurityLevel(metric, CREDIT_CARD_FORM, security_level); } if (base::ContainsKey(form_types, ADDRESS_FORM)) { UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.Address", metric, NUM_USER_HAPPINESS_METRICS); + LogUserHappinessBySecurityLevel(metric, ADDRESS_FORM, security_level); } if (base::ContainsKey(form_types, PASSWORD_FORM)) { UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.Password", metric, NUM_USER_HAPPINESS_METRICS); + LogUserHappinessBySecurityLevel(metric, PASSWORD_FORM, security_level); } if (base::ContainsKey(form_types, UNKNOWN_FORM_TYPE)) { UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.Unknown", metric, NUM_USER_HAPPINESS_METRICS); + LogUserHappinessBySecurityLevel(metric, UNKNOWN_FORM_TYPE, security_level); } } // static +void AutofillMetrics::LogUserHappinessBySecurityLevel( + UserHappinessMetric metric, + FormType form_type, + security_state::SecurityLevel security_level) { + if (security_level == security_state::SecurityLevel::SECURITY_LEVEL_COUNT) { + return; + } + + std::string histogram_name = "Security.UserHappiness."; + switch (form_type) { + case CREDIT_CARD_FORM: + histogram_name += "CreditCard"; + break; + + case ADDRESS_FORM: + histogram_name += "Address"; + break; + + case PASSWORD_FORM: + histogram_name += "Password"; + break; + + case UNKNOWN_FORM_TYPE: + histogram_name += "Unknown"; + break; + + default: + NOTREACHED(); + return; + } + + base::UmaHistogramEnumeration( + GetSecurityLevelHistogramName(histogram_name, security_level), metric, + NUM_USER_HAPPINESS_METRICS); +} + +// static void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill( const base::TimeDelta& duration) { LogFormFillDuration("Autofill.FillDuration.FromLoad.WithAutofill", duration);
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h index 807e81d1..4a9ac36 100644 --- a/components/autofill/core/browser/autofill_metrics.h +++ b/components/autofill/core/browser/autofill_metrics.h
@@ -21,6 +21,7 @@ #include "components/autofill/core/common/autofill_pref_names.h" #include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/signatures_util.h" +#include "components/security_state/core/security_state.h" #include "services/metrics/public/cpp/ukm_recorder.h" namespace autofill { @@ -768,7 +769,12 @@ SaveCardPromptMetric metric, bool is_uploading, bool is_reshow, - int previous_save_credit_card_prompt_user_decision); + int previous_save_credit_card_prompt_user_decision, + security_state::SecurityLevel security_level); + static void LogSaveCardPromptMetricBySecurityLevel( + SaveCardPromptMetric metric, + bool is_uploading, + security_state::SecurityLevel security_level); static void LogScanCreditCardPromptMetric(ScanCreditCardPromptMetric metric); // Should be called when credit card scan is finished. |duration| should be @@ -801,11 +807,20 @@ static void LogServerQueryMetric(ServerQueryMetric metric); - static void LogUserHappinessMetric(UserHappinessMetric metric, - FieldTypeGroup field_type_group); + static void LogUserHappinessMetric( + UserHappinessMetric metric, + FieldTypeGroup field_type_group, + security_state::SecurityLevel security_level); - static void LogUserHappinessMetric(UserHappinessMetric metric, - const std::set<FormType>& form_types); + static void LogUserHappinessMetric( + UserHappinessMetric metric, + const std::set<FormType>& form_types, + security_state::SecurityLevel security_level); + + static void LogUserHappinessBySecurityLevel( + UserHappinessMetric metric, + FormType form_type, + security_state::SecurityLevel security_level); // Logs |event| to the unmask prompt events histogram. static void LogUnmaskPromptEvent(UnmaskPromptEvent event);
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc index 1e2e4d3..6bd6f66a 100644 --- a/components/autofill/core/browser/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -211,6 +211,17 @@ public: MockAutofillClient() {} MOCK_METHOD1(ExecuteCommand, void(int)); + + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override { + return security_level_; + } + + void set_security_level(security_state::SecurityLevel security_level) { + security_level_ = security_level; + } + + private: + security_state::SecurityLevel security_level_; }; } // namespace @@ -5837,8 +5848,9 @@ TEST_F(AutofillMetricsTest, LogUserHappinessMetric_PasswordForm) { { base::HistogramTester histogram_tester; - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL, - PASSWORD_FIELD); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::USER_DID_AUTOFILL, PASSWORD_FIELD, + security_state::SecurityLevel::SECURITY_LEVEL_COUNT); histogram_tester.ExpectBucketCount("Autofill.UserHappiness", AutofillMetrics::USER_DID_AUTOFILL, 1); histogram_tester.ExpectBucketCount("Autofill.UserHappiness.Password", @@ -5850,8 +5862,9 @@ { base::HistogramTester histogram_tester; - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL, - USERNAME_FIELD); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::USER_DID_AUTOFILL, USERNAME_FIELD, + security_state::SecurityLevel::SECURITY_LEVEL_COUNT); histogram_tester.ExpectBucketCount("Autofill.UserHappiness", AutofillMetrics::USER_DID_AUTOFILL, 1); histogram_tester.ExpectBucketCount("Autofill.UserHappiness.Password", @@ -5865,8 +5878,9 @@ TEST_F(AutofillMetricsTest, LogUserHappinessMetric_UnknownForm) { { base::HistogramTester histogram_tester; - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL, - NO_GROUP); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::USER_DID_AUTOFILL, NO_GROUP, + security_state::SecurityLevel::SECURITY_LEVEL_COUNT); histogram_tester.ExpectBucketCount("Autofill.UserHappiness", AutofillMetrics::USER_DID_AUTOFILL, 1); histogram_tester.ExpectBucketCount("Autofill.UserHappiness.Unknown", @@ -5878,8 +5892,9 @@ { base::HistogramTester histogram_tester; - AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL, - TRANSACTION); + AutofillMetrics::LogUserHappinessMetric( + AutofillMetrics::USER_DID_AUTOFILL, TRANSACTION, + security_state::SecurityLevel::SECURITY_LEVEL_COUNT); histogram_tester.ExpectBucketCount("Autofill.UserHappiness", AutofillMetrics::USER_DID_AUTOFILL, 1); histogram_tester.ExpectBucketCount("Autofill.UserHappiness.Unknown", @@ -7330,4 +7345,190 @@ histogram_tester.ExpectTotalCount( "Autofill.SaveCardWithFirstAndLastNameComplete.Local", 2); } + +// Tests that the LogUserHappinessBySecurityLevel are recorded correctly. +TEST_F(AutofillMetricsTest, LogUserHappinessBySecurityLevel) { + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogUserHappinessBySecurityLevel( + AutofillMetrics::USER_DID_AUTOFILL, CREDIT_CARD_FORM, + security_state::SecurityLevel::SECURE); + histogram_tester.ExpectBucketCount( + "Security.UserHappiness.CreditCard.SECURE", + AutofillMetrics::USER_DID_AUTOFILL, 1); + } + + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogUserHappinessBySecurityLevel( + AutofillMetrics::SUGGESTIONS_SHOWN, ADDRESS_FORM, + security_state::SecurityLevel::DANGEROUS); + histogram_tester.ExpectBucketCount( + "Security.UserHappiness.Address.DANGEROUS", + AutofillMetrics::SUGGESTIONS_SHOWN, 1); + } + + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogUserHappinessBySecurityLevel( + AutofillMetrics::FIELD_WAS_AUTOFILLED, PASSWORD_FORM, + security_state::SecurityLevel::HTTP_SHOW_WARNING); + histogram_tester.ExpectBucketCount( + "Security.UserHappiness.Password.HTTP_SHOW_WARNING", + AutofillMetrics::FIELD_WAS_AUTOFILLED, 1); + } + + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogUserHappinessBySecurityLevel( + AutofillMetrics::USER_DID_AUTOFILL_ONCE, UNKNOWN_FORM_TYPE, + security_state::SecurityLevel::EV_SECURE); + histogram_tester.ExpectBucketCount( + "Security.UserHappiness.Unknown.EV_SECURE", + AutofillMetrics::USER_DID_AUTOFILL_ONCE, 1); + } + + { + // No metric should be recorded if the security level is + // SECURITY_LEVEL_COUNT. + base::HistogramTester histogram_tester; + AutofillMetrics::LogUserHappinessBySecurityLevel( + AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME, + CREDIT_CARD_FORM, security_state::SecurityLevel::SECURITY_LEVEL_COUNT); + histogram_tester.ExpectTotalCount("Security.UserHappiness.CreditCard.OTHER", + 0); + } +} + +// Verify that we correctly log LogUserHappinessBySecurityLevel dealing form the +// form event metrics. +TEST_F(AutofillMetricsTest, LogUserHappinessBySecurityLevel_FromFormEvents) { + // Load a fillable form. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin()); + + FormFieldData field; + test::CreateTestFormField("Name", "name", "", "text", &field); + form.fields.push_back(field); + test::CreateTestFormField("Email", "email", "", "text", &field); + form.fields.push_back(field); + test::CreateTestFormField("Phone", "phone", "", "text", &field); + form.fields.push_back(field); + + std::vector<FormData> forms(1, form); + + // Simulate seeing the form. + { + base::HistogramTester histogram_tester; + autofill_client_.set_security_level( + security_state::SecurityLevel::DANGEROUS); + autofill_manager_->OnFormsSeen(forms, TimeTicks()); + histogram_tester.ExpectBucketCount( + "Security.UserHappiness.Address.DANGEROUS", + AutofillMetrics::FORMS_LOADED, 1); + } + + // Simulate suggestions shown twice with separate popups. + { + base::HistogramTester histogram_tester; + autofill_client_.set_security_level( + security_state::SecurityLevel::HTTP_SHOW_WARNING); + autofill_manager_->DidShowSuggestions(true, form, field); + autofill_manager_->DidShowSuggestions(true, form, field); + histogram_tester.ExpectBucketCount( + "Security.UserHappiness.Address.HTTP_SHOW_WARNING", + AutofillMetrics::SUGGESTIONS_SHOWN, 2); + histogram_tester.ExpectBucketCount( + "Security.UserHappiness.Address.HTTP_SHOW_WARNING", + AutofillMetrics::SUGGESTIONS_SHOWN_ONCE, 1); + } +} + +// Tests that the LogSaveCardPromptMetricBySecurityLevel are recorded correctly. +TEST_F(AutofillMetricsTest, LogSaveCardPromptMetricBySecurityLevel) { + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogSaveCardPromptMetricBySecurityLevel( + AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, /*is_uploading=*/true, + security_state::SecurityLevel::SECURE); + histogram_tester.ExpectBucketCount( + "Security.SaveCardPromptMetric.Upload.SECURE", + AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1); + } + + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogSaveCardPromptMetricBySecurityLevel( + AutofillMetrics::SAVE_CARD_PROMPT_END_DENIED, /*is_uploading=*/false, + security_state::SecurityLevel::DANGEROUS); + histogram_tester.ExpectBucketCount( + "Security.SaveCardPromptMetric.Local.DANGEROUS", + AutofillMetrics::SAVE_CARD_PROMPT_END_DENIED, 1); + } + + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogSaveCardPromptMetricBySecurityLevel( + AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, /*is_uploading=*/true, + security_state::SecurityLevel::HTTP_SHOW_WARNING); + histogram_tester.ExpectBucketCount( + "Security.SaveCardPromptMetric.Upload.HTTP_SHOW_WARNING", + AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, 1); + } + + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogSaveCardPromptMetricBySecurityLevel( + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING, + /*is_uploading=*/false, security_state::SecurityLevel::EV_SECURE); + histogram_tester.ExpectBucketCount( + "Security.SaveCardPromptMetric.Local.EV_SECURE", + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING, 1); + } + + { + // No metric should be recorded if the security level is + // SECURITY_LEVEL_COUNT. + base::HistogramTester histogram_tester; + AutofillMetrics::LogSaveCardPromptMetricBySecurityLevel( + AutofillMetrics::SAVE_CARD_PROMPT_CVC_FIX_FLOW_SHOWN, + /*is_uploading=*/true, + security_state::SecurityLevel::SECURITY_LEVEL_COUNT); + histogram_tester.ExpectTotalCount( + "Security.SaveCardPromptMetric.Upload.OTHER", 0); + } +} + +// Verify that we correctly log LogSaveCardPromptMetricBySecurityLevel from the +// save card prompt metrics. +TEST_F(AutofillMetricsTest, + LogSaveCardPromptMetricBySecurityLevel_FromSaveCardPromptMetric) { + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogSaveCardPromptMetric( + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING, + /*is_uploading=*/true, /*is_reshow=*/false, + /*previous_save_credit_card_prompt_user_decision=*/1, + security_state::SecurityLevel::EV_SECURE); + histogram_tester.ExpectBucketCount( + "Security.SaveCardPromptMetric.Upload.EV_SECURE", + AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING, 1); + } + + { + base::HistogramTester histogram_tester; + AutofillMetrics::LogSaveCardPromptMetric( + AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, /*is_uploading=*/false, + /*is_reshow=*/true, + /*previous_save_credit_card_prompt_user_decision=*/0, + security_state::SecurityLevel::SECURE); + histogram_tester.ExpectBucketCount( + "Security.SaveCardPromptMetric.Local.SECURE", + AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1); + } +} + } // namespace autofill
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 98add90..1310a3c 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -42,6 +42,7 @@ #include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/form_field_data_predictions.h" #include "components/autofill/core/common/signatures_util.h" +#include "components/security_state/core/security_state.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "url/origin.h" @@ -791,7 +792,8 @@ auto* const field = this->field(i); if (IsUPIVirtualPaymentAddress(field->value)) { AutofillMetrics::LogUserHappinessMetric( - AutofillMetrics::USER_DID_ENTER_UPI_VPA, field->Type().group()); + AutofillMetrics::USER_DID_ENTER_UPI_VPA, field->Type().group(), + security_state::SecurityLevel::SECURITY_LEVEL_COUNT); } form_interactions_ukm_logger->LogFieldFillStatus(*this, *field,
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index 451be764..2063055 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -56,6 +56,11 @@ return nullptr; } +security_state::SecurityLevel +TestAutofillClient::GetSecurityLevelForUmaHistograms() { + return security_state::SecurityLevel::NONE; +} + void TestAutofillClient::ShowAutofillSettings() { }
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index 52e1561..19a23a6a 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -35,6 +35,7 @@ ukm::UkmRecorder* GetUkmRecorder() override; ukm::SourceId GetUkmSourceId() override; AddressNormalizer* GetAddressNormalizer() override; + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, UnmaskCardReason reason,
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index c131545c..e649908 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -706,24 +706,13 @@ return true; } -bool AutofillTable::AddFormFieldValuesTime( - const std::vector<FormFieldData>& elements, - std::vector<AutofillChange>* changes, - base::Time time) { - // Only add one new entry for each unique element name. Use |seen_names| to - // track this. Add up to |kMaximumUniqueNames| unique entries per form. - const size_t kMaximumUniqueNames = 256; - std::set<base::string16> seen_names; - bool result = true; - for (const FormFieldData& element : elements) { - if (seen_names.size() >= kMaximumUniqueNames) - break; - if (base::ContainsKey(seen_names, element.name)) - continue; - result = result && AddFormFieldValueTime(element, changes, time); - seen_names.insert(element.name); - } - return result; +bool AutofillTable::RemoveFormElement(const base::string16& name, + const base::string16& value) { + sql::Statement s(db_->GetUniqueStatement( + "DELETE FROM autofill WHERE name = ? AND value= ?")); + s.BindString16(0, name); + s.BindString16(1, value); + return s.Run(); } int AutofillTable::GetCountOfValuesContainedBetween(const base::Time& begin, @@ -807,77 +796,6 @@ return true; } -bool AutofillTable::InsertAutofillEntry(const AutofillEntry& entry) { - std::string sql = - "INSERT INTO autofill " - "(name, value, value_lower, date_created, date_last_used, count) " - "VALUES (?, ?, ?, ?, ?, ?)"; - sql::Statement s(db_->GetUniqueStatement(sql.c_str())); - s.BindString16(0, entry.key().name()); - s.BindString16(1, entry.key().value()); - s.BindString16(2, base::i18n::ToLower(entry.key().value())); - s.BindInt64(3, entry.date_created().ToTimeT()); - s.BindInt64(4, entry.date_last_used().ToTimeT()); - // TODO(isherman): The counts column is currently synced implicitly as the - // number of timestamps. Sync the value explicitly instead, since the DB now - // only saves the first and last timestamp, which makes counting timestamps - // completely meaningless as a way to track frequency of usage. - s.BindInt(5, entry.date_last_used() == entry.date_created() ? 1 : 2); - return s.Run(); -} - -bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element, - std::vector<AutofillChange>* changes, - base::Time time) { - sql::Statement s_exists(db_->GetUniqueStatement( - "SELECT COUNT(*) FROM autofill WHERE name = ? AND value = ?")); - s_exists.BindString16(0, element.name); - s_exists.BindString16(1, element.value); - if (!s_exists.Step()) - return false; - - bool already_exists = s_exists.ColumnInt(0) > 0; - if (already_exists) { - sql::Statement s(db_->GetUniqueStatement( - "UPDATE autofill SET date_last_used = ?, count = count + 1 " - "WHERE name = ? AND value = ?")); - s.BindInt64(0, time.ToTimeT()); - s.BindString16(1, element.name); - s.BindString16(2, element.value); - if (!s.Run()) - return false; - } else { - time_t time_as_time_t = time.ToTimeT(); - sql::Statement s(db_->GetUniqueStatement( - "INSERT INTO autofill " - "(name, value, value_lower, date_created, date_last_used, count) " - "VALUES (?, ?, ?, ?, ?, ?)")); - s.BindString16(0, element.name); - s.BindString16(1, element.value); - s.BindString16(2, base::i18n::ToLower(element.value)); - s.BindInt64(3, time_as_time_t); - s.BindInt64(4, time_as_time_t); - s.BindInt(5, 1); - if (!s.Run()) - return false; - } - - AutofillChange::Type change_type = - already_exists ? AutofillChange::UPDATE : AutofillChange::ADD; - changes->push_back( - AutofillChange(change_type, AutofillKey(element.name, element.value))); - return true; -} - -bool AutofillTable::RemoveFormElement(const base::string16& name, - const base::string16& value) { - sql::Statement s(db_->GetUniqueStatement( - "DELETE FROM autofill WHERE name = ? AND value= ?")); - s.BindString16(0, name); - s.BindString16(1, value); - return s.Run(); -} - bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) { if (IsAutofillGUIDInTrash(profile.guid())) return true; @@ -896,6 +814,70 @@ return AddAutofillProfilePieces(profile, db_); } +bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) { + DCHECK(base::IsValidGUID(profile.guid())); + + // Don't update anything until the trash has been emptied. There may be + // pending modifications to process. + if (!IsAutofillProfilesTrashEmpty()) + return true; + + std::unique_ptr<AutofillProfile> old_profile = + GetAutofillProfile(profile.guid()); + if (!old_profile) + return false; + + bool update_modification_date = *old_profile != profile; + + sql::Statement s(db_->GetUniqueStatement( + "UPDATE autofill_profiles " + "SET guid=?, company_name=?, street_address=?, dependent_locality=?, " + " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, " + " use_count=?, use_date=?, date_modified=?, origin=?, " + " language_code=?, validity_bitfield=? " + "WHERE guid=?")); + BindAutofillProfileToStatement(profile, + update_modification_date + ? AutofillClock::Now() + : old_profile->modification_date(), + &s); + s.BindString(15, profile.guid()); + + bool result = s.Run(); + DCHECK_GT(db_->GetLastChangeCount(), 0); + if (!result) + return result; + + // Remove the old names, emails, and phone numbers. + if (!RemoveAutofillProfilePieces(profile.guid(), db_)) + return false; + + return AddAutofillProfilePieces(profile, db_); +} + +bool AutofillTable::RemoveAutofillProfile(const std::string& guid) { + DCHECK(base::IsValidGUID(guid)); + + if (IsAutofillGUIDInTrash(guid)) { + sql::Statement s_trash(db_->GetUniqueStatement( + "DELETE FROM autofill_profiles_trash WHERE guid = ?")); + s_trash.BindString(0, guid); + + bool success = s_trash.Run(); + DCHECK_GT(db_->GetLastChangeCount(), 0) << "Expected item in trash"; + return success; + } + + sql::Statement s( + db_->GetUniqueStatement("DELETE FROM autofill_profiles WHERE guid = ?")); + s.BindString(0, guid); + + if (!s.Run()) + return false; + + return RemoveAutofillProfilePieces(guid, db_); +} + std::unique_ptr<AutofillProfile> AutofillTable::GetAutofillProfile( const std::string& guid) { DCHECK(base::IsValidGUID(guid)); @@ -1071,99 +1053,6 @@ transaction.Commit(); } -bool AutofillTable::UpdateAutofillProfile(const AutofillProfile& profile) { - DCHECK(base::IsValidGUID(profile.guid())); - - // Don't update anything until the trash has been emptied. There may be - // pending modifications to process. - if (!IsAutofillProfilesTrashEmpty()) - return true; - - std::unique_ptr<AutofillProfile> old_profile = - GetAutofillProfile(profile.guid()); - if (!old_profile) - return false; - - bool update_modification_date = *old_profile != profile; - - sql::Statement s(db_->GetUniqueStatement( - "UPDATE autofill_profiles " - "SET guid=?, company_name=?, street_address=?, dependent_locality=?, " - " city=?, state=?, zipcode=?, sorting_code=?, country_code=?, " - " use_count=?, use_date=?, date_modified=?, origin=?, " - " language_code=?, validity_bitfield=? " - "WHERE guid=?")); - BindAutofillProfileToStatement(profile, - update_modification_date - ? AutofillClock::Now() - : old_profile->modification_date(), - &s); - s.BindString(15, profile.guid()); - - bool result = s.Run(); - DCHECK_GT(db_->GetLastChangeCount(), 0); - if (!result) - return result; - - // Remove the old names, emails, and phone numbers. - if (!RemoveAutofillProfilePieces(profile.guid(), db_)) - return false; - - return AddAutofillProfilePieces(profile, db_); -} - -bool AutofillTable::RemoveAutofillProfile(const std::string& guid) { - DCHECK(base::IsValidGUID(guid)); - - if (IsAutofillGUIDInTrash(guid)) { - sql::Statement s_trash(db_->GetUniqueStatement( - "DELETE FROM autofill_profiles_trash WHERE guid = ?")); - s_trash.BindString(0, guid); - - bool success = s_trash.Run(); - DCHECK_GT(db_->GetLastChangeCount(), 0) << "Expected item in trash"; - return success; - } - - sql::Statement s( - db_->GetUniqueStatement("DELETE FROM autofill_profiles WHERE guid = ?")); - s.BindString(0, guid); - - if (!s.Run()) - return false; - - return RemoveAutofillProfilePieces(guid, db_); -} - -bool AutofillTable::ClearAutofillProfiles() { - sql::Statement s1(db_->GetUniqueStatement("DELETE FROM autofill_profiles")); - - if (!s1.Run()) - return false; - - sql::Statement s2( - db_->GetUniqueStatement("DELETE FROM autofill_profile_names")); - - if (!s2.Run()) - return false; - - sql::Statement s3( - db_->GetUniqueStatement("DELETE FROM autofill_profile_emails")); - - if (!s3.Run()) - return false; - - sql::Statement s4( - db_->GetUniqueStatement("DELETE FROM autofill_profile_phones")); - - return s4.Run(); -} - -bool AutofillTable::ClearCreditCards() { - sql::Statement s1(db_->GetUniqueStatement("DELETE FROM credit_cards")); - return s1.Run(); -} - bool AutofillTable::AddCreditCard(const CreditCard& credit_card) { sql::Statement s(db_->GetUniqueStatement( "INSERT INTO credit_cards" @@ -1181,6 +1070,69 @@ return true; } +bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) { + DCHECK(base::IsValidGUID(credit_card.guid())); + + std::unique_ptr<CreditCard> old_credit_card = + GetCreditCard(credit_card.guid()); + if (!old_credit_card) + return false; + + bool update_modification_date = *old_credit_card != credit_card; + + sql::Statement s(db_->GetUniqueStatement( + "UPDATE credit_cards " + "SET guid=?, name_on_card=?, expiration_month=?," + "expiration_year=?, card_number_encrypted=?, use_count=?, use_date=?," + "date_modified=?, origin=?, billing_address_id=?" + "WHERE guid=?1")); + BindCreditCardToStatement(credit_card, + update_modification_date + ? AutofillClock::Now() + : old_credit_card->modification_date(), + &s, *autofill_table_encryptor_); + + bool result = s.Run(); + DCHECK_GT(db_->GetLastChangeCount(), 0); + return result; +} + +bool AutofillTable::RemoveCreditCard(const std::string& guid) { + DCHECK(base::IsValidGUID(guid)); + sql::Statement s( + db_->GetUniqueStatement("DELETE FROM credit_cards WHERE guid = ?")); + s.BindString(0, guid); + + return s.Run(); +} + +bool AutofillTable::AddFullServerCreditCard(const CreditCard& credit_card) { + DCHECK_EQ(CreditCard::FULL_SERVER_CARD, credit_card.record_type()); + DCHECK(!credit_card.number().empty()); + DCHECK(!credit_card.server_id().empty()); + + sql::Transaction transaction(db_); + if (!transaction.Begin()) + return false; + + // Make sure there aren't duplicates for this card. + DeleteFromUnmaskedCreditCards(credit_card.server_id()); + DeleteFromMaskedCreditCards(credit_card.server_id()); + + CreditCard masked(credit_card); + masked.set_record_type(CreditCard::MASKED_SERVER_CARD); + masked.SetNumber(credit_card.LastFourDigits()); + masked.RecordAndLogUse(); + DCHECK(!masked.network().empty()); + AddMaskedCreditCards({masked}); + + AddUnmaskedCreditCard(credit_card.server_id(), credit_card.number()); + + transaction.Commit(); + + return db_->GetLastChangeCount() > 0; +} + std::unique_ptr<CreditCard> AutofillTable::GetCreditCard( const std::string& guid) { DCHECK(base::IsValidGUID(guid)); @@ -1289,42 +1241,6 @@ return s.Succeeded(); } -void AutofillTable::AddMaskedCreditCards( - const std::vector<CreditCard>& credit_cards) { - DCHECK_GT(db_->transaction_nesting(), 0); - sql::Statement masked_insert( - db_->GetUniqueStatement("INSERT INTO masked_credit_cards(" - "id," // 0 - "network," // 1 - "type," // 2 - "status," // 3 - "name_on_card," // 4 - "last_four," // 5 - "exp_month," // 6 - "exp_year," // 7 - "bank_name)" // 8 - "VALUES (?,?,?,?,?,?,?,?,?)")); - for (const CreditCard& card : credit_cards) { - DCHECK_EQ(CreditCard::MASKED_SERVER_CARD, card.record_type()); - masked_insert.BindString(0, card.server_id()); - masked_insert.BindString(1, card.network()); - masked_insert.BindInt(2, card.card_type()); - masked_insert.BindString(3, - ServerStatusEnumToString(card.GetServerStatus())); - masked_insert.BindString16(4, card.GetRawInfo(CREDIT_CARD_NAME_FULL)); - masked_insert.BindString16(5, card.LastFourDigits()); - masked_insert.BindString16(6, card.GetRawInfo(CREDIT_CARD_EXP_MONTH)); - masked_insert.BindString16(7, - card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); - masked_insert.BindString(8, card.bank_name()); - masked_insert.Run(); - masked_insert.Reset(true); - - // Save the use count and use date of the card. - UpdateServerCardMetadata(card); - } -} - void AutofillTable::SetServerCreditCards( const std::vector<CreditCard>& credit_cards) { sql::Transaction transaction(db_); @@ -1352,52 +1268,6 @@ transaction.Commit(); } -bool AutofillTable::AddFullServerCreditCard(const CreditCard& credit_card) { - DCHECK_EQ(CreditCard::FULL_SERVER_CARD, credit_card.record_type()); - DCHECK(!credit_card.number().empty()); - DCHECK(!credit_card.server_id().empty()); - - sql::Transaction transaction(db_); - if (!transaction.Begin()) - return false; - - // Make sure there aren't duplicates for this card. - DeleteFromUnmaskedCreditCards(credit_card.server_id()); - DeleteFromMaskedCreditCards(credit_card.server_id()); - - CreditCard masked(credit_card); - masked.set_record_type(CreditCard::MASKED_SERVER_CARD); - masked.SetNumber(credit_card.LastFourDigits()); - masked.RecordAndLogUse(); - DCHECK(!masked.network().empty()); - AddMaskedCreditCards({masked}); - - AddUnmaskedCreditCard(credit_card.server_id(), credit_card.number()); - - transaction.Commit(); - - return db_->GetLastChangeCount() > 0; -} - -void AutofillTable::AddUnmaskedCreditCard(const std::string& id, - const base::string16& full_number) { - sql::Statement s( - db_->GetUniqueStatement("INSERT INTO unmasked_credit_cards(" - "id," - "card_number_encrypted," - "unmask_date)" - "VALUES (?,?,?)")); - s.BindString(0, id); - - std::string encrypted_data; - autofill_table_encryptor_->EncryptString16(full_number, &encrypted_data); - s.BindBlob(1, encrypted_data.data(), - static_cast<int>(encrypted_data.length())); - s.BindInt64(2, AutofillClock::Now().ToInternalValue()); // unmask_date - - s.Run(); -} - bool AutofillTable::UnmaskServerCreditCard(const CreditCard& masked, const base::string16& full_number) { sql::Transaction transaction(db_); @@ -1420,22 +1290,6 @@ return db_->GetLastChangeCount() > 0; } -bool AutofillTable::DeleteFromMaskedCreditCards(const std::string& id) { - sql::Statement s( - db_->GetUniqueStatement("DELETE FROM masked_credit_cards WHERE id = ?")); - s.BindString(0, id); - s.Run(); - return db_->GetLastChangeCount() > 0; -} - -bool AutofillTable::DeleteFromUnmaskedCreditCards(const std::string& id) { - sql::Statement s(db_->GetUniqueStatement( - "DELETE FROM unmasked_credit_cards WHERE id = ?")); - s.BindString(0, id); - s.Run(); - return db_->GetLastChangeCount() > 0; -} - bool AutofillTable::MaskServerCreditCard(const std::string& id) { return DeleteFromUnmaskedCreditCards(id); } @@ -1539,42 +1393,6 @@ return changed; } -bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) { - DCHECK(base::IsValidGUID(credit_card.guid())); - - std::unique_ptr<CreditCard> old_credit_card = - GetCreditCard(credit_card.guid()); - if (!old_credit_card) - return false; - - bool update_modification_date = *old_credit_card != credit_card; - - sql::Statement s(db_->GetUniqueStatement( - "UPDATE credit_cards " - "SET guid=?, name_on_card=?, expiration_month=?," - "expiration_year=?, card_number_encrypted=?, use_count=?, use_date=?," - "date_modified=?, origin=?, billing_address_id=?" - "WHERE guid=?1")); - BindCreditCardToStatement(credit_card, - update_modification_date - ? AutofillClock::Now() - : old_credit_card->modification_date(), - &s, *autofill_table_encryptor_); - - bool result = s.Run(); - DCHECK_GT(db_->GetLastChangeCount(), 0); - return result; -} - -bool AutofillTable::RemoveCreditCard(const std::string& guid) { - DCHECK(base::IsValidGUID(guid)); - sql::Statement s( - db_->GetUniqueStatement("DELETE FROM credit_cards WHERE guid = ?")); - s.BindString(0, guid); - - return s.Run(); -} - bool AutofillTable::RemoveAutofillDataModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end, @@ -1749,29 +1567,33 @@ return s.Run(); } -bool AutofillTable::IsAutofillProfilesTrashEmpty() { - sql::Statement s( - db_->GetUniqueStatement("SELECT guid FROM autofill_profiles_trash")); +bool AutofillTable::ClearAutofillProfiles() { + sql::Statement s1(db_->GetUniqueStatement("DELETE FROM autofill_profiles")); - return !s.Step(); + if (!s1.Run()) + return false; + + sql::Statement s2( + db_->GetUniqueStatement("DELETE FROM autofill_profile_names")); + + if (!s2.Run()) + return false; + + sql::Statement s3( + db_->GetUniqueStatement("DELETE FROM autofill_profile_emails")); + + if (!s3.Run()) + return false; + + sql::Statement s4( + db_->GetUniqueStatement("DELETE FROM autofill_profile_phones")); + + return s4.Run(); } -bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) { - sql::Statement s(db_->GetUniqueStatement( - "SELECT guid FROM autofill_profiles_trash WHERE guid = ?")); - s.BindString(0, guid); - - return s.Step(); -} - -bool AutofillTable::SupportsMetadataForModelType( - syncer::ModelType model_type) const { - return (model_type == syncer::AUTOFILL || - model_type == syncer::AUTOFILL_PROFILE); -} - -int AutofillTable::GetKeyValueForModelType(syncer::ModelType model_type) const { - return syncer::ModelTypeToStableIdentifier(model_type); +bool AutofillTable::ClearCreditCards() { + sql::Statement s1(db_->GetUniqueStatement("DELETE FROM credit_cards")); + return s1.Run(); } bool AutofillTable::GetAllSyncMetadata(syncer::ModelType model_type, @@ -1791,33 +1613,6 @@ return true; } -bool AutofillTable::GetAllSyncEntityMetadata( - syncer::ModelType model_type, - syncer::MetadataBatch* metadata_batch) { - DCHECK(SupportsMetadataForModelType(model_type)) - << "Model type " << model_type << " not supported for metadata"; - DCHECK(metadata_batch); - - sql::Statement s( - db_->GetUniqueStatement("SELECT storage_key, value FROM " - "autofill_sync_metadata WHERE model_type=?")); - s.BindInt(0, GetKeyValueForModelType(model_type)); - - while (s.Step()) { - std::string storage_key = s.ColumnString(0); - std::string serialized_metadata = s.ColumnString(1); - sync_pb::EntityMetadata entity_metadata; - if (entity_metadata.ParseFromString(serialized_metadata)) { - metadata_batch->AddMetadata(storage_key, entity_metadata); - } else { - DLOG(WARNING) << "Failed to deserialize AUTOFILL model type " - "sync_pb::EntityMetadata."; - return false; - } - } - return true; -} - bool AutofillTable::UpdateSyncMetadata( syncer::ModelType model_type, const std::string& storage_key, @@ -1849,23 +1644,6 @@ return s.Run(); } -bool AutofillTable::GetModelTypeState(syncer::ModelType model_type, - sync_pb::ModelTypeState* state) { - DCHECK(SupportsMetadataForModelType(model_type)) - << "Model type " << model_type << " not supported for metadata"; - - sql::Statement s(db_->GetUniqueStatement( - "SELECT value FROM autofill_model_type_state WHERE model_type=?")); - s.BindInt(0, GetKeyValueForModelType(model_type)); - - if (!s.Step()) { - return true; - } - - std::string serialized_state = s.ColumnString(0); - return state->ParseFromString(serialized_state); -} - bool AutofillTable::UpdateModelTypeState( syncer::ModelType model_type, const sync_pb::ModelTypeState& model_type_state) { @@ -1919,234 +1697,6 @@ return true; } -bool AutofillTable::InitMainTable() { - if (!db_->DoesTableExist("autofill")) { - if (!db_->Execute("CREATE TABLE autofill (" - "name VARCHAR, " - "value VARCHAR, " - "value_lower VARCHAR, " - "date_created INTEGER DEFAULT 0, " - "date_last_used INTEGER DEFAULT 0, " - "count INTEGER DEFAULT 1, " - "PRIMARY KEY (name, value))") || - !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") || - !db_->Execute("CREATE INDEX autofill_name_value_lower ON " - "autofill (name, value_lower)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitCreditCardsTable() { - if (!db_->DoesTableExist("credit_cards")) { - if (!db_->Execute("CREATE TABLE credit_cards ( " - "guid VARCHAR PRIMARY KEY, " - "name_on_card VARCHAR, " - "expiration_month INTEGER, " - "expiration_year INTEGER, " - "card_number_encrypted BLOB, " - "date_modified INTEGER NOT NULL DEFAULT 0, " - "origin VARCHAR DEFAULT '', " - "use_count INTEGER NOT NULL DEFAULT 0, " - "use_date INTEGER NOT NULL DEFAULT 0, " - "billing_address_id VARCHAR) ")) { - NOTREACHED(); - return false; - } - } - - return true; -} - -bool AutofillTable::InitProfilesTable() { - if (!db_->DoesTableExist("autofill_profiles")) { - if (!db_->Execute("CREATE TABLE autofill_profiles ( " - "guid VARCHAR PRIMARY KEY, " - "company_name VARCHAR, " - "street_address VARCHAR, " - "dependent_locality VARCHAR, " - "city VARCHAR, " - "state VARCHAR, " - "zipcode VARCHAR, " - "sorting_code VARCHAR, " - "country_code VARCHAR, " - "date_modified INTEGER NOT NULL DEFAULT 0, " - "origin VARCHAR DEFAULT '', " - "language_code VARCHAR, " - "use_count INTEGER NOT NULL DEFAULT 0, " - "use_date INTEGER NOT NULL DEFAULT 0, " - "validity_bitfield UNSIGNED NOT NULL DEFAULT 0) ")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitProfileNamesTable() { - if (!db_->DoesTableExist("autofill_profile_names")) { - if (!db_->Execute("CREATE TABLE autofill_profile_names ( " - "guid VARCHAR, " - "first_name VARCHAR, " - "middle_name VARCHAR, " - "last_name VARCHAR, " - "full_name VARCHAR)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitProfileEmailsTable() { - if (!db_->DoesTableExist("autofill_profile_emails")) { - if (!db_->Execute("CREATE TABLE autofill_profile_emails ( " - "guid VARCHAR, " - "email VARCHAR)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitProfilePhonesTable() { - if (!db_->DoesTableExist("autofill_profile_phones")) { - if (!db_->Execute("CREATE TABLE autofill_profile_phones ( " - "guid VARCHAR, " - "number VARCHAR)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitProfileTrashTable() { - if (!db_->DoesTableExist("autofill_profiles_trash")) { - if (!db_->Execute("CREATE TABLE autofill_profiles_trash ( " - "guid VARCHAR)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitMaskedCreditCardsTable() { - if (!db_->DoesTableExist("masked_credit_cards")) { - if (!db_->Execute("CREATE TABLE masked_credit_cards (" - "id VARCHAR," - "status VARCHAR," - "name_on_card VARCHAR," - "network VARCHAR," - "last_four VARCHAR," - "exp_month INTEGER DEFAULT 0," - "exp_year INTEGER DEFAULT 0, " - "bank_name VARCHAR, " - "type INTEGER DEFAULT 0)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitUnmaskedCreditCardsTable() { - if (!db_->DoesTableExist("unmasked_credit_cards")) { - if (!db_->Execute("CREATE TABLE unmasked_credit_cards (" - "id VARCHAR," - "card_number_encrypted VARCHAR, " - "use_count INTEGER NOT NULL DEFAULT 0, " - "use_date INTEGER NOT NULL DEFAULT 0, " - "unmask_date INTEGER NOT NULL DEFAULT 0)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitServerCardMetadataTable() { - if (!db_->DoesTableExist("server_card_metadata")) { - if (!db_->Execute("CREATE TABLE server_card_metadata (" - "id VARCHAR NOT NULL," - "use_count INTEGER NOT NULL DEFAULT 0, " - "use_date INTEGER NOT NULL DEFAULT 0, " - "billing_address_id VARCHAR)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitServerAddressesTable() { - if (!db_->DoesTableExist("server_addresses")) { - // The space after language_code is necessary to match what sqlite does - // when it appends the column in migration. - if (!db_->Execute("CREATE TABLE server_addresses (" - "id VARCHAR," - "company_name VARCHAR," - "street_address VARCHAR," - "address_1 VARCHAR," - "address_2 VARCHAR," - "address_3 VARCHAR," - "address_4 VARCHAR," - "postal_code VARCHAR," - "sorting_code VARCHAR," - "country_code VARCHAR," - "language_code VARCHAR, " // Space required. - "recipient_name VARCHAR, " // Ditto. - "phone_number VARCHAR)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitServerAddressMetadataTable() { - if (!db_->DoesTableExist("server_address_metadata")) { - if (!db_->Execute("CREATE TABLE server_address_metadata (" - "id VARCHAR NOT NULL," - "use_count INTEGER NOT NULL DEFAULT 0, " - "use_date INTEGER NOT NULL DEFAULT 0, " - "has_converted BOOL NOT NULL DEFAULT FALSE)")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitAutofillSyncMetadataTable() { - if (!db_->DoesTableExist("autofill_sync_metadata")) { - if (!db_->Execute("CREATE TABLE autofill_sync_metadata (" - "model_type INTEGER NOT NULL, " - "storage_key VARCHAR NOT NULL, " - "value BLOB, " - "PRIMARY KEY (model_type, storage_key))")) { - NOTREACHED(); - return false; - } - } - return true; -} - -bool AutofillTable::InitModelTypeStateTable() { - if (!db_->DoesTableExist("autofill_model_type_state")) { - if (!db_->Execute("CREATE TABLE autofill_model_type_state (" - "model_type INTEGER NOT NULL PRIMARY KEY, value BLOB)")) { - NOTREACHED(); - return false; - } - } - return true; -} - bool AutofillTable::MigrateToVersion54AddI18nFieldsAndRemoveDeprecatedFields() { sql::Transaction transaction(db_); if (!transaction.Begin()) @@ -2777,4 +2327,454 @@ transaction.Commit(); } +bool AutofillTable::AddFormFieldValuesTime( + const std::vector<FormFieldData>& elements, + std::vector<AutofillChange>* changes, + base::Time time) { + // Only add one new entry for each unique element name. Use |seen_names| to + // track this. Add up to |kMaximumUniqueNames| unique entries per form. + const size_t kMaximumUniqueNames = 256; + std::set<base::string16> seen_names; + bool result = true; + for (const FormFieldData& element : elements) { + if (seen_names.size() >= kMaximumUniqueNames) + break; + if (base::ContainsKey(seen_names, element.name)) + continue; + result = result && AddFormFieldValueTime(element, changes, time); + seen_names.insert(element.name); + } + return result; +} + +bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element, + std::vector<AutofillChange>* changes, + base::Time time) { + sql::Statement s_exists(db_->GetUniqueStatement( + "SELECT COUNT(*) FROM autofill WHERE name = ? AND value = ?")); + s_exists.BindString16(0, element.name); + s_exists.BindString16(1, element.value); + if (!s_exists.Step()) + return false; + + bool already_exists = s_exists.ColumnInt(0) > 0; + if (already_exists) { + sql::Statement s(db_->GetUniqueStatement( + "UPDATE autofill SET date_last_used = ?, count = count + 1 " + "WHERE name = ? AND value = ?")); + s.BindInt64(0, time.ToTimeT()); + s.BindString16(1, element.name); + s.BindString16(2, element.value); + if (!s.Run()) + return false; + } else { + time_t time_as_time_t = time.ToTimeT(); + sql::Statement s(db_->GetUniqueStatement( + "INSERT INTO autofill " + "(name, value, value_lower, date_created, date_last_used, count) " + "VALUES (?, ?, ?, ?, ?, ?)")); + s.BindString16(0, element.name); + s.BindString16(1, element.value); + s.BindString16(2, base::i18n::ToLower(element.value)); + s.BindInt64(3, time_as_time_t); + s.BindInt64(4, time_as_time_t); + s.BindInt(5, 1); + if (!s.Run()) + return false; + } + + AutofillChange::Type change_type = + already_exists ? AutofillChange::UPDATE : AutofillChange::ADD; + changes->push_back( + AutofillChange(change_type, AutofillKey(element.name, element.value))); + return true; +} + +bool AutofillTable::SupportsMetadataForModelType( + syncer::ModelType model_type) const { + return (model_type == syncer::AUTOFILL || + model_type == syncer::AUTOFILL_PROFILE); +} + +int AutofillTable::GetKeyValueForModelType(syncer::ModelType model_type) const { + return syncer::ModelTypeToStableIdentifier(model_type); +} + +bool AutofillTable::GetAllSyncEntityMetadata( + syncer::ModelType model_type, + syncer::MetadataBatch* metadata_batch) { + DCHECK(SupportsMetadataForModelType(model_type)) + << "Model type " << model_type << " not supported for metadata"; + DCHECK(metadata_batch); + + sql::Statement s( + db_->GetUniqueStatement("SELECT storage_key, value FROM " + "autofill_sync_metadata WHERE model_type=?")); + s.BindInt(0, GetKeyValueForModelType(model_type)); + + while (s.Step()) { + std::string storage_key = s.ColumnString(0); + std::string serialized_metadata = s.ColumnString(1); + sync_pb::EntityMetadata entity_metadata; + if (entity_metadata.ParseFromString(serialized_metadata)) { + metadata_batch->AddMetadata(storage_key, entity_metadata); + } else { + DLOG(WARNING) << "Failed to deserialize AUTOFILL model type " + "sync_pb::EntityMetadata."; + return false; + } + } + return true; +} + +bool AutofillTable::GetModelTypeState(syncer::ModelType model_type, + sync_pb::ModelTypeState* state) { + DCHECK(SupportsMetadataForModelType(model_type)) + << "Model type " << model_type << " not supported for metadata"; + + sql::Statement s(db_->GetUniqueStatement( + "SELECT value FROM autofill_model_type_state WHERE model_type=?")); + s.BindInt(0, GetKeyValueForModelType(model_type)); + + if (!s.Step()) { + return true; + } + + std::string serialized_state = s.ColumnString(0); + return state->ParseFromString(serialized_state); +} + +bool AutofillTable::InsertAutofillEntry(const AutofillEntry& entry) { + std::string sql = + "INSERT INTO autofill " + "(name, value, value_lower, date_created, date_last_used, count) " + "VALUES (?, ?, ?, ?, ?, ?)"; + sql::Statement s(db_->GetUniqueStatement(sql.c_str())); + s.BindString16(0, entry.key().name()); + s.BindString16(1, entry.key().value()); + s.BindString16(2, base::i18n::ToLower(entry.key().value())); + s.BindInt64(3, entry.date_created().ToTimeT()); + s.BindInt64(4, entry.date_last_used().ToTimeT()); + // TODO(isherman): The counts column is currently synced implicitly as the + // number of timestamps. Sync the value explicitly instead, since the DB now + // only saves the first and last timestamp, which makes counting timestamps + // completely meaningless as a way to track frequency of usage. + s.BindInt(5, entry.date_last_used() == entry.date_created() ? 1 : 2); + return s.Run(); +} + +bool AutofillTable::IsAutofillProfilesTrashEmpty() { + sql::Statement s( + db_->GetUniqueStatement("SELECT guid FROM autofill_profiles_trash")); + + return !s.Step(); +} + +bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) { + sql::Statement s(db_->GetUniqueStatement( + "SELECT guid FROM autofill_profiles_trash WHERE guid = ?")); + s.BindString(0, guid); + + return s.Step(); +} + +void AutofillTable::AddMaskedCreditCards( + const std::vector<CreditCard>& credit_cards) { + DCHECK_GT(db_->transaction_nesting(), 0); + sql::Statement masked_insert( + db_->GetUniqueStatement("INSERT INTO masked_credit_cards(" + "id," // 0 + "network," // 1 + "type," // 2 + "status," // 3 + "name_on_card," // 4 + "last_four," // 5 + "exp_month," // 6 + "exp_year," // 7 + "bank_name)" // 8 + "VALUES (?,?,?,?,?,?,?,?,?)")); + for (const CreditCard& card : credit_cards) { + DCHECK_EQ(CreditCard::MASKED_SERVER_CARD, card.record_type()); + masked_insert.BindString(0, card.server_id()); + masked_insert.BindString(1, card.network()); + masked_insert.BindInt(2, card.card_type()); + masked_insert.BindString(3, + ServerStatusEnumToString(card.GetServerStatus())); + masked_insert.BindString16(4, card.GetRawInfo(CREDIT_CARD_NAME_FULL)); + masked_insert.BindString16(5, card.LastFourDigits()); + masked_insert.BindString16(6, card.GetRawInfo(CREDIT_CARD_EXP_MONTH)); + masked_insert.BindString16(7, + card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); + masked_insert.BindString(8, card.bank_name()); + masked_insert.Run(); + masked_insert.Reset(true); + + // Save the use count and use date of the card. + UpdateServerCardMetadata(card); + } +} + +void AutofillTable::AddUnmaskedCreditCard(const std::string& id, + const base::string16& full_number) { + sql::Statement s( + db_->GetUniqueStatement("INSERT INTO unmasked_credit_cards(" + "id," + "card_number_encrypted," + "unmask_date)" + "VALUES (?,?,?)")); + s.BindString(0, id); + + std::string encrypted_data; + autofill_table_encryptor_->EncryptString16(full_number, &encrypted_data); + s.BindBlob(1, encrypted_data.data(), + static_cast<int>(encrypted_data.length())); + s.BindInt64(2, AutofillClock::Now().ToInternalValue()); // unmask_date + + s.Run(); +} + +bool AutofillTable::DeleteFromMaskedCreditCards(const std::string& id) { + sql::Statement s( + db_->GetUniqueStatement("DELETE FROM masked_credit_cards WHERE id = ?")); + s.BindString(0, id); + s.Run(); + return db_->GetLastChangeCount() > 0; +} + +bool AutofillTable::DeleteFromUnmaskedCreditCards(const std::string& id) { + sql::Statement s(db_->GetUniqueStatement( + "DELETE FROM unmasked_credit_cards WHERE id = ?")); + s.BindString(0, id); + s.Run(); + return db_->GetLastChangeCount() > 0; +} + +bool AutofillTable::InitMainTable() { + if (!db_->DoesTableExist("autofill")) { + if (!db_->Execute("CREATE TABLE autofill (" + "name VARCHAR, " + "value VARCHAR, " + "value_lower VARCHAR, " + "date_created INTEGER DEFAULT 0, " + "date_last_used INTEGER DEFAULT 0, " + "count INTEGER DEFAULT 1, " + "PRIMARY KEY (name, value))") || + !db_->Execute("CREATE INDEX autofill_name ON autofill (name)") || + !db_->Execute("CREATE INDEX autofill_name_value_lower ON " + "autofill (name, value_lower)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitCreditCardsTable() { + if (!db_->DoesTableExist("credit_cards")) { + if (!db_->Execute("CREATE TABLE credit_cards ( " + "guid VARCHAR PRIMARY KEY, " + "name_on_card VARCHAR, " + "expiration_month INTEGER, " + "expiration_year INTEGER, " + "card_number_encrypted BLOB, " + "date_modified INTEGER NOT NULL DEFAULT 0, " + "origin VARCHAR DEFAULT '', " + "use_count INTEGER NOT NULL DEFAULT 0, " + "use_date INTEGER NOT NULL DEFAULT 0, " + "billing_address_id VARCHAR) ")) { + NOTREACHED(); + return false; + } + } + + return true; +} + +bool AutofillTable::InitProfilesTable() { + if (!db_->DoesTableExist("autofill_profiles")) { + if (!db_->Execute("CREATE TABLE autofill_profiles ( " + "guid VARCHAR PRIMARY KEY, " + "company_name VARCHAR, " + "street_address VARCHAR, " + "dependent_locality VARCHAR, " + "city VARCHAR, " + "state VARCHAR, " + "zipcode VARCHAR, " + "sorting_code VARCHAR, " + "country_code VARCHAR, " + "date_modified INTEGER NOT NULL DEFAULT 0, " + "origin VARCHAR DEFAULT '', " + "language_code VARCHAR, " + "use_count INTEGER NOT NULL DEFAULT 0, " + "use_date INTEGER NOT NULL DEFAULT 0, " + "validity_bitfield UNSIGNED NOT NULL DEFAULT 0) ")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitProfileNamesTable() { + if (!db_->DoesTableExist("autofill_profile_names")) { + if (!db_->Execute("CREATE TABLE autofill_profile_names ( " + "guid VARCHAR, " + "first_name VARCHAR, " + "middle_name VARCHAR, " + "last_name VARCHAR, " + "full_name VARCHAR)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitProfileEmailsTable() { + if (!db_->DoesTableExist("autofill_profile_emails")) { + if (!db_->Execute("CREATE TABLE autofill_profile_emails ( " + "guid VARCHAR, " + "email VARCHAR)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitProfilePhonesTable() { + if (!db_->DoesTableExist("autofill_profile_phones")) { + if (!db_->Execute("CREATE TABLE autofill_profile_phones ( " + "guid VARCHAR, " + "number VARCHAR)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitProfileTrashTable() { + if (!db_->DoesTableExist("autofill_profiles_trash")) { + if (!db_->Execute("CREATE TABLE autofill_profiles_trash ( " + "guid VARCHAR)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitMaskedCreditCardsTable() { + if (!db_->DoesTableExist("masked_credit_cards")) { + if (!db_->Execute("CREATE TABLE masked_credit_cards (" + "id VARCHAR," + "status VARCHAR," + "name_on_card VARCHAR," + "network VARCHAR," + "last_four VARCHAR," + "exp_month INTEGER DEFAULT 0," + "exp_year INTEGER DEFAULT 0, " + "bank_name VARCHAR, " + "type INTEGER DEFAULT 0)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitUnmaskedCreditCardsTable() { + if (!db_->DoesTableExist("unmasked_credit_cards")) { + if (!db_->Execute("CREATE TABLE unmasked_credit_cards (" + "id VARCHAR," + "card_number_encrypted VARCHAR, " + "use_count INTEGER NOT NULL DEFAULT 0, " + "use_date INTEGER NOT NULL DEFAULT 0, " + "unmask_date INTEGER NOT NULL DEFAULT 0)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitServerCardMetadataTable() { + if (!db_->DoesTableExist("server_card_metadata")) { + if (!db_->Execute("CREATE TABLE server_card_metadata (" + "id VARCHAR NOT NULL," + "use_count INTEGER NOT NULL DEFAULT 0, " + "use_date INTEGER NOT NULL DEFAULT 0, " + "billing_address_id VARCHAR)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitServerAddressesTable() { + if (!db_->DoesTableExist("server_addresses")) { + // The space after language_code is necessary to match what sqlite does + // when it appends the column in migration. + if (!db_->Execute("CREATE TABLE server_addresses (" + "id VARCHAR," + "company_name VARCHAR," + "street_address VARCHAR," + "address_1 VARCHAR," + "address_2 VARCHAR," + "address_3 VARCHAR," + "address_4 VARCHAR," + "postal_code VARCHAR," + "sorting_code VARCHAR," + "country_code VARCHAR," + "language_code VARCHAR, " // Space required. + "recipient_name VARCHAR, " // Ditto. + "phone_number VARCHAR)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitServerAddressMetadataTable() { + if (!db_->DoesTableExist("server_address_metadata")) { + if (!db_->Execute("CREATE TABLE server_address_metadata (" + "id VARCHAR NOT NULL," + "use_count INTEGER NOT NULL DEFAULT 0, " + "use_date INTEGER NOT NULL DEFAULT 0, " + "has_converted BOOL NOT NULL DEFAULT FALSE)")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitAutofillSyncMetadataTable() { + if (!db_->DoesTableExist("autofill_sync_metadata")) { + if (!db_->Execute("CREATE TABLE autofill_sync_metadata (" + "model_type INTEGER NOT NULL, " + "storage_key VARCHAR NOT NULL, " + "value BLOB, " + "PRIMARY KEY (model_type, storage_key))")) { + NOTREACHED(); + return false; + } + } + return true; +} + +bool AutofillTable::InitModelTypeStateTable() { + if (!db_->DoesTableExist("autofill_model_type_state")) { + if (!db_->Execute("CREATE TABLE autofill_model_type_state (" + "model_type INTEGER NOT NULL PRIMARY KEY, value BLOB)")) { + NOTREACHED(); + return false; + } + } + return true; +} + } // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h index 5166071..bb34d9c4 100644 --- a/components/autofill/core/browser/webdata/autofill_table.h +++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -581,7 +581,6 @@ bool InitMainTable(); bool InitCreditCardsTable(); - bool InitDatesTable(); bool InitProfilesTable(); bool InitProfileNamesTable(); bool InitProfileEmailsTable();
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index ac05ff7..cb5b03a 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -38,6 +38,12 @@ const base::Feature kAutofillPrefilledFields{"AutofillPrefilledFields", base::FEATURE_ENABLED_BY_DEFAULT}; +// Controls whether autofill suggestions are filtered by field values previously +// filled by website. +const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms{ + "AutofillShowAllSuggestionsOnPrefilledForms", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Controls whether or not a minimum number of fields is required before // heuristic field type prediction is run for a form. const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics{
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index 4386509..75124d23 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -24,6 +24,7 @@ extern const base::Feature kAutofillResetFullServerCardsOnAuthError; extern const base::Feature kAutofillRestrictUnownedFieldsToFormlessCheckout; extern const base::Feature kAutofillSendExperimentIdsInPaymentsRPCs; +extern const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms; extern const base::Feature kAutofillShowAutocompleteConsoleWarnings; extern const base::Feature kAutofillShowTypePredictions; extern const base::Feature kAutofillSkipComparingInferredLabels;
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index d40cee5..f49824e 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -795,13 +795,13 @@ // Unrecoverable errors that arrive via the syncer::UnrecoverableErrorHandler // interface are assumed to originate within the syncer. unrecoverable_error_reason_ = ERROR_REASON_SYNCER; - OnUnrecoverableErrorImpl(from_here, message, true); + OnUnrecoverableErrorImpl(from_here, message, CLEAR_DATA); } void ProfileSyncService::OnUnrecoverableErrorImpl( const base::Location& from_here, const std::string& message, - bool delete_sync_database) { + SyncStopDataFate data_fate) { DCHECK(HasUnrecoverableError()); unrecoverable_error_message_ = message; unrecoverable_error_location_ = from_here; @@ -814,11 +814,12 @@ NotifyObservers(); // Shut all data types down. + syncer::ShutdownReason reason = + (data_fate == KEEP_DATA) ? syncer::STOP_SYNC : syncer::DISABLE_SYNC; base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&ProfileSyncService::ShutdownImpl, - sync_enabled_weak_factory_.GetWeakPtr(), - delete_sync_database ? syncer::DISABLE_SYNC - : syncer::STOP_SYNC)); + FROM_HERE, + base::BindOnce(&ProfileSyncService::ShutdownImpl, + sync_enabled_weak_factory_.GetWeakPtr(), reason)); } void ProfileSyncService::ReenableDatatype(syncer::ModelType type) { @@ -861,7 +862,7 @@ if (!success) { // Something went unexpectedly wrong. Play it safe: stop syncing at once // and surface error UI to alert the user sync has stopped. - // Keep the directory around for now so that on restart we will retry + // Keep the sync data around for now so that on restart we will retry // again and potentially succeed in presence of transient file IO failures // or permissions issues, etc. // @@ -871,8 +872,8 @@ // directory corruption recovery mechanism makes it obsolete. By the time // we get here, we will have already tried and failed to delete the // directory. It would be no big deal if we tried to delete it again. - OnInternalUnrecoverableError(FROM_HERE, "BackendInitialize failure", false, - ERROR_REASON_ENGINE_INIT_FAILURE); + OnInternalUnrecoverableError(FROM_HERE, "BackendInitialize failure", + KEEP_DATA, ERROR_REASON_ENGINE_INIT_FAILURE); return; } @@ -1009,7 +1010,7 @@ // Trigger an unrecoverable error to stop syncing. OnInternalUnrecoverableError(FROM_HERE, last_actionable_error_.error_description, - true, ERROR_REASON_ACTIONABLE_ERROR); + CLEAR_DATA, ERROR_REASON_ACTIONABLE_ERROR); break; case syncer::DISABLE_SYNC_ON_CLIENT: if (error.error_type == syncer::NOT_MY_BIRTHDAY) { @@ -1041,7 +1042,7 @@ syncer::CLEAR_SERVER_DATA_RESET_LOCAL_DATA_RECEIVED, syncer::CLEAR_SERVER_DATA_MAX); break; - default: + case syncer::UNKNOWN_ACTION: NOTREACHED(); } NotifyObservers(); @@ -1138,7 +1139,7 @@ result.data_type_status_table.GetUnrecoverableErrorTypes()) + ": " + error.message(); LOG(ERROR) << "ProfileSyncService error: " << message; - OnInternalUnrecoverableError(error.location(), message, true, + OnInternalUnrecoverableError(error.location(), message, CLEAR_DATA, ERROR_REASON_CONFIGURATION_FAILURE); return; } @@ -2002,11 +2003,11 @@ void ProfileSyncService::OnInternalUnrecoverableError( const base::Location& from_here, const std::string& message, - bool delete_sync_database, + SyncStopDataFate data_fate, UnrecoverableErrorReason reason) { DCHECK(!HasUnrecoverableError()); unrecoverable_error_reason_ = reason; - OnUnrecoverableErrorImpl(from_here, message, delete_sync_database); + OnUnrecoverableErrorImpl(from_here, message, data_fate); } bool ProfileSyncService::IsRetryingAccessTokenFetchForTest() const {
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index 469ed8b..8078942 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -540,11 +540,9 @@ bool IsEncryptedDatatypeEnabled() const; // Helper for OnUnrecoverableError. - // TODO(tim): Use an enum for |delete_sync_database| here, in ShutdownImpl, - // and in SyncEngine::Shutdown. void OnUnrecoverableErrorImpl(const base::Location& from_here, const std::string& message, - bool delete_sync_database); + SyncStopDataFate data_fate); // Stops the sync engine. Does NOT set IsSyncRequested to false. Use // RequestStop for that. |data_fate| controls whether the local sync data is @@ -585,7 +583,7 @@ // Sync.UnrecoverableErrors histogram. void OnInternalUnrecoverableError(const base::Location& from_here, const std::string& message, - bool delete_sync_database, + SyncStopDataFate data_fate, UnrecoverableErrorReason reason); // Update UMA for syncing engine. @@ -710,9 +708,9 @@ // Whether the SyncEngine has been initialized. bool engine_initialized_; - // Set when sync receives DISABLED_BY_ADMIN error from server. Prevents - // ProfileSyncService from starting engine till browser restarted or user - // signed out. + // Set when sync receives STOP_SYNC_FOR_DISABLED_ACCOUNT error from server. + // Prevents ProfileSyncService from starting engine till browser restarted + // or user signed out. bool sync_disabled_by_admin_; // Information describing an unrecoverable error.
diff --git a/components/browser_sync/profile_sync_service_startup_unittest.cc b/components/browser_sync/profile_sync_service_startup_unittest.cc index 53e15929..7250edc 100644 --- a/components/browser_sync/profile_sync_service_startup_unittest.cc +++ b/components/browser_sync/profile_sync_service_startup_unittest.cc
@@ -159,8 +159,8 @@ SetUpFakeSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::STOPPED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::STOPPED)); // Should not actually start, rather just clean things up and wait // to be enabled. @@ -203,8 +203,8 @@ // Releasing the sync blocker will let ProfileSyncService configure the // DataTypeManager. EXPECT_CALL(*data_type_manager, Configure(_, _)); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); // Simulate the UI telling sync it has finished setting up. sync_blocker.reset(); @@ -228,8 +228,8 @@ SetUpFakeSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); EXPECT_CALL(*data_type_manager, Configure(_, _)); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); sync_service()->Initialize(); @@ -268,15 +268,17 @@ pref_service()->ClearPref(syncer::prefs::kSyncFirstSetupComplete); SetUpFakeSyncEngine(); - SetUpDataTypeManagerMock(); + DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); + EXPECT_CALL(*data_type_manager, Configure(_, _)); sync_service()->Initialize(); - // Sync should not start because there are no tokens yet. - EXPECT_FALSE(sync_service()->IsSyncActive()); - sync_service()->SetFirstSetupComplete(); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); - // Sync should not start because there are still no tokens. - EXPECT_FALSE(sync_service()->IsSyncActive()); + // Sync should start up the engine, even though there is no refresh token yet. + EXPECT_TRUE(sync_service()->IsSyncActive()); + // Since we're in AUTO_START mode, FirstSetupComplete gets set automatically. + EXPECT_TRUE(sync_service()->IsFirstSetupComplete()); } TEST_F(ProfileSyncServiceStartupCrosTest, StartFirstTime) { @@ -284,8 +286,8 @@ DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); pref_service()->ClearPref(syncer::prefs::kSyncFirstSetupComplete); EXPECT_CALL(*data_type_manager, Configure(_, _)); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); // The primary account is already populated, all that's left to do is provide // a refresh token. @@ -302,8 +304,8 @@ SetUpFakeSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); EXPECT_CALL(*data_type_manager, Configure(_, _)); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); sync_service()->Initialize(); @@ -361,8 +363,8 @@ SetUpFakeSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); EXPECT_CALL(*data_type_manager, Configure(_, _)); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); sync_service()->Initialize(); @@ -384,8 +386,8 @@ SetUpFakeSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); EXPECT_CALL(*data_type_manager, Configure(_, _)); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); sync_service()->Initialize(); @@ -414,8 +416,8 @@ SetUpFakeSyncEngine(); DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock(); EXPECT_CALL(*data_type_manager, Configure(_, _)); - EXPECT_CALL(*data_type_manager, state()) - .WillRepeatedly(Return(DataTypeManager::CONFIGURED)); + ON_CALL(*data_type_manager, state()) + .WillByDefault(Return(DataTypeManager::CONFIGURED)); ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true)); sync_service()->Initialize(); EXPECT_TRUE(sync_service()->IsEngineInitialized());
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc index 9659d6fc..b62b480 100644 --- a/components/browser_sync/profile_sync_service_unittest.cc +++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -9,9 +9,9 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/run_loop.h" +#include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" -#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "components/browser_sync/browser_sync_switches.h" #include "components/browser_sync/profile_sync_test_util.h" @@ -34,6 +34,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::_; using testing::ByMove; using testing::Return; @@ -43,7 +44,8 @@ class FakeDataTypeManager : public syncer::DataTypeManager { public: - using ConfigureCalled = base::Callback<void(syncer::ConfigureReason)>; + using ConfigureCalled = + base::RepeatingCallback<void(syncer::ConfigureReason)>; explicit FakeDataTypeManager(const ConfigureCalled& configure_called) : configure_called_(configure_called) {} @@ -71,14 +73,10 @@ ConfigureCalled configure_called_; }; -ACTION_P(ReturnNewDataTypeManager, configure_called) { +ACTION_P(ReturnNewFakeDataTypeManager, configure_called) { return std::make_unique<FakeDataTypeManager>(configure_called); } -using testing::Return; -using testing::StrictMock; -using testing::_; - class TestSyncServiceObserver : public syncer::SyncServiceObserver { public: TestSyncServiceObserver() @@ -100,7 +98,7 @@ // A variant of the FakeSyncEngine that won't automatically call back when asked // to initialized. Allows us to test things that could happen while backend init // is in progress. -class SyncEngineNoReturn : public syncer::FakeSyncEngine { +class FakeSyncEngineNoReturn : public syncer::FakeSyncEngine { void Initialize(InitParams params) override {} }; @@ -133,10 +131,11 @@ // FakeSyncEngine that calls an external callback when ClearServerData is // called. -class SyncEngineCaptureClearServerData : public syncer::FakeSyncEngine { +class FakeSyncEngineCaptureClearServerData : public syncer::FakeSyncEngine { public: - using ClearServerDataCalled = base::Callback<void(const base::Closure&)>; - explicit SyncEngineCaptureClearServerData( + using ClearServerDataCalled = + base::RepeatingCallback<void(const base::Closure&)>; + explicit FakeSyncEngineCaptureClearServerData( const ClearServerDataCalled& clear_server_data_called) : clear_server_data_called_(clear_server_data_called) {} @@ -164,7 +163,7 @@ // testing the SyncEngine. class ProfileSyncServiceTest : public ::testing::Test { protected: - ProfileSyncServiceTest() : component_factory_(nullptr) {} + ProfileSyncServiceTest() {} ~ProfileSyncServiceTest() override {} void SetUp() override { @@ -174,20 +173,18 @@ void TearDown() override { // Kill the service before the profile. - if (service_) - service_->Shutdown(); - - service_.reset(); + ShutdownAndDeleteService(); } - void IssueTestTokens() { + void SignIn() { identity::MakePrimaryAccountAvailable(signin_manager(), auth_service(), identity_manager(), "test_user@gmail.com"); } void CreateService(ProfileSyncService::StartBehavior behavior) { - component_factory_ = profile_sync_service_bundle_.component_factory(); + DCHECK(!service_); + ProfileSyncServiceBundle::SyncClientBuilder builder( &profile_sync_service_bundle_); ProfileSyncService::InitParams init_params = @@ -198,7 +195,7 @@ service_ = std::make_unique<ProfileSyncService>(std::move(init_params)); - ON_CALL(*component_factory_, CreateCommonDataTypeControllers(_, _)) + ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_, _)) .WillByDefault(testing::InvokeWithoutArgs([=]() { syncer::DataTypeController::TypeVector controllers; controllers.push_back( @@ -206,15 +203,16 @@ syncer::BOOKMARKS)); return controllers; })); - ON_CALL(*component_factory_, CreateSyncEngine(_, _, _, _)) + ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillByDefault(ReturnNewFakeSyncEngine()); - ON_CALL(*component_factory_, CreateDataTypeManager(_, _, _, _, _, _)) + ON_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) .WillByDefault( - ReturnNewDataTypeManager(GetDefaultConfigureCalledCallback())); + ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback())); } void CreateServiceWithLocalSyncBackend() { - component_factory_ = profile_sync_service_bundle_.component_factory(); + DCHECK(!service_); + ProfileSyncServiceBundle::SyncClientBuilder builder( &profile_sync_service_bundle_); ProfileSyncService::InitParams init_params = @@ -227,7 +225,7 @@ service_ = std::make_unique<ProfileSyncService>(std::move(init_params)); - ON_CALL(*component_factory_, CreateCommonDataTypeControllers(_, _)) + ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_, _)) .WillByDefault(testing::InvokeWithoutArgs([=]() { syncer::DataTypeController::TypeVector controllers; controllers.push_back( @@ -235,11 +233,11 @@ syncer::BOOKMARKS)); return controllers; })); - ON_CALL(*component_factory_, CreateSyncEngine(_, _, _, _)) + ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillByDefault(ReturnNewFakeSyncEngine()); - ON_CALL(*component_factory_, CreateDataTypeManager(_, _, _, _, _, _)) + ON_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) .WillByDefault( - ReturnNewDataTypeManager(GetDefaultConfigureCalledCallback())); + ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback())); } void ShutdownAndDeleteService() { @@ -281,16 +279,12 @@ base::Unretained(this)); } - void OnConfigureCalledRecordReason(syncer::ConfigureReason* reason_dest, - syncer::ConfigureReason reason) { - DCHECK(reason_dest); - *reason_dest = reason; - } - FakeDataTypeManager::ConfigureCalled GetRecordingConfigureCalledCallback( - syncer::ConfigureReason* reason) { - return base::Bind(&ProfileSyncServiceTest::OnConfigureCalledRecordReason, - base::Unretained(this), reason); + syncer::ConfigureReason* reason_dest) { + return base::BindLambdaForTesting( + [reason_dest](syncer::ConfigureReason reason) { + *reason_dest = reason; + }); } AccountTrackerService* account_tracker() { @@ -322,17 +316,13 @@ } syncer::SyncApiComponentFactoryMock* component_factory() { - return component_factory_; + return profile_sync_service_bundle_.component_factory(); } private: base::test::ScopedTaskEnvironment scoped_task_environment_; ProfileSyncServiceBundle profile_sync_service_bundle_; std::unique_ptr<ProfileSyncService> service_; - - // The current component factory used by sync. May be null if the server - // hasn't been created yet. - syncer::SyncApiComponentFactoryMock* component_factory_; }; // Verify that the server URLs are sane. @@ -348,12 +338,13 @@ TEST_F(ProfileSyncServiceTest, SuccessfulInitialization) { prefs()->SetManagedPref(syncer::prefs::kSyncManaged, std::make_unique<base::Value>(false)); - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce(ReturnNewFakeSyncEngine()); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager(GetDefaultConfigureCalledCallback())); + .WillOnce( + ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback())); InitializeForNthSync(); EXPECT_FALSE(service()->IsManaged()); EXPECT_TRUE(service()->IsSyncActive()); @@ -367,7 +358,8 @@ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce(ReturnNewFakeSyncEngine()); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager(GetDefaultConfigureCalledCallback())); + .WillOnce( + ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback())); InitializeForNthSync(); EXPECT_FALSE(service()->IsManaged()); EXPECT_TRUE(service()->IsSyncActive()); @@ -379,7 +371,7 @@ TEST_F(ProfileSyncServiceTest, NeedsConfirmation) { prefs()->SetManagedPref(syncer::prefs::kSyncManaged, std::make_unique<base::Value>(false)); - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::MANUAL_START); syncer::SyncPrefs sync_prefs(prefs()); @@ -417,7 +409,7 @@ TEST_F(ProfileSyncServiceTest, DisabledByPolicyBeforeInit) { prefs()->SetManagedPref(syncer::prefs::kSyncManaged, std::make_unique<base::Value>(true)); - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); InitializeForNthSync(); EXPECT_TRUE(service()->IsManaged()); @@ -427,7 +419,7 @@ // Verify that disable by enterprise policy works even after the backend has // been initialized. TEST_F(ProfileSyncServiceTest, DisabledByPolicyAfterInit) { - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); InitializeForNthSync(); @@ -441,14 +433,15 @@ EXPECT_FALSE(service()->IsSyncActive()); } -// Exercies the ProfileSyncService's code paths related to getting shut down +// Exercises the ProfileSyncService's code paths related to getting shut down // before the backend initialize call returns. TEST_F(ProfileSyncServiceTest, AbortedByShutdown) { CreateService(ProfileSyncService::AUTO_START); ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) - .WillByDefault(Return(ByMove(std::make_unique<SyncEngineNoReturn>()))); + .WillByDefault( + Return(ByMove(std::make_unique<FakeSyncEngineNoReturn>()))); - IssueTestTokens(); + SignIn(); InitializeForNthSync(); ASSERT_FALSE(service()->IsSyncActive()); @@ -458,7 +451,7 @@ // Test RequestStop() before we've initialized the backend. TEST_F(ProfileSyncServiceTest, EarlyRequestStop) { CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); service()->RequestStop(ProfileSyncService::KEEP_DATA); EXPECT_FALSE(service()->IsSyncRequested()); @@ -477,7 +470,7 @@ // Test RequestStop() after we've initialized the backend. TEST_F(ProfileSyncServiceTest, DisableAndEnableSyncTemporarily) { CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); InitializeForNthSync(); ASSERT_TRUE(service()->IsSyncActive()); @@ -499,7 +492,7 @@ #if !defined(OS_CHROMEOS) TEST_F(ProfileSyncServiceTest, EnableSyncAndSignOut) { CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); InitializeForNthSync(); EXPECT_TRUE(service()->IsSyncActive()); @@ -516,7 +509,7 @@ TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) { CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); InitializeForNthSync(); // Initial status. @@ -551,7 +544,7 @@ syncer::SyncCredentials init_credentials; CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>( @@ -599,7 +592,7 @@ base::Unretained(&invalidate_credentials_called)); CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>( @@ -654,7 +647,7 @@ syncer::SyncCredentials init_credentials; CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>( @@ -687,7 +680,7 @@ // Verify that LastSyncedTime and local DeviceInfo is cleared on sign out. TEST_F(ProfileSyncServiceTest, ClearDataOnSignOut) { - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); InitializeForNthSync(); ASSERT_TRUE(service()->IsSyncActive()); @@ -712,7 +705,7 @@ syncer::SyncCredentials init_credentials; CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>( @@ -771,7 +764,7 @@ syncer::SyncCredentials init_credentials; CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>( @@ -844,7 +837,7 @@ // Test Sync will stop after receive memory pressure TEST_F(ProfileSyncServiceTest, MemoryPressureRecording) { CreateService(ProfileSyncService::AUTO_START); - IssueTestTokens(); + SignIn(); InitializeForNthSync(); ASSERT_TRUE(service()->IsSyncActive()); @@ -886,7 +879,7 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( switches::kSyncClearDataOnPassphraseEncryption); - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); base::Closure captured_callback; @@ -897,11 +890,11 @@ // CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE. EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( - Return(ByMove(std::make_unique<SyncEngineCaptureClearServerData>( + Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>( base::BindRepeating(&OnClearServerDataCalled, base::Unretained(&captured_callback)))))); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); InitializeForNthSync(); ASSERT_TRUE(service()->IsSyncActive()); @@ -930,7 +923,7 @@ // restarted. configure_reason = syncer::CONFIGURE_REASON_UNKNOWN; EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); captured_callback.Run(); testing::Mock::VerifyAndClearExpectations(component_factory()); @@ -946,10 +939,10 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( switches::kSyncClearDataOnPassphraseEncryption); - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); InitializeForNthSync(); testing::Mock::VerifyAndClearExpectations(component_factory()); @@ -971,11 +964,11 @@ base::Closure captured_callback; EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( - Return(ByMove(std::make_unique<SyncEngineCaptureClearServerData>( + Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>( base::BindRepeating(&OnClearServerDataCalled, base::Unretained(&captured_callback)))))); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); InitializeForNthSync(); testing::Mock::VerifyAndClearExpectations(component_factory()); @@ -995,7 +988,7 @@ EXPECT_FALSE(captured_callback.is_null()); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); captured_callback.Run(); testing::Mock::VerifyAndClearExpectations(component_factory()); @@ -1011,11 +1004,11 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( switches::kSyncClearDataOnPassphraseEncryption); - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( - Return(ByMove(std::make_unique<SyncEngineCaptureClearServerData>( + Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>( base::BindRepeating(&OnClearServerDataCalled, base::Unretained(&captured_callback)))))); InitializeForNthSync(); @@ -1033,11 +1026,11 @@ CreateService(ProfileSyncService::AUTO_START); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce( - Return(ByMove(std::make_unique<SyncEngineCaptureClearServerData>( + Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>( base::BindRepeating(&OnClearServerDataCalled, base::Unretained(&captured_callback)))))); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); InitializeForNthSync(); testing::Mock::VerifyAndClearExpectations(component_factory()); @@ -1059,7 +1052,7 @@ EXPECT_FALSE(captured_callback.is_null()); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); captured_callback.Run(); testing::Mock::VerifyAndClearExpectations(component_factory()); @@ -1069,7 +1062,7 @@ // Test that the passphrase prompt due to version change logic gets triggered // on a datatype type requesting startup, but only happens once. TEST_F(ProfileSyncServiceTest, PassphrasePromptDueToVersion) { - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); InitializeForNthSync(); @@ -1098,13 +1091,15 @@ // Test that when ProfileSyncService receives actionable error // RESET_LOCAL_SYNC_DATA it restarts sync. TEST_F(ProfileSyncServiceTest, ResetSyncData) { - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); // Backend should get initialized two times: once during initialization and // once when handling actionable error. EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager(GetDefaultConfigureCalledCallback())) - .WillOnce(ReturnNewDataTypeManager(GetDefaultConfigureCalledCallback())); + .WillOnce( + ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback())) + .WillOnce( + ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback())); EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)) .WillOnce(ReturnNewFakeSyncEngine()) .WillOnce(ReturnNewFakeSyncEngine()); @@ -1119,7 +1114,7 @@ // Test that when ProfileSyncService receives actionable error // DISABLE_SYNC_ON_CLIENT it disables sync and signs out. TEST_F(ProfileSyncServiceTest, DisableSyncOnClient) { - IssueTestTokens(); + SignIn(); CreateService(ProfileSyncService::AUTO_START); InitializeForNthSync(); @@ -1173,12 +1168,12 @@ syncer::DataTypeManager::OK, syncer::ModelTypeSet()); syncer::ConfigureReason configure_reason = syncer::CONFIGURE_REASON_UNKNOWN; - IssueTestTokens(); + SignIn(); // First sync. CreateService(ProfileSyncService::AUTO_START); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); InitializeForFirstSync(); ASSERT_TRUE(service()->IsSyncActive()); @@ -1195,7 +1190,7 @@ // Nth sync. CreateService(ProfileSyncService::AUTO_START); EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) - .WillOnce(ReturnNewDataTypeManager( + .WillOnce(ReturnNewFakeDataTypeManager( GetRecordingConfigureCalledCallback(&configure_reason))); InitializeForNthSync(); ASSERT_TRUE(service()->IsSyncActive());
diff --git a/components/cdm/renderer/widevine_key_system_properties.cc b/components/cdm/renderer/widevine_key_system_properties.cc index 2342397..0db1b17 100644 --- a/components/cdm/renderer/widevine_key_system_properties.cc +++ b/components/cdm/renderer/widevine_key_system_properties.cc
@@ -133,10 +133,16 @@ return EmeConfigRule::IDENTIFIER_RECOMMENDED; } #elif defined(OS_ANDROID) - // Require hardware secure codecs when SW_SECURE_DECODE or above is specified. + // On Android, require hardware secure codecs for SW_SECURE_DECODE and above. if (robustness >= Robustness::SW_SECURE_DECODE) { return EmeConfigRule::HW_SECURE_CODECS_REQUIRED; } +#else + // On Linux/Mac/Win, require hardware secure codecs for HW_SECURE_CRYPTO and + // above. + if (robustness >= Robustness::HW_SECURE_CRYPTO) { + return EmeConfigRule::HW_SECURE_CODECS_REQUIRED; + } #endif // defined(OS_CHROMEOS) // TODO(crbug.com/848532): Handle HW_SECURE* levels for Windows.
diff --git a/components/content_settings/core/browser/cookie_settings.cc b/components/content_settings/core/browser/cookie_settings.cc index 2193d4c..47430ee 100644 --- a/components/content_settings/core/browser/cookie_settings.cc +++ b/components/content_settings/core/browser/cookie_settings.cc
@@ -41,13 +41,6 @@ CONTENT_SETTINGS_TYPE_COOKIES, provider_id); } -bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const { - ContentSetting setting; - GetCookieSetting(origin, origin, nullptr, &setting); - DCHECK(IsValidSetting(setting)); - return (setting == CONTENT_SETTING_SESSION_ONLY); -} - void CookieSettings::GetCookieSettings( ContentSettingsForOneType* settings) const { host_content_settings_map_->GetSettingsForOneType(
diff --git a/components/content_settings/core/browser/cookie_settings.h b/components/content_settings/core/browser/cookie_settings.h index ccdac9c..6d3abef 100644 --- a/components/content_settings/core/browser/cookie_settings.h +++ b/components/content_settings/core/browser/cookie_settings.h
@@ -47,13 +47,6 @@ // This may be called on any thread. ContentSetting GetDefaultCookieSetting(std::string* provider_id) const; - // Returns true if the cookie set by a page identified by |url| should be - // session only. Querying this only makes sense if |IsCookieAccessAllowed| - // has returned true. - // - // This may be called on any thread. - bool IsCookieSessionOnly(const GURL& url) const; - // Returns all patterns with a non-default cookie setting, mapped to their // actual settings, in the precedence order of the setting rules. |settings| // must be a non-nullptr outparam.
diff --git a/components/content_settings/core/common/cookie_settings_base.cc b/components/content_settings/core/common/cookie_settings_base.cc index 139bb994..e4909a9 100644 --- a/components/content_settings/core/common/cookie_settings_base.cc +++ b/components/content_settings/core/common/cookie_settings_base.cc
@@ -46,6 +46,13 @@ return IsAllowed(setting); } +bool CookieSettingsBase::IsCookieSessionOnly(const GURL& origin) const { + ContentSetting setting; + GetCookieSetting(origin, origin, nullptr, &setting); + DCHECK(IsValidSetting(setting)); + return setting == CONTENT_SETTING_SESSION_ONLY; +} + // static bool CookieSettingsBase::IsValidSetting(ContentSetting setting) { return (setting == CONTENT_SETTING_ALLOW ||
diff --git a/components/content_settings/core/common/cookie_settings_base.h b/components/content_settings/core/common/cookie_settings_base.h index 8d65ab5..e2318177 100644 --- a/components/content_settings/core/common/cookie_settings_base.h +++ b/components/content_settings/core/common/cookie_settings_base.h
@@ -37,6 +37,13 @@ bool IsCookieAccessAllowed(const GURL& url, const GURL& first_party_url) const; + // Returns true if the cookie set by a page identified by |url| should be + // session only. Querying this only makes sense if |IsCookieAccessAllowed| + // has returned true. + // + // This may be called on any thread. + bool IsCookieSessionOnly(const GURL& url) const; + // A helper for applying third party cookie blocking rules. virtual void GetCookieSetting(const GURL& url, const GURL& first_party_url,
diff --git a/components/content_settings/core/common/cookie_settings_base_unittest.cc b/components/content_settings/core/common/cookie_settings_base_unittest.cc index 337041a..0d960de 100644 --- a/components/content_settings/core/common/cookie_settings_base_unittest.cc +++ b/components/content_settings/core/common/cookie_settings_base_unittest.cc
@@ -117,6 +117,24 @@ EXPECT_TRUE(settings.IsCookieAccessAllowed(GURL(), GURL())); } +TEST(CookieSettingsBaseTest, IsCookieSessionOnlyWithAllowSetting) { + CallbackCookieSettings settings( + base::BindRepeating([](const GURL&) { return CONTENT_SETTING_ALLOW; })); + EXPECT_FALSE(settings.IsCookieSessionOnly(GURL())); +} + +TEST(CookieSettingsBaseTest, IsCookieSessionOnlyWithBlockSetting) { + CallbackCookieSettings settings( + base::BindRepeating([](const GURL&) { return CONTENT_SETTING_BLOCK; })); + EXPECT_FALSE(settings.IsCookieSessionOnly(GURL())); +} + +TEST(CookieSettingsBaseTest, IsCookieSessionOnlySessionWithOnlySetting) { + CallbackCookieSettings settings(base::BindRepeating( + [](const GURL&) { return CONTENT_SETTING_SESSION_ONLY; })); + EXPECT_TRUE(settings.IsCookieSessionOnly(GURL())); +} + TEST(CookieSettingsBaseTest, IsValidSetting) { EXPECT_FALSE(CookieSettingsBase::IsValidSetting(CONTENT_SETTING_DEFAULT)); EXPECT_FALSE(CookieSettingsBase::IsValidSetting(CONTENT_SETTING_ASK));
diff --git a/components/crash/android/OWNERS b/components/crash/android/OWNERS index 9c568c2e..1c0302a 100644 --- a/components/crash/android/OWNERS +++ b/components/crash/android/OWNERS
@@ -1,7 +1,3 @@ -# Java readability and UMA -mariakhomenko@chromium.org - -# Crash uploading mechanism gsennton@chromium.org isherman@chromium.org
diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn index 4d9d30a..d4fa4c3 100644 --- a/components/crash/content/app/BUILD.gn +++ b/components/crash/content/app/BUILD.gn
@@ -74,6 +74,7 @@ "//content/public/common:result_codes", "//sandbox", "//third_party/breakpad:client", + "//third_party/crashpad/crashpad/snapshot", ] # Clang's -mstackrealign doesn't work well with
diff --git a/components/crash/content/app/crash_reporter_client.cc b/components/crash/content/app/crash_reporter_client.cc index 464fe2e..f69c6c3 100644 --- a/components/crash/content/app/crash_reporter_client.cc +++ b/components/crash/content/app/crash_reporter_client.cc
@@ -171,6 +171,17 @@ } #endif +#if defined(OS_ANDROID) || defined(OS_LINUX) +void CrashReporterClient::GetSanitizationInformation( + const char* const** annotations_whitelist, + void** target_module, + bool* sanitize_stacks) { + *annotations_whitelist = nullptr; + *target_module = nullptr; + *sanitize_stacks = false; +} +#endif + bool CrashReporterClient::ShouldMonitorCrashHandlerExpensively() { return false; }
diff --git a/components/crash/content/app/crash_reporter_client.h b/components/crash/content/app/crash_reporter_client.h index e6a09126..485c2c8 100644 --- a/components/crash/content/app/crash_reporter_client.h +++ b/components/crash/content/app/crash_reporter_client.h
@@ -165,6 +165,22 @@ virtual bool ShouldEnableBreakpadMicrodumps(); #endif +#if defined(OS_ANDROID) || defined(OS_LINUX) + // Configures sanitization of crash dumps. + // |annotations_whitelist| is a nullptr terminated array of NUL-terminated + // strings of allowed annotation names or nullptr if all annotations are + // allowed. |target_module| is a pointer to a location inside a module to + // target or nullptr if there is no target module. Crash dumps are not + // produced when the crashing thread's stack and program counter do not + // reference the target module. |sanitize_stacks| is true if stacks should be + // sanitized for possible PII. If they are sanitized, only small integers and + // pointers to modules and stacks will be preserved. + virtual void GetSanitizationInformation( + const char* const** annotations_whitelist, + void** target_module, + bool* sanitize_stacks); +#endif + // This method should return true to configure a crash reporter capable of // monitoring itself for its own crashes to do so, even if self-monitoring // would be expensive. "Expensive" self-monitoring dedicates an additional
diff --git a/components/crash/content/app/crashpad_linux.cc b/components/crash/content/app/crashpad_linux.cc index d494877..f713492 100644 --- a/components/crash/content/app/crashpad_linux.cc +++ b/components/crash/content/app/crashpad_linux.cc
@@ -16,14 +16,17 @@ #include "base/files/scoped_file.h" #include "base/logging.h" #include "base/macros.h" +#include "base/no_destructor.h" #include "base/path_service.h" #include "base/posix/eintr_wrapper.h" #include "base/posix/global_descriptors.h" +#include "base/strings/stringprintf.h" #include "build/build_config.h" #include "components/crash/content/app/crash_reporter_client.h" #include "content/public/common/content_descriptors.h" #include "sandbox/linux/services/syscall_wrappers.h" #include "third_party/crashpad/crashpad/client/crashpad_client.h" +#include "third_party/crashpad/crashpad/snapshot/sanitized/sanitization_information.h" #include "third_party/crashpad/crashpad/util/linux/exception_handler_client.h" #include "third_party/crashpad/crashpad/util/linux/exception_information.h" #include "third_party/crashpad/crashpad/util/misc/from_pointer_cast.h" @@ -32,6 +35,18 @@ namespace crashpad { namespace { +bool SetSanitizationInfo(SanitizationInformation* info) { + const char* const* whitelist = nullptr; + void* target_module = nullptr; + bool sanitize_stacks = false; + crash_reporter::GetCrashReporterClient()->GetSanitizationInformation( + &whitelist, &target_module, &sanitize_stacks); + info->annotations_whitelist_address = FromPointerCast<VMAddress>(whitelist); + info->target_module_address = FromPointerCast<VMAddress>(target_module); + info->sanitize_stacks = sanitize_stacks; + return whitelist != nullptr || target_module != nullptr || sanitize_stacks; +} + // A signal handler for non-browser processes in the sandbox. // Sends a message to a crashpad::CrashHandlerHost to handle the crash. class SandboxedHandler { @@ -42,6 +57,7 @@ } bool Initialize() { + SetSanitizationInfo(&sanitization_); server_fd_ = base::GlobalDescriptors::GetInstance()->Get( service_manager::kCrashDumpSignal); @@ -107,6 +123,10 @@ FromPointerCast<decltype(info.exception_information_address)>( &exception_information); + info.sanitization_information_address = + FromPointerCast<decltype(info.sanitization_information_address)>( + &state->sanitization_); + ExceptionHandlerClient handler_client(connection.get()); handler_client.SetCanSetPtracer(false); handler_client.RequestCrashDump(info); @@ -115,6 +135,7 @@ Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr); } + SanitizationInformation sanitization_; int server_fd_; DISALLOW_COPY_AND_ASSIGN(SandboxedHandler); @@ -246,6 +267,13 @@ return base::FilePath(); } + static base::NoDestructor<crashpad::SanitizationInformation> + sanitization_info; + if (crashpad::SetSanitizationInfo(sanitization_info.get())) { + arguments.push_back(base::StringPrintf("--sanitization-information=%p", + sanitization_info.get())); + } + bool result = GetCrashpadClient().StartHandlerAtCrash( handler_path, database_path, metrics_path, url, process_annotations, arguments);
diff --git a/components/crash/content/browser/crash_handler_host_linux.cc b/components/crash/content/browser/crash_handler_host_linux.cc index 57f710a..e672add 100644 --- a/components/crash/content/browser/crash_handler_host_linux.cc +++ b/components/crash/content/browser/crash_handler_host_linux.cc
@@ -48,7 +48,7 @@ #if !defined(OS_CHROMEOS) #include "components/crash/content/app/crashpad.h" -#include "third_party/crashpad/crashpad/client/crashpad_client.h" +#include "third_party/crashpad/crashpad/client/crashpad_client.h" // nogncheck #endif using content::BrowserThread;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc index 4fd6a10..7a8985e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -468,12 +468,10 @@ void DataReductionProxyNetworkDelegate::OnCompletedInternal( net::URLRequest* request, - bool started) { + bool started, + int net_error) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(request); - // TODO(maksims): remove this once OnCompletedInternal() has net_error in - // arguments. - int net_error = request->status().error(); DCHECK_NE(net::ERR_IO_PENDING, net_error); if (data_reduction_proxy_bypass_stats_) data_reduction_proxy_bypass_stats_->OnUrlRequestCompleted(request, started,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h index 6885ea9..c463381 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
@@ -106,7 +106,8 @@ // |started| indicates whether the request has been started. If false, // some information like the socket address is not available. void OnCompletedInternal(net::URLRequest* request, - bool started) override; + bool started, + int net_error) override; // Checks if a LoFi or Lite Pages response was received and sets the state on // DataReductionProxyData for |request|.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc index 8dabccc..b67be94 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc
@@ -162,7 +162,7 @@ GURL new_url = url; #if defined(USE_GOOGLE_API_KEYS) std::string api_key = google_apis::GetAPIKey(); - if (google_apis::HasKeysConfigured() && !api_key.empty()) { + if (google_apis::HasAPIKeyConfigured() && !api_key.empty()) { new_url = net::AppendOrReplaceQueryParameter(url, kApiKeyName, api_key); } #endif
diff --git a/components/data_use_measurement/core/data_use_network_delegate.cc b/components/data_use_measurement/core/data_use_network_delegate.cc index 3f05e66..0ab9e375 100644 --- a/components/data_use_measurement/core/data_use_network_delegate.cc +++ b/components/data_use_measurement/core/data_use_network_delegate.cc
@@ -63,7 +63,8 @@ } void DataUseNetworkDelegate::OnCompletedInternal(net::URLRequest* request, - bool started) { + bool started, + int net_error) { ascriber_->OnUrlRequestCompleted(request, started); data_use_measurement_.OnCompleted(*request, started); }
diff --git a/components/data_use_measurement/core/data_use_network_delegate.h b/components/data_use_measurement/core/data_use_network_delegate.h index 4fb91f8..5a80d9aa 100644 --- a/components/data_use_measurement/core/data_use_network_delegate.h +++ b/components/data_use_measurement/core/data_use_network_delegate.h
@@ -56,7 +56,9 @@ void OnNetworkBytesSentInternal(net::URLRequest* request, int64_t bytes_sent) override; - void OnCompletedInternal(net::URLRequest* request, bool started) override; + void OnCompletedInternal(net::URLRequest* request, + bool started, + int net_error) override; void OnURLRequestDestroyedInternal(net::URLRequest* request) override;
diff --git a/components/download/internal/common/in_progress_download_manager.cc b/components/download/internal/common/in_progress_download_manager.cc index f3e2369..0db801b 100644 --- a/components/download/internal/common/in_progress_download_manager.cc +++ b/components/download/internal/common/in_progress_download_manager.cc
@@ -322,6 +322,12 @@ GURL(), GURL()); } +bool InProgressDownloadManager::ShouldOpenDownload( + DownloadItemImpl* item, + const ShouldOpenDownloadCallback& callback) { + return true; +} + base::Optional<DownloadEntry> InProgressDownloadManager::GetInProgressEntry( DownloadItemImpl* download) { if (!download || !download_metadata_cache_ || !download_db_cache_)
diff --git a/components/download/public/common/in_progress_download_manager.h b/components/download/public/common/in_progress_download_manager.h index 34a3a62..67afcb0 100644 --- a/components/download/public/common/in_progress_download_manager.h +++ b/components/download/public/common/in_progress_download_manager.h
@@ -116,13 +116,18 @@ const DownloadTargetCallback& callback) override; void ResumeInterruptedDownload(std::unique_ptr<DownloadUrlParameters> params, const GURL& site_url) override; + bool ShouldOpenDownload(DownloadItemImpl* item, + const ShouldOpenDownloadCallback& callback) override; base::Optional<DownloadEntry> GetInProgressEntry( DownloadItemImpl* download) override; void ReportBytesWasted(DownloadItemImpl* download) override; - // Called to remove a in-progress download. + // Called to remove an in-progress download. void RemoveInProgressDownload(const std::string& guid); + // Called to retrieve an in-progress download. + DownloadItemImpl* GetInProgressDownload(const std::string& guid); + void set_file_factory(std::unique_ptr<DownloadFileFactory> file_factory) { file_factory_ = std::move(file_factory); } @@ -156,8 +161,6 @@ std::unique_ptr<DownloadCreateInfo> info, DownloadItemImpl* download); - DownloadItemImpl* GetInProgressDownload(const std::string& guid); - // Active download handlers. std::vector<UrlDownloadHandler::UniqueUrlDownloadHandlerPtr> url_download_handlers_;
diff --git a/components/exo/pointer_unittest.cc b/components/exo/pointer_unittest.cc index 00a3a0d..0eedcf1c 100644 --- a/components/exo/pointer_unittest.cc +++ b/components/exo/pointer_unittest.cc
@@ -27,8 +27,6 @@ namespace exo { namespace { -using PointerTest = test::ExoTestBase; - class MockPointerDelegate : public PointerDelegate { public: MockPointerDelegate() {} @@ -46,6 +44,22 @@ MOCK_METHOD0(OnPointerFrame, void()); }; +class PointerTest : public test::ExoTestBase { + public: + PointerTest() = default; + + void SetUp() override { + test::ExoTestBase::SetUp(); + // Sometimes underlying infra (i.e. X11 / Xvfb) may emit pointer events + // which can break MockPointerDelegate's expectations, so they should be + // consumed before starting. See https://crbug.com/854674. + RunAllPendingInMessageLoop(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(PointerTest); +}; + TEST_F(PointerTest, SetCursor) { std::unique_ptr<Surface> surface(new Surface); std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index 073deda..a4c530a 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc
@@ -1376,48 +1376,119 @@ //////////////////////////////////////////////////////////////////////////////// // xdg_positioner_interface: +uint32_t InvertBitfield(uint32_t bitfield, uint32_t mask) { + return (bitfield & ~mask) | ((bitfield & mask) ^ mask); +} + +// TODO(oshima): propagate x/y flip state to children. struct WaylandPositioner { - // Calculate and return position from current state. - gfx::Point CalculatePosition() const { - gfx::Point position; - + static int CalculateX(const gfx::Size& size, + const gfx::Rect& anchor_rect, + uint32_t anchor, + uint32_t gravity, + int offset) { + int x = offset; if (anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT) - position.set_x(anchor_rect.x()); + x += anchor_rect.x(); else if (anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT) - position.set_x(anchor_rect.right()); + x += anchor_rect.right(); else - position.set_x(anchor_rect.CenterPoint().x()); - - if (anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP) - position.set_y(anchor_rect.y()); - else if (anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM) - position.set_y(anchor_rect.bottom()); - else - position.set_y(anchor_rect.CenterPoint().y()); - - gfx::Vector2d gravity_offset; + x += anchor_rect.CenterPoint().x(); if (gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT) - gravity_offset.set_x(size.width()); - else if (gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT) - gravity_offset.set_x(0); + return x - size.width(); + if (gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT) + return x; + return x - size.width() / 2; + } + + static int CalculateY(const gfx::Size& size, + const gfx::Rect& anchor_rect, + uint32_t anchor, + uint32_t gravity, + int offset) { + int y = offset; + if (anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP) + y += anchor_rect.y(); + else if (anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM) + y += anchor_rect.bottom(); else - gravity_offset.set_x(size.width() / 2); + y += anchor_rect.CenterPoint().y(); if (gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP) - gravity_offset.set_y(size.height()); - else if (gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM) - gravity_offset.set_y(0); - else - gravity_offset.set_y(size.height() / 2); + return y - size.height(); + if (gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM) + return y; + return y - size.height() / 2; + } - return position + offset - gravity_offset; + // Calculate and return position from current state. + gfx::Point CalculatePosition(const gfx::Rect& work_area) const { + constexpr uint32_t kHorizontalAnchors = + ZXDG_POSITIONER_V6_ANCHOR_LEFT | ZXDG_POSITIONER_V6_ANCHOR_RIGHT; + constexpr uint32_t kVerticalAnchors = + ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_BOTTOM; + constexpr uint32_t kHorizontalGravities = + ZXDG_POSITIONER_V6_GRAVITY_LEFT | ZXDG_POSITIONER_V6_GRAVITY_RIGHT; + constexpr uint32_t kVerticalGravities = + ZXDG_POSITIONER_V6_GRAVITY_TOP | ZXDG_POSITIONER_V6_GRAVITY_BOTTOM; + + // TODO(oshima): The size must be smaller than work area. + + gfx::Rect bounds( + gfx::Point(CalculateX(size, anchor_rect, anchor, gravity, offset.x()), + CalculateY(size, anchor_rect, anchor, gravity, offset.y())), + size); + + // Adjust x position if the bounds are not fully contained by the work area. + if (work_area.x() > bounds.x() || work_area.right() < bounds.right()) { + // Allow sliding horizontally if the surface is attached below + // or above the parent surface. + bool can_slide_x = (anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM && + gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM) || + (anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP && + gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP); + if (adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X && + can_slide_x) { + if (bounds.x() < work_area.x()) + bounds.set_x(work_area.x()); + else if (bounds.right() > work_area.right()) + bounds.set_x(work_area.right() - size.width()); + } else if (adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X) { + bounds.set_x(CalculateX( + size, anchor_rect, InvertBitfield(anchor, kHorizontalAnchors), + InvertBitfield(gravity, kHorizontalGravities), -offset.x())); + } + } + + // Adjust y position if the bounds are not fully contained by the work area. + if (work_area.y() > bounds.y() || work_area.bottom() < bounds.bottom()) { + // Allow sliding vertically if the surface is attached left or + // right of the parent surface. + bool can_slide_y = (anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT && + gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT) || + (anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT && + gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT); + if (adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y && + can_slide_y) { + if (bounds.y() < work_area.y()) + bounds.set_y(work_area.y()); + else if (bounds.bottom() > work_area.bottom()) + bounds.set_y(work_area.bottom() - size.height()); + } else if (adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y) { + bounds.set_y(CalculateY( + size, anchor_rect, InvertBitfield(anchor, kVerticalAnchors), + InvertBitfield(gravity, kVerticalGravities), -offset.y())); + } + } + return bounds.origin(); } gfx::Size size; gfx::Rect anchor_rect; uint32_t anchor = ZXDG_POSITIONER_V6_ANCHOR_NONE; uint32_t gravity = ZXDG_POSITIONER_V6_GRAVITY_NONE; + uint32_t adjustment = ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE; gfx::Vector2d offset; }; @@ -1484,11 +1555,10 @@ GetUserDataAs<WaylandPositioner>(resource)->gravity = gravity; } -void xdg_positioner_v6_set_constraint_adjustment( - wl_client* client, - wl_resource* resource, - uint32_t constraint_adjustment) { - NOTIMPLEMENTED(); +void xdg_positioner_v6_set_constraint_adjustment(wl_client* client, + wl_resource* resource, + uint32_t adjustment) { + GetUserDataAs<WaylandPositioner>(resource)->adjustment = adjustment; } void xdg_positioner_v6_set_offset(wl_client* client, @@ -1916,9 +1986,14 @@ "get_popup is called after constructed"); return; } + display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow( + parent->GetWidget()->GetNativeWindow()); + gfx::Rect work_area = display.work_area(); + wm::ConvertRectFromScreen(parent->GetWidget()->GetNativeWindow(), &work_area); gfx::Point position = GetUserDataAs<WaylandPositioner>(positioner_resource) - ->CalculatePosition(); + ->CalculatePosition(work_area); // |position| is relative to the parent's contents view origin, and |origin| // is in screen coordinates. gfx::Point origin = position;
diff --git a/components/favicon/ios/DEPS b/components/favicon/ios/DEPS index 715e140..2c09495 100644 --- a/components/favicon/ios/DEPS +++ b/components/favicon/ios/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/image_fetcher/ios", "+ios/web/public", + "+services/network/public/cpp", # Only parts of skia are compiled on iOS, so we explicitly list the # files that can be included to avoid bringing in more code.
diff --git a/components/favicon/ios/web_favicon_driver.mm b/components/favicon/ios/web_favicon_driver.mm index 8792446..9b708fff 100644 --- a/components/favicon/ios/web_favicon_driver.mm +++ b/components/favicon/ios/web_favicon_driver.mm
@@ -15,6 +15,7 @@ #include "ios/web/public/navigation_manager.h" #include "ios/web/public/web_state/navigation_context.h" #include "ios/web/public/web_state/web_state.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "skia/ext/skia_utils_ios.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/image/image.h" @@ -154,7 +155,7 @@ FaviconService* favicon_service, history::HistoryService* history_service) : FaviconDriverImpl(favicon_service, history_service), - image_fetcher_(web_state->GetBrowserState()->GetRequestContext()), + image_fetcher_(web_state->GetBrowserState()->GetSharedURLLoaderFactory()), web_state_(web_state) { web_state_->AddObserver(this); }
diff --git a/components/feed/core/feed_image_manager_unittest.cc b/components/feed/core/feed_image_manager_unittest.cc index bc3fd38..17b1821 100644 --- a/components/feed/core/feed_image_manager_unittest.cc +++ b/components/feed/core/feed_image_manager_unittest.cc
@@ -16,8 +16,9 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "components/image_fetcher/core/image_decoder.h" #include "components/image_fetcher/core/image_fetcher_impl.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/image/image.h" @@ -59,7 +60,7 @@ class FeedImageManagerTest : public testing::Test { public: - FeedImageManagerTest() : fake_url_fetcher_factory_(nullptr) {} + FeedImageManagerTest() {} ~FeedImageManagerTest() override { feed_image_manager_.reset(); @@ -75,17 +76,17 @@ std::make_unique<FeedImageDatabase>(database_dir_.GetPath()); image_database_ = image_database.get(); - request_context_getter_ = scoped_refptr<net::TestURLRequestContextGetter>( - new net::TestURLRequestContextGetter( - scoped_task_environment_.GetMainThreadTaskRunner())); + shared_factory_ = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_); auto decoder = std::make_unique<FakeImageDecoder>(); decoder->SetExpectedData(kImageData); fake_image_decoder_ = decoder.get(); feed_image_manager_ = std::make_unique<FeedImageManager>( - std::make_unique<image_fetcher::ImageFetcherImpl>( - std::move(decoder), request_context_getter_.get()), + std::make_unique<image_fetcher::ImageFetcherImpl>(std::move(decoder), + shared_factory_), std::move(image_database)); RunUntilIdle(); @@ -111,19 +112,19 @@ FakeImageDecoder* fake_image_decoder() { return fake_image_decoder_; } - net::FakeURLFetcherFactory* fake_url_fetcher_factory() { - return &fake_url_fetcher_factory_; + network::TestURLLoaderFactory* test_url_loader_factory() { + return &test_url_loader_factory_; } MOCK_METHOD1(OnImageLoaded, void(std::string)); private: + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; std::unique_ptr<FeedImageManager> feed_image_manager_; FeedImageDatabase* image_database_; base::ScopedTempDir database_dir_; FakeImageDecoder* fake_image_decoder_; - scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; - net::FakeURLFetcherFactory fake_url_fetcher_factory_; base::test::ScopedTaskEnvironment scoped_task_environment_; DISALLOW_COPY_AND_ASSIGN(FeedImageManagerTest); @@ -158,9 +159,7 @@ TEST_F(FeedImageManagerTest, FetchImagePopulatesCache) { // Expect the image to be fetched by URL. { - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); base::MockCallback<ImageFetchedCallback> image_callback; EXPECT_CALL(image_callback, Run(testing::Property(&gfx::Image::IsEmpty, testing::Eq(false)))); @@ -179,7 +178,7 @@ } // Fetch again. The cache should be populated, no network request is needed. { - fake_url_fetcher_factory()->ClearFakeResponses(); + test_url_loader_factory()->ClearResponses(); base::MockCallback<ImageFetchedCallback> image_callback; EXPECT_CALL(image_callback, Run(testing::Property(&gfx::Image::IsEmpty, testing::Eq(false)))); @@ -193,12 +192,9 @@ TEST_F(FeedImageManagerTest, FetchSecondImageIfFirstFailed) { // Expect the image to be fetched by URL. { - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_NOT_FOUND, - net::URLRequestStatus::FAILED); - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL2), kImageData2, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData, + net::HTTP_NOT_FOUND); + test_url_loader_factory()->AddResponse(kImageURL2, kImageData2); base::MockCallback<ImageFetchedCallback> image_callback; EXPECT_CALL(image_callback, Run(testing::Property(&gfx::Image::IsEmpty, testing::Eq(false)))); @@ -224,9 +220,7 @@ image_database()->SaveImage(kImageURL, kImageData); RunUntilIdle(); { - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); // Set decoding always error. fake_image_decoder()->SetDecodingValid(false); base::MockCallback<ImageFetchedCallback> image_callback;
diff --git a/components/google/core/browser/OWNERS b/components/google/core/browser/OWNERS index 741e9e0..991eb9d1 100644 --- a/components/google/core/browser/OWNERS +++ b/components/google/core/browser/OWNERS
@@ -1,3 +1,2 @@ -per-file google_tld_list.h=mariakhomenko@chromium.org per-file google_tld_list.h=msramek@chromium.org
diff --git a/components/image_fetcher/DEPS b/components/image_fetcher/DEPS index aec4d91..aa4abf5 100644 --- a/components/image_fetcher/DEPS +++ b/components/image_fetcher/DEPS
@@ -1,6 +1,8 @@ include_rules = [ "+components/data_use_measurement/core", "+net", + "+services/network/public/cpp", + "+services/network/test", "+ui/gfx/geometry", "+ui/gfx/image", "+url",
diff --git a/components/image_fetcher/core/BUILD.gn b/components/image_fetcher/core/BUILD.gn index 795d2aa..f9d5576 100644 --- a/components/image_fetcher/core/BUILD.gn +++ b/components/image_fetcher/core/BUILD.gn
@@ -19,6 +19,7 @@ "//base", "//components/data_use_measurement/core", "//net", + "//services/network/public/cpp", "//ui/gfx", "//ui/gfx/geometry", "//url", @@ -36,6 +37,7 @@ public_deps = [ ":core", + "//services/network:test_support", "//testing/gmock", ] }
diff --git a/components/image_fetcher/core/image_data_fetcher.cc b/components/image_fetcher/core/image_data_fetcher.cc index aa203ab5..2ebb33f 100644 --- a/components/image_fetcher/core/image_data_fetcher.cc +++ b/components/image_fetcher/core/image_data_fetcher.cc
@@ -9,9 +9,10 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_status.h" +#include "net/url_request/url_request.h" // for ReferrerPolicy +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" #include "url/gurl.h" using data_use_measurement::DataUseUserData; @@ -24,14 +25,12 @@ namespace image_fetcher { -const int ImageDataFetcher::kFirstUrlFetcherId = 163163; - // An active image URL fetcher request. The struct contains the related requests // state. struct ImageDataFetcher::ImageDataFetcherRequest { ImageDataFetcherRequest(ImageDataFetcherCallback callback, - std::unique_ptr<net::URLFetcher> url_fetcher) - : callback(std::move(callback)), url_fetcher(std::move(url_fetcher)) {} + std::unique_ptr<network::SimpleURLLoader> loader) + : callback(std::move(callback)), loader(std::move(loader)) {} ~ImageDataFetcherRequest() {} @@ -39,24 +38,29 @@ // be run even if the image data could not be fetched successfully. ImageDataFetcherCallback callback; - std::unique_ptr<net::URLFetcher> url_fetcher; + std::unique_ptr<network::SimpleURLLoader> loader; }; ImageDataFetcher::ImageDataFetcher( - net::URLRequestContextGetter* url_request_context_getter) - : url_request_context_getter_(url_request_context_getter), - data_use_service_name_(DataUseUserData::IMAGE_FETCHER_UNTAGGED), - next_url_fetcher_id_(kFirstUrlFetcherId) {} + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : url_loader_factory_(url_loader_factory), + data_use_service_name_(DataUseUserData::IMAGE_FETCHER_UNTAGGED) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} -ImageDataFetcher::~ImageDataFetcher() {} +ImageDataFetcher::~ImageDataFetcher() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} void ImageDataFetcher::SetDataUseServiceName( DataUseServiceName data_use_service_name) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); data_use_service_name_ = data_use_service_name; } void ImageDataFetcher::SetImageDownloadLimit( base::Optional<int64_t> max_download_bytes) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); max_download_bytes_ = max_download_bytes; } @@ -76,74 +80,85 @@ const std::string& referrer, net::URLRequest::ReferrerPolicy referrer_policy, const net::NetworkTrafficAnnotationTag& traffic_annotation) { - std::unique_ptr<net::URLFetcher> url_fetcher = - net::URLFetcher::Create(next_url_fetcher_id_++, image_url, - net::URLFetcher::GET, this, traffic_annotation); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto request = std::make_unique<network::ResourceRequest>(); + request->url = image_url; + request->referrer_policy = referrer_policy; + request->referrer = GURL(referrer); + request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES | + net::LOAD_DO_NOT_SEND_AUTH_DATA; - DataUseUserData::AttachToFetcher(url_fetcher.get(), data_use_service_name_); + // TODO(https://crbug.com/808498) re-add data use measurement once + // SimpleURLLoader supports it. Parameter: + // data_use_service_name_ - std::unique_ptr<ImageDataFetcherRequest> request( - new ImageDataFetcherRequest(std::move(callback), std::move(url_fetcher))); - request->url_fetcher->SetRequestContext(url_request_context_getter_.get()); - request->url_fetcher->SetReferrer(referrer); - request->url_fetcher->SetReferrerPolicy(referrer_policy); - request->url_fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | - net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DO_NOT_SEND_AUTH_DATA); - request->url_fetcher->Start(); + std::unique_ptr<network::SimpleURLLoader> loader = + network::SimpleURLLoader::Create(std::move(request), traffic_annotation); - pending_requests_[request->url_fetcher.get()] = std::move(request); + // For compatibility in error handling. This is a little wasteful since the + // body will get thrown out anyway, though. + loader->SetAllowHttpErrorResults(true); + + if (max_download_bytes_.has_value()) { + loader->DownloadToString( + url_loader_factory_.get(), + base::BindOnce(&ImageDataFetcher::OnURLLoaderComplete, + base::Unretained(this), loader.get()), + max_download_bytes_.value()); + } else { + loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory_.get(), + base::BindOnce(&ImageDataFetcher::OnURLLoaderComplete, + base::Unretained(this), loader.get())); + } + + std::unique_ptr<ImageDataFetcherRequest> request_track( + new ImageDataFetcherRequest(std::move(callback), std::move(loader))); + + pending_requests_[request_track->loader.get()] = std::move(request_track); } -void ImageDataFetcher::OnURLFetchComplete(const net::URLFetcher* source) { +void ImageDataFetcher::OnURLLoaderComplete( + const network::SimpleURLLoader* source, + std::unique_ptr<std::string> response_body) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(pending_requests_.find(source) != pending_requests_.end()); - bool success = source->GetStatus().status() == net::URLRequestStatus::SUCCESS; + bool success = source->NetError() == net::OK; RequestMetadata metadata; - if (success && source->GetResponseHeaders()) { - source->GetResponseHeaders()->GetMimeType(&metadata.mime_type); - metadata.http_response_code = source->GetResponseHeaders()->response_code(); + if (success && source->ResponseInfo() && source->ResponseInfo()->headers) { + net::HttpResponseHeaders* headers = source->ResponseInfo()->headers.get(); + metadata.mime_type = source->ResponseInfo()->mime_type; + metadata.http_response_code = headers->response_code(); // Just read the first value-pair for this header (not caring about |iter|). - source->GetResponseHeaders()->EnumerateHeader( + headers->EnumerateHeader( /*iter=*/nullptr, kContentLocationHeader, &metadata.content_location_header); success &= (metadata.http_response_code == net::HTTP_OK); } std::string image_data; - if (success) { - source->GetResponseAsString(&image_data); + if (success && response_body) { + image_data = std::move(*response_body); } FinishRequest(source, metadata, image_data); } -void ImageDataFetcher::OnURLFetchDownloadProgress( - const net::URLFetcher* source, - int64_t current, - int64_t total, - int64_t current_network_bytes) { - if (!max_download_bytes_.has_value()) { - return; - } - if (total <= max_download_bytes_.value() && - current <= max_download_bytes_.value()) { - return; - } - DCHECK(pending_requests_.find(source) != pending_requests_.end()); - DLOG(WARNING) << "Image data exceeded download size limit."; - RequestMetadata metadata; - metadata.http_response_code = net::URLFetcher::RESPONSE_CODE_INVALID; - - FinishRequest(source, metadata, /*image_data=*/std::string()); -} - -void ImageDataFetcher::FinishRequest(const net::URLFetcher* source, +void ImageDataFetcher::FinishRequest(const network::SimpleURLLoader* source, const RequestMetadata& metadata, const std::string& image_data) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto request_iter = pending_requests_.find(source); DCHECK(request_iter != pending_requests_.end()); std::move(request_iter->second->callback).Run(image_data, metadata); pending_requests_.erase(request_iter); } +void ImageDataFetcher::InjectResultForTesting(const RequestMetadata& metadata, + const std::string& image_data) { + DCHECK_EQ(pending_requests_.size(), 1u); + FinishRequest(pending_requests_.begin()->first, metadata, image_data); +} + } // namespace image_fetcher
diff --git a/components/image_fetcher/core/image_data_fetcher.h b/components/image_fetcher/core/image_data_fetcher.h index 5d02ab3..7dfe059 100644 --- a/components/image_fetcher/core/image_data_fetcher.h +++ b/components/image_fetcher/core/image_data_fetcher.h
@@ -13,37 +13,34 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/optional.h" +#include "base/sequence_checker.h" #include "components/data_use_measurement/core/data_use_user_data.h" #include "components/image_fetcher/core/image_fetcher_types.h" #include "components/image_fetcher/core/request_metadata.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_fetcher_delegate.h" -#include "net/url_request/url_request.h" #include "url/gurl.h" -namespace net { -class URLFetcher; -class URLRequestContextGetter; -} // namespace net +namespace network { +class SharedURLLoaderFactory; +class SimpleURLLoader; +} // namespace network namespace image_fetcher { -class ImageDataFetcher : public net::URLFetcherDelegate { +class ImageDataFetcher { public: - // Fetchers created by this class will be assigned an incremental id starting - // from |kFirstUrlFetcherId|, so unit tests can differentiate the URLFetchers - // used by this class from other fetchers. - const static int kFirstUrlFetcherId; - + // Note that this must be used consistently on the thread that owns + // |url_loader_factory|. See SharedURLLoaderFactory::Clone() if changing + // thread is required. explicit ImageDataFetcher( - net::URLRequestContextGetter* url_request_context_getter); - ~ImageDataFetcher() override; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + ~ImageDataFetcher(); // Sets a service name against which to track data usage. void SetDataUseServiceName(DataUseServiceName data_use_service_name); // Sets an upper limit for image downloads. - // Already running downloads are affected. + // Already running downloads are not affected. void SetImageDownloadLimit(base::Optional<int64_t> max_download_bytes); // Fetches the raw image bytes from the given |image_url| and calls the given @@ -62,38 +59,36 @@ net::URLRequest::ReferrerPolicy referrer_policy, const net::NetworkTrafficAnnotationTag& traffic_annotation); + // Test-only method to inject a fetch result directly, w/o regard for how the + // underlying loading is doing. This requires there to be a single pending + // fetch only. + void InjectResultForTesting(const RequestMetadata& metadata, + const std::string& image_data); + private: struct ImageDataFetcherRequest; - // Methods inherited from URLFetcherDelegate - void OnURLFetchComplete(const net::URLFetcher* source) override; - void OnURLFetchDownloadProgress(const net::URLFetcher* source, - int64_t current, - int64_t total, - int64_t current_network_bytes) override; + void OnURLLoaderComplete(const network::SimpleURLLoader* source, + std::unique_ptr<std::string> response_body); - void FinishRequest(const net::URLFetcher* source, + void FinishRequest(const network::SimpleURLLoader* source, const RequestMetadata& metadata, const std::string& image_data); // All active image url requests. - std::map<const net::URLFetcher*, std::unique_ptr<ImageDataFetcherRequest>> + std::map<const network::SimpleURLLoader*, + std::unique_ptr<ImageDataFetcherRequest>> pending_requests_; - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; DataUseServiceName data_use_service_name_; - // The next ID to use for a newly created URLFetcher. Each URLFetcher gets an - // id when it is created. The |url_fetcher_id_| is incremented by one for each - // newly created URLFetcher. The URLFetcher ID can be used during testing to - // get individual URLFetchers and modify their state. Outside of tests this ID - // is not used. - int next_url_fetcher_id_; - // Upper limit for the number of bytes to download per image. base::Optional<int64_t> max_download_bytes_; + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(ImageDataFetcher); };
diff --git a/components/image_fetcher/core/image_data_fetcher_unittest.cc b/components/image_fetcher/core/image_data_fetcher_unittest.cc index bfcedd2..4c9c3229 100644 --- a/components/image_fetcher/core/image_data_fetcher_unittest.cc +++ b/components/image_fetcher/core/image_data_fetcher_unittest.cc
@@ -13,10 +13,12 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "net/http/http_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_request_status.h" #include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -32,9 +34,10 @@ class ImageDataFetcherTest : public testing::Test { public: ImageDataFetcherTest() - : test_request_context_getter_( - new net::TestURLRequestContextGetter(message_loop_.task_runner())), - image_data_fetcher_(test_request_context_getter_.get()) {} + : shared_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)), + image_data_fetcher_(shared_factory_) {} ~ImageDataFetcherTest() override {} MOCK_METHOD2(OnImageDataFetched, @@ -49,17 +52,18 @@ protected: base::MessageLoop message_loop_; - scoped_refptr<net::URLRequestContextGetter> test_request_context_getter_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; ImageDataFetcher image_data_fetcher_; - net::TestURLFetcherFactory fetcher_factory_; - private: DISALLOW_COPY_AND_ASSIGN(ImageDataFetcherTest); }; TEST_F(ImageDataFetcherTest, FetchImageData) { + std::string content = kURLResponseData; + image_data_fetcher_.FetchImageData( GURL(kImageURL), base::BindOnce(&ImageDataFetcherTest::OnImageDataFetched, @@ -69,35 +73,33 @@ RequestMetadata expected_metadata; expected_metadata.mime_type = std::string("image/png"); expected_metadata.http_response_code = net::HTTP_OK; - EXPECT_CALL(*this, OnImageDataFetched(std::string(kURLResponseData), - expected_metadata)); + EXPECT_CALL(*this, OnImageDataFetched(content, expected_metadata)); - // Get and configure the TestURLFetcher. - net::TestURLFetcher* test_url_fetcher = - fetcher_factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId); - ASSERT_NE(nullptr, test_url_fetcher); - EXPECT_TRUE(test_url_fetcher->GetLoadFlags() & net::LOAD_DO_NOT_SEND_COOKIES); - EXPECT_TRUE(test_url_fetcher->GetLoadFlags() & net::LOAD_DO_NOT_SAVE_COOKIES); - EXPECT_TRUE(test_url_fetcher->GetLoadFlags() & - net::LOAD_DO_NOT_SEND_AUTH_DATA); - test_url_fetcher->set_status( - net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); - test_url_fetcher->SetResponseString(kURLResponseData); - test_url_fetcher->set_response_code(net::HTTP_OK); + // Check to make sure the request is pending with proper flags, and + // provide a response. + int pending_load_flags = 0; + EXPECT_TRUE( + test_url_loader_factory_.IsPending(kImageURL, &pending_load_flags)); + EXPECT_TRUE(pending_load_flags & net::LOAD_DO_NOT_SEND_COOKIES); + EXPECT_TRUE(pending_load_flags & net::LOAD_DO_NOT_SAVE_COOKIES); + EXPECT_TRUE(pending_load_flags & net::LOAD_DO_NOT_SEND_AUTH_DATA); + network::ResourceResponseHead head; std::string raw_header = "HTTP/1.1 200 OK\n" "Content-type: image/png\n\n"; - std::replace(raw_header.begin(), raw_header.end(), '\n', '\0'); - scoped_refptr<net::HttpResponseHeaders> headers( - new net::HttpResponseHeaders(raw_header)); - test_url_fetcher->set_response_headers(headers); - - // Call the URLFetcher delegate to continue the test. - test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher); + head.headers = new net::HttpResponseHeaders( + net::HttpUtil::AssembleRawHeaders(raw_header.c_str(), raw_header.size())); + head.mime_type = "image/png"; + network::URLLoaderCompletionStatus status; + status.decoded_body_length = content.size(); + test_url_loader_factory_.AddResponse(GURL(kImageURL), head, content, status); + base::RunLoop().RunUntilIdle(); } TEST_F(ImageDataFetcherTest, FetchImageData_NotFound) { + std::string content = kURLResponseData; + image_data_fetcher_.FetchImageData( GURL(kImageURL), base::BindOnce(&ImageDataFetcherTest::OnImageDataFetched, @@ -110,27 +112,25 @@ // For 404, expect an empty result even though correct image data is sent. EXPECT_CALL(*this, OnImageDataFetched(std::string(), expected_metadata)); - // Get and configure the TestURLFetcher. - net::TestURLFetcher* test_url_fetcher = - fetcher_factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId); - ASSERT_NE(nullptr, test_url_fetcher); - test_url_fetcher->set_status( - net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); - test_url_fetcher->SetResponseString(kURLResponseData); + // Check to make sure the request is pending, and provide a response. + EXPECT_TRUE(test_url_loader_factory_.IsPending(kImageURL)); + network::ResourceResponseHead head; std::string raw_header = "HTTP/1.1 404 Not Found\n" "Content-type: image/png\n\n"; - std::replace(raw_header.begin(), raw_header.end(), '\n', '\0'); - scoped_refptr<net::HttpResponseHeaders> headers( - new net::HttpResponseHeaders(raw_header)); - test_url_fetcher->set_response_headers(headers); - - // Call the URLFetcher delegate to continue the test. - test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher); + head.headers = new net::HttpResponseHeaders( + net::HttpUtil::AssembleRawHeaders(raw_header.c_str(), raw_header.size())); + head.mime_type = "image/png"; + network::URLLoaderCompletionStatus status; + status.decoded_body_length = content.size(); + test_url_loader_factory_.AddResponse(GURL(kImageURL), head, content, status); + base::RunLoop().RunUntilIdle(); } TEST_F(ImageDataFetcherTest, FetchImageData_WithContentLocation) { + std::string content = kURLResponseData; + image_data_fetcher_.FetchImageData( GURL(kImageURL), base::BindOnce(&ImageDataFetcherTest::OnImageDataFetched, @@ -144,25 +144,21 @@ // For 404, expect an empty result even though correct image data is sent. EXPECT_CALL(*this, OnImageDataFetched(std::string(), expected_metadata)); - // Get and configure the TestURLFetcher. - net::TestURLFetcher* test_url_fetcher = - fetcher_factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId); - ASSERT_NE(nullptr, test_url_fetcher); - test_url_fetcher->set_status( - net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); - test_url_fetcher->SetResponseString(kURLResponseData); + // Check to make sure the request is pending, and provide a response. + EXPECT_TRUE(test_url_loader_factory_.IsPending(kImageURL)); + network::ResourceResponseHead head; std::string raw_header = "HTTP/1.1 404 Not Found\n" "Content-type: image/png\n" "Content-location: http://test-location/image.png\n\n"; - std::replace(raw_header.begin(), raw_header.end(), '\n', '\0'); - scoped_refptr<net::HttpResponseHeaders> headers( - new net::HttpResponseHeaders(raw_header)); - test_url_fetcher->set_response_headers(headers); - - // Call the URLFetcher delegate to continue the test. - test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher); + head.headers = new net::HttpResponseHeaders( + net::HttpUtil::AssembleRawHeaders(raw_header.c_str(), raw_header.size())); + head.mime_type = "image/png"; + network::URLLoaderCompletionStatus status; + status.decoded_body_length = content.size(); + test_url_loader_factory_.AddResponse(GURL(kImageURL), head, content, status); + base::RunLoop().RunUntilIdle(); } TEST_F(ImageDataFetcherTest, FetchImageData_FailedRequest) { @@ -177,15 +173,15 @@ EXPECT_CALL( *this, OnImageDataFetchedFailedRequest(std::string(), expected_metadata)); - // Get and configure the TestURLFetcher. - net::TestURLFetcher* test_url_fetcher = - fetcher_factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId); - ASSERT_NE(nullptr, test_url_fetcher); - test_url_fetcher->set_status(net::URLRequestStatus( - net::URLRequestStatus::FAILED, net::ERR_INVALID_URL)); + // Check to make sure the request is pending, and provide a response. + EXPECT_TRUE(test_url_loader_factory_.IsPending(kImageURL)); - // Call the URLFetcher delegate to continue the test. - test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher); + network::ResourceResponseHead head; + head.mime_type = "image/png"; + network::URLLoaderCompletionStatus status; + status.error_code = net::ERR_INVALID_URL; + test_url_loader_factory_.AddResponse(GURL(kImageURL), head, "", status); + base::RunLoop().RunUntilIdle(); } TEST_F(ImageDataFetcherTest, FetchImageData_MultipleRequests) { @@ -205,23 +201,15 @@ // Multiple calls to FetchImageData for the same URL will result in // multiple URLFetchers being created. - net::TestURLFetcher* test_url_fetcher = - fetcher_factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId); - ASSERT_NE(nullptr, test_url_fetcher); - test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher); - - test_url_fetcher = - fetcher_factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId + 1); - ASSERT_NE(nullptr, test_url_fetcher); - test_url_fetcher->delegate()->OnURLFetchComplete(test_url_fetcher); + EXPECT_EQ(2, test_url_loader_factory_.NumPending()); + test_url_loader_factory_.AddResponse(kImageURL, ""); + base::RunLoop().RunUntilIdle(); } TEST_F(ImageDataFetcherTest, FetchImageData_CancelFetchIfImageExceedsMaxSize) { - // In order to know whether the fetcher was canceled, it must notify about its - // deletion. - fetcher_factory_.set_remove_fetcher_on_delete(true); + const int64_t kMaxDownloadBytes = 1024; + std::string oversize_download(kMaxDownloadBytes + 1, '#'); - const int64_t kMaxDownloadBytes = 1024 * 1024; image_data_fetcher_.SetImageDownloadLimit(kMaxDownloadBytes); image_data_fetcher_.FetchImageData( GURL(kImageURL), @@ -236,55 +224,9 @@ expected_metadata.http_response_code = net::URLFetcher::RESPONSE_CODE_INVALID; EXPECT_CALL(*this, OnImageDataFetched(std::string(), expected_metadata)); - // Get and configure the TestURLFetcher. - net::TestURLFetcher* test_url_fetcher = - fetcher_factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId); - ASSERT_NE(nullptr, test_url_fetcher); - - // Create a completely valid response that is never used. This is to make sure - // that the answer isn't accidentally invalid but intentionally. - test_url_fetcher->set_status( - net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); - test_url_fetcher->SetResponseString(kURLResponseData); - test_url_fetcher->set_response_code(net::HTTP_OK); - std::string raw_header = - "HTTP/1.1 200 OK\n" - "Content-type: image/png\n\n"; - std::replace(raw_header.begin(), raw_header.end(), '\n', '\0'); - scoped_refptr<net::HttpResponseHeaders> headers( - new net::HttpResponseHeaders(raw_header)); - test_url_fetcher->set_response_headers(headers); - - test_url_fetcher->delegate()->OnURLFetchDownloadProgress( - test_url_fetcher, - /*current=*/0, // Bytes received up to the call. - /*total=*/-1, // not determined - /*current_network_bytes=*/0); // not relevant - // The URL fetch should be running ... - ASSERT_NE(nullptr, fetcher_factory_.GetFetcherByID( - ImageDataFetcher::kFirstUrlFetcherId)); - - test_url_fetcher->delegate()->OnURLFetchDownloadProgress( - test_url_fetcher, - 768 * 1024, // Current bytes are not exeeding the limit. - /*total=*/-1, /*current_network_bytes=*/0); - // ... and running ... - ASSERT_NE(nullptr, fetcher_factory_.GetFetcherByID( - ImageDataFetcher::kFirstUrlFetcherId)); - - test_url_fetcher->delegate()->OnURLFetchDownloadProgress( - test_url_fetcher, kMaxDownloadBytes, // Still not exeeding the limit. - /*total=*/-1, /*current_network_bytes=*/0); - // ... and running ... - ASSERT_NE(nullptr, fetcher_factory_.GetFetcherByID( - ImageDataFetcher::kFirstUrlFetcherId)); - - test_url_fetcher->delegate()->OnURLFetchDownloadProgress( - test_url_fetcher, kMaxDownloadBytes + 1, // Limits are exceeded. - /*total=*/-1, /*current_network_bytes=*/0); - // ... and be canceled. - EXPECT_EQ(nullptr, fetcher_factory_.GetFetcherByID( - ImageDataFetcher::kFirstUrlFetcherId)); + EXPECT_TRUE(test_url_loader_factory_.IsPending(kImageURL)); + test_url_loader_factory_.AddResponse(kImageURL, oversize_download); + base::RunLoop().RunUntilIdle(); } } // namespace image_fetcher
diff --git a/components/image_fetcher/core/image_fetcher.h b/components/image_fetcher/core/image_fetcher.h index c5894c1..33fa25d 100644 --- a/components/image_fetcher/core/image_fetcher.h +++ b/components/image_fetcher/core/image_fetcher.h
@@ -35,7 +35,7 @@ // Sets an upper limit for image downloads that is by default disabled. // Setting |max_download_bytes| to a negative value will disable the limit. - // Already running downloads are immediately affected. + // Already running downloads are not affected. virtual void SetImageDownloadLimit( base::Optional<int64_t> max_download_bytes) = 0;
diff --git a/components/image_fetcher/core/image_fetcher_impl.cc b/components/image_fetcher/core/image_fetcher_impl.cc index 5b98424..3b1615f 100644 --- a/components/image_fetcher/core/image_fetcher_impl.cc +++ b/components/image_fetcher/core/image_fetcher_impl.cc
@@ -9,17 +9,17 @@ #include "base/bind.h" #include "base/threading/thread_task_runner_handle.h" #include "net/base/load_flags.h" -#include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/gfx/image/image.h" namespace image_fetcher { ImageFetcherImpl::ImageFetcherImpl( std::unique_ptr<ImageDecoder> image_decoder, - net::URLRequestContextGetter* url_request_context) - : url_request_context_(url_request_context), + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : url_loader_factory_(url_loader_factory), image_decoder_(std::move(image_decoder)), - image_data_fetcher_(new ImageDataFetcher(url_request_context_.get())) {} + image_data_fetcher_(new ImageDataFetcher(url_loader_factory)) {} ImageFetcherImpl::~ImageFetcherImpl() {}
diff --git a/components/image_fetcher/core/image_fetcher_impl.h b/components/image_fetcher/core/image_fetcher_impl.h index 05c0b468..0b7a2eb 100644 --- a/components/image_fetcher/core/image_fetcher_impl.h +++ b/components/image_fetcher/core/image_fetcher_impl.h
@@ -24,8 +24,8 @@ class Image; } -namespace net { -class URLRequestContextGetter; +namespace network { +class SharedURLLoaderFactory; } namespace image_fetcher { @@ -33,8 +33,9 @@ // The standard (non-test) implementation of ImageFetcher. class ImageFetcherImpl : public ImageFetcher { public: - ImageFetcherImpl(std::unique_ptr<ImageDecoder> image_decoder, - net::URLRequestContextGetter* url_request_context); + ImageFetcherImpl( + std::unique_ptr<ImageDecoder> image_decoder, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); ~ImageFetcherImpl() override; // Sets a service name against which to track data usage. @@ -89,7 +90,7 @@ gfx::Size desired_image_frame_size_; - scoped_refptr<net::URLRequestContextGetter> url_request_context_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; std::unique_ptr<ImageDecoder> image_decoder_;
diff --git a/components/image_fetcher/core/image_fetcher_impl_unittest.cc b/components/image_fetcher/core/image_fetcher_impl_unittest.cc index 3348f40..8b556eb9 100644 --- a/components/image_fetcher/core/image_fetcher_impl_unittest.cc +++ b/components/image_fetcher/core/image_fetcher_impl_unittest.cc
@@ -14,9 +14,10 @@ #include "base/test/scoped_task_environment.h" #include "components/image_fetcher/core/image_decoder.h" #include "components/image_fetcher/core/image_fetcher.h" +#include "net/http/http_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/image/image.h" @@ -67,30 +68,29 @@ class ImageFetcherImplTest : public testing::Test { public: - ImageFetcherImplTest() : fake_url_fetcher_factory_(nullptr) { - request_context_getter_ = scoped_refptr<net::TestURLRequestContextGetter>( - new net::TestURLRequestContextGetter( - scoped_task_environment_.GetMainThreadTaskRunner())); - + ImageFetcherImplTest() + : shared_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)) { auto decoder = std::make_unique<FakeImageDecoder>(); fake_image_decoder_ = decoder.get(); image_fetcher_ = std::make_unique<image_fetcher::ImageFetcherImpl>( - std::move(decoder), request_context_getter_.get()); + std::move(decoder), shared_factory_); } void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } FakeImageDecoder* image_decoder() { return fake_image_decoder_; } - net::FakeURLFetcherFactory* fake_url_fetcher_factory() { - return &fake_url_fetcher_factory_; + network::TestURLLoaderFactory* test_url_loader_factory() { + return &test_url_loader_factory_; } ImageFetcherImpl* image_fetcher() { return image_fetcher_.get(); } private: std::unique_ptr<ImageFetcherImpl> image_fetcher_; FakeImageDecoder* fake_image_decoder_; - net::FakeURLFetcherFactory fake_url_fetcher_factory_; - scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; base::test::ScopedTaskEnvironment scoped_task_environment_; DISALLOW_COPY_AND_ASSIGN(ImageFetcherImplTest); @@ -103,9 +103,7 @@ } TEST_F(ImageFetcherImplTest, FetchImageAndDataSuccess) { - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); base::MockCallback<ImageDataFetcherCallback> data_callback; base::MockCallback<ImageFetcherCallback> image_callback; EXPECT_CALL(data_callback, Run(kImageData, _)); @@ -119,9 +117,7 @@ TEST_F(ImageFetcherImplTest, FetchImageAndData3xSuccess) { // Fetch an image three times. - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); base::MockCallback<ImageDataFetcherCallback> data_callback1; base::MockCallback<ImageFetcherCallback> image_callback1; EXPECT_CALL(data_callback1, Run(kImageData, _)); @@ -149,9 +145,7 @@ image_decoder()->SetBeforeImageDecoded(base::BindLambdaForTesting([&]() { // This happens after the network request completes. // Shouldn't need to fetch. - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), "", - net::HTTP_NOT_FOUND, - net::URLRequestStatus::FAILED); + test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND); image_fetcher()->FetchImageAndData( kFetchID2, GURL(kImageURL), data_callback3.Get(), image_callback3.Get(), TRAFFIC_ANNOTATION_FOR_TESTS); @@ -163,8 +157,7 @@ TEST_F(ImageFetcherImplTest, FetchImageAndData2xFail) { // Fetch an image two times. The fetch fails. image_decoder()->SetEnabled(false); - fake_url_fetcher_factory()->SetFakeResponse( - GURL(kImageURL), "", net::HTTP_NOT_FOUND, net::URLRequestStatus::FAILED); + test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND); base::MockCallback<ImageDataFetcherCallback> data_callback1; base::MockCallback<ImageFetcherCallback> image_callback1; EXPECT_CALL(data_callback1, Run("", _)); @@ -188,9 +181,7 @@ TEST_F(ImageFetcherImplTest, FetchOnlyData) { image_decoder()->SetEnabled(false); - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); base::MockCallback<ImageDataFetcherCallback> data_callback; EXPECT_CALL(data_callback, Run(kImageData, _)); @@ -202,9 +193,7 @@ } TEST_F(ImageFetcherImplTest, FetchDataThenImage) { - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); base::MockCallback<ImageDataFetcherCallback> data_callback; EXPECT_CALL(data_callback, Run(kImageData, _)); @@ -223,9 +212,7 @@ } TEST_F(ImageFetcherImplTest, FetchImageThenData) { - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); base::MockCallback<ImageFetcherCallback> image_callback; EXPECT_CALL(image_callback, Run(kFetchID, ValidImage(), _)); @@ -240,9 +227,7 @@ image_decoder()->SetBeforeImageDecoded(base::BindLambdaForTesting([&]() { // This happens after the network request completes. // Shouldn't need to fetch. - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), "", - net::HTTP_NOT_FOUND, - net::URLRequestStatus::FAILED); + test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND); image_fetcher()->FetchImageAndData( kFetchID2, GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(), TRAFFIC_ANNOTATION_FOR_TESTS);
diff --git a/components/image_fetcher/ios/BUILD.gn b/components/image_fetcher/ios/BUILD.gn index 99ab37a4..015a12f 100644 --- a/components/image_fetcher/ios/BUILD.gn +++ b/components/image_fetcher/ios/BUILD.gn
@@ -34,8 +34,10 @@ ":ios", ":webp_transcode_unit_tests_bundle_data", "//base", + "//base/test:test_support", "//net", - "//net:test_support", + "//services/network:test_support", + "//services/network/public/cpp", "//testing/gmock", "//testing/gtest", "//ui/gfx",
diff --git a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h index a12da7b..9c13e03 100644 --- a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h +++ b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h
@@ -12,8 +12,8 @@ #include "components/image_fetcher/core/image_data_fetcher.h" #include "components/image_fetcher/core/image_fetcher_types.h" -namespace net { -class URLRequestContextGetter; +namespace network { +class SharedURLLoaderFactory; } class GURL; @@ -24,7 +24,7 @@ public: // The TaskRunner is used to decode the image if it is WebP-encoded. explicit IOSImageDataFetcherWrapper( - net::URLRequestContextGetter* url_request_context_getter); + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); virtual ~IOSImageDataFetcherWrapper(); // Helper to start downloading and possibly decoding the image without a @@ -47,6 +47,11 @@ // Sets a service name against which to track data usage. void SetDataUseServiceName(DataUseServiceName data_use_service_name); + // Test-only accessor for underlying ImageDataFetcher. + ImageDataFetcher* AccessImageDataFetcherForTesting() { + return &image_data_fetcher_; + } + private: ImageDataFetcherCallback CallbackForImageDataFetcher( ImageDataFetcherBlock callback);
diff --git a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm index 12e5f756..aaf955d 100644 --- a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm +++ b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm
@@ -10,7 +10,7 @@ #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_fetcher.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "url/url_constants.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -22,8 +22,8 @@ namespace image_fetcher { IOSImageDataFetcherWrapper::IOSImageDataFetcherWrapper( - net::URLRequestContextGetter* url_request_context_getter) - : image_data_fetcher_(url_request_context_getter) {} + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : image_data_fetcher_(url_loader_factory) {} IOSImageDataFetcherWrapper::~IOSImageDataFetcherWrapper() {}
diff --git a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm index 9d067a7..1f8bcb2 100644 --- a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm +++ b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm
@@ -9,17 +9,17 @@ #include <memory> #include "base/mac/scoped_block.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/stl_util.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #import "components/image_fetcher/ios/webp_decoder.h" #include "net/http/http_response_headers.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_fetcher_delegate.h" -#include "net/url_request/url_request_test_util.h" +#include "net/http/http_status_code.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -111,27 +111,25 @@ result_ = [UIImage imageWithData:data]; called_ = true; } copy]) { - image_fetcher_ = std::make_unique<IOSImageDataFetcherWrapper>( - new net::TestURLRequestContextGetter( - base::ThreadTaskRunnerHandle::Get())); + shared_factory_ = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &factory_); + image_fetcher_ = + std::make_unique<IOSImageDataFetcherWrapper>(shared_factory_); } - net::TestURLFetcher* SetupFetcher() { + void SetupFetcher() { image_fetcher_->FetchImageDataWebpDecoded(GURL(kTestUrl), callback_); EXPECT_EQ(nil, result_); EXPECT_EQ(false, called_); - net::TestURLFetcher* fetcher = - factory_.GetFetcherByID(ImageDataFetcher::kFirstUrlFetcherId); - DCHECK(fetcher); - DCHECK(fetcher->delegate()); - return fetcher; } // Message loop for the main test thread. base::test::ScopedTaskEnvironment environment_; base::mac::ScopedBlock<ImageDataFetcherBlock> callback_; - net::TestURLFetcherFactory factory_; + network::TestURLLoaderFactory factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; std::unique_ptr<IOSImageDataFetcherWrapper> image_fetcher_; NSData* result_data_ = nil; UIImage* result_ = nil; @@ -142,77 +140,88 @@ }; TEST_F(IOSImageDataFetcherWrapperTest, TestError) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(404); - fetcher->delegate()->OnURLFetchComplete(fetcher); + SetupFetcher(); + factory_.AddResponse(kTestUrl, "", net::HTTP_NOT_FOUND); + environment_.RunUntilIdle(); EXPECT_EQ(nil, result_); EXPECT_TRUE(called_); } TEST_F(IOSImageDataFetcherWrapperTest, TestJpg) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString( + SetupFetcher(); + factory_.AddResponse( + kTestUrl, std::string(reinterpret_cast<const char*>(kJPGImage), sizeof(kJPGImage))); - fetcher->delegate()->OnURLFetchComplete(fetcher); + environment_.RunUntilIdle(); EXPECT_NE(nil, result_); EXPECT_TRUE(called_); } TEST_F(IOSImageDataFetcherWrapperTest, TestPng) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString( + SetupFetcher(); + factory_.AddResponse( + kTestUrl, std::string(reinterpret_cast<const char*>(kPNGImage), sizeof(kPNGImage))); - fetcher->delegate()->OnURLFetchComplete(fetcher); + environment_.RunUntilIdle(); EXPECT_NE(nil, result_); EXPECT_TRUE(called_); } TEST_F(IOSImageDataFetcherWrapperTest, TestGoodWebP) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString(std::string( - reinterpret_cast<const char*>(kWEBPImage), sizeof(kWEBPImage))); - scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders( - std::string(kWEBPHeaderResponse, arraysize(kWEBPHeaderResponse)))); - fetcher->set_response_headers(headers); - fetcher->delegate()->OnURLFetchComplete(fetcher); + SetupFetcher(); + + std::string content(reinterpret_cast<const char*>(kWEBPImage), + sizeof(kWEBPImage)); + network::ResourceResponseHead head; + head.headers = new net::HttpResponseHeaders( + std::string(kWEBPHeaderResponse, base::size(kWEBPHeaderResponse))); + head.mime_type = "image/webp"; + network::URLLoaderCompletionStatus status; + status.decoded_body_length = content.size(); + factory_.AddResponse(GURL(kTestUrl), head, content, status); environment_.RunUntilIdle(); EXPECT_NE(nil, result_); EXPECT_TRUE(called_); } TEST_F(IOSImageDataFetcherWrapperTest, TestGoodWebPNoHeader) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString(std::string( - reinterpret_cast<const char*>(kWEBPImage), sizeof(kWEBPImage))); - fetcher->delegate()->OnURLFetchComplete(fetcher); + SetupFetcher(); + factory_.AddResponse(kTestUrl, + std::string(reinterpret_cast<const char*>(kWEBPImage), + sizeof(kWEBPImage))); environment_.RunUntilIdle(); EXPECT_TRUE([DecodedWebpImage() isEqualToData:result_data_]); EXPECT_TRUE(called_); } TEST_F(IOSImageDataFetcherWrapperTest, TestBadWebP) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString("This is not a valid WebP image"); - scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders( - std::string(kWEBPHeaderResponse, arraysize(kWEBPHeaderResponse)))); - fetcher->set_response_headers(headers); - fetcher->delegate()->OnURLFetchComplete(fetcher); + SetupFetcher(); + + std::string content = "This is not a valid WebP image"; + network::ResourceResponseHead head; + head.headers = new net::HttpResponseHeaders( + std::string(kWEBPHeaderResponse, base::size(kWEBPHeaderResponse))); + head.mime_type = "image/webp"; + network::URLLoaderCompletionStatus status; + status.decoded_body_length = content.size(); + factory_.AddResponse(GURL(kTestUrl), head, content, status); environment_.RunUntilIdle(); EXPECT_EQ(nil, result_); EXPECT_TRUE(called_); } TEST_F(IOSImageDataFetcherWrapperTest, DeleteDuringWebPDecoding) { - net::TestURLFetcher* fetcher = SetupFetcher(); - fetcher->set_response_code(200); - fetcher->SetResponseString(std::string( - reinterpret_cast<const char*>(kWEBPImage), sizeof(kWEBPImage))); - fetcher->delegate()->OnURLFetchComplete(fetcher); + SetupFetcher(); + // To control timing of events precisely below, this needs to inject the + // result synchronously, so it's done via some test-only methods rather than + // via TestURLLoaderFactory. + image_fetcher::RequestMetadata metadata; + metadata.mime_type = "image/webp"; + metadata.http_response_code = 200; + image_fetcher_->AccessImageDataFetcherForTesting()->InjectResultForTesting( + metadata, std::string(reinterpret_cast<const char*>(kWEBPImage), + sizeof(kWEBPImage))); + // Delete the image fetcher, and check that the callback is called. image_fetcher_.reset(); environment_.RunUntilIdle();
diff --git a/components/minidump_uploader/OWNERS b/components/minidump_uploader/OWNERS index 6b952ef..1c0302a 100644 --- a/components/minidump_uploader/OWNERS +++ b/components/minidump_uploader/OWNERS
@@ -1,7 +1,3 @@ -# Java readability -mariakhomenko@chromium.org - -# Crash uploading mechanism gsennton@chromium.org isherman@chromium.org
diff --git a/components/mirroring/service/BUILD.gn b/components/mirroring/service/BUILD.gn index 1396260..7a3cfe4 100644 --- a/components/mirroring/service/BUILD.gn +++ b/components/mirroring/service/BUILD.gn
@@ -27,6 +27,8 @@ sources = [ "captured_audio_input.cc", "captured_audio_input.h", + "media_remoter.cc", + "media_remoter.h", "message_dispatcher.cc", "message_dispatcher.h", "mirror_settings.cc", @@ -85,6 +87,7 @@ "fake_network_service.h", "fake_video_capture_host.cc", "fake_video_capture_host.h", + "media_remoter_unittest.cc", "message_dispatcher_unittest.cc", "receiver_response_unittest.cc", "remoting_sender_unittest.cc",
diff --git a/components/mirroring/service/media_remoter.cc b/components/mirroring/service/media_remoter.cc new file mode 100644 index 0000000..c1c39fd --- /dev/null +++ b/components/mirroring/service/media_remoter.cc
@@ -0,0 +1,195 @@ +// 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/mirroring/service/media_remoter.h" + +#include "base/base64.h" +#include "base/callback.h" +#include "base/json/json_writer.h" +#include "base/logging.h" +#include "base/strings/string_piece.h" +#include "base/values.h" +#include "components/mirroring/service/interface.h" +#include "components/mirroring/service/message_dispatcher.h" +#include "components/mirroring/service/remoting_sender.h" +#include "media/cast/net/cast_transport.h" + +using media::cast::Codec; +using media::cast::FrameSenderConfig; + +namespace mirroring { + +MediaRemoter::MediaRemoter( + Client* client, + const media::mojom::RemotingSinkMetadata& sink_metadata, + MessageDispatcher* message_dispatcher) + : client_(client), + sink_metadata_(sink_metadata), + message_dispatcher_(message_dispatcher), + binding_(this), + cast_environment_(nullptr), + transport_(nullptr), + state_(MIRRORING), + weak_factory_(this) { + DCHECK(client_); + DCHECK(message_dispatcher_); + + media::mojom::RemoterPtr remoter; + binding_.Bind(mojo::MakeRequest(&remoter)); + client_->ConnectToRemotingSource(std::move(remoter), + mojo::MakeRequest(&remoting_source_)); + remoting_source_->OnSinkAvailable(sink_metadata_.Clone()); +} + +MediaRemoter::~MediaRemoter() { + // Stop this remoting session if mirroring is stopped during a remoting + // session. For example, user stops mirroring through the cast dialog or + // closes the tab. + Stop(media::mojom::RemotingStopReason::ROUTE_TERMINATED); +} + +void MediaRemoter::OnMessageFromSink(const ReceiverResponse& response) { + DCHECK_EQ(ResponseType::RPC, response.type); + remoting_source_->OnMessageFromSink( + std::vector<uint8_t>(response.rpc.begin(), response.rpc.end())); +} + +void MediaRemoter::StartRpcMessaging( + scoped_refptr<media::cast::CastEnvironment> cast_environment, + media::cast::CastTransport* transport, + const FrameSenderConfig& audio_config, + const FrameSenderConfig& video_config) { + DCHECK(!cast_environment_); + DCHECK(!transport_); + DCHECK_EQ(Codec::CODEC_UNKNOWN, audio_config_.codec); + DCHECK_EQ(Codec::CODEC_UNKNOWN, video_config_.codec); + DCHECK(audio_config.codec == Codec::CODEC_AUDIO_REMOTE || + video_config.codec == Codec::CODEC_VIDEO_REMOTE); + + if (state_ != STARTING_REMOTING) + return; // Start operation was canceled. + // A remoting streaming session started. Start RPC message transport and + // notify the remoting source to start data streaming. + cast_environment_ = std::move(cast_environment); + transport_ = transport; + audio_config_ = audio_config; + video_config_ = video_config; + message_dispatcher_->Subscribe( + ResponseType::RPC, base::BindRepeating(&MediaRemoter::OnMessageFromSink, + weak_factory_.GetWeakPtr())); + state_ = REMOTING_STARTED; + remoting_source_->OnStarted(); +} + +void MediaRemoter::OnMirroringResumed() { + if (state_ == REMOTING_DISABLED) + return; + DCHECK_EQ(STOPPING_REMOTING, state_); + state_ = MIRRORING; + // Notify the remoting source to enable starting media remoting again. + remoting_source_->OnSinkAvailable(sink_metadata_.Clone()); +} + +void MediaRemoter::OnRemotingFailed() { + DCHECK(state_ == STARTING_REMOTING || state_ == REMOTING_STARTED); + if (state_ == STARTING_REMOTING) { + // TODO(xjz): Rename SERVICE_NOT_CONNECTED to INVALID_ANSWER_MESSAGE. + remoting_source_->OnStartFailed( + media::mojom::RemotingStartFailReason::SERVICE_NOT_CONNECTED); + } + state_ = REMOTING_DISABLED; + remoting_source_->OnSinkGone(); + // Fallback to mirroring. + client_->RestartMirroringStreaming(); +} + +void MediaRemoter::Stop(media::mojom::RemotingStopReason reason) { + if (state_ != STARTING_REMOTING && state_ != REMOTING_STARTED) + return; + if (state_ == REMOTING_STARTED) { + message_dispatcher_->Unsubscribe(ResponseType::RPC); + audio_sender_.reset(); + video_sender_.reset(); + cast_environment_ = nullptr; + transport_ = nullptr; + audio_config_ = FrameSenderConfig(); + video_config_ = FrameSenderConfig(); + } + state_ = STOPPING_REMOTING; + remoting_source_->OnStopped(reason); + // Prevent the start of remoting until switching completes. + remoting_source_->OnSinkGone(); + // Switch to mirroring. + client_->RestartMirroringStreaming(); +} + +void MediaRemoter::Start() { + if (state_ != MIRRORING) { + VLOG(2) << "Warning: Ignore start request. state=" << state_; + return; + } + state_ = STARTING_REMOTING; + client_->RequestRemotingStreaming(); +} + +void MediaRemoter::StartDataStreams( + mojo::ScopedDataPipeConsumerHandle audio_pipe, + mojo::ScopedDataPipeConsumerHandle video_pipe, + media::mojom::RemotingDataStreamSenderRequest audio_sender_request, + media::mojom::RemotingDataStreamSenderRequest video_sender_request) { + if (state_ != REMOTING_STARTED) + return; // Stop() was called before. + DCHECK(cast_environment_); + DCHECK(transport_); + if (audio_pipe.is_valid() && + audio_config_.codec == Codec::CODEC_AUDIO_REMOTE) { + audio_sender_ = std::make_unique<RemotingSender>( + cast_environment_, transport_, audio_config_, std::move(audio_pipe), + std::move(audio_sender_request), + base::BindOnce(&MediaRemoter::OnRemotingDataStreamError, + base::Unretained(this))); + } + if (video_pipe.is_valid() && + video_config_.codec == Codec::CODEC_VIDEO_REMOTE) { + video_sender_ = std::make_unique<RemotingSender>( + cast_environment_, transport_, video_config_, std::move(video_pipe), + std::move(video_sender_request), + base::BindOnce(&MediaRemoter::OnRemotingDataStreamError, + base::Unretained(this))); + } +} + +void MediaRemoter::SendMessageToSink(const std::vector<uint8_t>& message) { + if (state_ != REMOTING_STARTED) + return; + std::string encoded_rpc; + base::Base64Encode( + base::StringPiece(reinterpret_cast<const char*>(message.data()), + message.size()), + &encoded_rpc); + base::Value rpc(base::Value::Type::DICTIONARY); + rpc.SetKey("type", base::Value("RPC")); + rpc.SetKey("rpc", base::Value(std::move(encoded_rpc))); + CastMessage rpc_message; + rpc_message.message_namespace = kRemotingNamespace; + const bool did_serialize_rpc = + base::JSONWriter::Write(rpc, &rpc_message.json_format_data); + DCHECK(did_serialize_rpc); + message_dispatcher_->SendOutboundMessage(rpc_message); +} + +void MediaRemoter::EstimateTransmissionCapacity( + media::mojom::Remoter::EstimateTransmissionCapacityCallback callback) { + NOTIMPLEMENTED(); + std::move(callback).Run(0); +} + +void MediaRemoter::OnRemotingDataStreamError() { + if (state_ != REMOTING_STARTED) + return; + state_ = REMOTING_DISABLED; + Stop(media::mojom::RemotingStopReason::DATA_SEND_FAILED); +} + +} // namespace mirroring
diff --git a/components/mirroring/service/media_remoter.h b/components/mirroring/service/media_remoter.h new file mode 100644 index 0000000..edaf8e3c --- /dev/null +++ b/components/mirroring/service/media_remoter.h
@@ -0,0 +1,147 @@ +// 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 COMPONENTS_MIRRORING_SERVICE_MEDIA_REMOTER_H_ +#define COMPONENTS_MIRRORING_SERVICE_MEDIA_REMOTER_H_ + +#include "base/macros.h" +#include "media/cast/cast_config.h" +#include "media/mojo/interfaces/remoting.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace media { +namespace cast { +class CastEnvironment; +class CastTransport; +} // namespace cast +} // namespace media + +namespace mirroring { + +class MessageDispatcher; +struct ReceiverResponse; +class RemotingSender; + +// MediaRemoter remotes media content directly to a Cast Receiver. When +// MediaRemoter is started, it connects itself with a source tab in browser +// through the Mirroring Service mojo interface and allows the browser to access +// this MediaRemoter to start/stop individual remoting sessions, which are +// caused by user actions (i.e., when they somehow indicate a desire to +// enter/leave an immersive video-watching mode). +// +// When a remoting session is started, MediaRemoter will first request that tab +// mirroring be switched into content remoting mode. If granted, it will notify +// the browser that this has succeeded. At this point, two-way RPC binary +// messaging begins, and the MediaRemoter simply forwards messages between the +// browser and the Cast Receiver. The audio/video data streams are delivered +// from the media renderer to the Mirroring Service through mojo datapipes, and +// are then sent out to Cast Receiver through Cast Streaming. +class MediaRemoter final : public media::mojom::Remoter { + public: + class Client { + public: + virtual ~Client() {} + + // Connects the |remoter| with a source tab. + virtual void ConnectToRemotingSource( + media::mojom::RemoterPtr remoter, + media::mojom::RemotingSourceRequest source_request) = 0; + + // Requests to start remoting. StartRpcMessaging() / OnRemotingStartFailed() + // will be called when starting succeeds / fails. + virtual void RequestRemotingStreaming() = 0; + + // Requests to resume mirroring. + virtual void RestartMirroringStreaming() = 0; + }; + + MediaRemoter(Client* client, + const media::mojom::RemotingSinkMetadata& sink_metadata, + MessageDispatcher* message_dispatcher); + + ~MediaRemoter() override; + + // Callback from |message_dispatcher_| for received RPC messages. + void OnMessageFromSink(const ReceiverResponse& response); + + // Called when OFFER/ANSWER exchange for a remoting session succeeds. + void StartRpcMessaging( + scoped_refptr<media::cast::CastEnvironment> cast_environment, + media::cast::CastTransport* transport, + const media::cast::FrameSenderConfig& audio_config, + const media::cast::FrameSenderConfig& video_config); + + // Called when a mirroring session is successfully resumed. + void OnMirroringResumed(); + + // Error occurred either during the start of remoting or in the middle of + // remoting. In either case, this call fallbacks to mirroring, and prevents + // further starting of media remoting during this mirroring session. + void OnRemotingFailed(); + + // media::mojom::Remoter implememtation. Stops the current remoting session. + // This could be called either by the RemotingSource or the Session. + void Stop(media::mojom::RemotingStopReason reason) override; + + private: + // media::mojom::Remoter implememtation. + void Start() override; + void StartDataStreams( + mojo::ScopedDataPipeConsumerHandle audio_pipe, + mojo::ScopedDataPipeConsumerHandle video_pipe, + media::mojom::RemotingDataStreamSenderRequest audio_sender_request, + media::mojom::RemotingDataStreamSenderRequest video_sender_request) + override; + void SendMessageToSink(const std::vector<uint8_t>& message) override; + void EstimateTransmissionCapacity( + media::mojom::Remoter::EstimateTransmissionCapacityCallback callback) + override; + + // Called by RemotingSender when error occurred. Will stop this remoting + // session and fallback to mirroring. + void OnRemotingDataStreamError(); + + Client* const client_; // Outlives this class. + const media::mojom::RemotingSinkMetadata sink_metadata_; + MessageDispatcher* const message_dispatcher_; // Outlives this class. + mojo::Binding<media::mojom::Remoter> binding_; + media::mojom::RemotingSourcePtr remoting_source_; + scoped_refptr<media::cast::CastEnvironment> cast_environment_; + std::unique_ptr<RemotingSender> audio_sender_; + std::unique_ptr<RemotingSender> video_sender_; + media::cast::CastTransport* transport_; // Outlives this class; + media::cast::FrameSenderConfig audio_config_; + media::cast::FrameSenderConfig video_config_; + + // State transition diagram: + // + // .-----------> MIRRORING + // | | + // | V + // | STARTING_REMOTING + // | | + // | V + // | .-----------------------------. + // | | | | + // | | V V + // | | REMOTING_STARTED ----> REMOTING_DISABLED + // | | | + // | V V + // .--STOPPING_REMOTING + enum { + MIRRORING, // In mirroring. + STARTING_REMOTING, // Starting a remoting session. + REMOTING_STARTED, // Remoting started successfully. + REMOTING_DISABLED, // Remoting was disabled (because of error). + STOPPING_REMOTING, // Stopping the remoting session. + } state_; + + base::WeakPtrFactory<MediaRemoter> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(MediaRemoter); +}; + +} // namespace mirroring + +#endif // COMPONENTS_MIRRORING_SERVICE_MEDIA_REMOTER_H_
diff --git a/components/mirroring/service/media_remoter_unittest.cc b/components/mirroring/service/media_remoter_unittest.cc new file mode 100644 index 0000000..18776e5 --- /dev/null +++ b/components/mirroring/service/media_remoter_unittest.cc
@@ -0,0 +1,220 @@ +// 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/mirroring/service/media_remoter.h" + +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" +#include "base/time/default_tick_clock.h" +#include "components/mirroring/service/message_dispatcher.h" +#include "components/mirroring/service/mirror_settings.h" +#include "media/cast/cast_environment.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::InvokeWithoutArgs; +using ::testing::_; +using ::testing::Mock; +using media::mojom::RemotingSinkMetadata; +using media::mojom::RemotingStopReason; +using media::cast::RtpPayloadType; +using media::cast::Codec; + +namespace mirroring { + +namespace { + +class MockRemotingSource final : public media::mojom::RemotingSource { + public: + MockRemotingSource() : binding_(this) {} + ~MockRemotingSource() override {} + + void Bind(media::mojom::RemotingSourceRequest request) { + binding_.Bind(std::move(request)); + } + + MOCK_METHOD0(OnSinkGone, void()); + MOCK_METHOD0(OnStarted, void()); + MOCK_METHOD1(OnStartFailed, void(media::mojom::RemotingStartFailReason)); + MOCK_METHOD1(OnMessageFromSink, void(const std::vector<uint8_t>&)); + MOCK_METHOD1(OnStopped, void(RemotingStopReason)); + MOCK_METHOD1(OnSinkAvailable, void(const RemotingSinkMetadata&)); + void OnSinkAvailable( + media::mojom::RemotingSinkMetadataPtr metadata) override { + OnSinkAvailable(*metadata); + } + + private: + mojo::Binding<media::mojom::RemotingSource> binding_; +}; + +RemotingSinkMetadata DefaultSinkMetadata() { + RemotingSinkMetadata metadata; + metadata.features.push_back(media::mojom::RemotingSinkFeature::RENDERING); + metadata.video_capabilities.push_back( + media::mojom::RemotingSinkVideoCapability::CODEC_VP8); + metadata.audio_capabilities.push_back( + media::mojom::RemotingSinkAudioCapability::CODEC_BASELINE_SET); + metadata.friendly_name = "Test"; + return metadata; +} + +} // namespace + +class MediaRemoterTest : public CastMessageChannel, + public MediaRemoter::Client, + public ::testing::Test { + public: + MediaRemoterTest() + : message_dispatcher_(this, error_callback_.Get()), + sink_metadata_(DefaultSinkMetadata()) {} + ~MediaRemoterTest() override { scoped_task_environment_.RunUntilIdle(); } + + protected: + MOCK_METHOD1(Send, void(const CastMessage&)); + MOCK_METHOD0(OnConnectToRemotingSource, void()); + MOCK_METHOD0(RequestRemotingStreaming, void()); + MOCK_METHOD0(RestartMirroringStreaming, void()); + + // MediaRemoter::Client implementation. + void ConnectToRemotingSource( + media::mojom::RemoterPtr remoter, + media::mojom::RemotingSourceRequest source_request) override { + remoter_ = std::move(remoter); + remoting_source_.Bind(std::move(source_request)); + OnConnectToRemotingSource(); + } + + void CreateRemoter() { + EXPECT_FALSE(media_remoter_); + EXPECT_CALL(*this, OnConnectToRemotingSource()).Times(1); + EXPECT_CALL(remoting_source_, OnSinkAvailable(_)).Times(1); + media_remoter_ = std::make_unique<MediaRemoter>(this, sink_metadata_, + &message_dispatcher_); + scoped_task_environment_.RunUntilIdle(); + Mock::VerifyAndClear(this); + Mock::VerifyAndClear(&remoting_source_); + } + + // Requests to start a remoting session. + void StartRemoting() { + ASSERT_TRUE(remoter_); + EXPECT_CALL(*this, RequestRemotingStreaming()).Times(1); + remoter_->Start(); + scoped_task_environment_.RunUntilIdle(); + Mock::VerifyAndClear(this); + } + + // Stops the current remoting session. + void StopRemoting() { + ASSERT_TRUE(remoter_); + EXPECT_CALL(remoting_source_, OnStopped(RemotingStopReason::USER_DISABLED)) + .Times(1); + EXPECT_CALL(remoting_source_, OnSinkGone()).Times(1); + EXPECT_CALL(*this, RestartMirroringStreaming()).Times(1); + remoter_->Stop(media::mojom::RemotingStopReason::USER_DISABLED); + scoped_task_environment_.RunUntilIdle(); + Mock::VerifyAndClear(this); + Mock::VerifyAndClear(&remoting_source_); + } + + // Signals that a remoting streaming session starts successfully. + void RemotingStreamingStarted() { + ASSERT_TRUE(media_remoter_); + scoped_refptr<media::cast::CastEnvironment> cast_environment = + new media::cast::CastEnvironment( + base::DefaultTickClock::GetInstance(), + scoped_task_environment_.GetMainThreadTaskRunner(), + scoped_task_environment_.GetMainThreadTaskRunner(), + scoped_task_environment_.GetMainThreadTaskRunner()); + EXPECT_CALL(remoting_source_, OnStarted()).Times(1); + media_remoter_->StartRpcMessaging( + cast_environment, nullptr, media::cast::FrameSenderConfig(), + MirrorSettings::GetDefaultVideoConfig(RtpPayloadType::REMOTE_VIDEO, + Codec::CODEC_VIDEO_REMOTE)); + scoped_task_environment_.RunUntilIdle(); + Mock::VerifyAndClear(&remoting_source_); + } + + // Signals that mirroring is resumed successfully. + void MirroringResumed() { + EXPECT_CALL(remoting_source_, OnSinkAvailable(_)).Times(1); + media_remoter_->OnMirroringResumed(); + scoped_task_environment_.RunUntilIdle(); + Mock::VerifyAndClear(&remoting_source_); + } + + // Signals that remoting session failed to start. + void RemotingStartFailed() { + ASSERT_TRUE(media_remoter_); + EXPECT_CALL(remoting_source_, OnStartFailed(_)).Times(1); + EXPECT_CALL(remoting_source_, OnSinkGone()).Times(1); + EXPECT_CALL(*this, RestartMirroringStreaming()).Times(1); + media_remoter_->OnRemotingFailed(); + scoped_task_environment_.RunUntilIdle(); + Mock::VerifyAndClear(this); + Mock::VerifyAndClear(&remoting_source_); + } + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + base::MockCallback<MessageDispatcher::ErrorCallback> error_callback_; + MessageDispatcher message_dispatcher_; + const media::mojom::RemotingSinkMetadata sink_metadata_; + MockRemotingSource remoting_source_; + media::mojom::RemoterPtr remoter_; + std::unique_ptr<MediaRemoter> media_remoter_; + + DISALLOW_COPY_AND_ASSIGN(MediaRemoterTest); +}; + +TEST_F(MediaRemoterTest, StartAndStopRemoting) { + CreateRemoter(); + StartRemoting(); + RemotingStreamingStarted(); + StopRemoting(); +} + +TEST_F(MediaRemoterTest, StopRemotingWhileStarting) { + CreateRemoter(); + // Starts a remoting session. + StartRemoting(); + // Immediately stops the remoting session while not started yet. + StopRemoting(); + + // Signals that successfully switch to mirroring. + MirroringResumed(); + // Now remoting can be started again. + StartRemoting(); +} + +TEST_F(MediaRemoterTest, RemotingStartFailed) { + CreateRemoter(); + StartRemoting(); + RemotingStartFailed(); +} + +TEST_F(MediaRemoterTest, SwitchBetweenMultipleSessions) { + CreateRemoter(); + + // Start a remoting session. + StartRemoting(); + RemotingStreamingStarted(); + + // Stop the remoting session and switch to mirroring. + StopRemoting(); + MirroringResumed(); + + // Switch to remoting again. + StartRemoting(); + RemotingStreamingStarted(); + + // Switch to mirroring again. + StopRemoting(); + MirroringResumed(); +} + +} // namespace mirroring
diff --git a/components/ntp_snippets/features.cc b/components/ntp_snippets/features.cc index fb18f9f1..85d50a8 100644 --- a/components/ntp_snippets/features.cc +++ b/components/ntp_snippets/features.cc
@@ -35,7 +35,7 @@ &kRemoteSuggestionsBackendFeature}; const base::Feature kArticleSuggestionsExpandableHeader{ - "NTPArticleSuggestionsExpandableHeader", base::FEATURE_DISABLED_BY_DEFAULT}; + "NTPArticleSuggestionsExpandableHeader", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kArticleSuggestionsFeature{ "NTPArticleSuggestions", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc b/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc index 64dc9e19..7d330a8 100644 --- a/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc +++ b/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc
@@ -19,8 +19,8 @@ #include "components/ntp_snippets/remote/remote_suggestions_database.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/image/image.h" @@ -74,21 +74,22 @@ // both callbacks used, only image_callback used, only image_data_callback used. class CachedImageFetcherTest : public testing::TestWithParam<TestType> { public: - CachedImageFetcherTest() : fake_url_fetcher_factory_(nullptr) { + CachedImageFetcherTest() { EXPECT_TRUE(database_dir_.CreateUniqueTempDir()); RequestThrottler::RegisterProfilePrefs(pref_service_.registry()); database_ = std::make_unique<RemoteSuggestionsDatabase>(database_dir_.GetPath()); - request_context_getter_ = scoped_refptr<net::TestURLRequestContextGetter>( - new net::TestURLRequestContextGetter( - scoped_task_environment_.GetMainThreadTaskRunner())); + + shared_factory_ = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_); auto decoder = std::make_unique<FakeImageDecoder>(); fake_image_decoder_ = decoder.get(); cached_image_fetcher_ = std::make_unique<ntp_snippets::CachedImageFetcher>( - std::make_unique<image_fetcher::ImageFetcherImpl>( - std::move(decoder), request_context_getter_.get()), + std::make_unique<image_fetcher::ImageFetcherImpl>(std::move(decoder), + shared_factory_), &pref_service_, database_.get()); RunUntilIdle(); EXPECT_TRUE(database_->IsInitialized()); @@ -138,21 +139,22 @@ RemoteSuggestionsDatabase* database() { return database_.get(); } FakeImageDecoder* fake_image_decoder() { return fake_image_decoder_; } - net::FakeURLFetcherFactory* fake_url_fetcher_factory() { - return &fake_url_fetcher_factory_; + network::TestURLLoaderFactory* test_url_loader_factory() { + return &test_url_loader_factory_; } CachedImageFetcher* cached_image_fetcher() { return cached_image_fetcher_.get(); } private: + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; std::unique_ptr<CachedImageFetcher> cached_image_fetcher_; std::unique_ptr<RemoteSuggestionsDatabase> database_; base::ScopedTempDir database_dir_; FakeImageDecoder* fake_image_decoder_; - net::FakeURLFetcherFactory fake_url_fetcher_factory_; + TestingPrefServiceSimple pref_service_; - scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; base::test::ScopedTaskEnvironment scoped_task_environment_; DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherTest); @@ -171,23 +173,20 @@ TEST_P(CachedImageFetcherTest, FetchImagePopulatesCache) { // Expect the image to be fetched by URL. { - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kImageData, - net::HTTP_OK, - net::URLRequestStatus::SUCCESS); + test_url_loader_factory()->AddResponse(kImageURL, kImageData); Fetch(kImageData, true); } // Fetch again. The cache should be populated, no network request is needed. { - fake_url_fetcher_factory()->ClearFakeResponses(); + test_url_loader_factory()->ClearResponses(); Fetch(kImageData, true); } } TEST_P(CachedImageFetcherTest, FetchNonExistingImage) { const std::string kErrorResponse = "error-response"; - fake_url_fetcher_factory()->SetFakeResponse(GURL(kImageURL), kErrorResponse, - net::HTTP_NOT_FOUND, - net::URLRequestStatus::FAILED); + test_url_loader_factory()->AddResponse(kImageURL, kErrorResponse, + net::HTTP_NOT_FOUND); // Expect an empty image is fetched if the URL cannot be requested. Fetch("", false); }
diff --git a/components/offline_pages/content/background_loader/background_loader_contents.cc b/components/offline_pages/content/background_loader/background_loader_contents.cc index 5bb1d64..ed7a6be 100644 --- a/components/offline_pages/content/background_loader/background_loader_contents.cc +++ b/components/offline_pages/content/background_loader/background_loader_contents.cc
@@ -11,6 +11,10 @@ BackgroundLoaderContents::BackgroundLoaderContents( content::BrowserContext* browser_context) : browser_context_(browser_context) { + // It is very important that we create the web contents with + // CreateParams::initially_hidden == false, and that we never change the + // visibility after that. If we did change it, then background throttling + // could kill the background offliner while it was running. web_contents_ = content::WebContents::Create( content::WebContents::CreateParams(browser_context_)); web_contents_->SetAudioMuted(true);
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 1a6ce4f2..0bc863c 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -21,6 +21,7 @@ icons = [ "answer_currency.icon", + "answer_default.icon", "answer_dictionary.icon", "answer_finance.icon", "answer_sunrise.icon",
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc index 59fc322..52ff81bf 100644 --- a/components/omnibox/browser/omnibox_edit_model.cc +++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -205,8 +205,6 @@ } bool OmniboxEditModel::ResetDisplayUrls() { - const base::string16 old_current_permanent_url = GetCurrentPermanentUrlText(); - url_for_editing_ = controller()->GetToolbarModel()->GetFormattedFullURL(); display_only_url_ = OmniboxFieldTrial::IsHideSteadyStateUrlSchemeAndSubdomainsEnabled() @@ -223,8 +221,7 @@ // always safe to change the text; this also prevents someone toggling "Show // URL" (which sounds as if it might be persistent) from seeing just that URL // forever afterwards. - return (GetCurrentPermanentUrlText() != old_current_permanent_url) && - (!has_focus() || (!user_input_in_progress_ && !PopupIsOpen())); + return !has_focus() || (!user_input_in_progress_ && !PopupIsOpen()); } GURL OmniboxEditModel::PermanentURL() const {
diff --git a/components/omnibox/browser/omnibox_edit_model_unittest.cc b/components/omnibox/browser/omnibox_edit_model_unittest.cc index 9a6f88f2..8d9aede3 100644 --- a/components/omnibox/browser/omnibox_edit_model_unittest.cc +++ b/components/omnibox/browser/omnibox_edit_model_unittest.cc
@@ -274,3 +274,9 @@ std::string(OmniboxEditModel::kMaxPasteAndGoTextLength + 1, '.')); EXPECT_FALSE(model()->OmniboxEditModel::CanPasteAndGo(long_text)); } + +// Verify ResetDisplayUrls returns true even if omnibox text has not been +// modified +TEST_F(OmniboxEditModelTest, ResetOmniboxTextOnRenavigatingCurrentPage) { + EXPECT_TRUE(model()->ResetDisplayUrls()); +}
diff --git a/components/omnibox/browser/vector_icons/answer_default.icon b/components/omnibox/browser/vector_icons/answer_default.icon new file mode 100644 index 0000000..d7aa9f5 --- /dev/null +++ b/components/omnibox/browser/vector_icons/answer_default.icon
@@ -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. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 12.23f, 14.28f, +V_LINE_TO, 9.82f, +H_LINE_TO, 23.33f, +CUBIC_TO, 23.49f, 10.57f, 23.63f, 11.28f, 23.63f, 12.28f, +CUBIC_TO, 23.63f, 19.13f, 19.08f, 24, 12.24f, 24, +CUBIC_TO, 5.69f, 24, 0.38f, 18.62f, 0.38f, 12, +CUBIC_TO, 0.38f, 5.38f, 5.69f, 0, 12.23f, 0, +R_CUBIC_TO, 3.2f, 0, 5.88f, 1.19f, 7.93f, 3.13f, +R_LINE_TO, -3.37f, 3.31f, +R_CUBIC_TO, -0.85f, -0.82f, -2.34f, -1.79f, -4.56f, -1.79f, +R_CUBIC_TO, -3.92f, 0, -7.13f, 3.3f, -7.13f, 7.34f, +R_CUBIC_TO, 0, 4.04f, 3.2f, 7.34f, 7.13f, 7.34f, +R_CUBIC_TO, 4.54f, 0, 6.21f, -3.18f, 6.52f, -5.06f, +CLOSE
diff --git a/components/onc/onc_constants.cc b/components/onc/onc_constants.cc index 93ba40c..3ff5a96 100644 --- a/components/onc/onc_constants.cc +++ b/components/onc/onc_constants.cc
@@ -462,6 +462,7 @@ "AllowOnlyPolicyNetworksToAutoconnect"; const char kAllowOnlyPolicyNetworksToConnect[] = "AllowOnlyPolicyNetworksToConnect"; +const char kBlacklistedHexSSIDs[] = "BlacklistedHexSSIDs"; const char kDisableNetworkTypes[] = "DisableNetworkTypes"; } // global_network_config
diff --git a/components/onc/onc_constants.h b/components/onc/onc_constants.h index 67c7336..1006424c 100644 --- a/components/onc/onc_constants.h +++ b/components/onc/onc_constants.h
@@ -467,6 +467,7 @@ namespace global_network_config { ONC_EXPORT extern const char kAllowOnlyPolicyNetworksToAutoconnect[]; ONC_EXPORT extern const char kAllowOnlyPolicyNetworksToConnect[]; +ONC_EXPORT extern const char kBlacklistedHexSSIDs[]; ONC_EXPORT extern const char kDisableNetworkTypes[]; } // global_network_config
diff --git a/components/password_manager/core/browser/hash_password_manager.cc b/components/password_manager/core/browser/hash_password_manager.cc index bb24acb..e9d6c795 100644 --- a/components/password_manager/core/browser/hash_password_manager.cc +++ b/components/password_manager/core/browser/hash_password_manager.cc
@@ -225,17 +225,14 @@ } } -void HashPasswordManager::ClearAllGaiaPasswordHash() { +void HashPasswordManager::ClearAllPasswordHash(bool is_gaia_password) { if (!prefs_) return; ListPrefUpdate update(prefs_, prefs::kPasswordHashDataList); for (auto it = update->GetList().begin(); it != update->GetList().end();) { - // For a very tiny portion of Canary users, |is_gaia_password| field might - // be not set for sync password. Therefore, when clearing Gaia passwords, - // we remove the password hash as long as |is_gaia_password| is not set to - // false. - if (GetAndDecryptField(*it, kIsGaiaFieldKey) != "false") { + if (GetAndDecryptField(*it, kIsGaiaFieldKey) == + BooleanToString(is_gaia_password)) { it = update->GetList().erase(it); } else { it++;
diff --git a/components/password_manager/core/browser/hash_password_manager.h b/components/password_manager/core/browser/hash_password_manager.h index de7d9b0..735a561 100644 --- a/components/password_manager/core/browser/hash_password_manager.h +++ b/components/password_manager/core/browser/hash_password_manager.h
@@ -32,7 +32,9 @@ void ClearSavedPasswordHash(); void ClearSavedPasswordHash(const std::string& username, bool is_gaia_password); - void ClearAllGaiaPasswordHash(); + // If |is_gaia_password| is true, clears all Gaia password hashes, otherwise + // clears all enterprise password hashes. + void ClearAllPasswordHash(bool is_gaia_password); // Returns empty if no hash is available. base::Optional<SyncPasswordData> RetrievePasswordHash();
diff --git a/components/password_manager/core/browser/hash_password_manager_unittest.cc b/components/password_manager/core/browser/hash_password_manager_unittest.cc index e7132fd..a5c4ec9 100644 --- a/components/password_manager/core/browser/hash_password_manager_unittest.cc +++ b/components/password_manager/core/browser/hash_password_manager_unittest.cc
@@ -196,20 +196,25 @@ hash_password_manager.SavePasswordHash( "username3", base::UTF8ToUTF16("enterprise_password"), /*is_gaia_password=*/false); + hash_password_manager.SavePasswordHash( + "username4", base::UTF8ToUTF16("enterprise_password"), + /*is_gaia_password=*/false); hash_password_manager.ClearSavedPasswordHash("other_username", /*is_gaia_password=*/true); - EXPECT_EQ(3u, hash_password_manager.RetrieveAllPasswordHashes().size()); + EXPECT_EQ(4u, hash_password_manager.RetrieveAllPasswordHashes().size()); hash_password_manager.ClearSavedPasswordHash("username2", /*is_gaia_password=*/false); - EXPECT_EQ(3u, hash_password_manager.RetrieveAllPasswordHashes().size()); + EXPECT_EQ(4u, hash_password_manager.RetrieveAllPasswordHashes().size()); hash_password_manager.ClearSavedPasswordHash("username3", /*is_gaia_password=*/false); EXPECT_FALSE(hash_password_manager.HasPasswordHash( "username3", /*is_gaia_password=*/false)); - EXPECT_EQ(2u, hash_password_manager.RetrieveAllPasswordHashes().size()); - hash_password_manager.ClearAllGaiaPasswordHash(); + EXPECT_EQ(3u, hash_password_manager.RetrieveAllPasswordHashes().size()); + hash_password_manager.ClearAllPasswordHash(/*is_gaia_password=*/true); + EXPECT_EQ(1u, hash_password_manager.RetrieveAllPasswordHashes().size()); + hash_password_manager.ClearAllPasswordHash(/*is_gaia_password=*/false); EXPECT_EQ(0u, hash_password_manager.RetrieveAllPasswordHashes().size()); }
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 2214d76..4831cb3 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -365,10 +365,7 @@ // TODO(crbug.com/841438): Delete migration code when most users complete // the migration. hash_password_manager_.MaybeMigrateExistingSyncPasswordHash(sync_username); - ScheduleTask(base::BindRepeating( - &PasswordStore::SaveProtectedPasswordHashImpl, this, - base::Passed(hash_password_manager_.RetrieveAllPasswordHashes()), - /*should_log_metrics=*/true)); + SchedulePasswordHashUpdate(/*should_log_metrics=*/true); } void PasswordStore::SaveGaiaPasswordHash( @@ -398,12 +395,7 @@ metrics_util::SyncPasswordHashChange::NOT_SYNC_PASSWORD_CHANGE) { metrics_util::LogSyncPasswordHashChange(event); } - PasswordHashDataList all_hashes( - hash_password_manager_.RetrieveAllPasswordHashes()); - ScheduleTask( - base::BindRepeating(&PasswordStore::SaveProtectedPasswordHashImpl, this, - std::move(all_hashes), - /*should_log_metrics=*/false)); + SchedulePasswordHashUpdate(/*should_log_metrics=*/false); } } @@ -412,12 +404,7 @@ metrics_util::SyncPasswordHashChange event) { if (hash_password_manager_.SavePasswordHash(sync_password_data)) { metrics_util::LogSyncPasswordHashChange(event); - PasswordHashDataList all_hashes( - hash_password_manager_.RetrieveAllPasswordHashes()); - ScheduleTask( - base::BindRepeating(&PasswordStore::SaveProtectedPasswordHashImpl, this, - std::move(all_hashes), - /*should_log_metrics=*/false)); + SchedulePasswordHashUpdate(/*should_log_metrics=*/false); } } @@ -426,7 +413,7 @@ /*is_gaia_password=*/true); // TODO(crbug.com/844134): Find a way to clear corresponding Gaia password // hash when user logs out individual Gaia account in content area. - hash_password_manager_.ClearAllGaiaPasswordHash(); + hash_password_manager_.ClearAllPasswordHash(/*is_gaia_password=*/true); ScheduleTask(base::BindRepeating( &PasswordStore::ClearProtectedPasswordHashImpl, this)); } @@ -438,6 +425,14 @@ notifier_ = std::move(notifier); notifier_->SubscribeToSigninEvents(this); } + +void PasswordStore::SchedulePasswordHashUpdate(bool should_log_metrics) { + ScheduleTask(base::BindRepeating( + &PasswordStore::SaveProtectedPasswordHashImpl, this, + base::Passed(hash_password_manager_.RetrieveAllPasswordHashes()), + should_log_metrics)); +} + #endif PasswordStore::~PasswordStore() {
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index f6953121..8ed13646 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -293,6 +293,9 @@ void SetPasswordStoreSigninNotifier( std::unique_ptr<PasswordStoreSigninNotifier> notifier); + // Schedule the update of password hashes used by reuse detector. + void SchedulePasswordHashUpdate(bool should_log_metrics); + #endif protected:
diff --git a/components/payments/content/installable_payment_app_crawler.cc b/components/payments/content/installable_payment_app_crawler.cc index e4ca352..76c83fd 100644 --- a/components/payments/content/installable_payment_app_crawler.cc +++ b/components/payments/content/installable_payment_app_crawler.cc
@@ -11,6 +11,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/manifest_icon_downloader.h" #include "content/public/browser/manifest_icon_selector.h" +#include "content/public/browser/payment_app_provider.h" #include "content/public/browser/permission_manager.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents.h" @@ -211,6 +212,14 @@ app_info->sw_scope = absolute_scope.spec(); } + std::string error_message; + if (!content::PaymentAppProvider::GetInstance()->IsValidInstallablePaymentApp( + web_app_manifest_url, GURL(app_info->sw_js_url), + GURL(app_info->sw_scope), &error_message)) { + WarnIfPossible(error_message); + return false; + } + // TODO(crbug.com/782270): Support multiple installable payment apps for a // payment method. if (installable_apps_.find(method_manifest_url) != installable_apps_.end())
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index bd60ddfc..4ac1d00 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -12,6 +12,7 @@ #include "base/bind_helpers.h" #include "base/callback_helpers.h" #include "base/guid.h" +#include "base/json/json_reader.h" #include "base/logging.h" #include "base/stl_util.h" #include "components/policy/core/common/cloud/cloud_policy_util.h" @@ -734,6 +735,13 @@ status_ = status; if (status == DM_STATUS_SUCCESS) { dm_token_ = response.register_response().device_management_token(); + if (response.register_response().has_configuration_seed()) { + configuration_seed_ = base::DictionaryValue::From(base::JSONReader::Read( + response.register_response().configuration_seed(), + base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS)); + if (!configuration_seed_) + LOG(ERROR) << "Failed to parse configuration seed"; + } DVLOG(1) << "Client registration complete - DMToken = " << dm_token_; // Device mode is only relevant for device policy really, it's the
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h index 64bd314..129becb 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.h +++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -19,6 +19,7 @@ #include "base/observer_list.h" #include "base/optional.h" #include "base/time/time.h" +#include "base/values.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/remote_commands/remote_command_job.h" #include "components/policy/policy_export.h" @@ -310,6 +311,9 @@ const std::string& dm_token() const { return dm_token_; } const std::string& client_id() const { return client_id_; } + const base::DictionaryValue* configuration_seed() const { + return configuration_seed_.get(); + }; // The device mode as received in the registration request. DeviceMode device_mode() const { return device_mode_; } @@ -466,6 +470,7 @@ std::vector<std::string> state_keys_to_upload_; std::string dm_token_; + std::unique_ptr<base::DictionaryValue> configuration_seed_; DeviceMode device_mode_ = DEVICE_MODE_NOT_SET; std::string client_id_; base::Time last_policy_timestamp_;
diff --git a/components/policy/resources/policy_templates_bn.xtb b/components/policy/resources/policy_templates_bn.xtb index 85ad81e..c4d6804 100644 --- a/components/policy/resources/policy_templates_bn.xtb +++ b/components/policy/resources/policy_templates_bn.xtb
@@ -67,7 +67,7 @@ ডিফল্ট মান হিসেবে RollbackDisabled ধরে নেওয়া হয়।</translation> <translation id="1221359380862872747">ডেমো লগইনে নির্দিষ্ট url লোড করুন</translation> -<translation id="1223789468190631420">বিশ্বস্ত উত্সগুলির জন্য নিরাপদ ব্রাউজিং চালু করার পরিসংখ্যান</translation> +<translation id="1223789468190631420">বিশ্বস্ত উত্সগুলির জন্য নিরাপদ ব্রাউজিং চালু করার স্ট্যাটাস</translation> <translation id="123081309365616809">ডিভাইসের কাস্টিং কন্টেন্ট সক্ষম করুন</translation> <translation id="1257550411839719984">ডিফল্ট ডাউনলোড ডিরেক্টরি সেট করুন</translation> <translation id="1265053460044691532">SAML এর মাধ্যমে একজন যাচাইকৃত ব্যবহারকারী অফলাইনে লগ ইন করতে পারেন, যার জন্য সময় সীমিত করুন।</translation> @@ -210,11 +210,11 @@ এই সেটিং অক্ষম থাকলে বা কনফিগার করা না থাকলে, এন্টারপ্রাইজ ব্যবহারকারীরা ARC ব্যবহার করতে পারবে না।</translation> <translation id="1561424797596341174">দূরবর্তী অ্যাক্সেস হোস্টের ত্রুটিমুক্তকরণ বিল্ডের জন্য নীতি ওভাররাইড</translation> <translation id="1561967320164410511">স্বতন্ত্রভাবে নিশ্চিত করার জন্য U2F এবং এক্সটেনশন</translation> -<translation id="1574554504290354326">এই সেটিংসটি শীঘ্রই বন্ধ হয়ে যাবে, এর পরিবর্তে SafeBrowsingExtendedReportingEnabled ব্যবহার করুন।SafeBrowsingExtendedReportingEnabled চালু অথবা বন্ধ করার অর্থ হল 'ফল্সে' SafeBrowsingExtendedReportingOptInAllowed সেট করার সমান। +<translation id="1574554504290354326">এই সেটিংসটি শীঘ্রই বন্ধ হয়ে যাবে, এর পরিবর্তে SafeBrowsingExtendedReportingEnabled ব্যবহার করুন। SafeBrowsingExtendedReportingOptInAllowed 'ফল্সে' সেট করা থাকলে, SafeBrowsingExtendedReportingEnabled চালু বা বন্ধ করলে কোনও কাজ হয় না। - এই নীতিটি 'ফল্সে' সেট করলে ব্যবহারকারীরা চাইলেও সিস্টেমের কিছু তথ্য এবং পৃষ্ঠার কিছু কন্টেন্ট Google এর সার্ভারে আর পাঠাতে পারবেন না। এটি 'ট্রুতে' সেট করলে বা কনফিগার না করলে বিপজ্জনক অ্যাপ এবং সাইট শনাক্ত করার কাজে সাহায্য করার জন্য ব্যবহারকারীরা সিস্টেমের কিছু তথ্য এবং পৃষ্ঠার কিছু কন্টেন্ট নিরাপদ ব্রাউজিং এ পাঠাতে পারবেন। + এই নীতিটি 'ফল্সে' সেট করলে ব্যবহারকারীরা চাইলেও সিস্টেমের কিছু তথ্য এবং পৃষ্ঠার কিছু কন্টেন্ট Google এর সার্ভারে আর পাঠাতে পারবেন না। এটি 'ট্রুতে' সেট করলে বা কনফিগার না করলে বিপজ্জনক অ্যাপ এবং সাইট শনাক্ত করার কাজে সাহায্য করার জন্য ব্যবহারকারীরা সিস্টেমের কিছু তথ্য এবং পৃষ্ঠার কিছু কন্টেন্ট নিরাপদ ব্রাউজিং-এ পাঠাতে পারবেন। - নিরাপদ ব্রাউজিং এর বিষয়ে আরও জানতে https://developers.google.com/safe-browsing এ যান।</translation> + নিরাপদ ব্রাউজিংয়ের বিষয়ে আরও জানার জন্য https://developers.google.com/safe-browsing দেখুন।</translation> <translation id="1583248206450240930">ডিফল্ট ভাবে <ph name="PRODUCT_FRAME_NAME" /> ব্যবহার করুন</translation> <translation id="1599424828227887013">Android ডিভাইসে নির্দিষ্ট উৎসের জন্য সাইট আইসোলেশন চালু করুন</translation> <translation id="1608755754295374538">এই URLগুলিকে বিজ্ঞপ্তি ছাড়াই অডিও ক্যাপচার ডিভাইসগুলিতে অ্যাক্সেসের অধিকার দেওয়া হবে</translation> @@ -688,7 +688,7 @@ <translation id="2769952903507981510">দূরবর্তী অ্যাক্সেস হোস্টের জন্য আবশ্যক ডোমেন নাম কনফিগার করুন</translation> <translation id="2787173078141616821">Android এর স্থিতি সম্পর্কে তথ্য প্রতিবেদন করে</translation> <translation id="2793923553868251161">উৎসগুলিকে নিরাপদ কন্টেক্সট হিসেবে গণ্য করা হবে।</translation> -<translation id="2799297758492717491">URLপ্যাটার্নগুলির সাদা তালিকাতে মিডিয়া অটোপ্লে এর অনুমতি দিন</translation> +<translation id="2799297758492717491">URL প্যাটার্নগুলির সাদা তালিকাতে মিডিয়া অটোপ্লে এর অনুমতি দিন</translation> <translation id="2801230735743888564">ডিভাইস অফলাইনে থাকার সময় ব্যবহারকারীদেরকে ডাইনোসর ইস্টার ডিম গেম খেলার অনুমতি দেয়। এই নীতিটি মিথ্যাতে সেট করা থাকলে, ডিভাইস অফলাইনে থাকা অবস্থায় ব্যবহারকারীর ডাইনোসর ইস্টার ডিম গেম খেলতে পারবে না। এই সেটিং সত্যতে সেট করা থাকলে, ব্যবহারকারীরা ডাইনোসর গেম খেলার অনুমতি পায়। এই নীতিটি সেট না করা থাকলে, ব্যবহারকারীদেরকে নথিভুক্ত Chrome OS এ ডাইনোসর ইস্টার ডিম গেম খেলার অনুমতি দেওয়া হয় না, কিন্তু অন্যান্য পরিস্থিতিতে এটি খেলার অনুমতি দেওয়া হয়।</translation> @@ -968,7 +968,7 @@ নিরাপদ ব্রাউজিংয়ের বিষয়ে আরও জানার জন্য https://developers.google.com/safe-browsing দেখুন। - <ph name="MS_AD_NAME" /> ডোমেনে যুক্ত নয় এমন উইন্ডোজে এই নীতিটি উপলভ্য নয়।</translation> + <ph name="MS_AD_NAME" /> ডোমেনে যুক্ত নয় এমন Windows দৃষ্টান্তগুলিতে এই নীতিটি উপলভ্য নয়।</translation> <translation id="3577251398714997599">যে সাইটে ব্যাঘাতকারী বিজ্ঞাপন দেখানো হয় সেই সাইটের জন্য বিজ্ঞাপন সেটিংস</translation> <translation id="3591584750136265240">লগইন প্রমাণীকরণ আচরণ কনফিগার করে</translation> <translation id="3627678165642179114">বানান পরীক্ষা ওয়েব পরিষেবা সক্ষম বা অক্ষম করুন</translation> @@ -1002,15 +1002,15 @@ এই নীতিগুলি সেট না করে ছেড়ে যাওয়া হলে, ব্যবহারকারী নিজে থেকে প্রক্সী সেটিং চয়ন করার অনুমতি পায়।</translation> <translation id="3758249152301468420">ডেভেলপারের টুল অক্ষম করুন</translation> -<translation id="3764248359515129699">লিগ্যাসি সার্টিফিকেট কর্তৃপক্ষের একটি তালিকা জন্য শংসাপত্রের স্বচ্ছতার প্রয়োজনীয়তা জারিকরণ অক্ষম করে। +<translation id="3764248359515129699">লিগ্যাসি সার্টিফিকেট কর্তৃপক্ষের একটি তালিকার জন্য সার্টিফিকেট ট্রান্সপারেন্সির প্রয়োজনীয়তা জারিকরণ বন্ধ করে। - এই নীতিটি সার্টিফিকেট চেইন সার্টিফিকেট ট্রান্সপারেন্সি প্রকাশের প্রয়োজনীয়তা অক্ষম করার অনুমতি দেয় যেগুলিতে একটি নির্দিষ্ট বিষয়ের PublicKeyInfo হ্যাশ সাথে সার্টিফিকেট আছে। এটি এমন শংসাপত্রের অনুমতি দেয় যা অন্যথায় অবিশ্বস্ত হবে, কারণ তারা সঠিকভাবে প্রকাশ্যে প্রকাশিত করা হয় নি, এন্টারপ্রাইজ হোস্টগুলির জন্য ব্যবহার করা চালিয়ে যেতে। + এই নীতিটি সার্টিফিকেট চেইনের জন্য সার্টিফিকেট ট্রান্সপারেন্সি প্রকাশের প্রয়োজনীয়তা বন্ধ করার অনুমতি দেয় যেগুলিতে নির্দিষ্ট subjectPublicKeyInfo হ্যাশ সহ সার্টিফিকেট রয়েছে। এটি এমন সার্টিফিকেটের অনুমতি দেয় যা অন্যথায় অবিশ্বস্ত হবে, কারণ এন্টারপ্রাইজ হোস্টগুলির জন্য ব্যবহার করা চালিয়ে যেতে সেগুলি সঠিকভাবে সর্বজনীনভাবে প্রকাশ করা হয়নি। - নিয়মানুযায়ী যখন এই নীতি সেট করা হয় তখন শংসাপত্রের স্বচ্ছতার বলবত্করণ অক্ষম করতে, হ্যাশ অবশ্যই একটি বিষয়বস্তুর PublicKeyInfo হতে হবে যা CA সার্টিফিকেটে প্রদর্শিত হবে যা লেগ্যাসি সার্টিফিকেট অথোরিটি (সিএ) হিসেবে স্বীকৃত। একটি লেগ্যাসি CA হল একটি CA যা <ph name="PRODUCT_NAME" /> দ্বারা সমর্থিত ডিফল্ট এক বা একাধিক অপারেটিং সিস্টেম দ্বারা সর্বজনীনভাবে বিশ্বস্ত, কিন্তু Android ওপেন সোর্স প্রোজেক্ট বা <ph name="PRODUCT_OS_NAME" /> দ্বারা বিশ্বস্ত নয়। + নিয়মানুযায়ী যখন এই নীতি সেট করা হয় তখন সার্টিফিকেট ট্রান্সপারেন্সির প্রয়োগ বন্ধ করতে, হ্যাশ অবশ্যই একটি subjectPublicKeyInfo হতে হবে যা CA সার্টিফিকেটে প্রদর্শিত হবে যা লেগ্যাসি সার্টিফিকেট অথোরিটি (CA) হিসেবে স্বীকৃত। একটি লেগ্যাসি CA হল এমন একটি CA যা সাধারণত <ph name="PRODUCT_NAME" /> দ্বারা সমর্থিত এক বা একাধিক অপারেটিং সিস্টেম দ্বারা সর্বজনীনভাবে বিশ্বস্ত, কিন্তু Android ওপেন সোর্স প্রোজেক্ট বা <ph name="PRODUCT_OS_NAME" /> দ্বারা বিশ্বস্ত নয়। - একটি subjectPublicKeyInfohash হ্যাশ কংক্যাটেনেটিং অ্যালগরিদম, নাম "/" অক্ষর দ্বারা নির্দিষ্ট করা হয় এবং ঐ হ্যাশ অ্যালগরিদম এর Base64 এনকোডিং নিদিষ্ট সার্টিফিকেটের DER- এনকোডেড subjectPublicKeyInfo প্রয়োগ হয়। এই Base64 এনকোডিংটি একটি SPKI আঙ্গুলের ছাপ হিসাবে একই বিন্যাস, RFC 7469- এ বর্ণিত, বিভাগ 2.4। অস্বীকৃত হ্যাশ অ্যালগরিদম উপেক্ষিত। এই সময়ে শুধুমাত্র সমর্থিত হ্যাশ অ্যালগরিদম "sha256" হয়। + একটি subjectPublicKeyInfohash হ্যাশ কংক্যাটেনেটিং অ্যালগরিদম নাম, "/" অক্ষর দ্বারা নির্দিষ্ট করা হয় এবং ঐ হ্যাশ অ্যালগরিদমের Base64 এনকোডিং নিদিষ্ট সার্টিফিকেটের DER-এনকোডেড subjectPublicKeyInfo প্রয়োগ হয়। RFC 7469, বিভাগ 2.4-এ থাকা বর্ণনা অনুযায়ী এই Base64 এনকোডিংটি একটি SPKI আঙ্গুলের ছাপের মতো একই ফর্ম্যাটের হয়। শনাক্ত করা যায়নি এমন হ্যাশ অ্যালগরিদম উপেক্ষা করা হয়। এই মুহুর্তে শুধুমাত্র সমর্থিত হ্যাশ অ্যালগরিদম হল "sha256"। - যদি এই নীতিটি সেট না করা হয়, তাহলে কোনো শংসাপত্র যা শংসাপত্র ট্রান্সপারেন্সি মাধ্যমে প্রকাশ করা প্রয়োজন তা অবিশ্বস্ত হিসাবে গণ্য করা হবে যদি এটি শংসাপত্রের স্বচ্ছতা নীতি অনুযায়ী প্রকাশ না করা হয়।</translation> + যদি এই নীতিটি সেট না করা হয়, তাহলে কোনও সার্টিফিকেট যা সার্টিফিকেট ট্রান্সপারেন্সির মাধ্যমে প্রকাশ করা প্রয়োজন তা অবিশ্বস্ত হিসেবে গণ্য করা হবে যদি এটি সার্টিফিকেট ট্রান্সপারেন্সি নীতি অনুযায়ী প্রকাশ না করা হয়।</translation> <translation id="3765260570442823273">নিষ্ক্রিয় লগ-আউট সতর্কতা বার্তার স্থিতিকাল</translation> <translation id="377044054160169374">খারাপ অথবা অপব্যবহারমূলক অভিজ্ঞতার ক্ষেত্রে হস্তক্ষেপ প্রয়োগ করা</translation> <translation id="3780152581321609624">কার্বেরস SPN-এ অ-মানক পোর্ট অন্তর্ভুক্ত করুন</translation> @@ -1289,7 +1289,7 @@ <translation id="4377599627073874279">সব সাইটকে সকল ছবি দেখানোর অনুমতি দিন</translation> <translation id="437791893267799639">নীতি সেট করা হয়নি, ডেটা মাইগ্রেশন এবং ARC তে অনুমতি দেবেন না</translation> <translation id="4389091865841123886">TPM ব্যবস্থার মাধ্যমে রিমোট প্রত্যয়িতটি কনফিগার করুন৷</translation> -<translation id="4410236409016356088">থ্রোল্টলিং নেটওয়ার্ক বাড়ানো কমানো চালু করুন</translation> +<translation id="4410236409016356088">থ্রোটলিং নেটওয়ার্ক বাড়ানো কমানো চালু করুন</translation> <translation id="441217499641439905"><ph name="PRODUCT_OS_NAME" /> ফাইল অ্যাপে মোবাইল ডেটার মাধ্যমে Google ড্রাইভ বন্ধ করুন</translation> <translation id="4415603335307944578">যদি এই নীতি সত্যতে সেট করা হয় বা কনফিগার না করা হয়, তাহলে OS আপগ্রেডের পরে প্রথম লঞ্চের সময় ব্রাউজার আবার স্বাগতম পৃষ্ঠা দেখাবে। @@ -1314,7 +1314,7 @@ </translation> <translation id="4442582539341804154">যখন ডিভাইস নিস্ক্রিয় অথবা স্থগিত হয়ে যায় তখন লক সক্ষম করুন</translation> <translation id="4449545651113180484">স্ক্রীনকে ঘড়ির কাঁটার দিকে ২৭০ ডিগ্রী দ্বারা ঘোরান</translation> -<translation id="4454820008017317557"><ph name="PRODUCT_NAME" /> টুলবার আইকনটি দেখান</translation> +<translation id="4454820008017317557"><ph name="PRODUCT_NAME" /> টুলবার আইকনটি দেখুন</translation> <translation id="4467952432486360968">তৃতীয় পক্ষের কুকিজ অবরোধ করুন</translation> <translation id="4474167089968829729">পাসওয়ার্ড পরিচালকে পাসওয়ার্ড সংরক্ষণ করা সক্ষম করুন</translation> <translation id="4476769083125004742">এই নীতিটি <ph name="BLOCK_GEOLOCATION_SETTING" /> এ সেট করা হলে, Android অ্যাপ্লিকেশানগুলি অবস্থানের তথ্য অ্যাক্সেস করতে পারে না। আপনি যদি এই নীতিটি অন্য যেকোনো মানে সেট করেন বা সেট না করে ছেড়ে যান, তাহলে কোনো Android অ্যাপ্লিকেশান অবস্থানের তথ্য অ্যাক্সেস করতে চাইলে ব্যবহারকারীর সম্মতি চাওয়া হয়।</translation> @@ -1424,7 +1424,7 @@ পিনটি দুর্বল হিসাবে বিবেচিত হলে, ডিফল্ট ব্যবস্থা হিসাবে ব্যবহারকারীরা একটি সতর্কতা পাবে, যা ত্রুটি হবে না।</translation> <translation id="4723829699367336876">দূরবর্তী অ্যাক্সেস ক্লায়েন্ট থেকে ফায়ারওয়াল ট্র্যাভেরসাল সক্ষম করুন</translation> <translation id="4725528134735324213">Android ব্যাকআপ পরিষেবা সক্ষম করুন</translation> -<translation id="4725801978265372736">স্থানীয় ব্যবহারকারী এবং রিমোট অ্যাক্সেস হোস্ট মালিকের নাম মিল হওয়া আবশ্যক</translation> +<translation id="4725801978265372736">স্থানীয় ব্যবহারকারী এবং রিমোট অ্যাক্সেস হোস্ট মালিকের নামের মধ্যে মিল হওয়া আবশ্যক</translation> <translation id="4733471537137819387">একীকৃত HTTP প্রমাণীকরণের সাথে সম্পর্কিত নীতিসমূহ৷</translation> <translation id="4744190513568488164">যে সার্ভারগুলির জন্য <ph name="PRODUCT_NAME" /> প্রতিনিধিত্ব করে৷ @@ -2048,7 +2048,7 @@ আপনি যদি কোনো .pac প্রক্সী স্ক্রিপ্ট ব্যবহার করা চয়ন করেন, তাহলে Android অ্যাপগুলিকে স্ক্রিপ্ট URL সরবরাহ করা হয়।</translation> <translation id="6440051664870270040">সাইটগুলিকে একসাথে নেভিগেট এবং পপ-আপগুলি খোলার অনুমতি দিন</translation> -<translation id="645425387487868471"><ph name="PRODUCT_NAME" />-এর জন্য জোর করে সাইন- চালু করুন</translation> +<translation id="645425387487868471"><ph name="PRODUCT_NAME" />-এর জন্য জোর করে সাইন-ইন চালু করুন</translation> <translation id="6467613372414922590">ব্যবহারকারী লেভেলের নেটিভ মেসেজিং হোস্টগুলিকে অনুমতি দিন (প্রশাসকের অনুমতি ছাড়াই ইনস্টল করা)</translation> <translation id="6468980648680553776">এই নীতি থামিয়ে দেওয়া হয়েছে। অনুগ্রহ করে পরিবর্তে RemoteAccessHostClientDomainList ব্যবহার করুন।</translation> <translation id="6473623140202114570">এমন ডোমেনগুলির তালিকা কনফিগার করুন যা নিরাপদ ব্রাউজিং সতর্কতাগুলিকে ট্রিগার করবে না।</translation> @@ -2220,7 +2220,7 @@ এই সেটিংটি পরিবর্তন অথবা ওভাররাইড করা যায় না।</translation> <translation id="6908640907898649429">ডিফল্ট সার্চ সরবরাহকারীকে কনফিগার করে৷ আপনি ডিফল্ট সার্চ সরবরাহকারীটি যা ব্যবহারকারী ডিফল্ট সার্চ ব্যবহার করতে বা চয়ন করতে ব্যবহার করবে তা আপনি নির্দিষ্ট করতে পারেন৷</translation> -<translation id="6913068954484253496"><ph name="PRODUCT_NAME" />-কে সব আইপি ঠিকানার.কাস্ট ডিভাইসগুলিতে কানেক্ট করার অনুমতি দিন</translation> +<translation id="6913068954484253496"><ph name="PRODUCT_NAME" />-কে সব আইপি অ্যাড্রেস কাস্ট ডিভাইসগুলিতে কানেক্ট করার অনুমতি দিন</translation> <translation id="6915442654606973733">কথ্য প্রতিক্রিয়া অ্যাক্সেসযোগ্যতার বৈশিষ্ট্য সক্ষম করে৷ যদি এই নীতিটি সত্যতে সেট করা থাকে, তাহলে কথ্য প্রতিক্রিয়া সর্বদা সক্ষম থাকবে৷ @@ -2327,7 +2327,7 @@ <translation id="7123160381479171745">যেসব ব্যবহারকারীরা ডিভাইসে লগ-ইন করার মঞ্জুরিপ্রাপ্ত তাদের তালিকা নির্ধারণ করে। এন্ট্রিগুলি <ph name="USER_WHITELIST_ENTRY_FORMAT" /> রূপে হয়, যেমন <ph name="USER_WHITELIST_ENTRY_EXAMPLE" />। কোনও ডোমেনে অবাধ ব্যবহারকারীদের মঞ্জুরি দিতে <ph name="USER_WHITELIST_ENTRY_WILDCARD" /> রূপের এন্ট্রিগুলি ব্যবহার করুন। যদি এই নীতি কনফিগার করা না থাকলে, কোন ব্যবহারকারীদের প্রবেশ করুন করার মঞ্জুরি দেওয়া হবে সে ব্যাপারে কোনও বিধিনিষেধ থাকে না। মনে রাখবেন যে নতুন ব্যবহারকারী তৈরি করার জন্য <ph name="DEVICE_ALLOW_NEW_USERS_POLICY_NAME" /> নীতি এখনও উপযুক্তভাবে কনফিগার করা আবশ্যক।</translation> -<translation id="7126716959063786004">টাস্ক ম্যানেজারে প্রক্রিয়াগুলি সমাপ্ত করা চালু করে</translation> +<translation id="7126716959063786004">টাস্ক ম্যানেজারে প্রক্রিয়াগুলি বন্ধ করার সুবিধা চালু করে</translation> <translation id="7127892035367404455">টার্গেট ভার্সনে ফিরে যান</translation> <translation id="7128918109610518786">লঞ্চার বারে পিন করা অ্যাপ্লিকেশন হিসাবে <ph name="PRODUCT_OS_NAME" /> যে অ্যাপ্লিকেশন চিহ্নিতকারী দেখায় তার তালিকা প্রদান করে৷ @@ -2529,7 +2529,7 @@ উল্লেখ্য যে এই সীমাবদ্ধতা ওয়েব পৃষ্ঠার কন্টেন্ট থেকে সূচিত ডাউনলোডগুলিতে, পাশাপাশি 'ডাউনলোড লিঙ্ক ...' প্রসঙ্গ মেনু অপশনে প্রযোজ্য। এই সীমাবদ্ধতা বর্তমানে প্রদর্শিত পৃষ্ঠা সেভ/ডাউনলোড ক্ষেত্রে প্রযোজ্য হবে না, না এটা প্রিন্টিং অপশন থেকে পিডিএফ সেভিংস এর ক্ষেত্রে প্রযোজ্য নয়। - নিরাপদ ব্রাউজিং এ আরও তথ্যের জন্য Https://developers.google.com/safe-browsing দেখুন।</translation> + নিরাপদ ব্রাউজিং এ আরও তথ্যের জন্য https://developers.google.com/safe-browsing দেখুন।</translation> <translation id="7643883929273267746"><ph name="PRODUCT_NAME" /> এ দেখা যায় এমন অ্যাকাউন্টগুলি সীমাবদ্ধ করুন</translation> <translation id="7651739109954974365">ডিভাইসের জন্য ডেটা বিচরণ ঠিক কিনা সিদ্ধান্ত নিন. যদি সত্যতে সেট করতে চান, ডেটা বিচরণ অনুমোদিত৷ যদি অকনফিগার ছাড়া থাকে বা সেট ভুয়ো হয়, ডেটা বিচরণ উপলব্ধ হবে না৷</translation> <translation id="7673194325208122247">সময়কাল (মিলিসেকেন্ড)</translation> @@ -2610,7 +2610,7 @@ 2. একটি subjectPublicKeyInfo এর হ্যাশ যা শংসাপত্রের চেইনে একটি CA শংসাপত্রে প্রদর্শিত হবে, যা CA শংসাপত্র X.509v3 nameConstraints এক্সটেনশন মাধ্যমে সীমাবদ্ধ হয়, এক বা একাধিক directoryName nameConstraints গুলি permittedSubtrees এ উপস্থিত থাকে, এবং directoryName একটি ORGANIZATIONNAME অ্যাট্রিবিউট ধারণ করে। 3. একটি subjectPublicKeyInfo এর হ্যাশ যা শংসাপত্রের চেইনে একটি CA শংসাপত্রে প্রদর্শিত হবে, , CA শংসাপত্র এক বা তার বেশি organizationName অ্যাট্রিবিউটগুলি শংসাপত্র বিষয় মধ্যে থাকে এবং এবং সার্ভার শংসাপত্র একই সংখ্যক organizationName অ্যাট্রিবিউট, একই ক্রমের মধ্যে এবং এর সাথে রয়েছে বাইট টু বাইট অভিন্ন মান ধারণ করে। - একটি subjectPublicKeyInfohash হ্যাশ কংক্যাটেনেটিং অ্যালগরিদম, নাম "/" অক্ষর দ্বারা নির্দিষ্ট করা হয় এবং ঐ হ্যাশ অ্যালগরিদম এর Base64 এনকোডিং নিদিষ্ট সার্টিফিকেটের DER- এনকোডেড subjectPublicKeyInfo প্রয়োগ হয়। এই Base64 এনকোডিংটি একটি SPKI আঙ্গুলের ছাপ হিসাবে একই বিন্যাস, RFC 7469- এ বর্ণিত, বিভাগ 2.4। অস্বীকৃত হ্যাশ অ্যালগরিদম উপেক্ষিত। এই সময়ে শুধুমাত্র সমর্থিত হ্যাশ অ্যালগরিদম "sha256" হয়। + একটি subjectPublicKeyInfohash হ্যাশ কংক্যাটেনেটিং অ্যালগরিদম, নাম "/" অক্ষর দ্বারা নির্দিষ্ট করা হয় এবং ঐ হ্যাশ অ্যালগরিদম এর Base64 এনকোডিং নিদিষ্ট সার্টিফিকেটের DER- এনকোডেড subjectPublicKeyInfo প্রয়োগ হয়। এই Base64 এনকোডিংটি একটি SPKI আঙ্গুলের ছাপ হিসেবে একই বিন্যাস, RFC 7469- এ বর্ণিত, বিভাগ 2.4। অস্বীকৃত হ্যাশ অ্যালগরিদম উপেক্ষিত। এই সময়ে শুধুমাত্র সমর্থিত হ্যাশ অ্যালগরিদম "sha256" হয়। যদি এই নীতিটি সেট না করা হয়, কোনও শংসাপত্র যা শংসাপত্র ট্রান্সপারেন্সি মাধ্যমে প্রকাশ করা প্রয়োজন তা অবিশ্বস্ত হিসাবে গণ্য করা হবে যদি এটি শংসাপত্রের স্বচ্ছতা নীতি অনুযায়ী প্রকাশ না করা হয়।</translation> <translation id="7818131573217430250">লগইন স্ক্রীনে উচ্চ কনট্রাস্ট মোডের ডিফল্ট স্থিতি সেট করুন</translation>
diff --git a/components/policy/resources/policy_templates_ca.xtb b/components/policy/resources/policy_templates_ca.xtb index 648eea3b..c9f28a1 100644 --- a/components/policy/resources/policy_templates_ca.xtb +++ b/components/policy/resources/policy_templates_ca.xtb
@@ -890,8 +890,8 @@ <translation id="3746590506846867985"> Aquesta política s'aplica a la pantalla d'inici de sessió. Consulta també la política <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> que s'aplica a la sessió d'usuari. Es recomana definir el mateix valor en totes dues polítiques. En cas contrari, pot haver-hi un retard en iniciar una sessió d'usuari mentre s'aplica el valor especificat per la política de l'usuari. Si la política s'activa, cadascun dels orígens indicats en una llista separada per comes s'executarà amb el seu propi procés. Així mateix, s'aïllaran els orígens indicats per subdominis (per exemple, en especificar https://example.com/, l'adreça https://foo.example.com/ també s'aïllarà com a part del lloc web https://example.com/). - Si la política es desactiva, es produirà l'aïllament de llocs web no explícits i es desactivaran les proves de camp de les polítiques IsolateOrigins i SitePerProcess. Els usuaris podran activar IsolateOrigins manualment. - Si la política no es configura, a la pantalla d'inici de sessió s'utilitzarà la configuració d'aïllament del lloc web predeterminat a la plataforma. + Si la política es desactiva, no es produirà l'aïllament explícit de cap lloc web i es desactivaran les proves de camp de les polítiques IsolateOrigins i SitePerProcess. Els usuaris podran activar IsolateOrigins manualment. + Si la política no es configura, a la pantalla d'inici de sessió s'utilitzarà la configuració d'aïllament del lloc web predeterminada a la plataforma. </translation> <translation id="3750220015372671395">Bloqueja la generació de claus en aquests llocs web</translation> <translation id="3756011779061588474">Bloquejar el mode de desenvolupador</translation> @@ -1045,11 +1045,11 @@ <translation id="4056910949759281379">Desactiva el protocol SPDY</translation> <translation id="4059515172917655545">Aquesta política controla la disponibilitat dels serveis d'ubicació de Google. - Si aquesta política no es configura o s'estableix en <ph name="GLS_DISABLED" />, es desactiven els serveis d'ubicació de Google i l'usuari no els pot activar. + Si aquesta política no es configura o s'estableix en <ph name="GLS_DISABLED" />, es desactivaran els serveis d'ubicació de Google i l'usuari no els podrà activar. - Si aquesta política s'estableix en <ph name="GLS_UNDER_USER_CONTROL" />, es demana a l'usuari que triï si vol utilitzar els serveis d'ubicació de Google. En aquest cas, les aplicacions per a Android poden utilitzar els serveis per consultar la ubicació del dispositiu i també es comencen a enviar dades d'ubicació anònimes a Google. + Si aquesta política s'estableix en <ph name="GLS_UNDER_USER_CONTROL" />, es demana a l'usuari que triï si vol utilitzar els serveis d'ubicació de Google. Això permetrà que les aplicacions per a Android puguin utilitzar els serveis per consultar la ubicació del dispositiu i que s'enviïn dades d'ubicació anònimes a Google. - Tingues en compte que, si la política <ph name="DEFAULT_GEOLOCATION_SETTING_POLICY_NAME" /> s'estableix en <ph name="BLOCK_GEOLOCATION_SETTING" />, aquesta política s'ignora i els serveis d'ubicació de Google estan sempre desactivats.</translation> + Tingues en compte que, si la política <ph name="DEFAULT_GEOLOCATION_SETTING_POLICY_NAME" /> s'estableix en <ph name="BLOCK_GEOLOCATION_SETTING" />, aquesta política s'ignorarà i els serveis d'ubicació de Google es mantindran sempre desactivats.</translation> <translation id="408029843066770167">Permet fer consultes a un servei de temps de Google</translation> <translation id="4088589230932595924">S'ha forçat el mode d'incògnit</translation> <translation id="4088983553732356374">Us permet establir si els llocs web estan autoritzats per establir les dades locals. L'ajust de les dades locals es pot autoritzar o denegar per a tots els llocs web. @@ -1772,7 +1772,7 @@ Si decideixes fer servir un script de servidor intermediari .pac, es proporcionarà l'URL de script a les aplicacions per a Android.</translation> <translation id="6440051664870270040">Permet que els llocs web naveguin i obrin finestres emergents simultàniament</translation> -<translation id="6447948611083700881">Còpia de seguretat i restauració desactivada</translation> +<translation id="6447948611083700881">Còpia de seguretat i restauració desactivades</translation> <translation id="645425387487868471">Permet l'inici de sessió forçat a <ph name="PRODUCT_NAME" /></translation> <translation id="6473623140202114570">Configura la llista de dominis en què Navegació segura no activarà advertiments.</translation> <translation id="6491139795995924304">Permet el Bluetooth al dispositiu</translation> @@ -1957,7 +1957,7 @@ NOTA: a Android, l'aïllament de llocs web és experimental. Amb el temps se'n millorarà la compatibilitat, però actualment pot provocar problemes de rendiment. - NOTA: aquesta política només s'aplica a Chrome als dispositius Android amb més d'1 GB de RAM. Per aplicar-la en altres plataformes, fes servir SitePerProcess. + NOTA: aquesta política només s'aplica a Chrome als dispositius Android amb més d'1 GB de RAM. Per aplicar-la en altres plataformes que no siguin d'Android, fes servir SitePerProcess. </translation> <translation id="6922040258551909078"> Si la política s'estableix en "true", la política per al núvol té prioritat si entra en conflicte amb la política de l'equip. @@ -2233,9 +2233,9 @@ <translation id="7673194325208122247">Període de temps (mil·lisegons)</translation> <translation id="7676708657861783864">Les galetes definides per les pàgines que coincideixin amb aquests patrons d'URL es limitaran a la sessió actual. És a dir, se suprimiran en tancar el navegador. - En el cas dels URL no inclosos als patrons que s'especifiquen o de tots els URL si no es defineix aquesta política, s'utilitzarà el valor global predeterminat indicat a la política DefaultCookiesSetting (si s'ha definit) el valor personalitzat que hagi definit l'usuari. + En el cas dels URL no inclosos als patrons que s'especifiquen, o de tots els URL si no es defineix aquesta política, s'utilitzarà el valor global predeterminat indicat a la política DefaultCookiesSetting (si s'ha definit) o el valor personalitzat que hagi definit l'usuari. - Tingues en compte que, si <ph name="PRODUCT_NAME" /> s'executa en "mode de segon pla", no es pot tancar la sessió quan es tanca l'última finestra del navegador, sinó que continuarà activa fins que es tanqui el navegador. Consulta la política BackgroundModeEnabled per obtenir més informació sobre com pots configurar aquest comportament. + Tingues en compte que, si <ph name="PRODUCT_NAME" /> s'executa en "mode de segon pla", pot ser que la sessió no es tanqui quan es tanqui l'última finestra del navegador, sinó que continuarà activa fins que es tanqui el navegador. Consulta la política BackgroundModeEnabled per obtenir més informació sobre com pots configurar aquest comportament. Consulta també les polítiques CookiesAllowedForUrls i CookiesBlockedForUrls. Tingues en compte que no pot haver-hi conflictes entre els patrons d'URL d'aquestes tres polítiques. No s'ha especificat quina té prioritat. @@ -2306,7 +2306,7 @@ <translation id="7788872453000173219"> Per aconseguir l'aïllament dels llocs web i un impacte mínim per als usuaris, pots utilitzar la política IsolateOrigins amb una llista dels llocs web que vols aïllar. L'opció de configuració SitePerProcess aïlla tots els llocs web. Si la política s'activa, cada lloc web s'executarà amb el seu propi procés. - Si la política es desactiva, es produirà l'aïllament de llocs web no explícits i es desactivaran les proves de camp de les polítiques IsolateOrigins i SitePerProcess. Els usuaris podran continuar activant SitePerProcess manualment. + Si la política es desactiva, no es produirà l'aïllament explícit de cap lloc web i es desactivaran les proves de camp de les polítiques IsolateOrigins i SitePerProcess. Els usuaris podran continuar activant SitePerProcess manualment. Si la política no es configura, l'usuari podrà canviar aquesta opció de configuració. A <ph name="PRODUCT_OS_NAME" />, es recomana definir el mateix valor a la política de dispositius <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" />. En cas contrari, pot haver-hi un retard en iniciar una sessió d'usuari mentre s'aplica el valor especificat per la política de l'usuari. @@ -2351,7 +2351,7 @@ Aquesta política s'aplica a la pantalla d'inici de sessió. Consulta també la política <ph name="SITE_PER_PROCESS_POLICY_NAME" /> que s'aplica a la sessió d'usuari. Es recomana definir el mateix valor en totes dues polítiques. En cas contrari, pot haver-hi un retard en iniciar una sessió d'usuari mentre s'aplica el valor especificat per la política de l'usuari. Per aconseguir l'aïllament dels llocs web i un impacte mínim per als usuaris, pots utilitzar la política IsolateOrigins amb una llista dels llocs web que vols aïllar. L'opció de configuració SitePerProcess aïlla tots els llocs web. Si la política s'activa, cada lloc web s'executarà amb el seu propi procés. - Si la política es desactiva, es produirà l'aïllament de llocs web no explícits i es desactivaran les proves de camp de les polítiques IsolateOrigins i SitePerProcess. Els usuaris podran continuar activant SitePerProcess manualment. + Si la política es desactiva, no es produirà l'aïllament explícit de cap lloc web i es desactivaran les proves de camp de les polítiques IsolateOrigins i SitePerProcess. Els usuaris podran continuar activant SitePerProcess manualment. Si no es configura la política, l'usuari podrà canviar aquesta opció de configuració. </translation> <translation id="7912255076272890813">Configuració dels tipus d'aplicacions i d'extensions permeses</translation> @@ -2370,12 +2370,12 @@ <translation id="7941975817681987555">No prediguis accions de xarxa en cap connexió de xarxa</translation> <translation id="7952880400776676958"> Si la política s'activa, cadascun dels orígens indicats en una llista separada per comes s'executarà amb el seu propi procés. Així mateix, s'aïllaran els orígens indicats per subdominis (per exemple, en especificar https://example.com/, l'adreça https://foo.example.com/ també s'aïllarà com a part del lloc web https://example.com/). - Si la política es desactiva, es produirà l'aïllament de llocs web no explícits i es desactivaran les proves de camp de les polítiques IsolateOriginsAndroid i SitePerProcessAndroid. Els usuaris podran continuar activant IsolateOrigins manualment. + Si la política es desactiva, no es produirà l'aïllament explícit de cap lloc web i es desactivaran les proves de camp de les polítiques IsolateOriginsAndroid i SitePerProcessAndroid. Els usuaris podran continuar activant IsolateOrigins manualment. Si no es configura la política, l'usuari podrà canviar aquesta opció de configuració. NOTA: a Android, l'aïllament de llocs web és experimental. Amb el temps se'n millorarà la compatibilitat, però actualment pot provocar problemes de rendiment. - NOTA: aquesta política només s'aplica a Chrome als dispositius Android amb més d'1 GB de RAM. Per aplicar-la en altres plataformes, fes servir IsolateOrigins. + NOTA: aquesta política només s'aplica a Chrome als dispositius Android amb més d'1 GB de RAM. Per aplicar-la en altres plataformes que no siguin d'Android, fes servir IsolateOrigins. </translation> <translation id="7953256619080733119">Amfitrions d'excepcions manuals d'usuari gestionat</translation> <translation id="7961779417826583251">Desactiva l'aplicació de la Transparència de certificats a les autoritats certificadores heretades incloses en una llista</translation>
diff --git a/components/policy/resources/policy_templates_gu.xtb b/components/policy/resources/policy_templates_gu.xtb index 64b166b..f101777 100644 --- a/components/policy/resources/policy_templates_gu.xtb +++ b/components/policy/resources/policy_templates_gu.xtb
@@ -2204,7 +2204,7 @@ આ નીતિ <ph name="PRODUCT_NAME" />માં ડિફૉલ્ટ પ્રિન્ટર પસંદ કરવાના નિયમો નક્કી કરે છે, જે પ્રોફાઇલ સાથે પ્રિન્ટનું કાર્ય પ્રથમ વખત થાય ત્યારે ઉપયોગમાં લેવાય છે. જ્યારે આ નીતિ સેટ કરેલ હોય, ત્યારે <ph name="PRODUCT_NAME" /> આપેલ બધી જ વિશેષતાઓ સાથે મેળ ખાતું પ્રિન્ટર શોધવાનો પ્રયત્ન કરશે અને તેને ડિફૉલ્ટ પ્રિન્ટર તરીકે પસંદ કરશે. નીતિ સાથે મેળ ખાતું જે પ્રથમ પ્રિન્ટર મળે તે પસંદ કરવામાં આવે છે, અને જો એક કરતાં વધારે પ્રિન્ટર મળે, તો પ્રિન્ટર શોધાયાના ક્રમના આધારે કોઈપણ મેળ ખાતું પ્રિન્ટર પસંદ કરી શકાશે. - જો આ નીતિ સેટ કરવામાં આવી ન હોય અથવા સમય સમાપ્ત થતા સુધીમાં મેળ ખાતું પ્રિન્ટર ન મળે, તો પ્રિન્ટર ડિફૉલ્ટ તરીકે બિલ્ટ-ઇન PDF હોય છે અથવા જ્યારે PDF પ્રિન્ટર ઉપલબ્ધ ન હોય ત્યારે પ્રિન્ટર પસંદ કરેલ નથી હોય છે. + જો આ નીતિ સેટ કરવામાં આવી ન હોય અથવા સમય સમાપ્ત થતા સુધીમાં મેળ ખાતું પ્રિન્ટર ન મળે, તો પ્રિન્ટર ડિફૉલ્ટ તરીકે બિલ્ટ-ઇન PDF પ્રિન્ટર પસંદ કરે છે અથવા જ્યારે PDF પ્રિન્ટર ઉપલબ્ધ ન હોય તેવા કિસ્સામાં ડિફૉલ્ટ તરીકે પ્રિન્ટર પસંદ કરેલ નથી બતાવે છે. આ મૂલ્યનું, નીચે આપેલ સ્કીમાને કન્ફર્મ કરે તે રીતે, JSON ઑબ્જેક્ટ તરીકે વિશ્લેષણ કરાય છે: { @@ -2533,7 +2533,7 @@ <translation id="7519251620064708155">આ સાઇટ્સ પર કી જનરેશનની મંજૂરી આપો</translation> <translation id="7529083451528428240">તમને ક્લાયન્ટના સમય અથવા દિવસના વપરાશના ક્વોટાના આધારે વપરાશકર્તાના સ્થાનને લૉક કરવાની મંજૂરી આપે છે. - |time_window_limit| એ દૈનિક વિંડો બતાવે છે જેમાં વપરાશકર્તાનું સત્ર લૉક થયેલું હોવું જોઈએ. અમે અઠવાડિયાના પ્રત્યેક દિવસ માટે માત્ર એક નિયમને સમર્થન આપીએ છીએ, તેથી |entries|ના અરે કદમાં 0-7 સુધીના હોઈ શકે છે. |starts_at| અને |ends_at| એ વિંડોની મર્યાદાની શરૂઆત અને અંત છે, જ્યારે |starts_at| કરતાં |ends_at|નું મૂલ્ય વધારે નાનું હોય, તેનો અર્થ છે કે |time_limit_window| તે પછીના દિવસે સમાપ્ત થાય છે. |last_updated_millis| એ આ એન્ટ્રી છેલ્લે અપડેટ થયાનો UTC ટાઇમસ્ટૅમ્પ છે, જે સ્ટ્રિંગ તરીકે મોકલવામાં આવે છે, કારણ કે ટાઇમસ્ટૅમ્પ પૂર્ણ સંખ્યામાં ફિટ નહીં થાય. + |time_window_limit| એ દૈનિક વિંડો બતાવે છે જેમાં વપરાશકર્તાનું સત્ર લૉક થયેલું હોવું જોઈએ. અમે અઠવાડિયાના પ્રત્યેક દિવસ માટે માત્ર એક નિયમને સમર્થન આપીએ છીએ, તેથી |entries|નું અરે કદ 0-7 સુધી બદલાઈ શકે છે. |starts_at| અને |ends_at| એ વિંડોની મર્યાદાની શરૂઆત અને અંત છે, જ્યારે |starts_at| કરતાં |ends_at|નું મૂલ્ય વધારે નાનું હોય, તેનો અર્થ છે કે |time_limit_window| તે પછીના દિવસે સમાપ્ત થાય છે. |last_updated_millis| એ આ એન્ટ્રી છેલ્લે અપડેટ થયાનો UTC ટાઇમસ્ટૅમ્પ છે, જે સ્ટ્રિંગ તરીકે મોકલવામાં આવે છે, કારણ કે ટાઇમસ્ટૅમ્પ પૂર્ણ સંખ્યામાં ફિટ નહીં થાય. |time_usage_limit| દૈનિક સ્ક્રીન ક્વોટા દર્શાવે છે, તેથી જ્યારે વપરાશકર્તા એ મર્યાદાએ પહોંચી જાય, ત્યારે વપરાશકર્તાનું સત્ર લૉક થઈ જાય છે. અઠવાડિયાના દરેક દિવસ માટેની લાક્ષણિકતા હોય છે અને જો તે દિવસ માટેનો સક્રિય ડેટા હોય તો જ તે સેટ કરવી જોઈએ. |usage_quota_mins| એ સમયની માત્રા છે જેને મેનેજ કરેલ ઉપકરણ એક દિવસ માટે ઉપયોગમાં લઈ શકાય છે અને |reset_at| એ સમય છે જ્યારે વપરાશ ક્વોટા રિન્યૂ થાય છે. |reset_at| માટેનું ડિફૉલ્ટ મૂલ્ય મધ્ય રાત્રિ ({'hour': 0, 'minute': 0}) છે. |last_updated_millis| એ આ એન્ટ્રી છેલ્લે અપડેટ થયાનો UTC ટાઇમસ્ટૅમ્પ છે, જે સ્ટ્રિંગ તરીકે મોકલવામાં આવે છે, કારણ કે ટાઇમસ્ટૅમ્પ પૂર્ણ સંખ્યામાં ફિટ નહીં થાય.
diff --git a/components/policy/resources/policy_templates_hi.xtb b/components/policy/resources/policy_templates_hi.xtb index f2de312..47aa9a5 100644 --- a/components/policy/resources/policy_templates_hi.xtb +++ b/components/policy/resources/policy_templates_hi.xtb
@@ -3,18 +3,18 @@ <translationbundle lang="hi"> <translation id="101438888985615157">स्क्रीन को 180 डिग्री पर घुमाएं</translation> <translation id="1017967144265860778">लॉगिन स्क्रीन पर पावर प्रबंधन</translation> -<translation id="1019101089073227242">उपयोगकर्ता डेटा निर्देशिका सेट करें</translation> -<translation id="1022361784792428773">वे एक्सटेंशन आईडी जिन्हें उपयोगकर्ता को इंस्टॉल करने से बचना चाहिए (या सभी के लिए *)</translation> +<translation id="1019101089073227242">'उपयोगकर्ता डेटा निर्देशिका' सेट करें</translation> +<translation id="1022361784792428773">वैसे एक्सटेंशन आईडी जिन्हें इंस्टॉल करने से उपयोगकर्ता को बचना चाहिए (या सभी के लिए *)</translation> <translation id="102492767056134033">लॉगिन स्क्रीन पर ऑन-स्क्रीन कीबोर्ड की डिफ़ॉल्ट स्थिति सेट करें</translation> -<translation id="1027000705181149370">यह बताती है कि SAML IdP के ज़रिए लॉग इन के दौरान सेट की गई पहचान करने वाली कुकी, उपयोगकर्ता की प्रोफ़ाइल में भेजी जानी चाहिए या नहीं. +<translation id="1027000705181149370">यह बताती है कि SAML IdP के ज़रिए लॉग इन के दौरान सेट की गई पहचान की पुष्टि करने वाली कुकी, उपयोगकर्ता की प्रोफ़ाइल में भेजी जानी चाहिए या नहीं. - जब कोई उपयोगकर्ता लॉग इन के दौरान किसी SAML IdP के ज़रिए पहचान साबित करता है तो, IdP के ज़रिए सेट की गई कुकी पहले किसी अस्थायी प्रोफ़ाइल में लिखी जाती हैं. पहचान संंबंधी स्थिति को आगे बढ़ाने के लिए इन कुकी को उपयोगकर्ता की प्रोफ़ाइल में भेजा जा सकता है. + जब कोई उपयोगकर्ता लॉग इन के दौरान किसी SAML IdP के ज़रिए पहचान साबित करता है तो, IdP के ज़रिए सेट की गई कुकी पहले किसी अस्थायी प्रोफ़ाइल में लिखी जाती हैं. पहचान की पुष्टि संंबंधी स्थिति को आगे बढ़ाने के लिए इन कुकी को उपयोगकर्ता की प्रोफ़ाइल में भेजा जा सकता है. जब इस नीति को सही पर सेट किया जाता है तो, IdP के ज़रिए सेट की गई कुकी तब-तब उपयोगकर्ता की प्रोफ़ाइल में भेजी जाती हैं, जब-जब वे लॉग इन के दौरान SAML IdP से अलग पहचान साबित करते हैं. जब इस नीति को गलत पर सेट किया जाता है या सेट नहीं किया जाता है तो, IdP के ज़रिए सेट की गई कुकी सिर्फ़ उस समय उपयोगकर्ता की प्रोफ़ाइल में भेजी जाती हैं, जब वे किसी डिवाइस पर पहली बार लॉग इन करते हैं. - यह पॉलिसी सिर्फ़ ऐसे उपयोगकर्ताओं को प्रभावित करती है जिनका डोमेन, डिवाइस के नाम दर्ज़ करने वाले डोमेन से मिलता-जुलता है. बाकी सभी उपयोगकर्ताओं के लिए, IdP के ज़रिए सेट की गई कुकी सिर्फ़ उस समय उनकी प्रोफ़ाइल में भेजी जाती हैं, जब वे किसी डिवाइस पर पहली बार लॉग इन करते हैं.</translation> + यह नीति सिर्फ़ ऐसे उपयोगकर्ताओं को प्रभावित करती है जिनका डोमेन, डिवाइस के नाम दर्ज़ करने वाले डोमेन से मिलता-जुलता है. बाकी सभी उपयोगकर्ताओं के लिए, IdP के ज़रिए सेट की गई कुकी सिर्फ़ उस समय उनकी प्रोफ़ाइल में भेजी जाती हैं, जब वे किसी डिवाइस पर पहली बार लॉग इन करते हैं.</translation> <translation id="1040446814317236570">PAC URL चालू करें (https:// के लिए)</translation> <translation id="1044878202534415707">CPU/RAM उपयोग जैसे हार्डवेयर के आंकड़ों की रिपोर्ट करें. @@ -28,20 +28,20 @@ <translation id="1062011392452772310">डिवाइस के लिए दूरस्थ अनुप्रमाणन सक्षम करें</translation> <translation id="1062407476771304334">प्रतिस्थापित करें</translation> <translation id="1079801999187584280">डेवलपर टूल के इस्तेमाल की मंज़ूरी न दें</translation> -<translation id="1093082332347834239">यदि यह सेटिंग सक्षम की जाती है, तो दूरस्थ सहायता होस्ट <ph name="UIACCESS_PERMISSION_NAME" /> अनुमतियों वाली प्रक्रिया में चलेगा. इससे दूरस्थ उपयोगकर्ताओं को स्थानीय उपयोगकर्ता के डेस्कटॉप पर एलिवेटेड विंडो से सहभागिता करने की अनुमति मिल जाएगी. +<translation id="1093082332347834239">अगर यह सेटिंग चालू की जाती है तो, 'रिमोट सहायता होस्ट' <ph name="UIACCESS_PERMISSION_NAME" /> अनुमतियों वाली प्रक्रिया में चलेगा. इससे रिमोट उपयोगकर्ताओं को स्थानीय उपयोगकर्ता के डेस्कटॉप पर एलिवेटेड (ऊपर दिख रही) विंडो से इंटरैक्ट करने की अनुमति मिल जाएगी. - यदि यह सेटिंग अक्षम की जाती है या कॉन्फ़िगर नहीं की जाती है, तो दूरस्थ सहायता होस्ट उपयोगकर्ता के प्रसंग में चलेगा और दूरस्थ उपयोगकर्ता डेस्कटॉप पर एलिवेटेड विंडो में सहभागिता नहीं कर सकेंगे.</translation> + अगर यह सेटिंग बंद की जाती है या कॉन्फ़िगर नहीं की जाती है तो, 'रिमोट सहायता होस्ट' उपयोगकर्ता के संदर्भ में चलेगा और रिमोट उपयोगकर्ता डेस्कटॉप पर एलिवेटेड विंडो में इंटरैक्ट नहीं कर सकेंगे.</translation> <translation id="1096105751829466145">सामान्य खोज प्रदाता</translation> <translation id="1099282607296956954">साइट आइसोलेशन को हर साइट के लिए चालू करें</translation> <translation id="1117535567637097036">Android के इंटेंट प्रबंधित करते समय इस नीति द्वारा सेट किए गए प्रोटोकॉल हैंडलर का उपयोग नहीं किया जाता.</translation> -<translation id="1118093128235245168">साइटों को उपयोगकर्ता से किसी कनेक्ट किए हुए USB डिवाइस का एक्सेस मांगने दें</translation> -<translation id="1128903365609589950">यह नीति वह निर्देशिका (डायरेक्ट्री) कॉन्फ़िगर करती है, <ph name="PRODUCT_NAME" /> जिसका उपयोग डिस्क पर कैश फ़ाइलें सेव करने के लिए करेगा. +<translation id="1118093128235245168">साइटों को उपयोगकर्ता से किसी कनेक्ट किए हुए यूएसबी डिवाइस का एक्सेस मांगने की अनुमति दें</translation> +<translation id="1128903365609589950">यह नीति वह निर्देशिका कॉन्फ़िगर करती है, <ph name="PRODUCT_NAME" /> जिसका उपयोग डिस्क पर कैश फ़ाइलें सेव करने के लिए करेगा. अगर आप यह नीति सेट करते हैं तो, <ph name="PRODUCT_NAME" /> इस निर्देशिका का उपयोग करेगा, भले ही उपयोगकर्ता ने '--disk-cache-dir' फ़्लैग तय किया हो या न तय किया हो. डेटा खोने या दूसरी गड़बड़ियों से बचने के लिए इस नीति को किसी वॉल्यूम की मूल निर्देशिका पर या दूसरे कामों के लिए उपयोग की जाने वाली निर्देशिका पर सेट नहीं किया जाना चाहिए, क्योंकि <ph name="PRODUCT_NAME" /> उसकी सामग्री प्रबंधित करता है. उपयोग किए जा सकने वाले वैरिएबल की सूची देखने के लिए https://www.chromium.org/administrators/policy-list-3/user-data-directory-variables पर जाएं. - अगर यह नीति सेट नहीं की जाती है तो 'डिफ़ॉल्ट कैश निर्देशिका' का उपयोग किया जाएगा और उपयोगकर्ता उसे '--disk-cache-dir' कमांड लाइन फ़्लैग से ओवरराइड कर सकेगा.</translation> + अगर यह नीति सेट नहीं की जाती है तो 'डिफ़ॉल्ट कैश निर्देशिका' का उपयोग किया जाएगा और उपयोगकर्ता उसे '--disk-cache-dir' कमांड लाइन फ़्लैग से रद्द कर सकेगा.</translation> <translation id="1138294736309071213">यह नीति केवल रिटेल मोड में सक्रिय है. रिटेल मोड में डिवाइस के लिए साइन-इन स्क्रीन पर स्क्रीन सेवर दिखाने से पहले अवधि निर्धारित करता है. @@ -70,19 +70,19 @@ <translation id="1223789468190631420">सुरक्षित ब्राउज़िंग विश्वसनीय स्रोतों की स्थिति चालू करती है</translation> <translation id="123081309365616809">डिवाइस पर सामग्री कास्ट करना सक्षम करें</translation> <translation id="1257550411839719984">डिफ़ॉल्ट डाउनलोड निर्देशिका सेट करें</translation> -<translation id="1265053460044691532">उस समय को सीमित करें, जिसमें SAML द्वारा प्रमाणीकृत उपयोगकर्ता ऑफ़लाइन प्रवेश कर सकता है.</translation> +<translation id="1265053460044691532">उस समय को सीमित करें, जिसमें SAML के ज़रिए प्रमाणित किया गया उपयोगकर्ता ऑफ़लाइन लॉग इन कर सकता है.</translation> <translation id="1291880496936992484">चेतावनी: RC4 को वर्शन 52 (सितंबर 2016 के आस-पास) के बाद पूरी तरह <ph name="PRODUCT_NAME" /> से निकाल दिया जाएगा और तब यह पॉलिसी काम करना बंद कर देगी. यदि पॉलिसी को सेट नहीं किया जाता है या असत्य पर सेट किया जाता है, तो RC4 के सिफ़र सुइट को TLS में सक्षम नहीं किया जाएगा. अन्यथा किसी पुराने सर्वर के साथ संगतता बनाए रखने के लिए उसे सत्य पर सेट किया जा सकता है. यह एक स्टॉपगैप उपाय है और सर्वर को पुनः कॉन्फ़िगर किया जाना चाहिए.</translation> <translation id="1297182715641689552">किसी .pac प्रॉक्सी स्क्रिप्ट का उपयोग करें</translation> <translation id="1304973015437969093">बिना सूचना के इंस्टॉल किए जाने वाले एक्सटेंशन/ऐप्लिकेशन आईडी और अपडेट यूआरएल</translation> -<translation id="1313457536529613143">स्क्रीन के मंद रहने या स्क्रीन के बंद हो जाने के तुरंत बाद उपयोगकर्ता गतिविधि का निरीक्षण करते समय मंद स्क्रीन विलंब को मापे जाने का प्रतिशत निर्दिष्ट करता है. +<translation id="1313457536529613143">स्क्रीन की रोशनी कम होने या स्क्रीन बंद हो जाने के तुरंत बाद उपयोगकर्ता की किसी गतिविधि का पता चलने पर, यह नीति, स्क्रीन की रोशनी कितनी देर में कम हो, इस समय को स्केल करने (घटाने या बढ़ाने) का प्रतिशत तय करती है. - यदि यह नीति सेट हो, तो यह स्क्रीन के मंद रहने या स्क्रीन के बंद हो जाने के तुरंत बाद उपयोगकर्ता गतिविधि का निरीक्षण करते समय मंद स्क्रीन विलंब को मापे जाने का प्रतिशत निर्दिष्ट करती है. जब मंद विलंब मापा जाता है, तो बंद स्क्रीन, स्क्रीन लॉक, प्रयोग में नहीं विलंब को मंद स्क्रीन विलंब से वही समान दूरी बनाए रखने के लिए एडजस्ट किया जाता हैजो मूल रूप से कॉन्फ़िगर की गई है. + अगर यह नीति सेट हो तो, स्क्रीन की रोशनी कम होने या स्क्रीन बंद हो जाने के तुरंत बाद उपयोगकर्ता की किसी गतिविधि का पता चलने पर, स्क्रीन की रोशनी कितनी देर में कम हो, इस समय को घटाने या बढ़ाने का प्रतिशत तय करती है. जब इस समय को कम या ज़्यादा किया जाता है तो, बंद स्क्रीन, स्क्रीन लॉक और 'उपयोग में नहीं' की स्थिति में पहुंचने में लगने वाले समय को एडजस्ट किया जाता है. इसे ऐसे एडजस्ट किया जाता है कि इस समय और स्क्रीन की रोशनी कम होने में लगने वाले समय के बीच वही समान दूरी बनी रहे जो मूल रूप से कॉन्फ़िगर की गई है. - यदि नीति सेट नहीं हो, तो डिफ़ॉल्ट मापन कारक का उपयोग किया जाता है. + अगर नीति सेट नहीं हो तो, 'डिफ़ॉल्ट स्केल फ़ैक्टर' का उपयोग किया जाता है. - मापन कारक 100% या अधिक होना चाहिए.</translation> + 'स्केल फ़ैक्टर' 100% या ज़्यादा होना चाहिए.</translation> <translation id="131353325527891113">प्रवेश स्क्रीन पर उपयोगकर्ता नाम दिखाएं</translation> <translation id="1327466551276625742">ऑफ़लाइन होने पर नेटवर्क कॉन्फ़िगरेशन संकेत को सक्षम करें</translation> <translation id="1330145147221172764">ऑन-स्क्रीन कीबोर्ड सक्षम करें</translation> @@ -112,27 +112,27 @@ <translation id="1427655258943162134">प्रॉक्सी सर्वर का पता या URL</translation> <translation id="1435659902881071157">डिवाइस-स्तरीय नेटवर्क कॉन्फ़िगरेशन</translation> <translation id="1438739959477268107">डिफ़ॉल्ट कुंजी जेनरेशन सेटिंग</translation> -<translation id="1454846751303307294">आपको यूआरएल पैटर्न की सूची सेट करने देती है जो उन साइटों को निर्दिष्ट करती है जिन्हें JavaScript चलाने की अनुमति नहीं होती. +<translation id="1454846751303307294">वैसी साइट जिनमें JavaScript चलाने की अनुमति नहीं है, उनके लिए यूआरएल पैटर्न की सूची सेट करने की सुविधा देती है. - अगर यह नीति सेट किए बिना छोड़ दी जाती है तो सभी साइटों के लिए 'DefaultJavaScriptSetting' नीति के सेट होने पर इससे, या अन्यथा उपयोगकर्ता के व्यक्तिगत कॉन्फ़िगरेशन से वैश्विक डिफ़ॉल्ट मान का उपयोग किया जाएगा.</translation> + अगर इस नीति को सेट नहीं किया जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultJavaScriptSetting' सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> <translation id="1456822151187621582">Windows (<ph name="PRODUCT_OS_NAME" /> क्लाइंट):</translation> -<translation id="1464848559468748897"><ph name="PRODUCT_OS_NAME" /> डिवाइस पर एकाधिक प्रोफ़ाइल सत्र में उपयोगकर्ता व्यवहार को नियंत्रित करती है. +<translation id="1464848559468748897">यह नीति <ph name="PRODUCT_OS_NAME" /> डिवाइसों पर 'एक से ज़्यादा प्रोफ़ाइल सत्र' में उपयोगकर्ता के व्यवहार को नियंत्रित करती है. - यदि यह नीति 'MultiProfileUserBehaviorUnrestricted' पर सेट है, तो उपयोगकर्ता एकाधिक प्रोफ़ाइल सत्र में या तो प्राथमिक या द्वितीयक उपयोगकर्ता हो सकता है. + अगर यह नीति 'MultiProfileUserBehaviorUnrestricted' पर सेट है तो, उपयोगकर्ता 'एक से ज़्यादा प्रोफ़ाइल सत्र' में या तो प्राथमिक या कोई दूसरा उपयोगकर्ता हो सकता है. - यदि यह नीति 'MultiProfileUserBehaviorMustBePrimary' पर सेट है, तो उपयोगकर्ता एकाधिक प्रोफ़ाइल सत्र में केवल प्राथमिक उपयोगकर्ता हो सकता है. + अगर यह नीति 'MultiProfileUserBehaviorMustBePrimary' पर सेट है तो, उपयोगकर्ता 'एक से ज़्यादा प्रोफ़ाइल सत्र' में सिर्फ़ प्राथमिक उपयोगकर्ता हो सकता है. - यदि यह नीति 'MultiProfileUserBehaviorNotAllowed' पर सेट है, तो उपयोगकर्ता एकाधिक प्रोफ़ाइल सत्र का भाग नहीं हो सकता. + अगर यह नीति 'MultiProfileUserBehaviorNotAllowed' पर सेट है तो, उपयोगकर्ता 'एक से ज़्यादा प्रोफ़ाइल सत्र' का हिस्सा नहीं हो सकता. - यदि आप इस सेटिंग को सेट करते हैं, तो उपयोगकर्ता इसे बदल या ओवरराइड नहीं कर सकते. + अगर आप इस सेटिंग को सेट करते हैं तो, उपयोगकर्ता इसे बदल नहीं सकते या ओवरराइड नहीं कर सकते. - यदि सेटिंग को उपयोगकर्ता के एकाधिक प्रोफ़ाइल सत्र में प्रवेश किए हुए रहने के दौरान बदला जाता है, तो सत्र के सभी उपयोगकर्ताओं की उनकी संगत सेटिंग के विरुद्ध जाँच की जाएगी. यदि उपयोगकर्ताओं में से किसी एक को सत्र में रहने की अनुमति नहीं दी जाती तो सत्र बंद कर दिया जाएगा. + अगर सेटिंग को उपयोगकर्ता के 'एक से ज़्यादा प्रोफ़ाइल सत्र' में साइन इन रहने के दौरान बदला जाता है तो, सत्र के सभी उपयोगकर्ताओं की उनकी-उनकी सेटिंग के हिसाब से जाँच की जाएगी. अगर उपयोगकर्ताओं में से किसी एक को सत्र में रहने की अनुमति नहीं दी जाती तो सत्र बंद कर दिया जाएगा. - यदि नीति को सेट किए बिना छोड़ दिया जाता है, तो एंटरप्राइज़-प्रबंधित उपयोगकर्ताओं के लिए डिफ़ॉल्ट मान 'MultiProfileUserBehaviorMustBePrimary' लागू होता है और गैर-प्रबंधित उपयोगकर्ताओं के लिए 'MultiProfileUserBehaviorUnrestricted' का उपयोग किया जाएगा.</translation> + अगर नीति सेट नहीं की जाती है तो, एंटरप्राइज़-प्रबंधित उपयोगकर्ताओं के लिए डिफ़ॉल्ट मान 'MultiProfileUserBehaviorMustBePrimary' लागू होगा और गैर-प्रबंधित उपयोगकर्ताओं के लिए 'MultiProfileUserBehaviorUnrestricted' का उपयोग किया जाएगा.</translation> <translation id="1465619815762735808">चलाने के लिए क्लिक करें</translation> -<translation id="1466133662354365542">यह नीति <ph name="PRODUCT_NAME" /> की 'अपने आप भरने की सुविधा (ऑटो फ़िल)' चालू करती है. इससे उपयोगकर्ताओं को यह सहूलियत मिलती है कि वेब फ़ॉर्म में क्रेडिट कार्ड और पते की जानकारी अपने आप भर जाती है. पहले से सेव की गई जानकारी का इस्तेमाल करके ऐसा किया जाता है. +<translation id="1466133662354365542"><ph name="PRODUCT_NAME" /> की 'अपने आप भरने की सुविधा (ऑटोफ़िल)' चालू करती है. इसके ज़रिए उपयोगकर्ताओं को क्रेडिट कार्ड और पते से जुड़ी जानकारी जैसी पहले से जमा सूचनाओं की मदद से वेब फ़ॉर्म को अपने आप भरने की सुविधा मिलती है. - अगर आप इस सेटिंग को बंद कर देते हैं तो, 'अपने आप भरने की सुविधा' कभी कोई सुझाव नहीं देगी या क्रेडिट कार्ड की जानकारी को अपने आप नहीं भरेगी और न ही यह क्रेडिट कार्ड की उस जानकारी को सेव करेगी जिसे उपयोगकर्ता ने शायद वेब ब्राउज़ करते समय सबमिट किया हो. + अगर आप इस सेटिंग को बंद कर देते हैं तो, 'अपने आप भरने की सुविधा' कभी कोई सुझाव नहीं देगी या क्रेडिट कार्ड की जानकारी को अपने आप नहीं भरेगी. साथ ही यह, ना तो क्रेडिट कार्ड की उस जानकारी को सेव करेगी जिसे उपयोगकर्ता ने शायद वेब ब्राउज़ करते समय सबमिट किया हो. अगर आप इस सेटिंग को चालू करते हैं या कोई मान सेट नहीं करते हैं तो, उपयोगकर्ता यूज़र इंटरफ़ेस (यूआई) में 'अपने आप भरने की सुविधा (क्रेडिट कार्ड सहित)' को पूरी तरह नियंत्रित कर पाएगा.</translation> <translation id="1468307069016535757">लॉग इन स्क्रीन पर ज़्यादा कंट्रास्ट वाले मोड की उपलब्धता सुविधा की डिफ़ॉल्ट स्थिति तय करें. @@ -141,10 +141,10 @@ अगर नीति गलत पर सेट है तो, लॉग इन स्क्रीन के दिखाई देने पर ज़्यादा कंट्रास्ट वाला मोड बंद हो जाएगा. - अगर आप इस नीति को जोड़ते हैं तो, उपयोगकर्ता ज़्यादा कंट्रास्ट वाले मोड को चालू या बंद करके इसे अस्थायी रूप से रद्द कर सकते हैं. हालांकि, उपयोगकर्ता की पसंद स्थायी नहीं होती है और लॉग इन स्क्रीन के फिर से दिखाई देने या उपयोगकर्ता जब लॉग इन स्क्रीन पर एक मिनट तक निष्क्रिय बना रहता है तो, डिफ़ॉल्ट स्थिति लागू हो जाती है. + अगर आप इस नीति को सेट करते हैं तो, उपयोगकर्ता ज़्यादा कंट्रास्ट वाले मोड को चालू या बंद करके इसे अस्थायी रूप से रद्द कर सकते हैं. हालांकि, उपयोगकर्ता की पसंद स्थायी नहीं होती है और लॉग इन स्क्रीन के फिर से दिखाई देने या उपयोगकर्ता जब लॉग इन स्क्रीन पर एक मिनट तक कोई गतिविधि नहीं करता तो, डिफ़ॉल्ट स्थिति लागू हो जाती है. अगर यह नीति जोड़े बिना छोड़ दी जाती है तो, लॉग इन स्क्रीन के पहली बार दिखाई देने पर ज़्यादा कंट्रास्ट वाला मोड बंद हो जाता है. उपयोगकर्ता जब चाहें ज़्यादा कंट्रास्ट वाला मोड चालू या बंद कर सकते हैं और उपयोगकर्ताओं के बीच लॉग इन स्क्रीन पर इसकी स्थिति स्थायी हो जाती है.</translation> -<translation id="1468707346106619889">अगर इस नीति को 'सही' पर सेट किया गया है तो, 'यूनिफ़ाइड डेस्कटॉप' की अनुमति मिल जाती है और +<translation id="1468707346106619889">अगर इस नीति को सही' पर सेट किया गया है तो, 'यूनिफ़ाइड डेस्कटॉप' की अनुमति मिल जाती है और यह सुविधा डिफ़ॉल्ट रूप से चालू रहती है. इससे ऐप्लिकेशन, एक से ज़्यादा स्क्रीन पर दिखाई दे सकता है. उपयोगकर्ता को अगर अकेले ही कुछ देखना है तो वह डिसप्ले सेटिंग में 'यूनिफ़ाइड डेस्कटॉप' के @@ -168,13 +168,13 @@ <translation id="1522425503138261032">उपयोगकर्ताओं के वास्तविक स्थान पर नज़र रखने के लिए साइटों को अनुमति दें</translation> <translation id="152657506688053119">डिफ़ॉल्ट खोज की सुविधा के लिए वैकल्पिक URL की सूची</translation> <translation id="1530812829012954197">होस्ट ब्राउज़र में हमेशा, दिए गए इन URL का पैटर्न बनाएं</translation> -<translation id="1553684822621013552">जब इस पॉलिसी को सत्य पर सेट किया जाता है, उपयोगकर्ता के लिए ARC को सक्षम किया जाएगा - (अतिरिक्त पॉलिसी सेटिंग जाँच के अधीन - ARC तब भी - अनुपलब्ध रहेगा यदि अल्पकालिक मोड या एकाधिक प्रवेश को - वर्तमान उपयोगकर्ता सत्र में सक्षम किया गया है). +<translation id="1553684822621013552">जब यह नीति सही पर सेट होती है तो, उपयोगकर्ता के लिए एआरसी को चालू कर दिया जाएगा + (नीति संबंधी सेटिंग की और ज़्यादा जाँच का विषय - एआरसी तब भी + उपलब्ध नहीं रहेगा अगर मौजूदा उपयोगकर्ता सत्र में अल्पकालिक मोड या एक से ज़्यादा साइन इन + को चालू किया गया हो). - यदि यह सेटिंग अक्षम है या कॉन्फ़िगर नहीं है तो एंटरप्राइज़ उपयोगकर्ता - ARC का उपयोग नहीं कर सकेंगे.</translation> + अगर यह सेटिंग बंद है या कॉन्फ़िगर नहीं है तो, एंटरप्राइज़ उपयोगकर्ता + एआरसी का उपयोग नहीं कर सकेंगे.</translation> <translation id="1561424797596341174">दूरस्थ ऐक्सेस होस्ट के डीबग बिल्ड के लिए पॉलिसी ओवरराइड</translation> <translation id="1561967320164410511">अलग-अलग प्रमाणन करने के लिए U2F सहित एक्सटेंशन</translation> <translation id="1574554504290354326">यह सेटिंग रोक दी गई है, इसके बजाय SafeBrowsingExtendedReportingEnabled का इस्तेमाल करें. SafeBrowsingExtendedReportingEnabled को चालू या बंद करना SafeBrowsingExtendedReportingOptInAllowed को गलत पर सेट करने जैसा है. @@ -210,13 +210,13 @@ <translation id="172374442286684480">सभी साइटों को स्थानीय डेटा सेट करने की अनुमति देना</translation> <translation id="1734716591049455502">रिमोट पहुंच विकल्प कॉन्फ़िगर करें</translation> <translation id="1736269219679256369">SSL चेतावनी पृष्ठ से जारी रखने की अनुमति देना</translation> -<translation id="1749815929501097806">सेवा की उन शर्तों को सेट करें, जिन्हें उपयोगकर्ता को डिवाइस-स्थानीय खाता सत्र शुरू करने से पहले स्वीकार करना होता है. +<translation id="1749815929501097806">सेवा की उन शर्तों को सेट करती है, जिन्हें उपयोगकर्ता को डिवाइस-स्थानीय खाता सत्र शुरू करने से पहले स्वीकार करना होता है. अगर यह नीति जोड़ी जाती है तो, <ph name="PRODUCT_OS_NAME" /> सेवा की शर्तों को डाउनलोड करेगा और डिवाइस-स्थानीय खाता सत्र शुरू होने पर उन्हें उपयोगकर्ता को पेश करेगा. सेवा की शर्तों को स्वीकार करने के बाद ही उपयोगकर्ता को सत्र में जाने की अनुमति मिलेगी. अगर यह नीति सेट नहीं की जाती तो, सेवा की शर्तें नहीं दिखाई जातीं. - नीति को किसी ऐसे URL से जोड़ा जाना चाहिए जिससे <ph name="PRODUCT_OS_NAME" /> सेवा की शर्तें डाउनलोड कर सके. सेवा की शर्तें सामान्य लेख में होनी चाहिए जिसे MIME किस्म के लेख/सामान्य के रूप में दिया गया हो. किसी मार्कअप की अनुमति नहीं है.</translation> + नीति को किसी ऐसे यूआरएल से जोड़ा जाना चाहिए जिससे <ph name="PRODUCT_OS_NAME" /> सेवा की शर्तें डाउनलोड कर सके. सेवा की शर्तें सामान्य लेख में होनी चाहिए जिसे एमआईएमई किस्म के लेख/सामान्य के रूप में दिया गया हो. किसी मार्कअप की अनुमति नहीं है.</translation> <translation id="1750315445671978749">सभी डाउनलोड ब्लॉक करें</translation> <translation id="1781356041596378058">यह नीति Android डेवलपर विकल्प का एक्सेस भी नियंत्रित करती है. यदि आप इस नीति को सही पर सेट करते हैं, तो उपयोगकर्ता डेवलपर विकल्प का एक्सेस नियंत्रित नहीं कर सकते. यदि आप इस नीति को गलत पर सेट करते हैं या सेट किए बिना छोड़ देते हैं, तो उपयोगकर्ता Android सेटिंग ऐप्लिकेशन में बिल्ड संख्या पर सात बार टैप करके डेवलपर विकल्प एक्सेस कर सकते हैं.</translation> <translation id="178832255504524723">पासवर्ड बदलने का यूआरएल कॉन्फ़िगर करना (सिर्फ़ HTTP और HTTPS स्कीम). अगर उपयोगकर्ताओं के पासवर्ड प्रकाशित हो गए हैं तो पासवर्ड सुरक्षा सेवा उन्हें अपने पासवर्ड बदलने के लिए यह यूआरएल भेजेगी. @@ -225,12 +225,12 @@ अगर यह सेटिंग चालू हो तो, उपयोगकर्ताओं के पासवर्ड प्रकाशित हो जाने पर पासवर्ड सुरक्षा सेवा उन्हें अपने पासवर्ड बदलने के लिए यह यूआरएल भेजेगी. अगर यह सेटिंग बंद हो या सेट न की गई हो तो, पासवर्ड सुरक्षा सेवा उपयोगकर्ताओं को उनका पासवर्ड बदलने के लिए https://myaccounts.google.com भेजेगी. यह नीति Windows के उन इंस्टैंस पर नहीं मिलेगी जो किसी <ph name="MS_AD_NAME" /> डोमेन में शामिल नहीं हुए हैं.</translation> -<translation id="1797233582739332495">उपयोगकर्ता को बार-बार यह सूचित करने वाला संकेत दिखाती है कि फिर से लॉन्च करना ज़रूरी है</translation> +<translation id="1797233582739332495">उपयोगकर्ता को बार-बार यह सूचित करने वाला संकेत दिखाता है कि फिर से लॉन्च करना ज़रूरी है</translation> <translation id="1803646570632580723">लॉन्चर में दिखाए जाने वाले पिन किए गए ऐप्स की सूची</translation> <translation id="1808715480127969042">इन साइटों पर कुकी अवरुद्ध करें</translation> <translation id="1810261428246410396">इंस्टैंट टेदरिंग को मंज़ूरी देती है.</translation> <translation id="1827523283178827583">निश्चित प्रॉक्सी सर्वर का उपयोग करें</translation> -<translation id="1843117931376765605">उपयोगकर्ता नीति के लिए रीफ्रेश दर</translation> +<translation id="1843117931376765605">'उपयोगकर्ता नीति' के लिए रीफ्रेश दर</translation> <translation id="1844620919405873871">तुरंत अनलॉक करने संबंधी नीतियां कॉन्फ़िगर करती है.</translation> <translation id="1847960418907100918">POST के साथ त्वरित खोज करते समय उपयोग किए जाने वाले पैरामीटर निर्दिष्ट करती है. इसमें अल्पविराम द्वारा अलग किए गए नाम/मान के युग्म शामिल होते हैं. यदि कोई मान टेम्पलेट पैरामीटर, जैसे उपरोक्त उदाहरण में {searchTerms} है, तो उसे वास्तविक खोज शब्द डेटा से प्रतिस्थापित कर दिया जाएगा. @@ -246,24 +246,24 @@ अगर यह नीति कॉन्फ़िगर नहीं है या इसे "tls1.2" पर सेट किया हुआ है तो, फिर <ph name="PRODUCT_NAME" /> फ़ॉलबैक प्रक्रिया को अब पूरा नहीं करता है. ध्यान दें कि यह पहले वाले टीएलएस वर्शन का समर्थन बंद नहीं करता, सिर्फ़ <ph name="PRODUCT_NAME" /> बग वाले सर्वर पर काम करेगा या नहीं जो वर्शन से ठीक से व्यवहार नहीं कर सकते हैं. वरना, अगर बग वाले सर्वर के साथ काम करने की स्थिति बनाए रखनी ज़रूरी हो तो, इस नीति को "tls1.1" पर सेट किया जा सकता है. यह एक अस्थायी उपाय है और सर्वर को जल्दी ही ठीक किया जाना चाहिए.</translation> -<translation id="1864269674877167562">यदि इस पॉलिसी को किसी खाली स्ट्रिंग पर सेट किया जाता है या कॉन्फ़िगर नहीं किया जाता है, तो <ph name="PRODUCT_OS_NAME" /> प्रवेश प्रवाह के दौरान कोई स्वत:पूर्ण विकल्प नहीं दिखाएगा. - यदि इस पॉलिसी को डोमेन नाम का प्रतिनिधित्व करने वाली किसी स्ट्रिंग पर सेट किया जाता है, तो <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता के प्रवेश करने के दौरान एक स्वत:पूर्ण विकल्प दिखाएगा जिससे उपयोगकर्ता डोमेन नाम एक्सेटेंशन के बिना केवल अपना उपयोगकर्ता नाम लिख सकेगा. उपयोगकर्ता इस डोमेन नाम एक्सटेंशन को ओवरराइट कर सकेगा.</translation> +<translation id="1864269674877167562">अगर इस नीति को किसी खाली स्ट्रिंग पर सेट किया जाता है या कॉन्फ़िगर नहीं किया जाता है तो, उपयोगकर्ता के साइन इन के दौरान <ph name="PRODUCT_OS_NAME" /> अपने आप पूरा होने वाला कोई विकल्प नहीं दिखाएगा. + अगर इस नीति को डोमेन नाम के बारे में बताने वाले किसी स्ट्रिंग पर सेट किया जाता है तो, उपयोगकर्ता के साइन इन करने पर <ph name="PRODUCT_OS_NAME" /> अपने आप पूरा होने वाला विकल्प दिखाएगा. इसकी मदद से उपयोगकर्ता डोमेन नाम एक्सेटेंशन के बिना सिर्फ़ अपना नाम लिख सकेगा. उपयोगकर्ता इस डोमेन नाम एक्सटेंशन को बदल सकेगा.</translation> <translation id="1865417998205858223">प्रमुख अनुमतियां</translation> <translation id="186719019195685253">AC पावर पर चलते समय प्रयोग में नहीं विलंब तक पहुंच जाने पर की जाने वाली कार्यवाही</translation> -<translation id="187819629719252111"><ph name="PRODUCT_NAME" /> को फाइल चयन संबंधी संवाद दिखाने की अनुमति देकर मशीन पर लोकल फ़ाइल का एक्सेस देती है. +<translation id="187819629719252111">यह नीति, <ph name="PRODUCT_NAME" /> को 'फाइल चुनने का संवाद' दिखाने की अनुमति देकर मशीन पर मौजूद स्थानीय फ़ाइल का एक्सेस देती है. - अगर आप यह सेटिंग चालू करते हैं तो, उपयोगकर्ता सामान्य रूप से फ़ाइल चयन संबंधी संवाद खोल सकते हैं. + अगर आप यह सेटिंग चालू करते हैं तो, उपयोगकर्ता सामान्य रूप से 'फ़ाइल चुनने का संवाद' खोल सकते हैं. - अगर आप यह सेटिंग बंद करते हैं तो, जब भी उपयोगकर्ता कोई ऐसा कार्य करता है जिसकी वजह से चयन संबंधी संवाद डॉयलॉग सामने आता है (जैसे बुकमार्क मंगाना, फ़ाइलें अपलोड करना, लिंक सेव करना जैसे अन्य कदम) तो, एक मैसेज दिखाई देता है. साथ ही, उपयोगकर्ता से उम्मीद की जाती है कि उसने फ़ाइल चयन संबंधी संवाद आने पर 'अभी नहीं' बटन पर क्लिक किया होगा. + अगर आप यह सेटिंग बंद करते हैं तो, जब भी उपयोगकर्ता कोई ऐसा काम करता है, जिसकी वजह से 'फ़ाइल चुनने का संवाद' सामने आता है (जैसे बुकमार्क लेकर आना, फ़ाइल अपलोड करना, लिंक सेव करना वगैरह) तो इसके बजाय एक मैसेज दिखाई देता है और यह मान लिया जाता है कि उपयोगकर्ता ने 'फ़ाइल चुनने के संवाद' पर 'रद्द करें' क्लिक कर दिया है. - अगर यह सेटिंग सेट नहीं है तो, उपयोगकर्ता सामान्य रूप से फ़ाइल चयन संबंधी संवाद खोल सकते हैं.</translation> -<translation id="1879485426724769439">डिवाइस के लिए उपयोग किए जाने वाले समय क्षेत्र के बारे में बताती है. उपयोगकर्ता वर्तमान सत्र के लिए बताए गए समय क्षेत्र को रद्द कर सकते हैं. हालांकि, लॉग आउट करने पर वह वापस बताए गए समय क्षेत्र पर सेट हो जाता है. अगर गलत मान दिया जाता है तो, नीति इसके बजाय "GMT" के उपयोग से फिर भी सक्रिय रहेगी. अगर कोई खाली स्ट्रिंग दी जाती है तो, नीति को अनदेखा कर दिया जाता है. + अगर यह सेटिंग सेट नहीं है तो, उपयोगकर्ता सामान्य रूप से 'फ़ाइल चुनने का संवाद' खोल सकते हैं.</translation> +<translation id="1879485426724769439">डिवाइस के लिए उपयोग किए जाने वाले समय क्षेत्र के बारे में बताती है. उपयोगकर्ता वर्तमान सत्र के लिए बताए गए समय क्षेत्र को रद्द कर सकते हैं. हालांकि, लॉग आउट करने पर वह वापस बताए गए समय क्षेत्र पर सेट हो जाता है. अगर गलत मान दिया जाता है तो, नीति इसके बजाय "जीएमटी (ग्रीनविच मानक समय)" के उपयोग से फिर भी सक्रिय रहेगी. अगर कोई खाली स्ट्रिंग दी जाती है तो, नीति को अनदेखा कर दिया जाता है. अगर इस नीति का उपयोग नहीं किया जाता है तो, फ़िलहाल सक्रिय समय क्षेत्र इस्तेमाल में बने रहेंगे. हालांकि, उपयोगकर्ता समय क्षेत्र को बदल सकते हैं और यह बदलाव लगातार होता रहता है. इसलिए किसी एक उपयोगकर्ता की तरफ़ से किया गया बदलाव, लॉग इन स्क्रीन और सभी अन्य उपयोगकर्ताओं को प्रभावित करता है. नए डिवाइस "यूएस/प्रशांत" में सेट समय क्षेत्र के साथ शुरू होते हैं. - मान का फ़ॉर्मैट "IANA समय क्षेत्र डेटाबेस" ("https://en.wikipedia.org/wiki/Tz_database" देखें) में दिए गए समय क्षेत्रों के नामों का पालन करता है. खास तौर पर, ज़्यादातर समय क्षेत्र "continent/large_city" या "ocean/large_city" से जुड़े हो सकते हैं. + मान का फ़ॉर्मैट "आईएएनए समय क्षेत्र डेटाबेस" ("https://en.wikipedia.org/wiki/Tz_database" देखें) में दिए गए समय क्षेत्रों के नामों का पालन करता है. खास तौर पर, ज़्यादातर समय क्षेत्र "continent/large_city" या "ocean/large_city" से जुड़े हो सकते हैं. इस नीति को सेट करने से, डिवाइस के 'जगह की जानकारी' के ज़रिए अपने आप समय क्षेत्र को ठीक करने की प्रक्रिया पूरी तरह बंद हो जाती है. यह SystemTimezoneAutomaticDetection नीति को भी रद्द कर सकती है.</translation> <translation id="1888871729456797026">डेस्कटॉप पर क्लाउड नीति का नामांकन टोकन</translation> @@ -292,15 +292,15 @@ </translation> <translation id="193259052151668190">अलग किए जाने वाले USB डिवाइस की श्वेतसूची</translation> <translation id="1933378685401357864">वॉलपेपर चित्र</translation> -<translation id="1956493342242507974"><ph name="PRODUCT_OS_NAME" /> में प्रवेश स्क्रीन पर पावर प्रबंधन कॉन्फ़िगर करें. +<translation id="1956493342242507974"><ph name="PRODUCT_OS_NAME" /> में लॉग इन स्क्रीन पर पावर प्रबंधन को कॉन्फ़िगर करें. - यह नीति प्रवेश स्क्रीन के दिखाई देने पर कुछ समय के लिए कोई भी उपयोगकर्ता गतिविधि नहीं होने पर आपको <ph name="PRODUCT_OS_NAME" /> के व्यवहार करने के तरीके को कॉन्फ़िगर करने देती है. नीति एकाधिक सेटिंग नियंत्रित करती है. उनके व्यक्तिगत सीमेंटिक और मान श्रेणियों के लिए, सत्र में पावर प्रबंधन को नियंत्रित करने वाली संबंधित नीतियां देखें. इन नीतियों के साथ भिन्नताएं निम्न हैं: - * निष्क्रिय या लिड बंद होने पर की जाने वाली कार्यवाहियां सत्र को समाप्त करने के लिए नहीं हो सकतीं. - * AC पावर पर चलते समय निष्क्रिय होने पर की जाने वाली डिफ़ॉल्ट कार्यवाही शट डाउन करना है. + यह नीति आपको यह कॉन्फ़िगर करने की सुविधा देती है कि लॉग इन स्क्रीन के दिखाई देने पर कुछ समय तक अगर किसी भी तरह की उपयोगकर्ता गतिविधि नहीं हो तो, <ph name="PRODUCT_OS_NAME" /> का व्यवहार कैसा होगा. यह नीति एक साथ कई सेटिंग नियंत्रित करती है. अलग-अलग तौर पर इन सेटिंग का मतलब जानने और मान श्रेणियों के लिए, उन संबंधित नीतियों को देखें जो किसी सत्र में पावर प्रबंधन को नियंत्रित करती हैं. इन नीतियों में ये अंतर हैं: + * कोई गतिविधि नहीं होने या लिड बंद होने पर की जाने वाली कार्रवाइयां सत्र को खत्म नहीं कर सकतीं. + * AC पावर पर चलते समय, कोई गतिविधि नहीं होने पर की जाने वाली डिफ़ॉल्ट कार्रवाई शट डाउन करना है. - यदि कोई सेटिंग अनिर्दिष्ट छोड़ दी जाती है, तो डिफ़ॉल्ट मान का उपयोग किया जाता है. + अगर कोई सेटिंग तय किए बिना छोड़ दी जाती है तो, डिफ़ॉल्ट मान का उपयोग किया जाता है. - यदि यह नीति सेट नहीं है, तो सभी सेटिंग के लिए डिफ़ॉल्ट का उपयोग किया जाता है.</translation> + अगर यह नीति सेट नहीं होती है तो, सभी सेटिंग के लिए डिफ़ॉल्ट का उपयोग किया जाता है.</translation> <translation id="1960840544413786116">स्थानीय विश्वसनीय एंकरों की ओर से जारी किए जाने वाले ऐसे प्रमाणपत्रों को अनुमति दें या नहीं जिनमें subjectAlternativeName एक्सटेंशन मौजूद नहीं है</translation> <translation id="1964634611280150550">गुप्त मोड अक्षम किया गया</translation> <translation id="1964802606569741174">इस नीति का Android YouTube ऐप्लिकेशन पर कोई प्रभाव नहीं पड़ता. यदि YouTube पर सुरक्षा मोड लागू किया जाना चाहिए, तो Android YouTube ऐप्लिकेशन के इंस्टॉलेशन की अनुमति नहीं दी जानी चाहिए.</translation> @@ -332,9 +332,9 @@ यदि इस पॉलिसी को सेट नहीं किया जाता है, तो चारों योजनाओं का उपयोग किया जाएगा.</translation> <translation id="2067011586099792101">सामग्री पैक से बाहर की साइटों की एक्सेस अवरुद्ध करें</translation> -<translation id="2070270043919235595">उपयोगकर्ताओं को सूचित करती है कि जिस अपडेट की मंज़ूरी बाकी है उसे लागू करने के लिए <ph name="PRODUCT_NAME" /> को फिर से लॉन्च करना होगा. +<translation id="2070270043919235595">यह नीति उपयोगकर्ताओं को सूचित करती है कि जिस अपडेट की मंज़ूरी बाकी है, उसे लागू करने के लिए <ph name="PRODUCT_NAME" /> को फिर से लॉन्च करना होगा. - यह नीति सेटिंग उपयोगकर्ता को इस बात की सूचना देने के लिए सूचनाएं चालू करती है कि ब्राउज़र को फिर से लॉन्च करने का सुझाव दिया गया है या ऐसा करना ज़रूरी है. अगर सेट नहीं होती है, तो <ph name="PRODUCT_NAME" /> उपयोगकर्ता को यह बताती है कि उसके मेन्यू में खास बदलावों के ज़रिए फिर से लॉन्च करना ज़रूरी है. अगर 'सुझाया गया' पर सेट होती है, तो उपयोगकर्ता को बार-बार यह चेतावनी दिखाएगी कि फिर से लॉन्च करने का सुझाव दिया गया है. उपयोगकर्ता फिर से लॉन्च करने को टालने के लिए इस चेतावनी को खारिज कर सकता है. अगर 'ज़रूरी' पर सेट होती है, तो उपयोगकर्ता को बार-बार यह चेतावनी दिखाएगी कि सूचना की अवधि खत्म होने पर ब्राउज़र को बिना पूछे फिर से लॉन्च कर दिया जाएगा. डिफ़ॉल्ट रूप से यह अवधि सात दिनों की होती है और <ph name="RELAUNCH_NOTIFICATION_PERIOD_POLICY_NAME" /> नीति सेटिंग के ज़रिए कॉन्फ़िगर की जा सकती है. + यह नीति सेटिंग, उपयोगकर्ता को यह बताने के लिए सूचनाएं चालू करती है कि ब्राउज़र को फिर से लॉन्च करने का सुझाव दिया गया है या ऐसा करना ज़रूरी है. अगर यह सेट नहीं होती है तो, <ph name="PRODUCT_NAME" /> उपयोगकर्ता को यह बताता है कि उसके मेन्यू में खास बदलावों के ज़रिए फिर से लॉन्च करना ज़रूरी है. अगर यह नीति 'सुझाया गया' पर सेट होती है तो, उपयोगकर्ता को बार-बार यह चेतावनी दिखाती है कि फिर से लॉन्च करने का सुझाव दिया गया है. उपयोगकर्ता फिर से लॉन्च करने को टालने के लिए इस चेतावनी को खारिज कर सकता है. अगर यह नीति 'ज़रूरी' पर सेट होती है तो, उपयोगकर्ता को बार-बार यह चेतावनी दिखाएगी कि सूचना की समय सीमा खत्म होने पर ब्राउज़र को बिना पूछे फिर से लॉन्च कर दिया जाएगा. डिफ़ॉल्ट रूप से यह समय सीमा सात दिनों की होती है और <ph name="RELAUNCH_NOTIFICATION_PERIOD_POLICY_NAME" /> नीति सेटिंग के ज़रिए कॉन्फ़िगर की जा सकती है. फिर से लॉन्च करने के बाद उपयोगकर्ता का सत्र बहाल कर दिया जाता है.</translation> <translation id="2073552873076775140"><ph name="PRODUCT_NAME" /> में साइन इन करने देती है</translation> @@ -343,13 +343,13 @@ <translation id="2082205219176343977">डिवाइस के लिए कम से कम अनुमत Chrome वर्शन कॉन्फ़िगर करें.</translation> <translation id="209586405398070749">स्थिर चैनल</translation> <translation id="2098658257603918882">उपयोग और क्रैश-संबंधित डेटा की रिपोर्टिंग सक्षम करें</translation> -<translation id="2111016292707172233"><ph name="PRODUCT_NAME" /> के सामग्री व्यू में 'खोजने के लिए टैप करें' की सुविधा को चालू करती है. +<translation id="2111016292707172233">यह नीति <ph name="PRODUCT_NAME" /> के 'सामग्री व्यू' में 'खोजने के लिए टैप करें' सुविधा को चालू करती है. - अगर आप इस सेटिंग को चालू करते हैं तो, 'खोजने के लिए टैप करें' की सुविधा उपयोगकर्ता के लिए उपलब्ध होगी और वह इसे चालू या बंद कर सकता है. + अगर आप यह सेटिंग चालू करते हैं तो, 'खोजने के लिए टैप करें' सुविधा उपयोगकर्ता के लिए उपलब्ध होगी और वह इसे चालू या बंद कर सकता है. - अगर आप इस सेटिंग को बंद करते हैं तो, 'खोजने के लिए टैप करें' सुविधा को पूरी तरह बंद कर दिया जाएगा. + अगर आप यह सेटिंग बंद करते हैं तो, 'खोजने के लिए टैप करें' सुविधा पूरी तरह बंद कर दी जाएगी. - अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, यह इस सुविधा को चालू करने जैसा होगा, ऊपर दी गई जानकारी देखें.</translation> + अगर यह नीति सेट नहीं की जाती है तो, यह इस सुविधा को चालू करने जैसा होगा, ऊपर दी गई जानकारी देखें.</translation> <translation id="2113068765175018713">अपने आप रीबूट करके डिवाइस का सक्रिय समय सीमित करें</translation> <translation id="2127599828444728326">इन साइटों पर नोटिफ़िकेशन की अनुमति दें</translation> <translation id="2131902621292742709">बैटरी पावर पर चलते समय स्क्रीन मंद विलंब</translation> @@ -365,15 +365,17 @@ ध्यान रखें कि अगर <ph name="PRODUCT_NAME" /> चल रहा है और यह नीति बदल जाती है, तो यह सिर्फ़ खोले गए नए टैब पर लागू होगी. इसलिए हो सकता है कि कुछ टैब अभी भी पुराने तरीके का पालन करें.</translation> <translation id="2134437727173969994">स्क्रीन लॉक करने की अनुमति</translation> -<translation id="2137064848866899664">यदि यह पॉलिसी सेट की जाती है, तो प्रत्येक बार रीबूट करने - और पॉलिसी मान बदलने के बाद उसके पहली बार कनेक्ट होने पर - प्रत्येक प्रदर्शन को विशिष्ट अभिविन्यास में घुमाया जाता है. उपयोगकर्ता, प्रवेश करने के बाद सेटिंग पृष्ठ के माध्यम से प्रदर्शन को घुमा सकते हैं, लेकिन अगली बार - रीबूट करने पर पॉलिसी मान द्वारा उनकी सेटिंग ओवरराइड कर दी जाएगी. +<translation id="2137064848866899664">अगर यह नीति सेट की जाती है तो, हर बार फिर से चालू करने + और नीति मान बदलने के बाद उसके पहली बार कनेक्ट होने पर, + हर डिसप्ले को स्क्रीन की तय की गई दिशा में घुमाया जाता है. उपयोगकर्ता, लॉग इन करने के + बाद सेटिंग पेज के ज़रिए डिसप्ले को घुमा सकते हैं लेकिन अगली बार फिर से चालू करने पर + नीति मान उनकी सेटिंग ओवरराइड कर देगा. - यह पॉलिसी, प्राथमिक और द्वितीयक दोनों प्रदर्शनों पर लागू होती है. + यह पॉलिसी, प्राथमिक और बाकी सभी तरह के डिसप्ले पर लागू होती है. - यदि पॉलिसी सेट नहीं की जाती है, तो डिफ़ॉल्ट मान 0 डिग्री होता है और उपयोगकर्ता - उसे बदलने के लिए स्वतंत्र होता है. इस स्थिति में, डिफ़ॉल्ट मान को पुन: प्रारंभ करने पर फिर से लागू नहीं किया जाता है.</translation> + अगर नीति सेट नहीं की जाती है तो, डिफ़ॉल्ट मान 0 डिग्री होता है और उपयोगकर्ता + चाहे तो उसे बदल सकता है. ऐसा होता है तो, दोबारा शुरू करने पर डिफ़ॉल्ट + मान को फिर से लागू नहीं किया जाता.</translation> <translation id="2156132677421487971"><ph name="PRODUCT_NAME" /> के लिए नीतियां कॉन्फ़िगर करें, यह एक ऐसी सुविधा है जिसकी मदद से उपयोगकर्ता ब्राउज़र से टैब, साइटों या डेस्कटॉप की सामग्रियों को दूर स्थित प्रदर्शन और ध्वनि सिस्टम पर भेज सकते हैं.</translation> <translation id="2168397434410358693">AC पावर पर चलते समय प्रयोग में नहीं विलंब</translation> <translation id="2170233653554726857">WPAD ऑप्टिमाइज़ेशन सक्षम करें</translation> @@ -394,11 +396,11 @@ अगर SystemTimezone नीति सेट की जाती है तो, वह इस नीति को ओवरराइड कर लेती है. ऐसे में अपने आप होने वाली 'समय-क्षेत्र पहचान प्रक्रिया' पूरी तरह से बंद कर दी जाती है.</translation> <translation id="2178899310296064282">YouTube पर कम से कम मध्यम प्रतिबंधित मोड लागू करें</translation> <translation id="2182291258410176649">उपयोगकर्ता बैकअप और बहाली को चालू करने या नहीं करने का फ़ैसला लेता है</translation> -<translation id="2183294522275408937">यह सेटिंग नियंत्रित करती है कि तुरंत अनलॉक करें सुविधा का उपयोग जारी रखने के लिए, लॉक स्क्रीन कितने समय में पासवर्ड डालने का अनुरोध करेगी. हर बार लॉक स्क्रीन में कुछ डालने पर, अगर पिछली बार डाला गया पासवर्ड इस सेटिंग से ज़्यादा था तो, लॉक स्क्रीन पर तुरंत अनलॉक करें सुविधा मौजूद नहीं होगी. अगर इस समय के दौरान उपयोगकर्ता लॉक स्क्रीन पर बना रहता है तो, अगली बार गलत कोड डाले जाने पर या लॉक स्क्रीन पर फिर से जाने पर (जो भी पहले हो), पासवर्ड का अनुरोध किया जाएगा. +<translation id="2183294522275408937">यह सेटिंग नियंत्रित करती है कि 'तुरंत अनलॉक करें' सुविधा का उपयोग जारी रखने के लिए, लॉक स्क्रीन कितने समय में पासवर्ड डालने का अनुरोध करेगी. हर बार लॉक स्क्रीन दिखने पर, अगर पिछली बार डाले गए पासवर्ड का समय इस सेटिंग से ज़्यादा था तो, लॉक स्क्रीन पर 'तुरंत अनलॉक करें' सुविधा मौजूद नहीं होगी. अगर यह समय बीत जाने के बाद उपयोगकर्ता लॉक स्क्रीन पर बना रहता है तो, अगली बार गलत कोड डाले जाने पर या लॉक स्क्रीन पर फिर से जाने पर (जो भी पहले हो), पासवर्ड का अनुरोध किया जाएगा. - अगर यह सेटिंग कॉन्फ़िगर की जाती है तो, तुरंत अनलॉक करें सुविधा का उपयोग करने वाले उपयोगकर्ताओं से, इस सेटिंग के आधार पर लॉक स्क्रीन पर अपना पासवर्ड डालने का अनुरोध किया जाएगा. + अगर यह सेटिंग कॉन्फ़िगर की जाती है तो, 'तुरंत अनलॉक करें' सुविधा का उपयोग करने वाले उपयोगकर्ताओं से, इस सेटिंग के आधार पर लॉक स्क्रीन पर अपना पासवर्ड डालने का अनुरोध किया जाएगा. - अगर यह सेटिंग कॉन्फ़िगर नहीं की जाती है तो, तुरंत अनलॉक करें सुविधा का उपयोग करने वाले उपयोगकर्ताओं से, हर दिन लॉक स्क्रीन पर अपना पासवर्ड डालने का अनुरोध किया जाएगा.</translation> + अगर यह सेटिंग कॉन्फ़िगर नहीं की जाती है तो, 'तुरंत अनलॉक करें' का उपयोग करने वाले उपयोगकर्ताओं से हर दिन लॉक स्क्रीन पर अपना पासवर्ड डालने का अनुरोध किया जाएगा.</translation> <translation id="2194470398825717446">इस नीति का समर्थन M61 में रोक दिया गया है, कृपया इसके बजाय EcryptfsMigrationStrategy का उपयोग करें. यह बताती है कि ecryptfs के ज़रिए भेजे गए डिवाइस को किस तरह व्यवहार करना चाहिए और उसे ext4 एन्क्रिप्शन में संक्रमण करने की ज़रूरत होती है. @@ -415,7 +417,8 @@ <translation id="2223598546285729819">सामान्य सूचना सेटिंग</translation> <translation id="2231817271680715693">पहली बार चलाने पर सामान्य ब्राउज़र से ब्राउज़िंग इतिहास आयात करें</translation> <translation id="2236488539271255289">स्थानीय डेटा सेट करने के लिए किसी साइट को अनुमति न दें</translation> -<translation id="2240879329269430151">आपको यह सेट करने देती है कि वेबसाइटों को पॉप-अप प्रदर्शित करने की अनुमति है या नहीं. पॉप अप प्रदर्शित करना, सभी साइटों के लिए स्वीकृत या अस्वीकृत हो सकता है. यदि इस नीति को सेट किए बिना छोड़ दिया जाता है, तो 'BlockPopups' का उपयोग किया जाएगा और उपयोगकर्ता इसे परिवर्तित कर सकेंगे.</translation> +<translation id="2240879329269430151">यह सेट करने देती है कि वेबसाइटों को पॉप-अप दिखाने की अनुमति है या नहीं. पॉप-अप दिखाए जाने की अनुमति या तो सभी साइटों के लिए दी जा सकती है या फिर सभी साइटों के लिए खारिज की जा सकती है. + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, 'BlockPopups' का उपयोग किया जाएगा और उपयोगकर्ता इसमें बदलाव कर सकेंगे.</translation> <translation id="2269319728625047531">साइन-इन के दौरान सिंक सहमति दिखाना चालू करें</translation> <translation id="2274864612594831715">यह नीति 'वर्चुअल कीबोर्ड' को ChromeOS पर इनपुट डिवाइस के रूप में चालू करना कॉन्फ़िगर करती है. @@ -443,7 +446,7 @@ दो API (एपीआई) उन ऐप्लिकेशन/एक्सटेंशन के लिए उपलब्ध नहीं होते हैं जो अनइंस्टॉल न किए जा सकने वाले नहीं होते हैं.) - इस नीति को संभावित तौर पर विरोधी <ph name="EXTENSION_INSTALL_BLACKLIST_POLICY_NAME" /> नीति के बदले प्राथमिकता मिलती है. अगर इस सूची में से किसी ऐसे ऐप्लिकेशन या एक्सटेंशन को हटाया जाता है जो पहले अनइंस्टॉल न किए जा सकने वाला था तो, <ph name="PRODUCT_NAME" /> उसे अपने आप अनइंस्टॉल कर देता है. + इस नीति को संभावित तौर पर विरोधी <ph name="EXTENSION_INSTALL_BLACKLIST_POLICY_NAME" /> नीति पर प्राथमिकता मिलती है. अगर इस सूची में से किसी ऐसे ऐप्लिकेशन या एक्सटेंशन को हटाया जाता है जो पहले अनइंस्टॉल न किए जा सकने वाला था तो, <ph name="PRODUCT_NAME" /> उसे अपने आप अनइंस्टॉल कर देता है. Windows के ऐसे इंस्टेंस के लिए जो किसी <ph name="MS_AD_NAME" /> डोमेन में शामिल नहीं हैं, अनइंस्टॉल न किया जा सकना 'Chrome वेब स्टोर' में मौजूद ऐप्लिकेशन और एक्सटेंशन तक सीमित है. @@ -483,18 +486,18 @@ जब तक आप 'स्टार्टअप पर कार्रवाई' में 'यूआरएल की कोई सूची खोलें' का चयन नहीं करते हैं, तब तक 'स्टार्टअप पर खोले जाने वाले कार्रवाई' की सूची की सामग्री पर ध्यान नहीं दिया जाएगा.</translation> <translation id="2327252517317514801">G Suite एक्सेस करने की अनुमति वाले डोमेन तय करें</translation> -<translation id="2372547058085956601">सार्वजनिक सत्र स्वत:-प्रवेश विलंब. +<translation id="2372547058085956601">सार्वजनिक सत्र के लिए अपने आप होने वाले लॉग इन में देरी - यदि |DeviceLocalAccountAutoLoginId| नीति अनसेट होती है, तो इस नीति का कोई प्रभाव नहीं पड़ता. अन्यथा: + अगर |DeviceLocalAccountAutoLoginId| नीति सेट नहीं की गई है तो, इस नीति का कोई असर नहीं होता. नहीं तो: - यदि यह नीति सेट होती है, तो यह उपयोगकर्ता गतिविधि के बिना उस समयावधि को निर्धारित करती है जिसे |DeviceLocalAccountAutoLoginId| नीति द्वारा निर्दिष्ट सार्वजनिक सत्र में स्वचालित रूप से प्रवेश करने से पहले बीत जाना चाहिए. + अगर यह नीति सेट होती है तो, यह उपयोगकर्ता की गतिविधि के बिना उस समय सीमा को तय करती है जिसे |DeviceLocalAccountAutoLoginId| नीति के ज़रिए बताए गए सार्वजनिक सत्र में अपने आप लॉग इन करने से पहले बीत जाना चाहिए. - यदि यह नीति अनसेट होती है, तो समयबाह्य के रूप में 0 मिलीसेकंड का उपयोग किया जाएगा. + अगर यह नीति सेट नहीं की गई होती है तो, समय खत्म होने (टाइमआउट) के तौर पर 0 मिलीसेकंड का उपयोग किया जाएगा. - यह नीति मिलीसेकंड में निर्दिष्ट की जाती है.</translation> -<translation id="237494535617297575">आपको उन यूआरएल पैटर्न की सूची सेट करने देता है जो ऐसी साइटों को निर्दिष्ट करते हैं जिन पर सूचनाएं प्रदर्शित करने की अनुमति है. + यह नीति मिलीसेकंड में बताई जाती है.</translation> +<translation id="237494535617297575">वैसी साइट जिन्हें सूचनाएं दिखाने की अनुमति है, उनके लिए यूआरएल पैटर्न की सूची सेट करने की सुविधा देती है. - अगर यह नीति सेट किए बिना छोड़ दी जाती है तो सभी साइटों के लिए वैश्विक डिफ़ॉल्ट मान का उपयोग या तो 'DefaultNotificationsSetting' नीति के सेट होने पर उससे किया जाएगा, या अन्यथा उपयोगकर्ता के व्यक्तिगत कॉन्फ़िगरेशन से किया जाएगा.</translation> + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultNotificationsSetting' नीति सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> <translation id="2386362615870139244">स्क्रीन सक्रिय करने वाले लॉक की अनुमति दें</translation> <translation id="2411817661175306360">पासवर्ड सुरक्षा की ओर से चेतावनी बंद है</translation> <translation id="2411919772666155530">इन साइटों पर सूचनाएं अवरुद्ध करें</translation> @@ -527,9 +530,9 @@ <translation id="2466131534462628618">कैप्टिव पोर्टल प्रमाणीकरण प्रॉक्सी पर ध्यान नहीं देता है</translation> <translation id="2482676533225429905">स्थानीय संदेश सेवा</translation> <translation id="2483146640187052324">किसी भी नेटवर्क कनेक्शन पर नेटवर्क कार्रवाई का पूर्वानुमान लगाएं</translation> -<translation id="2485721741875148980">अगर यह नीति सही पर सेट की जाती है, तो उपयोगकर्ता को ब्राउज़र का इस्तेमाल करने से पहले अपनी प्रोफ़ाइल के ज़रिए <ph name="PRODUCT_NAME" /> में साइन इन करना होगा. और BrowserGuestModeEnabled का डिफ़ॉल्ट मान गलत पर सेट कर दिया जाएगा. ध्यान दें कि इस नीति को चालू करने के बाद साइन नहीं की गईं मौजूदा प्रोफ़ाइल लॉक कर दी जाएंगी और पहुंच से बाहर हो जाएंगी. अधिक जानकारी के लिए, सहायता केंद्र लेख देखें. +<translation id="2485721741875148980">अगर यह नीति 'सही' पर सेट की जाती है तो, उपयोगकर्ता को ब्राउज़र का इस्तेमाल करने से पहले अपनी प्रोफ़ाइल के ज़रिए <ph name="PRODUCT_NAME" /> में साइन इन करना होगा. BrowserGuestModeEnabled का डिफ़ॉल्ट मान 'गलत' पर सेट कर दिया जाएगा. ध्यान दें कि इस नीति को चालू करने के बाद, साइन नहीं की गईं मौजूदा प्रोफ़ाइल लॉक कर दी जाएंगी और एक्सेस नहीं की जा सकेंगी. ज़्यादा जानकारी के लिए, 'सहायता केंद्र लेख' देखें. - अगर यह नीति गलत पर सेट की जाती है या कॉन्फ़िगर नहीं की जाती है, तो उपयोगकर्ता <ph name="PRODUCT_NAME" /> में साइन इन किए बिना ब्राउज़र का इस्तेमाल कर सकता है.</translation> + अगर यह नीति 'गलत' पर सेट की जाती है या कॉन्फ़िगर नहीं की जाती है तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में साइन इन किए बिना ब्राउज़र का इस्तेमाल कर सकता है.</translation> <translation id="2486371469462493753">सूची में शामिल किए गए URL के लिए 'प्रमाणपत्र पारदर्शिता' की ज़रूरत को लागू करना बंद करती है. यह नीति तय किए गए किसी खास URL में होस्टनाम के प्रमाणपत्रों को 'प्रमाणपत्र पारदर्शिता' के ज़रिए ज़ाहिर नहीं करती है. यह उन प्रमाणपत्रों का उपयोग किया जाना जारी रखने की अनुमति देती है, जो भरोसे के लायक नहीं होते क्योंकि वे ठीक तरह से सार्वजनिक तौर पर ज़ाहिर नहीं किए गए थे. हालांकि, यह उन होस्ट के लिए गलत तरीके से जारी किए गए प्रमाणपत्रों का पता लगाना ज़्यादा मुश्किल बना देती है. @@ -560,13 +563,13 @@ <translation id="253135976343875019">AC पावर पर चलते समय प्रयोग में नहीं चेतवनी विलंब</translation> <translation id="2536525645274582300">उपयोगकर्ता Google स्थान सेवाओं को चालू करने या नहीं करने का फ़ैसला लेता है</translation> <translation id="2552966063069741410">समयक्षेत्र</translation> -<translation id="2562339630163277285">तुरंत नतीजे पाने के लिए इस्तेमाल होने वाले सर्च इंजन का URL तय करती है. URL में स्ट्रिंग <ph name="SEARCH_TERM_MARKER" /> होना चाहिए, जिसे क्वेरी के समय उपयोगकर्ता की ओर से लिखे गए लेख से बदल दिया जाएगा. +<translation id="2562339630163277285">यह नीति झटपट नतीजे देने के लिए उपयोग किए जाने वाले खोज इंजन का यूआरएल तय करती है. यूआरएल में स्ट्रिंग <ph name="SEARCH_TERM_MARKER" /> होनी चाहिए, जिसे क्वेरी के समय उपयोगकर्ता के अब तक लिखे गए लेख से बदल दिया जाएगा. - यह नीति वैकल्पिक है. अगर इसे जोड़ा नहीं गया है तो, तुरंत कोई खोज नतीजा नहीं मिलेगा. + यह नीति वैकल्पिक है. अगर सेट नहीं है तो, कोई झटपट खोज नतीजे नहीं दिए जाएंगे. - तुरंत खोज नतीजों से जुड़े Google के URL को इस तरह बताया जा सकता है: <ph name="GOOGLE_INSTANT_SEARCH_URL" />. + Google के झटपट नतीजों का यूआरएल इस रूप में तय किया जा सकता है: <ph name="GOOGLE_INSTANT_SEARCH_URL" />. - 'DefaultSearchProviderEnabled' नीति चालू होने पर ही इस नीति का पालन किया जाएगा.</translation> + यह नीति सिर्फ़ तब काम करेगी जब 'DefaultSearchProviderEnabled' नीति चालू होगी.</translation> <translation id="2569647487017692047">अगर यह नीति गलत पर सेट की जाती है तो, <ph name="PRODUCT_OS_NAME" /> ब्लूटूथ को बंद कर देगा और उपयोगकर्ता उसे वापस चालू नहीं कर पाएगा. अगर यह नीति सही पर सेट की जाती है या उसे सेट किए बिना छोड़ दिया जाता है तो, उपयोगकर्ता अपनी मर्ज़ी से ब्लूटूथ को चालू या बंद कर सकेगा. @@ -589,7 +592,7 @@ <translation id="2598508021807251719">वे स्थान-भाषाओं को कॉन्फ़िगर करती है जिनमें <ph name="PRODUCT_OS_NAME" /> दिखाया जा सकता है. अगर यह नीति सेट हो तो, उपयोगकर्ता <ph name="PRODUCT_OS_NAME" /> को सिर्फ़ इस नीति में बताई गई स्थान-भाषाओं में से किसी एक में दिखाए जाने के लिए कॉन्फ़िगर कर सकता है. अगर यह नीति सेट नहीं हो या किसी खाली सूची पर सेट हो तो, <ph name="PRODUCT_OS_NAME" /> को काम करने वाली सभी यूज़र इंटरफ़ेस (यूआई) स्थान-भाषाओं में दिखाया जा सकता है. अगर यह नीति गलत मानों वाली किसी सूची पर सेट हो तो, सभी गलत मानों को अनदेखा कर दिया जाएगा. अगर किसी उपयोगकर्ता ने <ph name="PRODUCT_OS_NAME" /> को पहले किसी ऐसी भाषा में दिखाए जाने के लिए कॉन्फ़िगर किया है जिसे यह नीति मंज़ूरी नहीं देती है तो, दिखाई जाने वाली स्थान-भाषा अगली बार उपयोगकर्ता के साइन इन करने पर मंज़ूरी दी गई स्थान-भाषा में बदल जाएगी. अगर उपयोगकर्ता ने पसंदीदा स्थान-भाषाएं कॉन्फ़िगर की थीं और पसंदीदा स्थान-भाषाओं में से किसी एक को इस नीति ने मंज़ूरी दी है तो, <ph name="PRODUCT_OS_NAME" /> इस स्थान-भाषा में बदल जाएगा. अगर ऐसा नहीं होता है तो, <ph name="PRODUCT_OS_NAME" /> इस नीति के बताए गए पहले सही मान में बदल जाएगा या अगर इस नीति में सिर्फ़ गलत प्रविष्टियां ही हों तो, वह किसी वैकल्पिक स्थान-भाषा (फ़िलहाल en-US) में बदल जाएगा.</translation> -<translation id="2623014935069176671">आरंभिक उपयोगकर्ता गतिविधि की प्रतीक्षा करें</translation> +<translation id="2623014935069176671">'उपयोगकर्ता की शुरुआती गतिविधि' का इंतज़ार करें</translation> <translation id="262740370354162807"><ph name="CLOUD_PRINT_NAME" /> पर दस्तावेज़ों का सबमिशन सक्षम करती है</translation> <translation id="2627554163382448569">एंटरप्राइज़ प्रिंटर के लिए कॉन्फ़िगरेशन उपलब्ध कराती है. @@ -607,16 +610,16 @@ उपयोगकर्ता अलग-अलग डिवाइस पर प्रिंटर कॉन्फ़िगर कर पाते हैं या नहीं, इस पर इस नीति का कोई असर नहीं होता. यह नीति अलग-अलग उपयोगकर्ताओं प्रिंटर को कॉनफ़िगर करने के तरीके की पूरक है. </translation> <translation id="2633084400146331575">मौखिक फ़ीडबैक सक्षम करें</translation> -<translation id="2646290749315461919">आपको यह सेट करने देती है कि क्या वेबसाइटों को उपयोगकर्ता का वास्तविक स्थान ट्रैक करने की अनुमति है. उपयोगकर्ता के वास्तविक स्थान को ट्रैक करने की अनुमति डिफ़ॉल्ट रूप से दी जा सकती है, डिफ़ॉल्ट रूप से अस्वीकार की जा सकती है या हर बार किसी वेबसाइट द्वारा वास्तविक स्थान का अनुरोध किए जाने पर उपयोगकर्ता से हर बार पूछा जा सकता है. +<translation id="2646290749315461919">आपको यह सेट करने की सुविधा देती है कि वेबसाइटों को उपयोगकर्ता की वास्तविक 'जगह की जानकारी' का पता लगाने अनुमति दी जाए या नहीं. उपयोगकर्ता की वास्तविक 'जगह की जानकारी' का पता लगाने की अनुमति डिफ़ॉल्ट रूप से दी जा सकती है, डिफ़ॉल्ट रूप से खारिज की जा सकती है या हर उस समय उपयोगकर्ता से पूछा जा सकता है जब कोई वेबसाइट डेस्कटॉप सूचनाएं दिखाना चाहती हो. - यदि यह नीति सेट किए बिना छोड़ दी जाती है, तो 'AskGeolocation' का उपयोग किया जाएगा और उपयोगकर्ता इसे बदल सकेगा.</translation> + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, 'AskGeolocation' का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> <translation id="2647069081229792812">बुकमार्क में बदलाव करने की सुविधा को चालू या बंद करती है</translation> <translation id="2650049181907741121">उपयोगकर्ता जब लिड बंद करे तब की जाने वाली कार्रवाई</translation> -<translation id="2655233147335439767">डिफ़ॉल्ट खोज करते समय उपयोग किए जाने वाले खोज इंजन का यूआरएल निर्दिष्ट करती है. यूआरएल में '<ph name="SEARCH_TERM_MARKER" />' स्ट्रिंग शामिल होना चाहिए, जिसे क्वेरी के समय उपयोगकर्ता खोजे जा रहे शब्द से बदल सकता है. +<translation id="2655233147335439767">यह नीति, डिफ़ॉल्ट खोज करते समय उपयोग किए जाने वाले खोज इंजन का यूआरएल तय करती है. यूआरएल में '<ph name="SEARCH_TERM_MARKER" />' स्ट्रिंग शामिल होनी चाहिए, जिसे क्वेरी के समय उपयोगकर्ता के खोजे जा रहे शब्द से बदल दिया जाएगा. - Google के खोज यूआरएल को इस रूप में निर्दिष्ट किया जा सकता है: <ph name="GOOGLE_SEARCH_URL" />. + Google के 'खोज यूआरएल' को इस रूप में तय किया जा सकता है: <ph name="GOOGLE_SEARCH_URL" />. - यह विकल्प 'DefaultSearchProviderEnabled' पॉलिसी सक्षम होने पर सेट किया हुआ होना चाहिए और ऐसा होने पर ही यह विकल्प कार्य करेगा.</translation> + जब 'DefaultSearchProviderEnabled' नीति चालू हो तो यह विकल्प सेट होना चाहिए. ऐसा होने पर ही यह विकल्प काम करेगा.</translation> <translation id="2660846099862559570">प्रॉक्सी का उपयोग कभी न करें</translation> <translation id="267596348720209223">खोज प्रदाता द्वारा समर्थित वर्ण एन्कोडिंग निर्दिष्ट करती है. एन्कोडिंग UTF-8, GB2312, और ISO-8859-1 जैसे कोड पेज नाम होते हैं. वे प्रदान किए गए क्रम में आज़माए जाते हैं. @@ -632,13 +635,13 @@ जब इस नीति को गलत पर सेट किया गया हो या कॉन्फ़िगर न किया गया हो, तो आइकन दिखाई देते हैं.</translation> <translation id="2744751866269053547">प्रोटोकॉल प्रबंधकों को पंजीकृत कराएं</translation> -<translation id="2746016768603629042">इस नीति का बहिष्कार कर दिया गया है, कृपया इसके बजाय DefaultJavaScriptSetting का उपयोग करें. +<translation id="2746016768603629042">यह नीति इस्तेमाल में नहीं है, कृपया इसके बजाय DefaultJavaScriptSetting का उपयोग करें. - <ph name="PRODUCT_NAME" /> में JavaScript अक्षम किए जाने के लिए उपयोग किया जा सकता है. + <ph name="PRODUCT_NAME" /> में JavaScript बंद करने लिए उपयोग की जा सकती है. - इस सेटिंग के अक्षम होने पर, वेब पेज JavaScript का उपयोग नहीं कर सकते और उपयोगकर्ता उस सेटिंग को बदल नहीं सकते. + अगर यह सेटिंग के बंद है तो, वेब पेज JavaScript का उपयोग नहीं कर सकते और उपयोगकर्ता उस सेटिंग को बदल नहीं सकता. - यदि यह सेटिंग सक्षम है या सेट नहीं है, तो वेब पेज JavaScript का उपयोग कर सकते हैं लेकिन उपयोगकर्ता उस सेटिंग को बदल सकता है.</translation> + अगर यह सेटिंग चालू है या सेट नहीं है तो, वेब पेज JavaScript का उपयोग कर सकते हैं लेकिन उपयोगकर्ता उस सेटिंग को बदल सकता है.</translation> <translation id="2753637905605932878">WebRTC द्वारा उपयोग किए जाने वाले स्थानीय UDP पोर्ट की सीमा प्रतिबंधित करें</translation> <translation id="2755385841634849932">यह नीति Android बैकअप और बहाली की उपलब्धता को नियंत्रित करती है. @@ -646,7 +649,7 @@ जब यह नीति <ph name="BR_UNDER_USER_CONTROL" /> पर सेट हो तो, उपयोगकर्ता से यह चुनने के लिए कहा जाता है कि Android बैकअप और बहाली का इस्तेमाल करना है या नहीं. अगर उपयोगकर्ता बैकअप और बहाली को चालू करता है तो, Android ऐप्लिकेशन डेटा को Android बैकअप सर्वरों पर अपलोड किया जाता है और संगत ऐप्लिकेशन के लिए ऐप्लिकेशन फिर से इंस्टॉल करने पर उन्हें दोबारा बहाल किया जाता है.</translation> <translation id="2757054304033424106">एक्सटेंशन/ऐप्स के ऐसे प्रकार जिन्हें इंस्टॉल किए जाने की अनुमति है</translation> -<translation id="2759224876420453487">एकाधिक प्रोफ़ाइल सत्र में उपयोगकर्ता के व्यवहार को नियंत्रित करें</translation> +<translation id="2759224876420453487">'एक से ज़्यादा प्रोफ़ाइल सत्र' में उपयोगकर्ता के व्यवहार को नियंत्रित करें</translation> <translation id="2761483219396643566">बैटरी पावर पर चलते समय प्रयोग में नहीं चेतावनी विलंब</translation> <translation id="2762164719979766599">प्रवेश स्क्रीन पर दिखाए जाने वाले डिवाइस-स्थानीय खातों की सूची निर्दिष्ट करता है. @@ -677,9 +680,9 @@ <translation id="2838830882081735096">डेटा माइग्रेशन और ARC की अनुमति न दें</translation> <translation id="2840269525054388612">उन प्रिंटर के बारे में बताती है जिनका इस्तेमाल कोई उपयोगकर्ता कर सकता है. - इस नीति का इस्तेमाल तभी किया जाता है अगर <ph name="DEVICE_PRINTERS_ACCESS_MODE" /> के लिए <ph name="PRINTERS_WHITELIST" /> को चुना गया हो + इस नीति का इस्तेमाल तभी किया जाता है जब <ph name="DEVICE_PRINTERS_ACCESS_MODE" /> के लिए <ph name="PRINTERS_WHITELIST" /> को चुना गया हो - अगर इस नीति का इस्तेमाल किया जाता है, तो सिर्फ़ ऐसे प्रिंटर उपयोगकर्ता को उपलब्ध कराए जाते हैं जिनके आईडी इस नीति में दिए गए मान से मिलान करते हैं. आईडी, <ph name="DEVICE_PRINTERS_POLICY" /> में बताई गई फ़ाइल के "id" या "guid" के मुताबिक होने चाहिए. + अगर इस नीति का इस्तेमाल किया जाता है तो, सिर्फ़ ऐसे प्रिंटर उपयोगकर्ता को उपलब्ध कराए जाते हैं जिनके आईडी इस नीति में दिए गए मान से मेल खाते हैं. आईडी <ph name="DEVICE_PRINTERS_POLICY" /> में बताई गई फ़ाइल के "id" या "guid" फ़ील्ड के मुताबिक होने चाहिए. </translation> <translation id="285480231336205327">उच्च कंट्रास्ट मोड सक्षम करें</translation> <translation id="2854919890879212089">इसके कारण <ph name="PRODUCT_NAME" />, 'प्रिंट की झलक' में डिफ़ॉल्ट पसंद के तौर पर, सबसे हाल में उपयोग किए गए प्रिंटर के बजाय सिस्टम डिफ़ॉल्ट प्रिंटर का इस्तेमाल करता है. @@ -688,12 +691,12 @@ अगर आप इस सेटिंग को चालू करते हैं तो, 'प्रिंट की झलक' डिफ़ॉल्ट पसंद के तौर पर OS सिस्टम डिफ़ॉल्ट प्रिंटर का उपयोग करेगा.</translation> <translation id="2867699958489427143">अगर OS वर्शन टार्गेट से नया है, तो रोल बैक करें और टार्गेट वर्शन पर रहें. इस प्रक्रिया के दौरान पूरा पावरवॉश करें.</translation> -<translation id="286802604195763750">आपको पासवर्ड सुरक्षा चेतावनी का ट्रिगर होना नियंत्रित करने देती है. पासवर्ड सुरक्षा उपयोगकर्ताओं को तब चेतावनी देती है जब वे संभावित रूप से संदिग्ध साइटों पर अपने सुरक्षित पासवर्ड का दोबारा इस्तेमाल करते हैं. +<translation id="286802604195763750">यह नीति आपको 'पासवर्ड सुरक्षा चेतावनी' को ट्रिगर करने का नियंत्रण देती है. 'पासवर्ड सुरक्षा' उपयोगकर्ताओं को तब चेतावनी देती है जब वे उन साइट पर अपने सुरक्षित पासवर्ड का दोबारा इस्तेमाल करते हैं जिनसे उनकी सुरक्षा को खतरा हो सकता है. - अगर यह नीति 'PasswordProtectionWarningOff' पर सेट की जाती है, तो कोई पासवर्ड सुरक्षा चेतावनी नहीं दिखाई जाएगी. - अगर यह नीति 'PasswordProtectionWarningOnPasswordReuse' पर सेट की जाती है, तो पासवर्ड सुरक्षा चेतावनी तब दिखाई जाएगी जब उपयोगकर्ता श्वेतसूची में नहीं रखी गई किसी साइट पर अपने Google पासवर्ड का दोबारा इस्तेमाल करेगा. - अगर यह नीति 'PasswordProtectionWarningOnPhishingReuse' पर सेट की जाती है, तो पासवर्ड सुरक्षा चेतावनी तब दिखाई जाएगी जब उपयोगकर्ता किसी फ़िशिंग साइट पर अपने Google पासवर्ड का दोबारा इस्तेमाल करेगा. - अगर यह नीति सेट किए बिना छोड़ दी जाती है, तो पासवर्ड सुरक्षा चेतावनी तब दिखाई जाएगी जब उपयोगकर्ता किसी फ़िशिंग साइट पर अपने Google पासवर्ड का दोबारा इस्तेमाल करेगा लेकिन उपयोगकर्ता इस सेटिंग को बदल सकेगा.</translation> + अगर यह नीति 'PasswordProtectionWarningOff' पर सेट की जाती है तो, कोई 'पासवर्ड सुरक्षा चेतावनी' नहीं दिखाई जाएगी. + अगर यह नीति 'PasswordProtectionWarningOnPasswordReuse' पर सेट की जाती है तो, 'पासवर्ड सुरक्षा चेतावनी' तब दिखाई जाएगी जब उपयोगकर्ता ऐसी किसी साइट पर अपने Google पासवर्ड का दोबारा इस्तेमाल करेगा जिसे मंज़ूरी नहीं मिली हुई है. + अगर यह नीति 'PasswordProtectionWarningOnPhishingReuse' पर सेट की जाती है तो, 'पासवर्ड सुरक्षा चेतावनी' तब दिखाई जाएगी जब उपयोगकर्ता किसी फ़िशिंग साइट पर अपने Google पासवर्ड का दोबारा इस्तेमाल करेगा. + अगर यह नीति सेट नहीं की जाती है तो, 'पासवर्ड सुरक्षा चेतावनी' तब दिखाई जाएगी जब उपयोगकर्ता किसी फ़िशिंग साइट पर अपने Google पासवर्ड का दोबारा इस्तेमाल करेगा लेकिन उपयोगकर्ता इस सेटिंग को बदल सकेगा.</translation> <translation id="2872961005593481000">शट डाउन करें</translation> <translation id="2874209944580848064">Android ऐप्लिकेशन का समर्थन करने वाले <ph name="PRODUCT_OS_NAME" /> डिवाइस के लिए नोट:</translation> <translation id="2877225735001246144">Kerberos की पुष्टि तय करते समय CNAME लुकअप बंद करें</translation> @@ -716,21 +719,22 @@ <translation id="2957513448235202597"><ph name="HTTP_NEGOTIATE" /> प्रमाणीकरण के लिए खाता प्रकार</translation> <translation id="2959898425599642200">प्रॉक्सी बायपास नियम</translation> <translation id="2960691910306063964">रिमोट ऐक्सेस वाले होस्ट के लिए 'बिना पिन के पहचान करने की सुविधा' चालू या बंद करें</translation> -<translation id="2976002782221275500">बैटरी पावर पर चलते समय, उस समयावधि को निर्दिष्ट करती है जितनी देर तक उपयोगकर्ता कोई भी इनपुट न दे, उसके बाद स्क्रीन मंद हो जाती है. +<translation id="2976002782221275500">बैटरी पावर पर चलते समय उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता अगर कोई भी इनपुट नहीं देता है तो, उसके बाद स्क्रीन की रोशनी कम हो जाती है. - जब इस नीति को शून्य से अधिक के मान पर सेट किया जाता है, तो यह <ph name="PRODUCT_OS_NAME" /> द्वारा स्क्रीन को मंद किए जाने से पहले की उस समयावधि को निर्दिष्ट करती है जिस दौरान उपयोगकर्ता को प्रयोग में नहीं रहना होगा. + जब इस नीति को शून्य से ज़्यादा मान पर सेट किया जाता है तो, यह <ph name="PRODUCT_OS_NAME" /> की ओर से स्क्रीन की रोशनी कम किए जाने से पहले की उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता कोई गतिविधि नहीं करता. - जब इस नीति को शून्य पर सेट किया जाता है, तो उपयोगकर्ता के प्रयोग में नहीं हो जाने पर <ph name="PRODUCT_OS_NAME" /> स्क्रीन को मंद नहीं करता. + जब इस नीति को शून्य पर सेट किया जाता है तो, उपयोगकर्ता की ओर से कोई गतिविधि नहीं करने के बावजूद <ph name="PRODUCT_OS_NAME" /> स्क्रीन की रोशनी कम नहीं करता. - जब इस नीति को सेट नहीं किया जाता, तो एक डिफ़ॉल्ट समयावधि का उपयोग किया जाता है. + जब यह नीति सेट नहीं की जाती है तो, एक डिफ़ॉल्ट समय सीमा का उपयोग किया जाता है. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए. मानों को स्क्रीन बंद विलंब (यदि सेट हो) और प्रयोग में नहीं विलंब से कम या उसके बराबर होने के लिए क्लैम्प किया जाता है.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए. मानों को, स्क्रीन बंद होने में देरी (अगर सेट हो) और कोई गतिविधि नहीं में देरी से कम या उसके बराबर पर रखा जाता है.</translation> <translation id="2987155890997901449">ARC सक्षम करें</translation> <translation id="2987227569419001736">वेब ब्लूटूथ API (एपीआई) का इस्तेमाल नियंत्रित करें</translation> <translation id="3016255526521614822">श्वेतसूची में शामिल नोट लेने वाले ऐप्लिकेशन की <ph name="PRODUCT_OS_NAME" /> लॉक स्क्रीन पर अनुमति है</translation> <translation id="3021562480854470924">उपलब्धियों के रोलबैक की मंज़ूर की गई संख्या</translation> <translation id="3030000825273123558">मेट्रिक रिपोर्ट करना सक्षम करें</translation> -<translation id="3034580675120919256">आपको यह सेट करने देती है कि वेबसाइटों को JavaScript चलाने की अनुमति हो या नहीं. JavaScript चलाया जाना या तो सभी वेबसाइटों के लिए अनुमत हो सकता है या सभी वेबसाइटों के लिए अस्वीकृत हो सकता है. यदि इस नीति को सेट किए बिना छोड़ दिया जाता है, तो 'AllowJavaScript' का उपयोग किया जाएगा और उपयोगकर्ता इसे बदल सकेगा.</translation> +<translation id="3034580675120919256">यह सेट करने की सुविधा देती है कि वेबसाइटों को JavaScript चलाने की अनुमति है या नहीं. JavaScript चलाने की अनुमति या तो सभी साइटों के लिए दी जा सकती है या फिर सभी साइटों के लिए खारिज की जा सकती है. + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, 'AllowJavaScript' का उपयोग किया जाएगा और उपयोगकर्ता इसमें बदलाव कर सकेंगे.</translation> <translation id="3038323923255997294">जब <ph name="PRODUCT_NAME" /> बंद हो पृष्ठभूमि ऐप्लिकेशन चलाना जारी रखें</translation> <translation id="3046192273793919231">ऑनलाइन स्थिति को मॉनीटर करने के लिए प्रबंधन सर्वर को नेटवर्क पैकेट भेजें</translation> <translation id="3048744057455266684">अगर इस नीति को जोड़ा गया है और ऑम्निबॉक्स से सुझाए गए किसी खोज URL की क्वेरी स्ट्रिंग में यह पैरामीटर शामिल है तो, सुझाव के ज़रिए अधूरे खोज URL के बजाय, खोज शब्दों और खोज की सुविधा को दिखाया जाएगा. @@ -832,9 +836,9 @@ अगर यह सेटिंग कॉन्फ़िगर की गई है, तो जिन एक्सटेंशन/ऐप्लिकेशन का प्रकार सूची में नहीं है उन्हें इंस्टॉल नहीं किया जाएगा. अगर यह सेटिंग कॉन्फ़िगर किए बिना छोड़ दी जाती है, तो स्वीकार्य एक्सटेंशन/ऐप्लिकेशन प्रकारों पर कोई भी प्रतिबंध लागू नहीं किया जाता.</translation> -<translation id="3322771899429619102">आपको उन यूआरएल पैटर्न की सूची सेट करने देती है, जो ऐसी साइट पर ले जाते हैं जो 'की' जनरेट करने की सुविधा इस्तेमाल कर सकती हैं. अगर कोई यूआरएल पैटर्न 'KeygenBlockedForUrls' में हो तो, वह इन अपवादों को ओवरराइड करता है. +<translation id="3322771899429619102">वैसी साइट जिन्हें कुंजी जनरेट करने की अनुमति नहीं है, उनके लिए यूआरएल पैटर्न की सूची सेट करने की सुविधा देती है. अगर कोई यूआरएल पैटर्न 'KeygenBlockedForUrls' में है तो, यह पॉलिसी ऐसे अपवादों को रद्द कर देती है. - अगर इस नीति को सेट नहीं किया जाता है तो, सभी साइटों के लिए ग्लोबल डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultKeygenSetting' नीति सेट है तो यह मान वहां से लिया जाएगा. अगर यह नीति भी सेट नहीं है तो, यह मान उपयोगकर्ता की निजी कॉनफ़िगरेशन से लिया जाएगा.</translation> + अगर इस नीति को नहीं जोड़ा जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultKeygenSetting' नीति सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> <translation id="332771718998993005"><ph name="PRODUCT_NAME" /> गंतव्य के रूप में दिखाया जाने वाला नाम तय करें. अगर इस नीति को खाली नहीं रहने वाली स्ट्रिंग पर सेट किया जाता है, तो उस स्ट्रिंग का उपयोग <ph name="PRODUCT_NAME" /> गंतव्य के नाम के रूप में किया जाएगा. ऐसा नहीं होने पर, डिवाइस का नाम ही गंतव्य नाम होगा. अगर यह नीति सेट नहीं की जाती है, तो डिवाइस का नाम ही गंतव्य नाम होगा और डिवाइस का मालिक (या डिवाइस का प्रबंधन करने वाले डोमेन का उपयोगकर्ता) उसे बदल सकेगा. नाम में 24 वर्ण ही हो सकते हैं.</translation> @@ -847,18 +851,18 @@ <translation id="3414260318408232239">अगर यह नीति कॉन्फ़िगर नहीं की जाती है तो फिर <ph name="PRODUCT_NAME" /> डिफ़ॉल्ट न्यूनतम वर्शन का इस्तेमाल करता है, जो कि TLS 1.0 है. अन्यथा उसे आगे दिए गए किसी एक मान पर सेट किया जा सकता है: "tls1", "tls1.1" या "tls1.2". सेट होने पर, <ph name="PRODUCT_NAME" /> बताए गए SSL/TLS वर्शन से नीचे वाले वर्शन का इस्तेमाल नहीं करेगा. नहीं पहचाने गए किसी मान को अनदेखा कर दिया जाएगा.</translation> -<translation id="3417418267404583991">यदि यह नीति सही पर सेट है या कॉन्फ़िगर नहीं है, तो <ph name="PRODUCT_OS_NAME" /> अतिथि प्रवेश सक्षम करेगा. अतिथि प्रवेश अज्ञात उपयोगकर्ता सत्र है और इसके लिए पासवर्ड की आवश्यकता नहीं है. +<translation id="3417418267404583991">अगर यह नीति सही पर सेट है या कॉन्फ़िगर नहीं है तो, <ph name="PRODUCT_OS_NAME" /> मेहमान लॉग इन मोड को चालू करेगा. मेहमान लॉग इन मोड बिना नाम वाले उपयोगकर्ता सत्र हैं और इनके लिए पासवर्ड की ज़रूरत नहीं होती है. - यदि यह नीति गलत पर सेट है, तो <ph name="PRODUCT_OS_NAME" /> अतिथि सत्रों को प्रारंभ नहीं होने देगा.</translation> + अगर यह नीति गलत पर सेट है तो, <ph name="PRODUCT_OS_NAME" /> मेहमान लॉग इन सत्रों को शुरू नहीं होने देगा.</translation> <translation id="3418871497193485241">YouTube पर सबसे कम पाबंदी वाला मोड लागू करती है और उपयोगकर्ताओं को कम पाबंदी वाला मोड चुनने से रोकती है. अगर यह सेटिंग 'सख्त' पर सेट की जाती है तो, YouTube पर सख्त पाबंदी वाला मोड हमेशा काम करता रहता है. - अगर यह सेटिंग 'थोड़ा नरम' पर सेट की जाती है तो, उपयोगकर्ता YouTube पर सिर्फ़ थोड़ा नरम - पाबंदी वाला मोड और सख्त पाबंदी वाला मोड में से किसी एक को चुन सकता है लेकिन वह पाबंदी मोड को बंद नहीं कर सकता + अगर यह सेटिंग 'थोड़ा नरम' पर सेट की जाती है तो, उपयोगकर्ता YouTube पर + सिर्फ़ 'थोड़ा नरम पाबंदी वाला मोड' और 'सख्त पाबंदी वाला मोड' में से किसी एक को चुन सकता है लेकिन वह पाबंदी मोड को बंद नहीं कर सकता. - अगर यह सेटिंग बंद कर दी जाती है या कोई मान सेट नहीं किया जाता है तो, <ph name="PRODUCT_NAME" /> YouTube पर पाबंदी वाला मोड लागू नहीं करता. हालांकि, YouTube की नीतियों जैसी बाहरी नीतियां अभी भी पाबंदी वाला मोड लागू कर सकती हैं.</translation> + अगर यह सेटिंग बंद कर दी जाती है या कोई मान सेट नहीं किया जाता है तो, <ph name="PRODUCT_NAME" /> YouTube पर पाबंदी वाला मोड लागू नहीं करता. हालांकि, YouTube की नीतियों जैसी बाहरी नीतियां अभी भी पाबंदी वाला मोड लागू कर सकती हैं.</translation> <translation id="3428247105888806363">नेटवर्क पूर्वानुमान सक्षम करें</translation> <translation id="3449886121729668969"><ph name="PRODUCT_NAME" /> की प्रॉक्सी सेटिंग कॉन्फ़िगर करती है. ये प्रॉक्सी सेटिंग ARC-ऐप्लिकेशन के लिए भी उपलब्ध होंगी. @@ -868,12 +872,12 @@ यह नीति वैकल्पिक है. अगर इसे जोड़ा नहीं गया है तो, कोई भी नया टैब पेज दिखाई नहीं होगा. 'DefaultSearchProviderEnabled' नीति चालू होने पर ही इस नीति का पालन किया जाएगा.</translation> -<translation id="3465852069254497664">उपयोगकर्ता को यह सूचित करती है कि ब्राउज़र को फिर से लॉन्च करने का सुझाव दिया गया है या ऐसा करना ज़रूरी है</translation> -<translation id="346731943813722404">निर्दिष्ट करती है कि पावर प्रबंधन विलंब और सत्र अवधि सीमा केवल किसी सत्र में प्रथम उपयोगकर्ता गतिविधि के बाद ही प्रारंभ हो या नहीं. +<translation id="3465852069254497664">उपयोगकर्ता को सूचित करती है कि ब्राउज़र को फिर से लॉन्च करने का सुझाव दिया गया है या ऐसा करना ज़रूरी है</translation> +<translation id="346731943813722404">यह तय करती है कि क्या पावर प्रबंधन में देरी और सत्र की समय सीमा, सिर्फ़ किसी सत्र में पहले उपयोगकर्ता की गतिविधि का पता लगाने के बाद ही शुरू हो या नहीं. - यदि यह नीति सही पर सेट है, तो पावर प्रबंधन विलंब और सत्र अवधि सीमा तब तक प्रारंभ नहीं होती जब तक कि किसी सत्र में पहली उपयोगकर्ता गतिविधि दिखाई नहीं देती. + अगर यह नीति सही पर सेट की जाती है तो, पावर प्रबंधन में देरी और सत्र की समय सीमा तब तक शुरू नहीं होती जब तक कि किसी सत्र में पहले उपयोगकर्ता की गतिविधि का पता नहीं चल जाता. - यदि यह नीति गलत पर सेट है या सेट किए बिना छोड़ दी गई है, तो पावर प्रबंधन विलंब और सत्र अवधि सीमा सत्र प्रारंभ होते ही तत्काल प्रारंभ हो जाती है.</translation> + अगर यह नीति गलत पर सेट हो या बिना सेट किए हुए छोड़ दी जाए तो, पावर प्रबंधन में देरी और सत्र की समय सीमा, सत्र के शुरू होते ही काम करना चालू कर देती हैं.</translation> <translation id="3478024346823118645">साइन-आउट करने पर उपयोगकर्ता का डेटा मिटाएं</translation> <translation id="348495353354674884">आभासी कीबोर्ड सक्षम करें</translation> <translation id="3487623755010328395"> @@ -897,17 +901,17 @@ अगर यह नीति 'DeveloperToolsAllowed' (मान 1) पर सेट की जाती है, तो डेवलपर टूल और 'JavaScript कंसोल' सभी संदर्भों में एक्सेस और इस्तेमाल किए जा सकते हैं, जिनमें एंटरप्राइज़ नीति के ज़रिए इंस्टॉल किए गए एक्सटेंशन का संदर्भ भी शामिल है. अगर यह नीति 'DeveloperToolsDisallowed' (मान 2) पर सेट की जाती है, तो डेवलपर टूल एक्सेस नहीं किए जा सकते हैं और अब वेबसाइट के तत्वों की जांच नहीं की जा सकती. डेवलपर टूल या 'JavaScript कंसोल' को खोलने वाले सभी कीबोर्ड शॉर्टकट और सभी मेन्यू या संदर्भ मेन्यू बंद हो जाएंगे.</translation> <translation id="3547954654003013442">प्रॉक्सी सेटिंग</translation> -<translation id="3556806727696701427"><ph name="PRODUCT_NAME" /> की सुरक्षित ब्राउज़िंग सुविधा को चालू करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. +<translation id="3556806727696701427">यह नीति <ph name="PRODUCT_NAME" /> की 'सुरक्षित ब्राउज़िंग' सुविधा को चालू करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. - अगर आप इस सेटिंग को चालू करते हैं तो, सुरक्षित ब्राउज़िंग हमेशा काम करते रहती है. + अगर आप यह सेटिंग चालू करते हैं तो, 'सुरक्षित ब्राउज़िंग' की सुविधा हमेशा काम करती है. - अगर आप इस सेटिंग को बंद करते हैं तो, सुरक्षित ब्राउज़िंग कभी काम नहीं करती है. + अगर आप यह सेटिंग बंद करते हैं तो, 'सुरक्षित ब्राउज़िंग' की सुविधा कभी काम नहीं करती. - अगर आप इस सेटिंग को चालू या बंद करते हैं तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में "फ़िशिंग और मैलवेयर सुरक्षा चालू करें" सेटिंग को बदल नहीं सकते हैं और न ही उसे रद्द कर सकते हैं. + अगर आप इस सेटिंग को चालू या बंद करते हैं तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में "फ़िशिंग और मैलवेयर सुरक्षा चालू करें" सेटिंग को बदल नहीं सकते. - अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, उसे चालू कर दिया जाएगा लेकिन उपयोगकर्ता उसे बदल सकेगा. + अगर नीति को सेट किए बिना छोड़ दिया जाता है तो, उसे चालू कर दिया जाएगा लेकिन उपयोगकर्ता उसे बदल सकेगा. - सुरक्षित ब्राउज़िंग के बारे में ज़्यादा जानकारी के लिए https://developers.google.com/safe-browsing देखें. + 'सुरक्षित ब्राउज़िंग' के बारे में ज़्यादा जानकारी के लिए https://developers.google.com/safe-browsing देखें. यह नीति उन Windows इंस्टेंस पर उपलब्ध नहीं है जो किसी <ph name="MS_AD_NAME" /> डोमेन से जुड़े हुए नहीं हैं.</translation> <translation id="3577251398714997599">तंग करने वाले विज्ञापनों वाली साइटों के लिए विज्ञापन सेटिंग</translation> @@ -920,7 +924,7 @@ <translation id="3709266154059827597">एक्सटेंशन इंस्टॉलेशन प्रतिबंध कॉन्फ़िगर करें</translation> <translation id="3711895659073496551">निलंबित</translation> <translation id="3715569262675717862">क्लाइंट प्रमाणपत्रों के हिसाब से प्रमाणीकरण</translation> -<translation id="3736879847913515635">उपयोगकर्ता प्रबंधक में व्यक्ति जोड़ना सक्षम करें</translation> +<translation id="3736879847913515635">उपयोगकर्ता प्रबंधक में 'किसी को जोड़ें' चालू करती है</translation> <translation id="3737544779868348650">डिवाइस नेटवर्क होस्टनाम</translation> <translation id="3746590506846867985"> यह नीति साइन-इन स्क्रीन पर लागू होती है. कृपया <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> नीति भी देखें जो उपयोगकर्ता सत्र पर लागू होती है. दोनों नीतियों को उसी मान पर सेट करने का सुझाव दिया जाता है. अगर दोनों मान का मिलान नहीं होता है तो, उपयोगकर्ता नीति में बताया गया मान लागू किए जाने के दौरान उपयोगकर्ता सत्र शुरू करते समय देरी हो सकती है. @@ -960,39 +964,39 @@ अगर यह नीति 'गलत' पर सेट है या इसे सेट नहीं किया जाता है तो, उपयोगकर्ता इसके 'संदर्भ मेन्यू' के ज़रिए आइकॉन पिन कर पाएंगे या उसे हटा पाएंगे. अगर "EnableMediaRouter" नीति 'गलत' पर सेट है तो, इस नीति के मान का कोई असर नहीं होगा और टूलबार आइकॉन नहीं दिखाया जाएगा.</translation> -<translation id="3788662722837364290">उपयोगकर्ता के निष्क्रिय हो जाने पर पावर प्रबंधन सेटिंग</translation> -<translation id="3793095274466276777"><ph name="PRODUCT_NAME" /> में डिफ़ॉल्ट ब्राउज़र परीक्षण कॉन्फ़िगर करता है और उपयोगकर्ताओं को उनमें बदलाव करने से रोकता है. +<translation id="3788662722837364290">जब उपयोगकर्ता कोई गतिविधि नहीं करता तब पावर प्रबंधन संबंधी सेटिंग</translation> +<translation id="3793095274466276777">यह नीति, <ph name="PRODUCT_NAME" /> में 'सामान्य ब्राउज़र जाँच' कॉन्फ़िगर करती है और उपयोगकर्ताओं को इसमें बदलाव करने से रोकती है. - अगर आप यह सेटिंग चालू करते हैं तो, <ph name="PRODUCT_NAME" /> स्टार्टअप पर हमेशा यह जाँच करेगा कि क्या यह डिफ़ॉल्ट ब्राउज़र है. साथ ही, अगर मुमकिन होगा तो, यह अपने आप उसे रजिस्टर करेगा. + अगर आप यह सेटिंग चालू करते हैं तो, <ph name="PRODUCT_NAME" /> स्टार्टअप पर हमेशा यह जाँच करेगा कि क्या यह डिफ़ॉल्ट ब्राउज़र है और अगर हो सका तो, इसे अपने आप रजिस्टर करेगा. - अगर यह सेटिंग बंद होती है तो, <ph name="PRODUCT_NAME" /> कभी इस बात की जाँच नहीं करेगा कि क्या यह डिफ़ॉल्ट ब्राउज़र है. साथ ही यह, यह विकल्प तय करने के उपयोगकर्ता के नियंत्रण को बंद कर देगी. + अगर यह सेटिंग बंद होती है तो, <ph name="PRODUCT_NAME" /> कभी इस बात की जाँच नहीं करेगा कि क्या यह डिफ़ॉल्ट ब्राउज़र है और इस विकल्प को सेट करने के उपयोगकर्ता के नियंत्रणों को बंद कर देगा. - अगर इस सेटिंग को सेट नहीं किया गया है तो, <ph name="PRODUCT_NAME" /> उपयोगकर्ता को यह नियंत्रित करने की सुविधा देता है कि क्या यह डिफ़ॉल्ट ब्राउज़र है, अगर नहीं है तो उपयोगकर्ता सूचनाएं दिखाई जाएं या नहीं.</translation> -<translation id="379602782757302612">आपको यह तय करने देती है कि उपयोगकर्ता कौन से एक्सटेंशन इंस्टॉल नहीं कर सकते हैं. अगर एक्सटेंशन प्रतिबंधित सूची में डाले गए हैं तो पहले से इंस्टॉल किए हुए एक्सटेंशन बंद कर दिए जाएंगे, साथ ही उपयोगकर्ताओं के पास उन्हें चालू करने का कोई तरीका नहीं होगा. प्रतिबंधित सूची में डाले गए किसी एक्सटेंशन को सूची से निकाल दिए जाने पर, वह अपने आप फिर से चालू हो जाएगा. + अगर यह सेटिंग सेट नहीं है, तो, <ph name="PRODUCT_NAME" /> उपयोगकर्ता को यह नियंत्रित करने की सुविधा देता है, कि क्या यह डिफ़ॉल्ट ब्राउज़र है और अगर नहीं है तो, 'उपयोगकर्ता सूचनाएं' दिखाई जाएं या नहीं.</translation> +<translation id="379602782757302612">आपको यह तय करने की सुविधा देती है कि उपयोगकर्ता कौनसे एक्सटेंशन इंस्टॉल नहीं कर सकते हैं. अगर एक्सटेंशन प्रतिबंधित सूची में डाले गए हैं तो पहले से इंस्टॉल किए हुए एक्सटेंशन बंद कर दिए जाएंगे, साथ ही उपयोगकर्ताओं के पास उन्हें चालू करने का कोई तरीका नहीं होगा. प्रतिबंधित सूची में डाले गए किसी एक्सटेंशन को सूची से निकाल दिए जाने पर, वह अपने आप फिर से चालू हो जाएगा. - प्रतिबंधित सूची में '*' मान का मतलब है कि सभी एक्सटेंशन तब तक प्रतिबंधित सूची में रहेंगे जब तक कि उन्हें खास तौर पर श्वेतसूची में नहीं डाला जाता. + प्रतिबंधित सूची में '*' मान का मतलब है कि सभी एक्सटेंशन तब तक प्रतिबंधित सूची में रहेंगे जब तक कि उन्हें खास तौर पर प्रतिबंधित सूची से हटा नहीं दिया जाता. - अगर यह नीति सेट किए बिना छोड़ दी जाती है तो उपयोगकर्ता <ph name="PRODUCT_NAME" /> में कोई भी एक्सटेंशन इंस्टॉल कर सकता है.</translation> -<translation id="3800626789999016379">उस निर्देशिका को कॉन्फ़िगर करती है जिसका उपयोग <ph name="PRODUCT_NAME" /> द्वारा फ़ाइलें डाउनलोड करने के लिए किया जाएगा. + अगर यह नीति सेट किए बिना छोड़ दी जाती है तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में कोई भी एक्सटेंशन इंस्टॉल कर सकता है.</translation> +<translation id="3800626789999016379">यह नीति उस निर्देशिका को कॉन्फ़िगर करती है, <ph name="PRODUCT_NAME" /> जिसका उपयोग फ़ाइलें डाउनलोड करने के लिए करेगा. - यदि आप इस पॉलिसी को सेट करते हैं, तो <ph name="PRODUCT_NAME" /> द्वारा, उपलब्ध कराई गई निर्देशिका का उपयोग इस बात पर ध्यान दिए बिना किया जाएगा कि उपयोगकर्ता ने कोई निर्देशिका निर्दिष्ट की है या नहीं या हर बार डाउनलोड करने के लिए स्थान का संकेत देना वाला फ़्लैग सक्षम किया है या नहीं. + अगर आप इस नीति को सेट करते हैं तो, <ph name="PRODUCT_NAME" /> उपलब्ध निर्देशिका का उपयोग करेगा, भले ही उपयोगकर्ता ने कोई निर्देशिका तय की हो या नहीं या हर बार डाउनलोड करने पर जगह दिखाने वाला फ़्लैग चालू किया हो या नहीं. - उपयोग किए जाने वाले चरों की सूची के लिए https://www.chromium.org/administrators/policy-list-3/user-data-directory-variables देखें. + उपयोग किए जा सकने वाले वैरिएबल की सूची के लिए https://www.chromium.org/administrators/policy-list-3/user-data-directory-variables देखें. - यदि यह पॉलिसी सेट किए बिना छोड़ दी जाती है तो डिफ़ॉल्ट निर्देशिका का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> + अगर यह नीति सेट नहीं है तो डिफ़ॉल्ट निर्देशिका का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> <translation id="3805659594028420438">TLS डोमेन-आबद्ध प्रमाणपत्र एक्सटेंशन सक्षम करें (बहिष्कृत)</translation> <translation id="3808945828600697669">अक्षम प्लग इन की सूची निर्दिष्ट करें</translation> <translation id="3811562426301733860">सभी साइटों पर विज्ञापनों की अनुमति दें</translation> <translation id="3816312845600780067">स्वत:-प्रवेश के लिए बेलआउट कीबोर्ड शॉर्टकट सक्षम करें</translation> -<translation id="3820526221169548563">ऑन-स्क्रीन कीबोर्ड पहुंच-योग्यता सुविधा सक्षम करें. +<translation id="3820526221169548563">ऑन-स्क्रीन कीबोर्ड एक्सेस की सुविधा चालू करें. - यदि यह नीति सही पर सेट है, तो ऑन-स्क्रीन कीबोर्ड हमेशा सक्षम रहेगा. + अगर यह नीति सही पर सेट होती है तो, ऑन-स्क्रीन कीबोर्ड हमेशा चालू रहेगा. - यदि यह नीति गलत पर सेट है, तो ऑन-स्क्रीन कीबोर्ड हमेशा अक्षम रहेगा. + अगर यह नीति गलत पर सेट होती है तो, ऑन-स्क्रीन कीबोर्ड हमेशा बंद रहेगा. - यदि आप इस नीति को सेट करते हैं, तो उपयोगकर्ता इसे बदल या ओवरराइड नहीं कर सकते हैं. + अगर आप इस नीति को सेट करते हैं तो, उपयोगकर्ता ना तो इसे बदल सकते हैं और ना ही रद्द कर सकते हैं. - यदि इस नीति को सेट किए बिना छोड़ दिया जाता है, तो आरंभ में ऑन-स्क्रीन कीबोर्ड अक्षम रहेगा लेकिन उसे उपयोगकर्ता द्वारा किसी भी समय सक्षम किया जा सकता है.</translation> + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, शुरुआत में ऑन-स्क्रीन कीबोर्ड बंद रहेगा लेकिन उपयोगकर्ता उसे किसी भी समय चालू कर सकता है.</translation> <translation id="382476126209906314">दूरस्थ पहुंच होस्ट के लिए TalkGadget का प्रारंभिक भाग कॉन्फ़िगर करें</translation> <translation id="3831376478177535007">इस सेटिंग के चालू होने पर, <ph name="PRODUCT_NAME" /> Symantec Corporation के Legacy PKI संचालनों की ओर से जारी किए गए प्रमाणपत्रों को तब अनुमति देता है अगर वे अन्यथा किसी पहचाने हुए CA प्रमाणपत्र को सफलता से मान्य करते हैं और उससे जुड़ते हैं. @@ -1006,9 +1010,9 @@ * वाले कालीसूची मान का अर्थ है कि सभी स्थानीय संदेश सेवा होस्ट कालीसूची में डाल दिए गए हैं और केवल श्वेतसूची में सूचीबद्ध स्थानीय संदेश सेवा होस्ट ही लोड किए जाएंगे. डिफ़ॉल्ट रूप से, सभी स्थानीय संदेश सेवा होस्ट श्वेतसूची में होते हैं, लेकिन यदि नीति के अनुसार सभी स्थानीय संदेश सेवा होस्ट को कालीसूची में डाल दिया गया है, तो श्वेतसूची का उपयोग उस नीति को ओवरराइड करने के लिए किया जा सकता है.</translation> -<translation id="384743459174066962">वैसे साइट जिनमें पॉपअप खोलने की अनुमति नहीं है, उनके लिए url पैटर्न की सूची सेट करने की सुविधा देती है. +<translation id="384743459174066962">वैसी साइट जिनमें पॉपअप खोलने की अनुमति नहीं है, उनके लिए यूआरएल पैटर्न की सूची सेट करने की सुविधा देती है. - अगर इस नीति को नहीं जोड़ा जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultPopupsSetting' सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultPopupsSetting' सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> <translation id="3851039766298741586">ऐप्लिकेशन आईडी और वर्शन जैसे सक्रिय किओस्क सत्र के बारे में जानकारी की रिपोर्ट करें. @@ -1070,22 +1074,22 @@ <translation id="3963602271515417124">अगर सही हो तो, डिवाइस के लिए दूर से ही प्रमाणित करने की सुविधा की मंज़ूरी होती है और एक प्रमाणपत्र अपने आप जनरेट हो जाएगा और उसे 'डिवाइस प्रबंधन सर्वर' पर अपलोड कर दिया जाएगा. अगर यह गलत पर सेट है या अगर सेट नहीं है तो, कोई प्रमाणपत्र जनरेट नहीं किया जाएगा और enterprise.platformKeys एक्सटेंशन API (एपीआई) पर कॉल नहीं किया जा सकेगा.</translation> -<translation id="3965339130942650562">जब तक निष्क्रिय उपयोगकर्ता लॉग-आउट लागू नहीं किया जाता तब तक टाइमआउट</translation> +<translation id="3965339130942650562">गतिविधि नहीं कर रहे उपयोगकर्ता को जब तक लॉग-आउट नहीं कर दिया जाता तब तक टाइमआउट</translation> <translation id="3973371701361892765">अलमारी को कभी भी स्वत:-न छिपाएं</translation> -<translation id="3984028218719007910">लॉगआउट के बाद <ph name="PRODUCT_OS_NAME" /> स्थानीय खाता डेटा रखना या न रखना निर्धारित करें. यदि सही पर सेट हो, तो <ph name="PRODUCT_OS_NAME" /> द्वारा कोई निरंतर खाता नहीं रखा जाएगा और उपयोगकर्ता सत्र से सभी डेटा लॉगआउट के बाद उपयोगकर्ता सत्र छोड़ दिए जाएंगे. यदि यह नीति गलत पर सेट हो या कॉन्फ़िगर नहीं की गई हो, तो डिवाइस (एनक्रिप्ट किया गया) स्थानीय उपयोगकर्ता डेटा रख सकता है.</translation> +<translation id="3984028218719007910">यह तय करती है कि <ph name="PRODUCT_OS_NAME" /> लॉग आउट के बाद स्थानीय खाता डेटा रखे या नहीं. अगर यह सही पर सेट होती है तो, <ph name="PRODUCT_OS_NAME" /> कोई निरंतर खाता नहीं रखता और लॉग आउट के बाद उपयोगकर्ता सत्र से सभी डेटा हटा दिए जाएंगे. अगर यह नीति गलत पर सेट हो या कॉन्फ़िगर नहीं की गई हो तो, डिवाइस (सुरक्षित किया गया) स्थानीय उपयोगकर्ता डेटा रख सकता है.</translation> <translation id="3997519162482760140">वैसे URL जिन्हें SAML लॉगिन पेजों पर वीडियो कैप्चर डिवाइस का एक्सेस दिया जाएगा</translation> -<translation id="4001275826058808087">एंटरप्राइज़ डिवाइस के आईटी व्यवस्थापक इस फ़्लैग का उपयोग यह नियंत्रित करने के लिए कर सकते हैं कि उपयोगकर्ताओं को Chrome OS पंजीकरण के द्वारा ऑफ़र रिडीम कराने की अनुमति दी जाए या नहीं. +<translation id="4001275826058808087">एंटरप्राइज़ डिवाइस के आईटी ए़डमिन इस फ़्लैग का उपयोग यह नियंत्रित करने के लिए कर सकते हैं कि उपयोगकर्ताओं को 'Chrome OS रजिस्ट्रेशन' के ज़रिए ऑफ़र रिडीम कराने की अनुमति दी जाए या नहीं. - यदि यह नीति सही पर सेट है या सेट किए बिना छोड़ दी जाती है, तो उपयोगकर्ता Chrome OS पंजीकरण के द्वारा ऑफ़र रिडीम करा सकेंगे. + अगर यह नीति 'सही' पर सेट है या सेट नहीं की जाती है तो, उपयोगकर्ता 'Chrome OS रजिस्ट्रेशन' के ज़रिए ऑफ़र रिडीम करा सकेंगे. - यदि यह नीति गलत पर सेट है, तो उपयोगकर्ता ऑफ़र रिडीम नहीं करा सकेंगे.</translation> + अगर यह नीति 'गलत' पर सेट है तो, उपयोगकर्ता ऑफ़र रिडीम नहीं करा सकेंगे.</translation> <translation id="4010738624545340900">फ़ाइल चयन संवादों के अनुरोध की अनुमति दें</translation> <translation id="4012737788880122133">सही पर सेट होने पर स्वत: अपडेट अक्षम करती है. इस सेटिंग के कॉन्फ़िगर नहीं होने या गलत पर सेट होने पर <ph name="PRODUCT_OS_NAME" /> डिवाइस अपने आप अपडेट की जाँच करते हैं. चेतावनी: स्वत: अपडेट सक्षम रहने देने की अनुशंसा की जाती है, ताकि उपयोगकर्ताओं को सॉफ़्टवेयर अपडेट और ज़रूरी सुरक्षा समाधान मिलें. स्वत: अपडेट बंद करने से उपयोगकर्ता जोखिम में पड़ सकते हैं.</translation> -<translation id="4020682745012723568">उपयोगकर्ता की प्रोफ़ाइल में स्थानांतरित कुकी Android ऐप्लिकेशन के लिए एक्सेस करने योग्य नहीं होती हैं.</translation> +<translation id="4020682745012723568">उपयोगकर्ता की प्रोफ़ाइल में ट्रांसफ़र की गईं कुकी, Android ऐप्लिकेशन से एक्सेस नहीं की जा सकतीं.</translation> <translation id="402759845255257575">किसी भी साइट को JavaScript चलाने की अनुमति न दें</translation> <translation id="4027608872760987929">डिफ़ॉल्ट खोज प्रदाता सक्षम करें</translation> <translation id="4039085364173654945">यह नियंत्रित करता है कि किसी पेज पर तृतीय-पक्ष उप-सामग्री को कोई HTTP मूल प्रमाणीकरण डॉयलॉग बॉक्स पॉप-अप करने की अनुमति है या नहीं. सामान्यत: यह फ़िशिंग से सुरक्षा के रूप में अक्षम होता है. यदि इस नीति को सेट नहीं किया जाता है, तो, यह अक्षम होती है और तृतीय-पक्ष उप-सामग्री को, HTTP मूल प्रमाणीकरण डॉयलॉग बॉक्स पॉप अप करने की अनुमति नहीं होगी.</translation> @@ -1104,14 +1108,14 @@ अगर इस नीति को 'सत्र की समय सीमा तक कुकी रखें' पर सेट किया जाता है तो, सत्र के बंद होने पर कुकी मिटा दी जाएंगी. ध्यान दें कि अगर <ph name="PRODUCT_NAME" /> 'बैकग्राउंड मोड' में चल रहा हो तो, हो सकता है कि अंतिम विंडो बंद होने के बाद सत्र बंद ना हो. इस व्यवहार को कॉन्फ़िगर करने के बारे में ज़्यादा जानकारी के लिए कृपया 'BackgroundModeEnabled' नीति देखें. अगर यह नीति सेट किए बिना छोड़ दी जाती है तो, 'AllowCookies' का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> -<translation id="4103289232974211388">उपयोगकर्ता पुष्टिकरण के बाद SAML IdP पर रीडायरेक्ट करें</translation> -<translation id="410478022164847452">AC पावर पर चलते समय, उस समयावधि को निर्दिष्ट करती है जितनी देर तक उपयोगकर्ता कोई भी इनपुट न दे, उसके बाद प्रयोग में नहीं कार्यवाही की जाती है. +<translation id="4103289232974211388">उपयोगकर्ता की ओर से पुष्टि करने के बाद SAML IdP पर रीडायरेक्ट करें</translation> +<translation id="410478022164847452">एसी पावर पर चलते समय, यह नीति उस अवधि को तय करती है, जितनी देर तक उपयोगकर्ता के कोई भी इनपुट न देने के बाद 'उपयोग में नहीं' की कार्रवाई की जाती है. - जब इस नीति को सेट किया जाता है, तो वह <ph name="PRODUCT_OS_NAME" /> द्वारा प्रयोग में नहीं कार्यवाही करने से पहले की उस समयावधि को निर्दिष्ट करती है जिसमें उपयोगकर्ता को प्रयोग में नहीं रहना होगा, जिसे अलग से कॉन्फ़िगर किया जा सकता है. + जब नीति सेट की जाती है तो, वह उस अवधि को तय करती है, जिसके बाद <ph name="PRODUCT_OS_NAME" /> 'उपयोग में नहीं' की कार्रवाई करता है. इसके लिए ज़रूरी है कि कम से कम इतनी अवधि तक उपयोगकर्ता कुछ भी न करे. इस कार्रवाई को अलग से कॉन्फ़िगर किया जा सकता है. - जब नीति सेट नहीं की जाती, तो एक डिफ़ॉल्ट समयावधि का उपयोग किया जाता है. + जब नीति सेट नहीं की जाती तो, एक डिफ़ॉल्ट अवधि का उपयोग किया जाता है. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए.</translation> <translation id="4105989332710272578">यूआरएल की एक सूची के लिए 'प्रमाणपत्र पारदर्शिता' को लागू करना बंद करें</translation> <translation id="4111405663956464686">चेतावनी: वर्शन 72 के आने पर (लगभग जनवरी 2019 में) ज़्यादातर TLS वर्शन नीति को <ph name="PRODUCT_NAME" /> से पूरी तरह से हटा दिया जाएगा. @@ -1169,7 +1173,7 @@ इसका नतीजा यह होगा कि इस नीति को किसी खाली सूची पर सेट करने से लॉक स्क्रीन पर नोट लेना पूरी तरह से बंद हो जाएगा. ध्यान रखें कि ऐप्लिकेशन आईडी वाली नीति का मतलब यह नहीं है कि उपयोगकर्ता लॉक स्क्रीन पर ऐप्लिकेशन को 'नोट लेने वाले ऐप्लिकेशन' के रूप में चालू कर सकेगा - उदाहरण के लिए, Chrome 61 पर, प्लैटफ़ॉर्म ने उपलब्ध ऐप्लिकेशन के समूह पर पाबंदी लगाई हुई है. - अगर नीति सेट नहीं की जाती है तो, उपयोगकर्ता लॉक स्क्रीन पर कौन-कौनसे ऐप्लिकेशन चालू कर सकता है, इस पर नीति की तरफ़ से कोई पाबंदी नहीं होगी.</translation> + अगर नीति सेट नहीं की जाती है तो, उपयोगकर्ता लॉक स्क्रीन पर कौन-कौनसे ऐप्लिकेशन चालू कर सकता है, इस पर नीति की कोई पाबंदी नहीं होगी.</translation> <translation id="4309640770189628899">क्या TLS में DHE सिफ़र सुइट सक्षम किए हुए हैं</translation> <translation id="4322842393287974810"><ph name="PRODUCT_OS_NAME" /> वर्शन को नियंत्रित करने के लिए शून्य विलंब किओस्क ऐप वाले स्वत: लॉन्च को अनुमति दें</translation> <translation id="4325690621216251241">सिस्टम ट्रे में एक प्रस्थान करें बटन जोड़ें</translation> @@ -1180,9 +1184,9 @@ हालांकि अगर SafeBrowsingEnabled नीति गलत पर सेट की जाती है, तो यह व्यवहार ट्रिगर नहीं होगा. अगर यह नीति 1 पर सेट होती है, तो तंग करने वाले विज्ञापनों वाली साइटों पर विज्ञापन ब्लॉक नहीं किए जाएंगे. अगर इस नीति को सेट नहीं किया जाता है, तो 2 का इस्तेमाल किया जाएगा.</translation> -<translation id="4347908978527632940">यदि सत्य है और उपयोगकर्ता एक निगरानी में रखा गया उपयोगकर्ता है, तो अन्य Android ऐप्स किसी सामग्री प्रदाता के माध्यम से उपयोगकर्ता के वेब प्रतिबंधों के लिए क्वेरी कर सकते हैं. +<translation id="4347908978527632940">अगर यह नीति सही पर सेट है और उपयोगकर्ता 'निगरानी में रखा गया' कोई उपयोगकर्ता है तो, अन्य Android ऐप्लिकेशन किसी सामग्री मुहैया कराने वाले के ज़रिए, उपयोगकर्ता के वेब प्रतिबंधों के लिए क्वेरी कर सकते हैं. - यदि गलत है या सेट नहीं की गई है, तो सामग्री प्रदाता कोई जानकारी वापस नहीं लौटाता है.</translation> + अगर यह नीति गलत पर सेट है या सेट नहीं की गई है तो, सामग्री मुहैया कराने वाला कोई जानकारी नहीं देता है.</translation> <translation id="435461861920493948">इसमें ऐसे पैटर्न की सूची होती है जो <ph name="PRODUCT_NAME" /> में खातों का दिखाई देना नियंत्रित करने के लिए इस्तेमाल किए जाते हैं. <ph name="PRODUCT_NAME" /> में खाता दिखाई देने की स्थिति तय करने के लिए डिवाइस पर मौजूद हर Google खाते की तुलना इस नीति में संग्रहित पैटर्न से की जाएगी. अगर खाते के नाम का मिलान सूची के किसी भी पैटर्न से हो जाता है, तो वह दिखाई देगा. मिलान नहीं होने पर खाता छिपा हुआ रहेगा. @@ -1199,11 +1203,11 @@ <translation id="441217499641439905"><ph name="PRODUCT_OS_NAME" /> फ़ाइल ऐप्लिकेशन में मोबाइल इंटरनेट कनेक्शन पर 'Google डिस्क' को बंद करती है</translation> <translation id="4418726081189202489">इस नीति को गलत पर सेट करने से <ph name="PRODUCT_NAME" /> एक सटीक टाइमस्टैम्प पाने के लिए Google के सर्वर को समय-समय पर क्वेरीज़ भेजना बंद कर देता है. अगर यह नीति सही पर सेट की जाती है या सेट नहीं की जाती है तो इन क्वेरी को सक्षम कर दिया जाएगा.</translation> <translation id="4423597592074154136">प्रॉक्सी सेटिंग मैन्युअल रूप से निर्दिष्ट करें</translation> -<translation id="4429220551923452215">बुकमार्क बार में ऐप्स शॉर्टकट को सक्षम या अक्षम करती है. +<translation id="4429220551923452215">'बुकमार्क बार' में 'ऐप्लिकेशन शॉर्टकट' को चालू या बंद करती है. - यदि यह नीति सेट नहीं की जाती तो फिर उपयोगकर्ता बुकमार्क बार संदर्भ मेनू से ऐप्स शॉर्टकट दिखाना या छिपाना चुन सकता है. + अगर यह नीति सेट नहीं की जाती तो, उपयोगकर्ता 'बुकमार्क बार संदर्भ मेन्यू' से 'ऐप्लिकेशन शॉर्टकट' दिखाना या छिपाना चुन सकता है. - यदि यह नीति कॉन्फ़िगर की जाती है तो फिर उपयोगकर्ता इसे बदल नहीं सकता और ऐप्स शॉर्टकट हमेशा ही दिखाए जाते हैं या कभी भी नहीं दिखाए जाते.</translation> + अगर यह नीति कॉन्फ़िगर की जाती है तो, उपयोगकर्ता इसे बदल नहीं सकता और 'ऐप्लिकेशन शॉर्टकट' हमेशा दिखाया जाता है या कभी नहीं दिखाया जाता.</translation> <translation id="4432762137771104529">सुरक्षित ब्राउज़िंग विस्तारित रिपोर्टिंग चालू करें</translation> <translation id="443454694385851356">विरासती (असुरक्षित)</translation> <translation id="443665821428652897">ब्राउज़र शटडाउन होने पर साइट डेटा साफ़ करें (हटा दिया गया)</translation> @@ -1234,27 +1238,27 @@ <translation id="4483649828988077221">अपने आप होने वाले अपडेट बंद करें</translation> <translation id="4485425108474077672">नया टैब पेज URL कॉन्फ़िगर करें</translation> <translation id="4492287494009043413">स्क्रीनशॉट लेना बंद करें</translation> -<translation id="450537894712826981">वह संचय आकार कॉन्फ़िगर करती है, जिसका उपयोग <ph name="PRODUCT_NAME" /> के द्वारा डिस्क पर संचित फ़ाइलें संग्रहित करने के लिए किया जाएगा. +<translation id="450537894712826981">यह नीति कैश मेमोरी का आकार कॉन्फ़िगर करती है, <ph name="PRODUCT_NAME" /> जिसका उपयोग डिस्क पर मौजूद कैश मीडिया फ़ाइलें सेव करने के लिए करेगा. - यदि आप इस नीति को सेट करते हैं, तो इस बात पर ध्यान दिए बिना कि उपयोगकर्ता ने '--media-cache-size' फ़्लैग को निर्दिष्ट किया है या नहीं, <ph name="PRODUCT_NAME" /> प्रदान किए गए संचय आकार का उपयोग करेगा. इस नीति में निर्दिष्ट मान कोई कठिन सीमा नहीं है, बल्कि संचय सिस्टम के लिए एक सुझाव है, कुछ मेगाबाइट से कम आकार का कोई भी मान बहुत छोटा होता है और उसे न्यूनतम संतुलित मान तक बढ़ा दिया जाएगा. + अगर आप इस नीति को सेट करते हैं तो, <ph name="PRODUCT_NAME" /> कैश मेमोरी के दिए गए आकार का उपयोग करेगा, भले ही उपयोगकर्ता ने '--media-cache-size' फ़्लैग तय किया हो या न किया हो. इस नीति में तय किया गया मान आगे-पीछे हो सकता है. यह 'कैशिंग सिस्टम' के लिए बस एक सुझाव है, कुछ मेगाबाइट से कम आकार का कोई भी मान बहुत छोटा होता है और उसे 'न्यूनतम संतुलित मान' तक बढ़ा दिया जाएगा. - यदि इस नीति का मान 0 है, तो डिफ़ॉल्ट संचय आकार का उपयोग किया जाएगा लेकिन उपयोगकर्ता उसे बदल नहीं सकेगा. + अगर इस नीति का मान 0 है तो, कैश मेमोरी के डिफ़ॉल्ट आकार का उपयोग किया जाएगा लेकिन उपयोगकर्ता उसे बदल नहीं सकेगा. - यदि यह नीति सेट नहीं है, तो डिफ़ॉल्ट आकार का उपयोग किया जाएगा और उपयोगकर्ता उसे --media-cache-size फ़्लैग से ओवरराइड कर सकेगा.</translation> + अगर यह नीति सेट नहीं है तो, डिफ़ॉल्ट आकार का उपयोग किया जाएगा और उपयोगकर्ता उसे --media-cache-size फ़्लैग से ओवरराइड कर सकेगा.</translation> <translation id="4508686775017063528">अगर यह नीति 'सही' पर सेट की जाती है या इसे सेट नहीं किया जाता है तो, <ph name="PRODUCT_NAME" /> को चालू कर दिया जाएगा और उपयोगकर्ता इसे ऐप्लिकेशन मेन्यू, पेज संदर्भ मेन्यू, Cast चालू वेबसाइट पर मीडिया नियंत्रणों और (अगर दिखाया जाता है तो) Cast टूलबार आइकॉन से लॉन्च कर पाएंगे. अगर यह नीति 'गलत' पर सेट की जाती है तो, <ph name="PRODUCT_NAME" /> को बंद कर दिया जाएगा.</translation> <translation id="4515404363392014383">भरोसेमंद स्रोतों के लिए सुरक्षित ब्राउज़िंग चालू करें</translation> <translation id="4518251772179446575">जब भी कोई साइट, उपयोगकर्ताओं के वास्तविक स्थान पर नज़र रखना चाहे, तब पूछें</translation> -<translation id="4519046672992331730"><ph name="PRODUCT_NAME" /> के ऑम्निबॉक्स में खोज सुझावों को चालू करती है और उपयोगकर्ता को इस सेटिंग को बदलने से रोकती है. +<translation id="4519046672992331730">यह नीति <ph name="PRODUCT_NAME" /> के ऑम्निबॉक्स में खोज सुझावों को चालू करती है और उपयोगकर्ता को इस सेटिंग को बदलने से रोकती है. अगर आप इस सेटिंग को चालू करते हैं तो, खोज सुझावों का उपयोग किया जाता है. अगर आप इस सेटिंग को बंद करते हैं तो, खोज सुझावों का कभी भी उपयोग नहीं किया जाता. - अगर आप इस सेटिंग को चालू या बंद करते हैं तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में इस सेटिंग को बदल नहीं सकते या रद्द नहीं कर सकते. + अगर आप इस सेटिंग को चालू या बंद करते हैं तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में इस सेटिंग को बदल नहीं सकते या ओवरराइड नहीं कर सकते. - अगर इस नीति को बिना जोड़े छोड़ दिया जाता है तो, इसे चालू किया जाएगा लेकिन उपयोगकर्ता इसे बदल नहीं सकेगा.</translation> + अगर इस नीति को सेट नहीं किया जाता है तो, इसे चालू किया जाएगा लेकिन उपयोगकर्ता इसे बदल नहीं सकेगा.</translation> <translation id="4531706050939927436">Google Play का उपयोग करके, Google Admin console की सहमति से Android ऐप्लिकेशन बलपूर्वक इंस्टॉल किए जा सकते हैं. वे इस नीति का उपयोग नहीं करते हैं.</translation> <translation id="4534500438517478692">Android प्रतिबंध का नाम:</translation> <translation id="4541530620466526913">डिवाइस-स्थानीय खाते</translation> @@ -1314,24 +1318,24 @@ अगर पिन कमज़ोर माना जाता है, तो डिफ़ॉल्ट रूप से उपयोगकर्ताओं को चेतावनी दिखाई देगी, न कि गड़बड़ी.</translation> <translation id="4723829699367336876">रिमोट पहुंच क्लाइंट से फ़ायरवॉल ट्रेवर्सल सक्षम करें</translation> <translation id="4725528134735324213">Android Backup Service सक्षम करें</translation> -<translation id="4725801978265372736">स्थानीय उपयोगकर्ता और रिमोट एक्सेस होस्ट के मालिक के नाम का मिलान होना ज़रूरी बनाती है</translation> +<translation id="4725801978265372736">स्थानीय उपयोगकर्ता और दूर से एक्सेस कर रहे होस्ट मालिक के नाम का मिलान करना ज़रूरी बनाती है</translation> <translation id="4733471537137819387">एकीकृत HTTP प्रमाणीकरण से संबंधित नीतियां.</translation> -<translation id="4744190513568488164">वे सर्वर जिन्हें <ph name="PRODUCT_NAME" /> सौंपा जा सकता है. +<translation id="4744190513568488164">वैसे सर्वर जिनका प्रतिनिधि <ph name="PRODUCT_NAME" /> हो सकता है. - एकाधिक सर्वर नामों को अल्पविराम द्वारा अलग करें. वाइल्डकार्ड (*) की अनुमति है. + कॉमा के ज़रिए कई सर्वर नामों को अलग करती है. वाइल्डकार्ड (*) की अनुमति है. - यदि आप इस नीति को सेट किए बिना छोड़ देते हैं तो <ph name="PRODUCT_NAME" /> उपयोगकर्ता क्रेडेंशियल नहीं सौंपेगा भले ही सर्वर की पहचान इंट्रानेट के रूप में की गई हो.</translation> + अगर आप इस नीति को सेट किए बिना छोड़ देते हैं तो, <ph name="PRODUCT_NAME" /> उपयोगकर्ता क्रेडेंशियल नहीं सौंपेगा भले ही सर्वर की पहचान इंट्रानेट के रूप में की गई हो.</translation> <translation id="4752880493649142945">RemoteAccessHostTokenValidationUrl से कनेक्ट करने के लिए क्लाइंट प्रमाणपत्र</translation> -<translation id="4791031774429044540">बड़ा कर्सर पहुंच-योग्यता सुविधा सक्षम करें. +<translation id="4791031774429044540">'बड़े कर्सर की सुलभता सुविधा' चालू करें. - यदि यह नीति सही पर सेट है, तो बड़ा कर्सर हमेशा सक्षम किया जाएगा. + अगर यह नीति 'सही' पर सेट है तो, बड़ा कर्सर हमेशा चालू रहेगा. - यदि यह नीति सही पर सेट है, तो बड़ा कर्सर हमेशा सक्षम किया जाएगा. + अगर यह नीति 'गलत' पर सेट है तो, बड़ा कर्सर हमेशा बंद रहेगा. - यदि आप इस नीति को सेट करते हैं, तो उपयोगकर्ता इसे बदल नहीं सकते या ओवरराइड नहीं कर सकते. + अगर आप इस नीति को सेट करते हैं तो, उपयोगकर्ता इसे बदल नहीं सकते या ओवरराइड नहीं कर सकते. - यदि इस नीति को सेट किए बिना छोड़ दिया जाता है, तो बड़ा कर्सर आरंभ में अक्षम किया जाएगा लेकिन उपयोगकर्ता द्वारा किसी भी समय सक्षम किया जा सकता है.</translation> + अगर यह नीति सेट नहीं की जाती है तो, बड़ा कर्सर शुरू में बंद रहेगा लेकिन उपयोगकर्ता इसे कभी भी चालू कर सकता है.</translation> <translation id="4802905909524200151"><ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट व्यवहार कॉन्फ़िगर करें</translation> <translation id="4807950475297505572">पर्याप्त खाली स्थान नहीं होने तक, जिन उपयोगकर्ताओं ने हाल ही में सबसे कम उपयोग किया है उन्हें निकाल दिया जाता है</translation> <translation id="4815725774537609998">यह नीति हटा दी गई है, इसके बजाय ProxyMode का उपयोग करें. @@ -1353,11 +1357,11 @@ <translation id="4816674326202173458">एंटरप्राइज़ उपयोगकर्ता को प्राथमिक और द्वितीयक दोनों होने दें (गैर-प्रबंधित उपयोगकर्ताओं के लिए डिफ़ॉल्ट व्यवहार)</translation> <translation id="4826326557828204741">बैटरी पावर पर चलते समय प्रयोग में नहीं विलंब तक पहुंच जाने पर की जाने वाली कार्यवाही</translation> <translation id="4834526953114077364">पर्याप्त खाली स्थान नहीं होने तक, हाल ही में सबसे कम उपयोग करने वाले उन उपयोगकर्ताओं को निकाल दिया जाता है, जिन्होंने पिछले 3 माह में प्रवेश नहीं किया है</translation> -<translation id="4838572175671839397">एक रेगुलर एक्सप्रेशन शामिल होता है, जिसका उपयोग यह निर्धारित करने में किया जाता है, कि कौन से उपयोगकर्ता <ph name="PRODUCT_NAME" /> में साइन कर सकते हैं. +<translation id="4838572175671839397">इस नीति में एक रेगुलर एक्सप्रेशन शामिल होता है, जिसका उपयोग यह तय करने में किया जाता है कि कौनसे उपयोगकर्ता <ph name="PRODUCT_NAME" /> में साइन कर सकते हैं. - यदि कोई उपयोगकर्ता ऐसे उपयोगकर्ता नाम से प्रवेश करने का प्रयास करता है, जिसका इस आकार से मिलान नहीं खाता है, तो एक उपयुक्त गड़बड़ी प्रदर्शित की जाती है. + अगर कोई उपयोगकर्ता ऐसे 'उपयोगकर्ता नाम' से लॉग इन करने की कोशिश करता है, जो इस पैटर्न से मेल नहीं खाता तो, उसी हिसाब से एक गड़बड़ी दिख जाती है. - यदि इस नीति को सेट नहीं या खाली पर छोड़ दिया जाता है, तो कोई भी उपयोगकर्ता <ph name="PRODUCT_NAME" /> में प्रवेश कर सकता है.</translation> + अगर इस नीति को सेट नहीं किया जाता या खाली छोड़ दिया जाता है तो, कोई भी उपयोगकर्ता <ph name="PRODUCT_NAME" /> में साइन इन कर सकता है.</translation> <translation id="4858735034935305895">पूर्ण स्क्रीन मोड की अनुमति दें</translation> <translation id="4869787217450099946">बताती है कि स्क्रीन को जगाने वाले लॉक की मंज़ूरी है या नहीं. स्क्रीन को जगाने वाले लॉक का अनुरोध एक्सटेंशन की ओर से पावर प्रबंधन एक्सटेंशन API (एपीआई) के ज़रिए किया जा सकता है. @@ -1374,48 +1378,52 @@ 'DefaultSearchProviderEnabled' के सक्षम होने पर ही इस नीति का पालन किया जाएगा.</translation> <translation id="489803897780524242">डिफ़ॉल्ट खोज प्रदाता के लिए पैरामीटर नियंत्रण खोज शब्द प्रतिस्थापना</translation> <translation id="4899708173828500852">सुरक्षित ब्राउज़िंग सक्षम करें</translation> -<translation id="4899802251198446659"><ph name="PRODUCT_NAME" /> में ऑडियो सामग्री होने पर यह कंट्रोल करने की सुविधा देती है कि वीडियो अपने आप (उपयोगकर्ता की मंज़ूरी के बिना) चल सकते हैं या नहीं. +<translation id="4899802251198446659">यह नीति आपको यह नियंत्रित करने देती है कि <ph name="PRODUCT_NAME" /> में, ऑडियो सामग्री होने पर वीडियो अपने आप (उपयोगकर्ता की सहमति के बिना) चल सकते हैं या नहीं. - अगर नीति को सही पर सेट किया गया है तो, <ph name="PRODUCT_NAME" /> को मीडिया अपने आप चलाने की अनुमति है. - अगर नीति को गलत पर सेट किया गया है तो, <ph name="PRODUCT_NAME" /> को अपने आप मीडिया चलाने की अनुमति नहीं है. कुछ यूआरएल पैटर्न के लिए, इसे रद्द करने के लिए AutoplayWhitelist नीति का इस्तेमाल किया जा सकता है. - डिफ़ॉल्ट रूप से, <ph name="PRODUCT_NAME" /> को अपने आप मीडिया चलाने की अनुमति नहीं है. कुछ यूआरएल पैटर्न के लिए, इसे रद्द करने के लिए AutoplayWhitelist नीति का इस्तेमाल किया जा सकता है. + अगर नीति को 'सही' पर सेट किया गया है तो, <ph name="PRODUCT_NAME" /> को मीडिया अपने आप चलने की अनुमति है. + अगर नीति को 'गलत' पर सेट किया गया है तो, <ph name="PRODUCT_NAME" /> को मीडिया अपने आप चलने की अनुमति नहीं है. कुछ 'यूआरएल पैटर्न' के मामले में इसे ओवरराइड करने के लिए AutoplayWhitelist नीति का इस्तेमाल किया जा सकता है. + डिफ़ॉल्ट रूप से, <ph name="PRODUCT_NAME" /> को अपने आप मीडिया चलाने की अनुमति नहीं है. कुछ 'यूआरएल पैटर्न' के मामले में इसे ओवरराइड के लिए AutoplayWhitelist नीति का इस्तेमाल किया जा सकता है. - ध्यान रखें कि अगर <ph name="PRODUCT_NAME" /> चल रहा है और यह नीति बदल जाती है तो, यह सिर्फ़ खोले गए नए टैब पर लागू होगी. इसलिए हो सकता है कि कुछ टैब अभी भी पुराने तरीके का पालन करें. + ध्यान रखें कि अगर <ph name="PRODUCT_NAME" /> चल रहा है और यह नीति बदल जाती है तो, यह सिर्फ़ नए खोले गए टैब पर लागू होगी. इस वजह से कुछ टैब अब भी पुराने तरीके से काम कर सकते हैं. </translation> <translation id="4906194810004762807">'डिवाइस नीति' के लिए रीफ्रेश दर</translation> <translation id="4917385247580444890">सशक्त</translation> <translation id="4923806312383904642">WebDriver को असंगत नीतियों को बदलने दें</translation> <translation id="494613465159630803">कास्ट पाने वाला</translation> -<translation id="4962262530309732070">अगर यह नीति सही या कॉन्फ़िगर नहीं की गई पर सेट है, तो <ph name="PRODUCT_NAME" /> उपयोगकर्ता प्रबंधक से व्यक्ति जोड़ने की अनुमति देगा. +<translation id="4962262530309732070">अगर यह नीति 'सही' या 'कॉन्फ़िगर' नहीं की गई पर सेट है तो, <ph name="PRODUCT_NAME" /> 'उपयोगकर्ता प्रबंधक' से 'व्यक्ति जोड़ें' की अनुमति देगा. - अगर यह नीति गलत पर सेट की जाती है, तो <ph name="PRODUCT_NAME" /> उपयोगकर्ता प्रबंधक से नई प्रोफ़ाइल बनाने की अनुमति नहीं देगा.</translation> + अगर यह नीति 'गलत' पर सेट की जाती है तो, <ph name="PRODUCT_NAME" /> 'उपयोगकर्ता प्रबंधक' से नई प्रोफ़ाइल बनाने की अनुमति नहीं देगा.</translation> <translation id="4971529314808359013">अगर साइट किसी प्रमाणपत्र का अनुरोध करती है, तो यह आपको यूआरएल पैटर्न की एक सूची निर्दिष्ट करने देती है जो उन साइटों को निर्दिष्ट करती है जिसके लिए <ph name="PRODUCT_NAME" /> से अपने आप किसी क्लाइंट प्रमाणपत्र का चयन किया जाता है. मान JSON शब्दकोशों की स्ट्रिंग वाली सूची होनी चाहिए. प्रत्येक शब्दकोश का प्रारूप { "pattern": "$URL_PATTERN", "filter" : $FILTER } होना चाहिए, जहां $URL_PATTERN एक सामग्री सेटिंग पैटर्न है. $FILTER प्रतिबंधित करता है कि किन क्लाइंट प्रमाणपत्रों से ब्राउज़र अपने आप चयन करेगा. भले ही फ़िल्टर कोई भी हो, केवल उन्हीं प्रमाणपत्रों का चयन किया जाएगा जिनका मिलान सर्वर के प्रमाणपत्र अनुरोध से होता है. अगर $FILTER का { "ISSUER": { "CN": "$ISSUER_CN" } } प्रारूप है, तो अतिरिक्त रूप से केवल क्लाइंट प्रमाणपत्रों का चयन किया जाता है जिन्हें CommonName $ISSUER_CN वाले प्रमाणपत्र से जारी किया जाता है. अगर $FILTER खाली शब्दकोश {} है, तो क्लाइंट प्रमाणपत्रों का चयन अतिरिक्त रूप से प्रतिबंधित नहीं किया जाता है. अगर इस नीति को सेट नहीं किया जाता है, तो किसी भी साइट के लिए स्वतः चयन नहीं किया जाएगा.</translation> -<translation id="4978405676361550165">अगर "OffHours" नीति सेट की जाती है तो, बताए गए समय अंतरालों के दौरान तय डिवाइस नीतियां (इन नीतियों की डिफ़ॉल्ट सेटिंग इस्तेमाल करना) अनदेखी कर दी जाती हैं. जब "OffHours" अवधि शुरू या खत्म होती है तो, Chrome हर इवेंट पर डिवाइस नीतियां फिर से लागू करता है. "OffHours" समय खत्म होने पर उपयोगकर्ता को बताया जाएगा और उसे अपने आप साइन आउट कर दिया जाएगा और डिवाइस नीति की सेटिंग बदल दी जाएंगी (उदाहरण के लिए, जब उपयोगकर्ता ने किसी ऐसे खाते से लॉग इन किया हो जिसे मंज़ूरी नहीं मिली है).</translation> +<translation id="4978405676361550165">अगर "OffHours" नीति सेट की जाती है तो, बताए गए समय अंतरालों के दौरान तय डिवाइस नीतियां (इन नीतियों की डिफ़ॉल्ट सेटिंग का इस्तेमाल करना) अनदेखी कर दी जाती हैं. जब "OffHours" समय सीमा शुरू या खत्म होती है तो, Chrome हर इवेंट पर डिवाइस नीतियां फिर से लागू करता है. "OffHours" समय खत्म होने पर उपयोगकर्ता को बताया जाएगा और उसे अपने आप साइन आउट कर दिया जाएगा और डिवाइस नीति की सेटिंग बदल दी जाएंगी (उदाहरण के लिए, जब उपयोगकर्ता ने किसी ऐसे खाते से लॉग इन किया हो जिसे मंज़ूरी नहीं मिली है).</translation> <translation id="4980635395568992380">डेटा प्रकार:</translation> <translation id="4983201894483989687">पुराने प्लग इन चलाने की अनुमति दें</translation> <translation id="4988291787868618635">प्रयोग में नहीं विलंब तक पहुंच जाने पर की जाने वाली कार्यवाही</translation> <translation id="4995548127349206948">NTLMv2 प्रमाणीकरण चालू है या नहीं.</translation> <translation id="5047604665028708335">सामग्री पैक से बाहर की साइटों की एक्सेस की अनुमति दें</translation> -<translation id="5052081091120171147">यह नीति, सक्षम होने पर ब्राउज़िंग इतिहास को वर्तमान डिफ़ॉल्ट ब्राउज़र से आयात किए जाने के लिए बाध्य करती है. सक्षम किए जाने पर, यह नीति आयात डॉयलॉग को भी प्रभावित करती है. अक्षम किए जाने पर, कोई ब्राउज़िंग इतिहास आयात नहीं किया जाता. यदि इसे सेट नहीं किया जाता है, तो उपयोगकर्ता से आयात करने के लिए पूछा जा सकता है, या स्वत: आयात हो सकता है.</translation> +<translation id="5052081091120171147">अगर यह नीति चालू हो तो, यह ब्राउज़िंग इतिहास को वर्तमान डिफ़ॉल्ट ब्राउज़र से आयात करने के लिए बाध्य करती है. चालू होने पर यह नीति, आयात संबंधी संवाद पर भी असर डालती है. + + अगर बंद हो तो, ब्राउज़िंग इतिहास को आयात नहीं किया जाता. + + अगर इसे सेट नहीं किया गया हो तो, उपयोगकर्ता से आयात करने के लिए पूछा जा सकता है या अपने आप आयात किया जा सकता है.</translation> <translation id="5056708224511062314">स्क्रीन आवर्धक अक्षम है</translation> <translation id="5058573563327660283">अपने आप सफ़ाई के दौरान डिस्क की जगह खाली करने के लिए इस्तेमाल की जाने वाली योजना चुनती है (रोकी गई)</translation> -<translation id="5067143124345820993">उपयोगकर्ता श्वेत सूची में प्रवेश करें</translation> +<translation id="5067143124345820993">बिना प्रतिबंध वाले लॉग इन उपयोगकर्ता की सूची</translation> <translation id="5068140065960598044"><ph name="PRODUCT_NAME" /> की क्लाउड नीति मशीन की नीति में बदल जाती है.</translation> <translation id="5085647276663819155">'प्रिंट की झलक दिखाने की सुविधा' बंद करें</translation> <translation id="5090209345759901501">Flash सामग्री सेटिंग को सभी सामग्री के लिए विस्तृत करें</translation> -<translation id="5093540029655764852">यह वह दर (दिनों में) बताती है जिस दर से क्लाइंट अपना मशीन से जनरेट खाता पासवर्ड बदलता है. पासवर्ड को क्लाइंट आकस्मिक रूप से जनरेट करता है और वह उपयोगकर्ता को दिखाई नहीं देता है. +<translation id="5093540029655764852">यह नीति वह दर (दिनों में) तय करती है जिस दर से क्लाइंट मशीन से जनरेट किया गया अपना 'खाता पासवर्ड' बदलता है. क्लाइंट जो पासवर्ड जनरेट करता है, वह रैंडम (किसी तय क्रम या तरीके के बिना) होता है और वह उपयोगकर्ता को दिखाई नहीं देता. - उपयोगकर्ता पासवर्ड की तरह ही, मशीन से जनरेट पासवर्ड भी नियमित रूप से बदले जाने चाहिए. इस नीति को बंद करने या ज़्यादा दिन के लिए सेट करने से सुरक्षा पर गलत प्रभाव पड़ सकता है क्योंकि इससे संभावित हमलावरों को मशीन से जनरेट खाता पासवर्ड ढूंढने और उसका इस्तेमाल करने के लिए ज़्यादा समय मिल जाता है. + 'उपयोगकर्ता पासवर्ड' की तरह ही, मशीन से जनरेट पासवर्ड भी नियमित रूप से बदले जाने चाहिए. इस नीति को बंद करने या ज़्यादा दिन के लिए सेट करने से सुरक्षा पर गलत असर पड़ सकता है क्योंकि इससे उन लोगों को मशीन से जनरेट 'खाता पासवर्ड' ढूंढने और उसका इस्तेमाल करने के लिए ज़्यादा समय मिल जाता है जो आपके खाते पर हमला कर सकते हैं. - अगर नीति सेट नहीं है, तो मशीन से जनरेट खाता पासवर्ड हर 30 दिन में बदल जाता है. + अगर नीति सेट नहीं है तो, मशीन से जनरेट 'खाता पासवर्ड' हर 30 दिन में बदल जाता है. - अगर नीति को 0 पर सेट किया जाता है, तो मशीन से जनरेट खाता पासवर्ड को बदलने की सुविधा बंद हो जाती है. + अगर नीति को 0 पर सेट किया जाता है तो, मशीन से जनरेट 'खाता पासवर्ड' को बदलने की सुविधा बंद हो जाती है. - ध्यान दें कि अगर क्लाइंट लंबे समय से ऑफ़लाइन है, तो पासवर्ड बताए गए दिनों की संख्या से पुराने हो सकते हैं.</translation> + ध्यान दें कि अगर क्लाइंट लंबे समय से ऑफ़लाइन है तो, पासवर्ड तय किए गए दिनों की संख्या से ज़्यादा पुराने हो सकते हैं.</translation> <translation id="5105313908130842249">बैटरी पावर पर चलते समय स्क्रीन लॉक विलंब</translation> <translation id="5108031557082757679">एंटरप्राइज़ डिवाइस प्रिंटर बंद</translation> <translation id="5130288486815037971">क्या TLS में RC4 सिफ़र सुइट सक्षम किए गए हैं</translation> @@ -1458,9 +1466,9 @@ यदि यह नीति सही पर सेट की जाती है, तो <ph name="PRODUCT_OS_NAME" /> डिवाइस को डेवलपर मोड में बूट होने से रोकेगा. डेवलपर स्विच चालू होने पर सिस्टम बूट होने से मना कर देगा और एक गड़बड़ी स्क्रीन दिखाएगा. यदि यह नीति सेट नहीं की जाती या गलत पर सेट की जाती है, तो डेवलपर मोड डिवाइस के लिए उपलब्ध रहेगा.</translation> -<translation id="5208240613060747912">आपको उन यूआरएल पैटर्न की सूची सेट करने देती है जो ऐसी साइटों को निर्दिष्ट करते हैं जिन्हें सूचनाओं को दिखाने की अनुमति नहीं है. +<translation id="5208240613060747912">यह नीति आपको उन 'यूआरएल पैटर्न' की सूची सेट करने देती है जो ऐसी साइटें बताते हैं जिनमें सूचनाएं दिखाने की अनुमति है. - अगर यह नीति सेट किए बिना छोड़ दी जाती है तो सभी साइटों के लिए वैश्विक डिफ़ॉल्ट मान का उपयोग या तो 'DefaultNotificationsSetting' नीति के सेट होने पर इससे किया जाएगा, या अन्यथा उपयोगकर्ता के व्यक्तिगत कॉन्फ़िगरेशन से किया जाएगा.</translation> + अगर यह नीति सेट नहीं की जाती है तो, सभी साइटों के लिए 'ग्लोबल डिफ़ॉल्ट मान' का उपयोग किया जाएगा. यह मान, 'DefaultPluginsSetting' नीति सेट होने पर उससे लिया जाएगा वरना उपयोगकर्ता के निजी कॉन्फ़िगरेशन से लिया जाएगा.</translation> <translation id="5219844027738217407">Android ऐप्लिकेशन के लिए, यह नीति केवल माइक्रोफ़ोन को प्रभावित करती है. जब यह नीति सही पर सेट होती है, तो माइक्रोफ़ोन को बिना किसी अपवाद के, सभी Android ऐप्लिकेशन के लिए म्यूट कर दिया जाता है.</translation> <translation id="523505283826916779">पहुंच-योग्यता विकल्प</translation> <translation id="5247006254130721952">खतरनाक डाउनलोड ब्लॉक करें</translation> @@ -1479,26 +1487,26 @@ '*' वाले कालीसूची मान का अर्थ है कि सभी स्थानीय संदेश सेवा होस्ट तब तक कालीसूची में होते हैं जब तक वे श्वेतसूची में स्पष्ट रूप से सूचीबद्ध होते हैं. यदि नीति सेट नहीं पर छोड़ दी जाती है, तो <ph name="PRODUCT_NAME" /> सभी इंस्टॉल किए गए स्थानीय संदेश सेवा होस्ट को लोड करेगा.</translation> -<translation id="5272684451155669299">अगर सही होती है तो, उपयोगकर्ता <ph name="CHALLENGE_USER_KEY_FUNCTION" /> का उपयोग करके <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> के ज़रिए निजता CA में अपनी पहचान दूर से ही प्रमाणित करने के लिए Chrome डिवाइस पर हार्डवेयर का उपयोग कर सकता है. +<translation id="5272684451155669299">अगर यह नीति सही पर सेट हो तो, उपयोगकर्ता <ph name="CHALLENGE_USER_KEY_FUNCTION" /> का उपयोग करके <ph name="ENTERPRISE_PLATFORM_KEYS_API" /> के ज़रिए निजता CA में अपनी पहचान दूर से ही प्रमाणित करने के लिए Chrome डिवाइस पर हार्डवेयर का उपयोग कर सकता है. - अगर यह गलत पर सेट की जाती है या अगर सेट नहीं की जाती है तो, API (एपीआई) को कॉल नहीं किए जा सकेंगे और एक गड़बड़ी कोड मिलेगा.</translation> + अगर यह गलत पर सेट हो या सेट नहीं की गई हो तो, एपीआई को कॉल नहीं किए जा सकेंगे और एक गड़बड़ी कोड मिलेगा.</translation> <translation id="5283457834853986457">प्लग इन का पता लगाने की सुविधा बंद करें (इस्तेमाल में नहीं)</translation> <translation id="5288772341821359899">अगर यह नीति सेट की हुई है तो, WebRTC जिस यूडीपी पोर्ट श्रेणी का इस्तेमाल करता है उसे किसी खास पोर्ट अंतराल (अंतिम बिंदुओं सहित) तक सीमित कर दिया जाता है. अगर नीति सेट नहीं की हुई है या, अगर वह खाली स्ट्रिंग पर या किसी अमान्य पोर्ट श्रेणी पर सेट है तो, WebRTC को किसी भी उपलब्ध स्थानीय यूडीपी पोर्ट का उपयोग करने की अनुमति होती है.</translation> <translation id="5290940294294002042">वैसे प्लग इन की सूची तय करें जिसे उपयोगकर्ता चालू या बंद कर सकता है</translation> -<translation id="5302612588919538756">इस पॉलिसी को रोक दिया गया है, इसकी जगह SyncDisabled का उपयोग कर सकते हैं. +<translation id="5302612588919538756">यह नीति लागू नहीं है, इसकी जगह SyncDisabled का उपयोग कर सकते हैं. उपयोगकर्ता को <ph name="PRODUCT_NAME" /> में साइन इन करने की अनुमति देती है. - अगर आप इस पॉलिसी को सेट करते हैं तो, आप यह कॉन्फ़िगर कर सकते हैं कि किसी उपयोगकर्ता को <ph name="PRODUCT_NAME" /> में साइन इन करने की अनुमति है या नहीं. इस पॉलिसी को 'फर्ज़ी' पर सेट करने से उन ऐप्लिकेशन और एक्सटेंशन को काम करने से रोक दिया जाएगा जो chrome.identity API (एपीआई) का उपयोग करते हैं इसलिए हो सकता है कि आप उसके बजाय SyncDisabled का उपयोग करना चाहें.</translation> -<translation id="5304269353650269372">उपयोगकर्ता इनपुट के बिना समयावधि निर्दिष्ट करती है जिसके बाद बैटरी पॉवर पर चलाए जाने पर एक चेतावनी डॉयलॉग दिखाया जाता है. + अगर आप इस नीति को सेट करते हैं तो, आप यह कॉन्फ़िगर कर सकते हैं कि किसी उपयोगकर्ता को <ph name="PRODUCT_NAME" /> में साइन इन करने की अनुमति है या नहीं. इस नीति को 'गलत' पर सेट करने से उन ऐप्लिकेशन और एक्सटेंशन को काम करने से रोक दिया जाएगा जो chrome.identity API (एपीआई) का उपयोग करते हैं इसलिए हो सकता है कि आप उसके बजाय SyncDisabled का उपयोग करना चाहें.</translation> +<translation id="5304269353650269372">बैटरी पावर पर चलते समय उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता कोई इनपुट नहीं देता और जिसके बाद चेतावनी वाला संवाद दिखाया जाता है. - जब यह नीति सेट होती है, तो <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता को यह चेतावनी डॉयलॉग दिखाए कि प्रयोग में नहींता की कार्यवाही की जाने वाली है, उसके पहले ही यह नीति उस समयावधि को निर्दिष्ट करती है जिसमें उपयोगकर्ता को प्रयोग में नहीं रहना है + जब इस नीति को सेट किया जाता है तो, यह <ph name="PRODUCT_OS_NAME" /> की ओर से कोई चेतावनी संवाद दिखाए जाने से पहले की उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता कोई गतिविधि नहीं करता. इस चेतावनी संवाद में उपयोगकर्ता को बताया जाता है कि जल्द ही गतिविधि नहीं करने संबंधी कार्रवाई की जाएगी. - जब यह नीति अनसेट होती है, तो कोई चेतावनी डॉयलॉग नहीं दिखाया जाता. + जब यह नीति सेट नहीं होती है तो, चेतावनी संबंधी कोई संवाद नहीं दिखाया जाता. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए. मानों को प्रयोग में नहीं विलंब से कम या उसके बराबर रहने के लिए क्लैम्प किया जाता है.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए. मानों को, कोई गतिविधि नहीं में देरी से कम या उसके बराबर पर रखा जाता है.</translation> <translation id="5307432759655324440">गुप्त मोड उपलब्धता</translation> <translation id="5318185076587284965">रिमोट एक्सेस होस्ट द्वारा रिले सर्वर का उपयोग सक्षम करें</translation> <translation id="5323128137188992869"><ph name="PRODUCT_NAME" /> का उपयोग करने वाले डिवाइस पर सामग्री कास्ट करने दें. @@ -1515,7 +1523,9 @@ अगर सही पर सेट है या कॉन्फ़िगर नहीं किया गया है तो, इस उपयोगकर्ता के ज़रिए निगरानी में रखे गए उपयोगकर्ता बनाए और प्रबंधित किए जा सकेंगे.</translation> <translation id="5370279767682621504">उन पोर्ट पर HTTP/0.9 की सुविधा चालू करती है जो डिफ़ॉल्ट नहीं हैं</translation> -<translation id="5378985487213287085">आपको यह सेट करने देती है कि वेबसाइटों को डेस्कटॉप सूचनाएं प्रदर्शित करने दी जाएं या नहीं. डेस्कटॉप सूचनाएं प्रदर्शित करने की अनुमति डिफ़ॉल्ट रूप से दी जा सकती है, डिफ़ॉल्ट रूप से अस्वीकृत की जा सकती है या उपयोगकर्ता से हर बार पूछा जा सकता है कि वेबसाइट डेस्कटॉप सूचनाएं दिखाना चाहती है. यदि इस नीति को सेट किए बिना छोड़ दिया जाता है, तो 'AskNotifications' का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> +<translation id="5378985487213287085">आपको यह सेट करने की सुविधा देती है कि वेबसाइटों को डेस्कटॉप सूचनाएं दिखाने की अनुमति दी जाए या नहीं. डेस्कटॉप सूचनाएं दिखाने की अनुमति डिफ़ॉल्ट रूप से दी जा सकती है, डिफ़ॉल्ट रूप से खारिज की जा सकती है या हर उस समय उपयोगकर्ता से पूछा जा सकता है जब कोई वेबसाइट डेस्कटॉप सूचनाएं दिखाना चाहती हो. + + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, 'AskNotifications' का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> <translation id="538108065117008131"><ph name="PRODUCT_FRAME_NAME" /> को सामग्री के निम्न प्रकारों को प्रबंधित करने की सुविधा देता है.</translation> <translation id="5391363090783552279">अगर यह नीति सही पर सेट की जाती है, तो <ph name="PRODUCT_NAME" /> सिर्फ़ RFC1918/RFC4913 निजी पतों पर ही नहीं बल्कि सभी आईपी पतों पर कास्ट डिवाइस से कनेक्ट करेगा. @@ -1539,7 +1549,11 @@ <translation id="5405289061476885481">यह कॉन्फ़िगर करती है कि <ph name="PRODUCT_OS_NAME" /> की साइन इन स्क्रीन पर किस कीबोर्ड लेआउट की अनुमति है. अगर यह नीति इनपुट के तरीकों की पहचान संबंधी किसी सूची पर सेट की जाती है तो साइन इन स्क्रीन पर, दिया गया इनपुट का तरीका उपलब्ध होगा. इनपुट के लिए वह तरीका पहले से चुना गया होगा जो सबसे पहले दिया गया होगा. उपयोगकर्ता पॉड जहां साइन इन स्क्रीन पर फ़ोकस करता है वहीं इस नीति की ओर से दिए गए इनपुट के तरीकों के अलावा इनपुट का वह तरीका भी उपलब्ध होगा जिसका इस्तेमाल उसने आखिरी बार किया था. अगर यह नीति सेट नहीं की जाती तो, इनपुट का तरीका उस स्थान-भाषा से लिया जाएगा जिसमें साइन इन स्क्रीन दिखाई जाती है. वैसे मान जो इनपुट के मान्य तरीके नहीं हैं, उन्हें अनदेखा कर दिया जाएगा.</translation> -<translation id="5423001109873148185">यह नीति सक्षम किए जाने पर खोज इंजन को वर्तमान डिफ़ॉल्ट ब्राउज़र से आयात करने के लिए बाध्य करती है. यदि सक्षम किया जाता है, तो यह नीति आयात डॉयलॉग को भी प्रभावित करती है. यदि अक्षम किया जाता है, तो डिफ़ॉल्ट खोज इंजन आयात नहीं होता. यदि इसे सेट नहीं किया जाए, तो उपयोगकर्ता से आयात करने के संबंध में पूछा जा सकता है, या आयात करना स्वचालित रूप से हो सकता है.</translation> +<translation id="5423001109873148185">अगर यह नीति चालू हो तो, यह सर्च इंजन को वर्तमान डिफ़ॉल्ट ब्राउज़र से आयात करने के लिए बाध्य करती है. चालू होने पर यह नीति, आयात संबंधी संवाद पर भी असर डालती है. + + अगर बंद हो तो, डिफ़ॉल्ट सर्च इंजन को आयात नहीं किया जाता. + + अगर इसे सेट नहीं किया गया हो तो, उपयोगकर्ता से आयात करने के लिए पूछा जा सकता है या अपने आप आयात किया जा सकता है.</translation> <translation id="5423197884968724595">Android WebView प्रतिबंध नाम:</translation> <translation id="5442026853063570579">यह नीति Android डेवलपर के लिए सेटिंग और टूल का एक्सेस भी नियंत्रित करती है. अगर आप इस नीति को 'DeveloperToolsDisallowed' (मान 2) पर सेट करते हैं, तो उपयोगकर्ता डेवलपर के लिए सेटिंग और टूल एक्सेस नहीं कर सकते. अगर आप इस नीति को किसी दूसरे मान पर सेट करते हैं या इसे सेट किए बिना छोड़ देते हैं, तो उपयोगकर्ता Android सेटिंग ऐप्लिकेशन में बिल्ड नंबर पर सात बार टैप करके डेवलपर के लिए सेटिंग और टूल एक्सेस कर सकते हैं.</translation> <translation id="5447306928176905178">मेमोरी जानकारी (JS हीप आकार) को पेज पर रिपोर्ट करना सक्षम करें (बहिष्कृत)</translation> @@ -1557,11 +1571,11 @@ नीति का मान मिलीसेकंड में बताया जाना चाहिए.</translation> <translation id="5511702823008968136">बुकमार्क बार सक्षम करें</translation> <translation id="5512418063782665071">होम पेज URL</translation> -<translation id="5523812257194833591">विलंब के बाद स्वत:-प्रवेश करने के लिए एक सार्वजनिक सत्र. +<translation id="5523812257194833591">देरी के बाद अपने अाप लॉग इन के लिए कोई सार्वजनिक सत्र. - यदि यह नीति सेट होती है, तो प्रवेश स्क्रीन पर एक समयावधि निकल जाने के बाद निर्दिष्ट सत्र, उपयोगकर्ता की सहभागिता के बिना ही स्वचालित रूप से प्रवेश हो जाएगा. सार्वजनिक सत्र को पहले से कॉन्फ़िगर किया हुआ होना चाहिए (|DeviceLocalAccounts| देखें). + अगर यह नीति सेट होती है तो, साइन इन स्क्रीन पर कोई समय सीमा खत्म हो जाने के बाद बताया गया सत्र, उपयोगकर्ता के इंटरैक्शन के बिना ही अपने आप लॉग इन हो जाएगा. सार्वजनिक सत्र पहले से कॉन्फ़िगर होना चाहिए (|DeviceLocalAccounts| देखें). - यदि यह नीति सेट नहीं है, तो कोई स्वत:-प्रवेश नहीं होगा.</translation> + अगर यह नीति सेट नहीं है तो, अपने आप लॉग इन नहीं होगा.</translation> <translation id="5526701598901867718">सभी (असुरक्षित)</translation> <translation id="5529037166721644841">यह नीति 'डिवाइस नीति की जानकारी' के लिए क्वेरी की गई 'डिवाइस प्रबंधन सेवा' की अवधि को मिलीसेकंड में तय करती है. @@ -1627,41 +1641,41 @@ <translation id="5781412041848781654">निर्दिष्ट करती है कि HTTP प्रमाणीकरण के लिए कौन सी GSSAPI लाइब्रेरी का उपयोग करना है. आप या तो केवल लाइब्रेरी का नाम या पूरा पथ सेट कर सकते हैं. यदि कोई सेटिंग प्रदान नहीं की जाती है, तो <ph name="PRODUCT_NAME" /> किसी डिफ़ॉल्ट लाइब्रेरी नाम का ही उपयोग करेगा.</translation> -<translation id="5781806558783210276">बैटरी पावर पर चलते समय, उस समयावधि को निर्दिष्ट करती है जितनी देर तक उपयोगकर्ता कोई भी इनपुट न दे, उसके बाद प्रयोग में नहीं कार्यवाही की जाती है. +<translation id="5781806558783210276">बैटरी पावर पर चलते समय, यह नीति उस अवधि को तय करती है, जितनी देर तक उपयोगकर्ता के कोई भी इनपुट न देने के बाद 'उपयोग में नहीं' की कार्रवाई की जाती है. - जब नीति सेट की जाती है, तो वह <ph name="PRODUCT_OS_NAME" /> द्वारा प्रयोग में नहीं कार्यवाही किए जाने से पहले की उस समयावधि को निर्दिष्ट करती है जिसमें उपयोगकर्ता को प्रयोग में नहीं रहना होगा, जिसे अलग से कॉन्फ़िगर किया जा सकता है. + जब नीति सेट की जाती है तो, वह उस अवधि को तय करती है, जिसके बाद <ph name="PRODUCT_OS_NAME" /> 'उपयोग में नहीं' की कार्रवाई करता है. इसके लिए ज़रूरी है कि कम से कम इतनी अवधि तक उपयोगकर्ता कुछ भी न करे. इस कार्रवाई को अलग से कॉन्फ़िगर किया जा सकता है. - जब नीति सेट नहीं की जाती, तो एक डिफ़ॉल्ट समयावधि का उपयोग किया जाता है. + जब नीति सेट नहीं की जाती तो, एक डिफ़ॉल्ट अवधि का उपयोग किया जाता है. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए.</translation> <translation id="5809728392451418079">डिवाइस-स्थानीय खातों के लिए प्रदर्शन नाम सेट करें</translation> <translation id="5814301096961727113">प्रवेश स्क्रीन पर बोले गए फ़ीडबैक की डिफ़ॉल्ट स्थिति सेट करें</translation> <translation id="5815129011704381141">अपडेट के बाद स्वचालित रूप से रीबूट करें</translation> -<translation id="5815353477778354428">उस निर्देशिका को कॉन्फ़िगर करती है जिसका उपयोग <ph name="PRODUCT_FRAME_NAME" /> द्वारा उपयोगकर्ता डेटा संग्रहित करने के लिए किया जाएगा. +<translation id="5815353477778354428">उस निर्देशिका को कॉन्फ़िगर करती है जिसका उपयोग <ph name="PRODUCT_FRAME_NAME" /> उपयोगकर्ता का डेटा जमा करने के लिए करेगा. - यदि आप यह पॉलिसी सेट करते हैं, तो <ph name="PRODUCT_FRAME_NAME" /> द्वारा, उपलब्ध कराई गई निर्देशिका का उपयोग किया जाएगा. + अगर इस नीति को सेट किया जाता है तो, <ph name="PRODUCT_FRAME_NAME" /> उपलब्ध कराई गई निर्देशिका का उपयोग करेगा. - उपयोग किए जाने वाले चरों की सूची देखने के लिए https://www.chromium.org/administrators/policy-list-3/user-data-directory-variables देखें. + उपयोग किए जा सकने वाले वैरिएबल की सूची देखने के लिए https://www.chromium.org/administrators/policy-list-3/user-data-directory-variables पर जाएं. - यदि यह सेटिंग सेट किए बिना छोड़ दी जाती है तो डिफ़ॉल्ट प्रोफ़ाइल निर्देशिका का उपयोग किया जाएगा.</translation> -<translation id="5826047473100157858">निर्दिष्ट करती है कि क्या उपयोगकर्ता <ph name="PRODUCT_NAME" /> में पेजों को गुप्त मोड में खोल सकता है. + अगर यह सेटिंग सेट किए बिना छोड़ दी जाती है तो, डिफ़ॉल्ट प्रोफ़ाइल निर्देशिका का उपयोग किया जाएगा.</translation> +<translation id="5826047473100157858">यह नीति तय करती है कि क्या उपयोगकर्ता <ph name="PRODUCT_NAME" /> में पेजों को 'गुप्त मोड' में खोल सकता है. - यदि 'सक्षम' चयनित हो या नीति सेट किए बिना छोड़ दी गई हो, तो हो सकता है कि पेज गुप्त मोड में खुलें. + अगर 'चालू' चुना गया है या नीति सेट नहीं की गई हो तो, हो सकता है कि पेज 'गुप्त मोड' में खुलें. - यदि 'अक्षम' चयनित हो, तो हो सकता है कि पेज गुप्त मोड में न खुलें. + अगर 'बंद' चुना गया है तो, हो सकता है कि पेज 'गुप्त मोड' में न खुलें. - यदि 'बलपूर्वक' चयनित हो, तो हो सकता है कि पेज केवल गुप्त मोड में ही खुलें.</translation> + अगर 'फ़ोर्स्ड (ज़बरदस्ती)' चुना गया हो तो, हो सकता है कि पेज सिर्फ़ 'गुप्त मोड' में खुलें.</translation> <translation id="583091600226586337"> - अगर नीति चालू है, तो हर फ़ाइल डाउनलोड करने से पहले उपयोगकर्ता से फ़ाइल सेव करने की जगह के बारे में पूछा जाएगा. - अगर नीति बंद है, तो डाउनलोड तुरंत शुरू हो जाएंगे और उपयोगकर्ता से फ़ाइल सेव करने की जगह के बारे में नहीं पूछा जाएगा. - अगर नीति कॉन्फ़िगर नहीं की गई है, तो उपयोगकर्ता इस सेटिंग को बदल सकेगा. + अगर नीति चालू है तो, हर फ़ाइल डाउनलोड करने से पहले उपयोगकर्ता से फ़ाइल सेव करने की जगह के बारे में पूछा जाएगा. + अगर नीति बंद है तो, डाउनलोड तुरंत शुरू हो जाएंगे और उपयोगकर्ता से फ़ाइल सेव करने की जगह के बारे में नहीं पूछा जाएगा. + अगर नीति कॉन्फ़िगर नहीं की गई है तो, उपयोगकर्ता इस सेटिंग को बदल सकेगा. </translation> <translation id="5835124959204887277">ऐसे यूआरएल और डोमेन के बारे में बताती है जिनके लिए सुरक्षा कुंजियों से प्रमाणन के प्रमाणपत्रों का अनुरोध करते समय कोई भी संकेत नहीं दिखाया जाएगा. इसके अलावा, सुरक्षा कुंजी को यह बताने वाला एक संकेत भेजा जाएगा कि व्यक्तिगत प्रमाणन का इस्तेमाल किया जा सकता है. इसके बिना, उपयोगकर्ताओं को Chrome 65+ में तब संकेत किया जाएगा जब साइटें सुरक्षा कुंजियों के प्रमाणन का अनुरोध करेंगी. यूआरएल (जैसे कि https://example.com/some/path) का मिलान सिर्फ़ U2F appID की तरह होगा. डोमेन (जैसे कि example.com) का मिलान सिर्फ़ webauthn RP ID की तरह होगा. इसलिए, किसी साइट के लिए U2F और webauthn API, दोनों को कवर करने के लिए, appID यूआरएल और डोमेन को सूचीबद्ध करने की ज़रूरत होगी.</translation> <translation id="5835412847081687053">किसी उपयोगकर्ता सत्र में मंज़ूर की गई यूज़र इंटरफ़ेस (यूआई) स्थान-भाषाएं कॉन्फ़िगर करें</translation> <translation id="5836064773277134605">रिमोट एक्सेस होस्ट द्वारा उपयोग की गई UDP पोर्ट श्रेणी प्रतिबंधित करें</translation> -<translation id="5862253018042179045">लॉग इन स्क्रीन पर 'कंप्यूटर के बोलकर दिए जाने वाले जवाब' के एक्सेस की सुविधा को डिफ़ॉल्ट पर सेट करें. +<translation id="5862253018042179045">लॉग इन स्क्रीन पर 'कंप्यूटर के बोलकर दिए जाने वाले जवाब' की सुलभता सुविधा को डिफ़ॉल्ट पर सेट करें. अगर यह नीति सही पर सेट है तो, लॉग इन स्क्रीन के दिखाई देने पर 'कंप्यूटर के बोलकर दिए जाने वाले जवाब की सुविधा' को चालू कर दिया जाएगा. @@ -1721,9 +1735,9 @@ यदि यह नीति सेट नहीं की जाती या गलत पर सेट कर दी जाती है, तो प्रिंट आदेश प्रिंट पूर्वावलोकन स्क्रीन ट्रिगर कर देते हैं.</translation> <translation id="6022948604095165524">स्टार्टअप पर क्रिया</translation> -<translation id="6023030044732320798">यह नीति ऐसी नीतियों के सेट के बारे में बताती है जिन्हें 'एआरसी रनटाइम' को सौंप दिया जाएगा. मान कोई मान्य जेएसओएन (जेसन) होना चाहिए. +<translation id="6023030044732320798">यह नीति ऐसी नीतियों के सेट के बारे में बताती है जिन्हें 'एआरसी रनटाइम' को सौंप दिया जाएगा. मान कोई मान्य जेसन (JSON) होना चाहिए. - इस नीति का इस्तेमाल यह कॉन्फ़िगर करने के लिए किया जा सकता है कि डिवाइस पर कौन से ऐप्लिकेशन अपने आप इंस्टॉल हुए हैं: + इस नीति का इस्तेमाल यह कॉन्फ़िगर करने के लिए किया जा सकता है कि डिवाइस पर कौनसे ऐप्लिकेशन अपने आप इंस्टॉल हुए हैं: { "type": "object", @@ -1734,7 +1748,7 @@ "type": "object", "properties": { "packageName": { - "ब्यौरा": "Android app पहचानकर्ता, उदाहरण के लिए, Gmail के लिए "com.google.android.gm"", + "ब्यौरा": "Android ऐप की पहचान करने वाला, उदाहरण के लिए, Gmail के लिए "com.google.android.gm", "type": "string" }, "installType": { @@ -1793,35 +1807,35 @@ <translation id="6111936128861357925">डाइनासोर ईस्टर गेम की अनुमति दें</translation> <translation id="6114416803310251055">अनुचित</translation> <translation id="6133088669883929098">सभी साइट को कुकी जेनरेशन का उपयोग करने दें</translation> -<translation id="6145799962557135888">आपको यूआरएल पैटर्न की सूची सेट करने देती है जो उन साइटों को निर्दिष्ट करती है जिन्हें JavaScript चलाने की अनुमति होती है. +<translation id="6145799962557135888">वैसी साइट जिनमें JavaScript चलाने की अनुमति है, उनके लिए यूआरएल पैटर्न की सूची सेट करने की सुविधा देती है. - अगर यह नीति सेट किए बिना छोड़ दी जाती है, तो सभी साइटों के लिए 'DefaultJavaScriptSetting' नीति के सेट होने पर इससे, या अन्यथा उपयोगकर्ता के व्यक्तिगत कॉन्फ़िगरेशन से वैश्विक डिफ़ॉल्ट मान का उपयोग किया जाएगा.</translation> + अगर इस नीति को नहीं जोड़ा जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultPopupsSetting' सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> <translation id="614662973812186053">यह नीति Android उपयोग और गड़बड़ी संबंधी डेटा को इकट्ठा करना भी नियंत्रित करती है.</translation> <translation id="6155936611791017817">प्रवेश स्क्रीन पर बड़े कर्सर की डिफ़ॉल्ट स्थिति सेट करें</translation> <translation id="6157537876488211233">प्रॉक्सी को अनदेखा करने के नियमों की विरामचिह्न द्वारा अलग की गई सूची</translation> <translation id="6158324314836466367">Enterprise वेब स्टोर नाम (बहिष्कृत)</translation> -<translation id="6181608880636987460">आपको ऐसी साइट बताने वाले यूआरएल पैटर्न की सूची सेट करने देती है जिन्हें <ph name="FLASH_PLUGIN_NAME" /> प्लग इन चलाने की अनुमति नहीं है. +<translation id="6181608880636987460">यह नीति आपको उन 'यूआरएल पैटर्न' की सूची सेट करने देती है जो ऐसी साइटें बताते हैं जिन्हें <ph name="FLASH_PLUGIN_NAME" /> प्लग इन चलाने की अनुमति नहीं है. - अगर यह नीति सेट किए बिना छोड़ दी जाती है, तो 'DefaultPluginsSetting' नीति सेट होने पर या तो उससे सभी साइटों के लिए वैश्विक डिफ़ॉल्ट मान का उपयोग किया जाएगा या फिर उपयोगकर्ता के व्यक्तिगत कॉन्फ़िगरेशन का उपयोग किया जाएगा.</translation> + अगर यह नीति सेट नहीं की जाती है तो, सभी साइटों के लिए 'ग्लोबल डिफ़ॉल्ट मान' का उपयोग किया जाएगा. यह मान, 'DefaultPluginsSetting' नीति सेट होने पर उससे लिया जाएगा वरना उपयोगकर्ता के निजी कॉन्फ़िगरेशन से लिया जाएगा.</translation> <translation id="6190022522129724693">सामान्य पॉपअप सेटिंग</translation> -<translation id="6197453924249895891">एक्सटेंशन की कॉर्पोरेट कुंजियों की ऐक्सेस देती है. +<translation id="6197453924249895891">यह नीति एक्सटेंशन को कॉर्पोरेट कुंजियों का एक्सेस देती है. - कुंजियों को कॉर्पोरेट उपयोग के लिए तब तय किया जाता है जबकि उन्हें किसी प्रबंधित खाते पर chrome.enterprise.platformKeys API (एपीआई) का उपयोग करके जनरेट किया गया हो. किसी अन्य तरीके से लाई गईं या जनरेट की गईं कुंजियों को कॉर्पोरेट उपयोग के लिए तय नहीं किया जाता. + कुंजियों को कॉर्पोरेट उपयोग के लिए तब तय किया जाता है जब उन्हें किसी प्रबंधित खाते पर chrome.enterprise.platformKeys API (एपीआई) का उपयोग करके जनरेट किया गया हो. किसी अन्य तरीके से लाई गईं या जनरेट की गईं कुंजियों को कॉर्पोरेट उपयोग के लिए तय नहीं किया जाता. - कॉर्पोरेट उपयोग के लिए तय की गई कुंजियों की ऐक्सेस सिर्फ़ इस नीति से नियंत्रित की जाती है. उपयोगकर्ता न तो एक्सटेंशन को कॉर्पोरेट कुंंजियों का ऐक्सेस दे सकता है न ही उन्हें वापस ले सकता है. + कॉर्पोरेट उपयोग के लिए तय की गई कुंजियों की एक्सेस सिर्फ़ इस नीति से नियंत्रित की जाती है. उपयोगकर्ता न तो एक्सटेंशन को कॉर्पोरेट कुंंजियों का एक्सेस दे सकता है न ही उन्हें वापस ले सकता है. - डिफ़ॉल्ट रूप से कोई एक्सटेंशन कॉर्पोरेट उपयोग के लिए तय की गई ऐसी कुंजी का उपयोग नहीं कर सकता, जो allowCorporateKeyUsage को उस एक्सटेंशन के लिए 'फ़र्ज़ी' पर सेट करने जैसा हो. + डिफ़ॉल्ट रूप से कोई एक्सटेंशन कॉर्पोरेट उपयोग के लिए तय की गई ऐसी कुंजी का उपयोग नहीं कर सकता, जो allowCorporateKeyUsage को उस एक्सटेंशन के लिए 'गलत' पर सेट करने जैसा हो. - अगर किसी एक्सटेंशन के लिए allowCorporateKeyUsage को 'सही' पर सेट किया जाता है, सिर्फ़ तभी वह कॉर्पोरेट उपयोग के लिए चिह्नित की गई किसी भी प्लैटफ़ॉर्म कुंजी का उपयोग आर्बिट्रेरी डेटा पर हस्ताक्षर करने के लिए कर सकती है. यह अनुमति तभी दी जानी चाहिए जब एक्सटेंशन, हमलावरों के ख़िलाफ़ कुंजी पर सुरक्षित ऐक्सेस के लिए भरोसेमंद हो.</translation> -<translation id="6211428344788340116">डिवाइस गतिविधि समय की रिपोर्ट करें. + अगर किसी एक्सटेंशन के लिए allowCorporateKeyUsage को 'सही' पर सेट किया जाता है, सिर्फ़ तभी वह कॉर्पोरेट उपयोग के लिए बताई गई किसी भी प्लैटफ़ॉर्म कुंजी का उपयोग आर्बिट्रेरी डेटा पर हस्ताक्षर करने के लिए कर सकती है. यह अनुमति तभी दी जानी चाहिए जब एक्सटेंशन, हमलावरों के ख़िलाफ़ कुंजी पर सुरक्षित एक्सेस के लिए भरोसेमंद हो.</translation> +<translation id="6211428344788340116">डिवाइस की गतिविधि से जुड़े समय के बारे में बताएं. - यदि यह नीति सेट नहीं की जाती है या सही पर सेट की जाती है, तो नामांकित डिवाइस उपयोगकर्ता के किसी डिवाइस पर सक्रिय होने पर समयावधियों की रिपोर्ट करेंगे. यदि यह नीति गलत पर सेट की जाती है, तो डिवाइस गतिविधि समय रिकॉर्ड या रिपोर्ट नहीं किए जाएंगे.</translation> + अगर यह नीति सेट नहीं की जाती है या सही पर सेट की जाती है तो, वैसे डिवाइस जिनका नाम दर्ज है, वे डिवाइस पर उपयोगकर्ता के सक्रिय होने पर उसकी समय सीमा के बारे में बताएंगे. अगर यह नीति गलत पर सेट की जाती है तो, डिवाइस की गतिविधि से जुड़े समय को न तो रिकॉर्ड किया जाएगा और न ही इसके बारे में बताया जाएगा.</translation> <translation id="6212868225782276239">प्रतिबंधित सूची में शामिल प्रिंटर छोड़कर सभी प्रिंटर दिखाए जाते हैं.</translation> -<translation id="6219965209794245435">यदि यह नीति सक्षम है तो ऑटोमैटिक भरने वाला फ़ॉर्म डेटा को पिछले डिफ़ॉल्ट ब्राउज़र से आयात किए जाने के लिए बाध्य करती है. यदि सक्षम है, तो यह नीति आयात संवाद को भी प्रभावित करती है. +<translation id="6219965209794245435">अगर यह नीति चालू हो तो, यह ऑटोमैटिक भरने वाले फ़ॉर्म डेटा को पिछले डिफ़ॉल्ट ब्राउज़र से आयात किए जाने के लिए बाध्य करती है. - यदि अक्षम है, तो ऑटोमैटिक भरने वाले फ़ॉर्म डेटा को आयात नहीं किया जाता. + अगर बंद हो तो, ऑटोमैटिक भरने वाले फ़ॉर्म डेटा का आयात नहीं किया जाता. - यदि इसे सेट नहीं किया गया है, तो उपयोगकर्ता से आयात करने या ना करने के लिए पूछा जा सकता है या फिर अपने आप फिर से आयात किया जा सकता है.</translation> + अगर इसे सेट नहीं किया गया हो तो, उपयोगकर्ता से आयात करने के लिए पूछा जा सकता है या अपने आप आयात किया जा सकता है.</translation> <translation id="6224304369267200483">यूआरएल/डोमेन ने अपने आप सीधे सुरक्षा कुंजी प्रमाणन की अनुमति दी है</translation> <translation id="6233173491898450179">डाउनलोड निर्देशिका सेट करें</translation> <translation id="6244210204546589761">स्टार्टअप पर खुलने वाले URL</translation> @@ -1833,7 +1847,7 @@ <translation id="6281043242780654992">स्थानीय संदेश सेवा के लिए नीतियां कॉन्फ़िगर करता है. कालीसूची में डाले गए स्थानीय संदेश सेवा होस्ट को तब तक अनुमति नहीं दी जाएगी जब तक वे श्वेतसूची में नहीं डाले जाते.</translation> <translation id="6282799760374509080">ऑडियो कैप्चर की अनुमति देना या अस्वीकार करना</translation> <translation id="6284362063448764300">TLS 1.1</translation> -<translation id="6310223829319187614">उपयोगकर्ता प्रवेश के दौरान डोमेन नाम स्वत: पूर्ण को सक्षम करें</translation> +<translation id="6310223829319187614">उपयोगकर्ता के साइन इन करने के दौरान डोमेन नाम के 'अपने आप पूरा होने की सुविधा' चालू करें</translation> <translation id="6315673513957120120">जब उपयोगकर्ता SSL त्रुटियों वाली साइटों पर नेविगेट करते हैं, तो Chrome एक चेतावनी पेज दिखाता है. डिफ़ॉल्ट रूप से या जब इस पॉलिसी को सत्य पर सेट किया जाता है, तब उपयोगकर्ताओं को इन चेतावनी पेजों के द्वारा क्लिक करने की अनुमति होती है. इस पॉलिसी को असत्य पर सेट करने से उपयोगकर्ताओं को किसी भी चेतावनी पेज के द्वारा क्लिक करने की अनुमति नहीं दी जाती है.</translation> <translation id="6353901068939575220">POST के साथ कोई URL खोजते समय उपयोग किए जाने वाले पैरामीटर तय करती है. इसमें अल्पविराम के ज़रिए अलग किए गए नाम/मान जोड़े शामिल होते हैं. अगर कोई मान टेम्पलेट पैरामीटर, जैसे ऊपर दिए गए उदाहरण में {searchTerms} है तो, उसे वास्तविक खोज शब्द डेटा से बदल दिया जाएगा. @@ -1841,7 +1855,7 @@ यह नीति वैकल्पिक है. अगर इसे जोड़ा नहीं गया है तो, खोज के अनुरोध को GET विधि के ज़रिए भेजा जाएगा. 'DefaultSearchProviderEnabled' नीति चालू होने पर ही इस नीति का पालन किया जाएगा.</translation> -<translation id="6367755442345892511">रिलीज़ चैनल उपयोगकर्ता द्वारा कॉन्फ़िगर करने योग्य होना चाहिए या नहीं</translation> +<translation id="6367755442345892511">उपयोगकर्ता 'रिलीज़ चैनल' कॉन्फ़िगर कर सके, ऐसा होना चाहिए या नहीं</translation> <translation id="6368011194414932347">होम पेज का यूआरएल कॉन्फ़िगर करें</translation> <translation id="6368403635025849609">इन साइटों पर JavaScript की अनुमति दें</translation> <translation id="6376659517206731212">अनिवार्य हो सकती है</translation> @@ -1849,7 +1863,7 @@ <translation id="637934607141010488">उन डिवाइस उपयोगकर्ताओं की सूची की रिपोर्ट करें जिन्होंने हाल ही में प्रवेश किया है. यदि नीति को गलत पर सेट किया जाता है, तो उपयोगकर्ताओं की रिपोर्ट नहीं की जाएगी.</translation> -<translation id="6392973646875039351"><ph name="PRODUCT_NAME" /> की अपने आप भरने की सुविधा (ऑटोफ़िल) चालू करती है. इससे उपयोगकर्ताओं को क्रेडिट कार्ड और पते से जुड़ी जानकारी जैसी पहले से जमा सूचनाओं की मदद से वेब फ़ॉर्म को अपने आप भरने की सुविधा मिलती है. +<translation id="6392973646875039351"><ph name="PRODUCT_NAME" /> की अपने आप भरने की सुविधा (ऑटोफ़िल) चालू करती है. इसके ज़रिए उपयोगकर्ताओं को क्रेडिट कार्ड और पते से जुड़ी जानकारी जैसी पहले से जमा सूचनाओं की मदद से वेब फ़ॉर्म को अपने आप भरने की सुविधा मिलती है. अगर आप इस सेटिंग को बंद कर देते हैं तो, उपयोगकर्ता अपने आप भरने की सुविधा (ऑटोफ़िल) का इस्तेमाल नहीं कर पाएंगे. @@ -1876,17 +1890,17 @@ यह नियंत्रित करने के लिए कि किन वेबसाइट को Flash चलाने की अनुमति है, "DefaultPluginsSetting", "PluginsAllowedForUrls" और "PluginsBlockedForUrls" नीतियां देखें. अगर यह सेटिंग बंद होती है या सेट नहीं की जाती है तो, अन्य जगहों से आई Flash सामग्री या छोटी सामग्री ब्लॉक की जा सकती है.</translation> -<translation id="653608967792832033">बैटरी पावर पर चलते समय, उस समयावधि को निर्दिष्ट करती है जितनी देर तक उपयोगकर्ता कोई भी इनपुट न दे, उसके बाद स्क्रीन लॉक हो जाती है. +<translation id="653608967792832033">बैटरी पावर पर चलते समय उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता अगर कोई भी इनपुट नहीं देता है तो, उसके बाद स्क्रीन बंद हो जाती है. - जब इस नीति को शून्य से अधिक के मान पर सेट किया जाता है, तो यह <ph name="PRODUCT_OS_NAME" /> द्वारा स्क्रीन को लॉक किए जाने से पहले की उस समयावधि को निर्दिष्ट करती है जिसमें उपयोगकर्ता को प्रयोग में नहीं रहना होगा. + जब इस नीति को शून्य से ज़्यादा मान पर सेट किया जाता है तो, यह <ph name="PRODUCT_OS_NAME" /> की ओर से स्क्रीन बंद किए जाने से पहले की उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता कोई गतिविधि नहीं करता. - जब इस नीति को शून्य पर सेट किया जाता है, तो उपयोगकर्ता के प्रयोग में नहीं हो जाने पर <ph name="PRODUCT_OS_NAME" /> स्क्रीन को लॉक नहीं करता. + जब इस नीति को शून्य पर सेट किया जाता है तो, उपयोगकर्ता की ओर से कोई गतिविधि नहीं करने के बावजूद <ph name="PRODUCT_OS_NAME" /> स्क्रीन को बंद नहीं करता. - जब इस नीति को सेट नहीं किया जाता, तो एक डिफ़ॉल्ट समयावधि का उपयोग किया जाता है. + जब यह नीति सेट नहीं की जाती है तो, एक डिफ़ॉल्ट समय सीमा का उपयोग किया जाता है. - प्रयोग में नहीं रहने पर स्क्रीन को लॉक करने का सुझाए गए तरीका निलंबन पर स्क्रीन लॉक करना और प्रयोग में नहीं विलंब के बाद <ph name="PRODUCT_OS_NAME" /> को निलंबित करने देना है. इस नीति का उपयोग केवल तभी किया जाना चाहिए जब स्क्रीन लॉकिंग, निलंबन से उपयुक्त समयावधि से पहले हो या जब प्रयोग में नहीं रहने पर निलंबन बिल्कुल भी आवश्यक न हो. + गतिविधि नहीं करने पर स्क्रीन को बंद करने का सुझाया गया तरीका यह है कि निलंबन पर स्क्रीन को बंद किया जाए और गतिविधि नहीं करने में देरी के बाद <ph name="PRODUCT_OS_NAME" /> को निलंबित करने दिया जाए. इस नीति का उपयोग सिर्फ़ तभी किया जाना चाहिए जब स्क्रीन को बंद करना, निलंबन से काफ़ी समय पहले सामने आए या गतिविधि नहीं करने पर निलंबित किया जाना बिल्कुल भी ज़रूरी न हो. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए. मानों को प्रयोग में नहीं विलंब से कम होने के लिए क्लैम्प किया जाता है.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए. मानों को, कोई गतिविधि नहीं में देरी से कम या उसके बराबर पर रखा जाता है.</translation> <translation id="6536600139108165863">डिवाइस के शटडाउन होने पर स्वचालित रीबूट होना</translation> <translation id="6539246272469751178">इस नीति का Android ऐप्लिकेशन पर कोई प्रभाव नहीं पड़ता. Android ऐप्लिकेशन हमेशा डिफ़ॉल्ट डाउनलोड निर्देशिका का उपयोग करते हैं और वे <ph name="PRODUCT_OS_NAME" /> द्वारा डाउनलोड की गईं फ़ाइलें किसी गैर-डिफ़ॉल्ट डाउनलोड निर्देशिका में एक्सेस नहीं कर सकते हैं.</translation> <translation id="654303922206238013">ecryptfs के लिए माइग्रेशन कार्यनीति</translation> @@ -1895,15 +1909,15 @@ उपयोगकर्ता द्वारा चयनित चैनल ChromeOsReleaseChannel नीति द्वारा ओवरराइड कर दिया जाएगा, लेकिन यदि नीति चैनल, डिवाइस पर इंस्टॉल किए हुए से अधिक स्थिर होता है, फिर वह चैनल, डिवाइस पर इंस्टॉल किए हुए की अपेक्षा अधिक स्थिर चैनल के किसी उच्च वर्शन संख्या पर पहुंच जाने के बाद ही स्विच करेगा.</translation> <translation id="6559057113164934677">किसी भी साइट को कैमरे और माइक्रोफ़ोन तक न पहुंचने दें</translation> <translation id="6561396069801924653">सिस्टम ट्रे मेनू में पहुंच-योग्यता विकल्प दिखाएं</translation> -<translation id="6565312346072273043">लॉगिन स्क्रीन पर 'ऑन-स्क्रीन कीबोर्ड' के एक्सेस की सुविधा को डिफ़ॉल्ट पर सेट करें. +<translation id="6565312346072273043">लॉग इन स्क्रीन पर 'ऑन-स्क्रीन कीबोर्ड' के एक्सेस की सुविधा को डिफ़ॉल्ट पर सेट करें. - अगर यह नीति 'सही' पर सेट है तो, लॉगिन स्क्रीन दिखाए जाने पर 'ऑन-स्क्रीन कीबोर्ड' चालू हो जाएगा. + अगर यह नीति सही पर सेट की जाती है तो, लॉग इन स्क्रीन दिखाए जाने पर 'ऑन-स्क्रीन कीबोर्ड' चालू हो जाएगा. - अगर यह नीति 'गलत' पर सेट है तो, लॉगिन स्क्रीन दिखाए जाने पर 'ऑन-स्क्रीन कीबोर्ड' बंद हो जाएगा. + अगर यह नीति गलत पर सेट की जाती है तो, लॉग इन स्क्रीन दिखाए जाने पर 'ऑन-स्क्रीन कीबोर्ड' बंद हो जाएगा. - अगर आप इस नीति को सेट करते हैं तो, उपयोगकर्ता 'ऑन-स्क्रीन कीबोर्ड' को चालू या बंद करके इसे कुछ समय के लिए ओवरराइड कर सकते हैं. हालांकि, उपयोगकर्ता की पसंद हमेशा एक जैसी नहीं होती और हर बार नई लॉगिन स्क्रीन दिखाई देने पर या उपयोगकर्ता के लॉगिन स्क्रीन पर एक मिनट तक कोई गतिविधि न करने पर 'डिफ़ॉल्ट स्थिति' बहाल हो जाती है. + अगर आप इस नीति को सेट करते हैं तो, उपयोगकर्ता 'ऑन-स्क्रीन कीबोर्ड' को चालू या बंद करके इसे कुछ समय के लिए रद्द कर सकते हैं. हालांकि, उपयोगकर्ता की पसंद हमेशा एक जैसी नहीं होती और हर बार नई लॉग इन स्क्रीन दिखाई देने पर या उपयोगकर्ता के लॉग इन स्क्रीन पर एक मिनट तक कोई गतिविधि न करने पर डिफ़ॉल्ट स्थिति बहाल हो जाती है. - अगर यह नीति सेट नहीं की जाती है तो, पहली बार लॉगिन स्क्रीन दिखाए जाने पर 'ऑन-स्क्रीन कीबोर्ड' की सुविधा बंद होती है. उपयोगकर्ता इस सुविधा को किसी भी समय चालू या बंद कर सकते हैं और लॉगिन स्क्रीन पर उपयोगकर्ताओं के लिए यह स्थिति एक जैसी होती है.</translation> + अगर यह नीति सेट नहीं की जाती है तो, पहली बार लॉग इन स्क्रीन दिखाए जाने पर 'ऑन-स्क्रीन कीबोर्ड' की सुविधा बंद होती है. उपयोगकर्ता इस सुविधा को किसी भी समय चालू या बंद कर सकते हैं और लॉग इन स्क्रीन पर उपयोगकर्ताओं के लिए यह स्थिति एक जैसी होती है.</translation> <translation id="6573305661369899995">URL प्रतिबंधों का बाहरी स्रोत सेट करें</translation> <translation id="6598235178374410284">उपयोगकर्ता अवतार चित्र</translation> <translation id="6603004149426829878">समयक्षेत्र का समाधान करने के दौरान सर्वर को हमेशा स्थान के सभी उपलब्ध सिग्नल भेजें</translation> @@ -1924,27 +1938,27 @@ अगर इस नीति को सेट नहीं किया जाता है या सूची खाली है तो, सभी स्कीम को <ph name="PRODUCT_NAME" /> में एक्सेस किया जा सकेगा.</translation> <translation id="6652197835259177259">स्थानीय रूप से प्रबंधित उपयोगकर्ताओं की सेटिंग</translation> -<translation id="6654559957643809067"><ph name="PRODUCT_NAME" /> में नेटवर्क पूर्वानुमान सक्षम करती है और उपयोगकर्ताओं को इस सेटिंग को बदलने से रोकती है. +<translation id="6654559957643809067">यह नीति, <ph name="PRODUCT_NAME" /> में 'नेटवर्क का अनुमान' सुविधा चालू करती है और उपयोगकर्ताओं को इस सेटिंग को बदलने से रोकती है. - यह वेब पृष्ठों की DNS प्रीफ़ेचिंग, TCP और SSL प्री-कनेक्शन और प्रीरेंडरिंग को नियंत्रित करती है. + यह वेब पेजों की डीएनएस प्रीफ़ेचिंग, टीसीपी और एसएसएल प्री-कनेक्शन और प्रीरेंडरिंग को नियंत्रित करती है. - यदि आप इस प्राथमिकता को 'हमेशा', 'कभी नहीं' या 'केवल वाई-फ़ाई' पर सेट करते हैं, तो उपयोगकर्ता <ph name="PRODUCT_NAME" /> में इस सेटिंग को बदल नहीं सकेंगे या इसे ओवरराइड नहीं कर सकेंगे. + अगर आप इस प्राथमिकता को 'हमेशा', 'कभी नहीं' या 'केवल वाई-फ़ाई' पर सेट करते हैं तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में इस सेटिंग को बदल नहीं सकेंगे या इसे ओवरराइड नहीं कर सकेंगे. - यदि यह नीति सेट किए बिना छोड़ दी जाती है, तो नेटवर्क पूर्वानुमान सक्षम हो जाएगा लेकिन उपयोगकर्ता उसे बदल सकेगा.</translation> + अगर यह नीति सेट नहीं की जाती है तो, 'नेटवर्क का अनुमान' सुविधा चालू हो जाएगी लेकिन उपयोगकर्ता उसे बदल सकेगा.</translation> <translation id="6658245400435704251">किसी अपडेट के पहली बार सर्वर पर पुश किए जाने से लेकर किसी डिवाइस द्वारा उसके डाउनलोड में बार-बार किए जाने वाले विलंब की अवधि निर्दिष्ट करता है. डिवाइस दीवार-घड़ी के समय के संबंध में और बाकी के भाग की अपडेट जाँच की संख्या के संबंध में कुछ समय तक प्रतीक्षा कर सकता है. किसी भी स्थिति में, स्कैटर समय के साथ ऊपरी रूप पर परिबद्ध होता है ताकि डिवाइस हमेशा के लिए कभी भी किसी अपडेट के डाउनलोड होने की प्रतीक्षा में अटक न जाए.</translation> -<translation id="6665670272107384733">यह सेट करती है कि झटपट अनलॉक करें का इस्तेमाल करने के लिए उपयोगकर्ता को कितने समय में पासवर्ड डालना होगा</translation> -<translation id="6681229465468164801">वैसी साइट जिन्हें किसी USB डिवाइस के एक्सेस के लिए उपयोगकर्ता से मंज़ूरी मांगने से रोका गया है, उनके लिए यूआरएल पैटर्न की सूची तय करने की सुविधा देती है. +<translation id="6665670272107384733">सेट करें कि तुरंत से अनलॉक करने की सुविधा का इस्तेमाल करने के लिए उपयोगकर्ता को कितने समय में पासवर्ड डालना होगा</translation> +<translation id="6681229465468164801">यह नीति आपको उन 'यूआरएल पैटर्न' की सूची सेट करने देती है जो ऐसी साइटों के बारे में बताते हैं जिन्हें उपयोगकर्ता से किसी यूएसबी डिवाइस के एक्सेस की मंज़ूरी मांगने से रोका गया है. - अगर इस नीति को नहीं जोड़ा जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultWebUsbGuardSetting' नीति सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा. + अगर यह नीति सेट नहीं की जाती है तो, सभी साइटों के लिए 'ग्लोबल डिफ़ॉल्ट मान' का उपयोग किया जाएगा. यह मान, 'DefaultPluginsSetting' नीति सेट होने पर उससे लिया जाएगा वरना उपयोगकर्ता के निजी कॉन्फ़िगरेशन से लिया जाएगा. - इस नीति में दिए गए यूआरएल पैटर्न का टकराव, WebUsbAskForUrls के ज़रिए कॉन्फ़िगर किए गए यूआरएल से नहीं होना चाहिए. हालांकि, यह साफ़ नहीं है कि अगर किसी यूआरएल का दोनों नीतियों से मिलान हो जाता है तो किस नीति को प्राथमिकता दी जाएगी.</translation> + इस नीति में दिया गया 'यूआरएल पैटर्न', WebUsbAskForUrls के ज़रिए कॉन्फ़िगर किए गए यूआरएल जैसा नहीं होना चाहिए. यह नहीं तय किया गया है कि अगर किसी यूआरएल का दोनों नीतियों से मिलान हो जाता है तो किस नीति को प्राथमिकता दी जाएगी.</translation> <translation id="6689792153960219308">हार्डवेयर स्थिति की रिपोर्ट करना</translation> <translation id="6699880231565102694">दूरस्थ पहुंच होस्ट के लिए द्वि-कारक प्रमाणीकरण सक्षम करें</translation> -<translation id="6724842112053619797">अगर आप यह सेटिंग सक्षम करते हैं, तो <ph name="PRODUCT_NAME" /> प्रोफ़ाइल में बुकमार्क, ऑटोमैटिक भरने वाला डेटा, पासवर्ड आदि जैसी संग्रहित सेटिंग भी रोमिंग उपयोगकर्ता प्रोफ़ाइल फ़ोल्डर में संग्रहित किसी फ़ाइल में या <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> नीति के ज़रिए व्यवस्थापक की ओर से तय किए गए किसी स्थान में लिख दी जाएंगी. इस नीति को सक्षम करने पर क्लाउड सिंक को अक्षम कर दिया जाता है. +<translation id="6724842112053619797">अगर आप इस सेटिंग को चालू करते हैं तो, <ph name="PRODUCT_NAME" /> प्रोफ़ाइल में बुकमार्क, अपने आप भरने वाला डेटा और पासवर्ड जैसे इकट्ठा किए गए सेटिंग भी, रोमिंग उपयोगकर्ता प्रोफ़ाइल फ़ोल्डर में जमा किसी फ़ाइल में या <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> नीति के ज़रिए एडमिन की ओर से तय किसी जगह में लिख दी जाएंगी. अगर यह नीति चालू की जाती है तो क्लाउड सिंक बंद हो जाता है. - अगर यह नीति अक्षम है या सेट किए बिना छोड़ दी गई है, तो केवल नियमित स्थानीय प्रोफ़ाइल का उपयोग किया जाएगा. + अगर यह नीति बंद है या सेट किए बिना छोड़ दी गई है तो, सिर्फ़ नियमित स्थानीय प्रोफ़ाइल का उपयोग किया जाएगा. - <ph name="SYNC_DISABLED_POLICY_NAME" /> नीति RoamingProfileSupportEnabled को ओवरराइड करके सभी डेटा सिंक्रनाइज़ेशन अक्षम करती है.</translation> + <ph name="SYNC_DISABLED_POLICY_NAME" /> नीति RoamingProfileSupportEnabled को रद्द करके सभी डेटा सिंक्र प्रक्रिया को बंद करती है.</translation> <translation id="6735701345096330595">वर्तनी जांच की भाषाएं बलपूर्वक चालू करें</translation> <translation id="673699536430961464">यह सेटिंग उपयोगकर्ताओं को अपने <ph name="PRODUCT_OS_NAME" /> डिवाइस पर साइन इन करने के बाद अपनी ब्राउज़र विंडो के सामग्री क्षेत्र में Google खातों के बीच स्विच करने देती है. @@ -1955,25 +1969,25 @@ अगर गुप्त मोड के ज़रिए किसी दूसरे खाते में साइन इन करने की अनुमति नहीं दी जाती है, तो IncognitoModeAvailability नीति का इस्तेमाल करके उस मोड को ब्लॉक करने पर विचार करें. ध्यान दें कि उपयोगकर्ता अपनी कुकी ब्लॉक करके अप्रमाणित स्थिति में Google की सभी सेवाएं एक्सेस कर सकेंगे.</translation> -<translation id="6738326937072482736"><ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट कार्यक्षमता की उपलब्धता और व्यवहार कॉन्फ़िगर करती है. +<translation id="6738326937072482736"><ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट की काम करने की क्षमता की मौजूदगी और व्यवहार को कॉन्फ़िगर करती है. - JSON प्रॉपर्टी में अलग-अलग सेटिंग तय की जा सकती हैं: + जेएसओएन प्रॉपर्टी में अलग-अलग सेटिंग तय की जा सकती हैं: - <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_POWERWASH" />: अगर <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_POWERWASH_TRUE" /> पर सेट की जाती है, तो उपयोगकर्ता <ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट इंस्टॉल करने के लिए पावरवॉश फ़्लो ट्रिगर कर सकेंगे. + <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_POWERWASH" />: अगर <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_POWERWASH_TRUE" /> पर सेट की जाती है तो, उपयोगकर्ता <ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट इंस्टॉल करने के लिए पावरवॉश फ़्लो का शुरू कर सकेंगे. - <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_PRESERVE_DEVICE_STATE" />: अगर <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_PRESERVE_DEVICE_STATE_TRUE" /> पर सेट की जाती है, तो उपयोगकर्ता <ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट फ़्लो शुरू कर पाएंगे जो सभी डिवाइस की स्थिति (एंटरप्राइज़ में नाम दर्ज कराना सहित) सुरक्षित रखता है, लेकिन उपयोगकर्ता का डेटा खो देता है. यह अपडेट फ़्लो, 68 और उसके बाद के वर्शन पर उपलब्ध है. + <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_PRESERVE_DEVICE_STATE" />: अगर <ph name="TPM_FIRMWARE_UPDATE_SETTINGS_ALLOW_USER_INITIATED_PRESERVE_DEVICE_STATE_TRUE" /> पर सेट की जाती है तो, उपयोगकर्ता <ph name="TPM_FIRMWARE_UPDATE_TPM" /> वे फ़र्मवेयर अपडेट फ़्लो शुरू कर पाएंगे जो सभी डिवाइस की स्थिति (एंटरप्राइज़ में नाम दर्ज कराना सहित) सुरक्षित रखता है, लेकिन उपयोगकर्ता का डेटा खो देता है. यह अपडेट फ़्लो, 68 और उसके बाद के वर्शन पर उपलब्ध है. - अगर नीति सेट नहीं की जाती है, तो <ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट कार्यक्षमता उपलब्ध नहीं होगी.</translation> -<translation id="6757438632136860443">आपको ऐसी साइट बताने वाले url पैटर्न की सूची सेट करने देती है, जिन्हें <ph name="FLASH_PLUGIN_NAME" /> प्लग इन चलाने की अनुमति है. + अगर नीति सेट नहीं की जाती है तो, <ph name="TPM_FIRMWARE_UPDATE_TPM" /> फ़र्मवेयर अपडेट की काम करने की क्षमता उपलब्ध नहीं होगी.</translation> +<translation id="6757438632136860443">वैसी साइट जिन्हें <ph name="FLASH_PLUGIN_NAME" /> प्लग इन चलाने की अनुमति है, उनके लिए यूआरएल पैटर्न की सूची सेट करने की सुविधा देती है. - अगर इस नीति को नहीं जोड़ा जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultPluginsSetting' सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> -<translation id="6766216162565713893">साइटों को उपयोगकर्ता से किसी आस-पास के ब्लूटूथ डिवाइस का एक्सेस मांगने की अनुमति दें</translation> + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultPluginsSetting' नीति सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा.</translation> +<translation id="6766216162565713893">साइट को उपयोगकर्ता से किसी आस-पास के ब्लूटूथ डिवाइस का एक्सेस मांगने की अनुमति दें</translation> <translation id="6770454900105963262">सक्रिय कियोस्क सत्रों के बारे में जानकारी की रिपोर्ट करना</translation> <translation id="6786747875388722282">एक्सटेंशन</translation> <translation id="6786967369487349613">रोमिंग प्रोफ़ाइल निर्देशिका सेट करें</translation> <translation id="6810445994095397827">इन साइटों पर JavaScript अवरुद्ध करें</translation> <translation id="681446116407619279">समर्थित प्रमाणीकरण स्कीम</translation> -<translation id="6835883744948188639">उपयोगकर्ता को बार-बार यह सूचित करने वाला संकेत दिखाती है कि फिर से लॉन्च करने का सुझाव दिया गया है</translation> +<translation id="6835883744948188639">उपयोगकर्ता को बार-बार यह सूचित करने वाला संकेत दिखाता है कि फिर से लॉन्च करने का सुझाव दिया गया है</translation> <translation id="6838056959556423778"><ph name="PRODUCT_NAME" /> डिफ़ॉल्ट प्रिंटर चुनने के नियमों को ओवरराइड करती है. यह नीति <ph name="PRODUCT_NAME" /> में डिफ़ॉल्ट प्रिंटर चुनने के नियम तय करती है. चुनने की यह प्रक्रिया 'प्रिंट फ़ंक्शन' को पहली बार किसी प्रोफ़ाइल के साथ इस्तेमाल करने पर सामने आती है. @@ -2006,9 +2020,9 @@ किसी फ़ील्ड को हटाने का मतलब है सभी मानों का मिलान करना, उदाहरण के लिए, कनेक्टिविटी तय नहीं करने से 'प्रिंट की झलक' सभी तरह के प्रिंटर, स्थानीय और क्लाउड प्रिंटर की खोज शुरू कर देगी. रेगुलर एक्सप्रेशन पैटर्न को JavaScript RegExp सिंटैक्स फ़ॉलो करना होगा और मिलान केस संवेदी होते हैं.</translation> <translation id="684856667300805181">इस नीति को <ph name="PRODUCT_NAME" /> 68 में हटा दिया गया है और उसकी जगह <ph name="ARC_GLS_POLICY_NAME" /> ने ले ली है.</translation> -<translation id="6856743875250214792">M66 में इस नीति का समर्थन रोक दिया गया है और इसे हटा दिया गया है, क्योंकि इसका इस्तेमाल केवल आंतरिक परीक्षण के लिए किया जाता था और यह एक सुरक्षा दायित्व है. +<translation id="6856743875250214792">M66 में यह नीति लागू नहीं है और इसे हटा दिया गया है क्योंकि इसका इस्तेमाल सिर्फ़ अंदरूनी जाँच के लिए किया जाता था और सुरक्षा के लिए यह कानूनी तौर पर जवाबदेह है. - यह <ph name="PRODUCT_NAME" /> के शुरू होने पर उसमें लागू होने वाले फ़्लैग बताती है. बताए गए फ़्लैग केवल लॉगिन स्क्रीन पर लागू होते हैं. इस नीति के ज़रिए सेट किए गए फ़्लैग उपयोगकर्ता सत्रों में लागू नहीं होते हैं.</translation> + यह <ph name="PRODUCT_NAME" /> के शुरू होने पर उस पर लागू होने वाले फ़्लैग तय करती है. ये फ़्लैग सिर्फ़ लॉगिन स्क्रीन पर लागू होते हैं. इस नीति के ज़रिए सेट किए गए फ़्लैग 'उपयोगकर्ता सत्रों' पर लागू नहीं होते.</translation> <translation id="685769593149966548">YouTube के लिए सख्त प्रतिबंधित मोड लागू करें</translation> <translation id="686079137349561371">Microsoft Windows 7 या बाद वाले वर्शन</translation> <translation id="687046793986382807">यह नीति <ph name="PRODUCT_NAME" /> वर्शन 35 से समाप्त हो चुकी है. @@ -2021,36 +2035,36 @@ <translation id="6903814433019432303">यह नीति सिर्फ़ रिटेल मोड में काम करती है. उन यूआरएल का समूह तय करती है जो डेमो सत्र के शुरू होने पर लोड होते हैं. यह नीति शुरुआती यूआरएल सेट करने की किसी भी अन्य प्रक्रिया को रद्द कर देगी और सिर्फ़ उसी सत्र पर लागू होगी जो किसी खास उपयोगकर्ता से जुड़ा हुआ नहीं होगा.</translation> -<translation id="6908347296939885026">G Suite में <ph name="PRODUCT_NAME" /> की प्रतिबंधित लॉग इन सुविधा चालू करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. +<translation id="6908347296939885026">G Suite में <ph name="PRODUCT_NAME" /> की पाबंदी वाली लॉग इन सुविधा को चालू करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. - अगर आप यह सेटिंग तय करते हैं, तो उपयोगकर्ता सिर्फ़ खास डोमेन के खातों का इस्तेमाल करके - Google ऐप एक्सेस कर सकेगा (ध्यान रखें कि यह सेटिंग - gmail.com/googlemail.com के लिए काम नहीं करती है). + अगर आप यह सेटिंग तय करते हैं तो, उपयोगकर्ता सिर्फ़ खास डोमेन के खातों का इस्तेमाल करके + ही 'Google ऐप' का एक्सेस कर सकेगा (ध्यान रखें कि यह सेटिंग + gmail.com/googlemail.com पर काम नहीं करती है). यह सेटिंग उपयोगकर्ता को किसी ऐसे प्रबंधित डिवाइस में लॉग इन करने से नहीं रोकेगी - जिसे Google प्रमाणीकरण की ज़रूरत होती है. उपयोगकर्ता को अभी भी अन्य डोमेन के खातों में - साइन इन करने की अनुमति होगी, लेकिन जब वे उन खातों के ज़रिए G Suite का इस्तेमाल - करने की कोशिश करेंगे तो उन्हें गड़बड़ी मिलेगी. + जिसे Google के ज़रिए पहचान साबित करने की ज़रूरत होती है. उपयोगकर्ता को अभी भी अन्य + डोमेन के खातों में साइन इन करने की अनुमति होगी, लेकिन जब वे उन खातों के ज़रिए G Suite + का इस्तेमाल करने की कोशिश करेंगे तो उन्हें गड़बड़ी की सूचना मिलेगी. - अगर आप इस सेटिंग को खाली/कॉन्फ़िगर किए बिना छोड़ देते हैं, तो - उपयोगकर्ता किसी भी खाते से G Suite एक्सेस कर सकेगा. + अगर आप इस सेटिंग को खाली/कॉन्फ़िगर किए बिना छोड़ देते हैं तो, + उपयोगकर्ता किसी भी खाते से G Suite को एक्सेस कर सकेगा. - इस नीति की वजह से X-GoogApps-Allowed-Domains हेडर सभी google.com डोमेन के - सभी HTTP और HTTPS अनुरोधों में जुड़ जाएगा, जैसा कि + इस नीति की वजह से X-GoogApps-Allowed-Domains हेडर google.com डोमेन के + सभी एचटीटीपी और एचटीटीपीएस अनुरोधों में जुड़ जाएगा, जैसा कि https://support.google.com/a/answer/1668854 में बताया गया है. - उपयोगकर्ता इस सेटिंग को बदल या ओवरराइड नहीं कर सकते.</translation> + उपयोगकर्ता इस सेटिंग को बदल या इसे रद्द नहीं कर सकते.</translation> <translation id="6908640907898649429">'डिफ़ॉल्ट खोज सेवा' कॉन्फ़िगर करती है. आप वह 'डिफ़ॉल्ट खोज सेवा' तय कर सकते हैं, उपयोगकर्ता जिसका उपयोग करेगा या जिसे डिफ़ॉल्ट खोज को बंद करने के लिए चुनेगा.</translation> <translation id="6913068954484253496"><ph name="PRODUCT_NAME" /> को सभी आईपी पतों पर कास्ट डिवाइस से कनेक्ट होने देती है.</translation> -<translation id="6915442654606973733">बोले गए फ़ीडबैक पहुंच-योग्यता सुविधा सक्षम करें. +<translation id="6915442654606973733">'कंप्यूटर के बोलकर दिए जाने वाले जवाब' की सुलभता सुविधा चालू करें - यदि यह नीति सही पर सेट है, तो बोले गए फ़ीडबैक को हमेशा सक्षम किया जाएगा. + अगर यह नीति 'सही' पर सेट है तो, 'कंप्यूटर के बोलकर दिए जाने वाले जवाब की सुविधा' हमेशा चालू रहेगी. - यदि यह नीति गलत पर सेट है, तो बोले गए फ़ीडबैक को हमेशा अक्षम किया जाएगा. + अगर यह नीति 'गलत' पर सेट है तो, 'कंप्यूटर के बोलकर दिए जाने वाले जवाब की सुविधा' हमेशा बंद रहेगी. - यदि आप इस नीति को सेट करते हैं, तो उपयोगकर्ता इसे बदल नहीं सकते या ओवरराइड नहीं कर सकते. + अगर आप इस नीति को सेट करते हैं तो, उपयोगकर्ता इसे बदल नहीं सकते या ओवरराइड नहीं कर सकते. - यदि इस नीति को सेट किए बिना छोड़ दिया जाता है, तो बोले गए फ़ीडबैक को आरंभ में अक्षम किया जाता है लेकिन उपयोगकर्ता द्वारा कभी भी सक्षम किया जा सकता है.</translation> + अगर इस नीति को सेट नहीं किया जाता है तो, 'कंप्यूटर के बोलकर दिए जाने वाले जवाब की सुविधा' शुरू में बंद होती है लेकिन उपयोगकर्ता इसे किसी भी समय चालू कर सकता है.</translation> <translation id="6916507170737609563"> आइसोलेशन और उपयोगकर्ताओं के लिए सीमित प्रभाव, इन दोनों का पूरा फ़ायदा उठाने के लिए, आप शायद उन साइटों की सूची के ज़रिए IsolateOriginsAndroid का इस्तेमाल करके IsolateOriginsAndroid नीति सेटिंग पर नज़र डालना चाहें, जिन्हें आप आइसोलेट करना चाहते हैं. यह सेटिंग, SitePerProcessAndroid, सभी साइटों को आइसोलेट करती हैं. अगर नीति चालू हो तो, हर साइट अपनी खुद की प्रक्रिया में चलेगी. @@ -2085,15 +2099,19 @@ <translation id="6943577887654905793">Mac/Linux प्राथमिकता नाम:</translation> <translation id="69525503251220566">डिफ़ॉल्ट खोज प्रदाता के लिए चित्र-द्वारा-खोजें सुविधा प्रदान करने वाला पैरामीटर</translation> <translation id="6956272732789158625">किसी भी साइट को कुंजी जेनरेशन का उपयोग न करने दें</translation> -<translation id="6994082778848658360">यह बताती है कि अगर दूसरे-तरीके से भी पुष्टि इस सुविधा से संगत है, तो उसे उपलब्ध कराने के लिए मौजूदा सुरक्षा तत्व हार्डवेयर का उपयोग किस तरह से किया जा सकता है. उपयोगकर्ता की वास्तविक मौजूदगी का पता लगाने के लिए मशीन के पावर बटन का उपयोग किया जाता है. +<translation id="6994082778848658360">यह नीति बताती है कि अगर मौजूदा सुरक्षा तत्व हार्डवेयर, दो तरीके से पहचान की पुष्टि की सुविधा के साथ काम कर सकता है तो, किस तरह उसका इस्तेमाल कर इस सुविधा का फ़ायदा उठाया जा सकता है. उपयोगकर्ता की मौजूदगी का पता लगाने के लिए मशीन के पावर बटन का उपयोग किया जाता है. - अगर 'अक्षम' को चुना जाता है, तो कोई दूसरा तरीका उपलब्ध नहीं कराया जाता है. + अगर 'बंद' को चुना जाता है तो, कोई दूसरा तरीका उपलब्ध नहीं कराया जाता. - अगर 'U2F' को चुना जाता है, तो एकीकृत दूसरा तरीका FIDO U2F विनिर्देश के अनुसार व्यवहार करेगा. + अगर 'U2F' को चुना जाता है तो, इससे जुड़ा दूसरा तरीका FIDO U2F निर्देश के अनुसार व्यवहार करेगा. - अगर 'U2F_EXTENDED' को चुना जाता है, तो एकीकृत दूसरा तरीका अलग-अलग प्रमाणन के लिए U2F फ़ंक्शन सहित कुछ एक्सटेंशन उपलब्ध कराएगा.</translation> + अगर 'U2F_EXTENDED' को चुना जाता है तो, इससे जुड़ा दूसरा तरीका U2F फ़ंक्शन के साथ-साथ व्यक्तिगत तौर पर पहचान की पुष्टि के लिए कुछ एक्सटेंशन उपलब्ध कराएगा.</translation> <translation id="6997592395211691850">स्थानीय ट्रस्ट एंकर के लिए ऑनलाइन OCSP/CRL जाँच आवश्यक हैं या नहीं</translation> -<translation id="7003334574344702284">यह नीति सक्षम होने पर सहेजे गए पासवर्ड को डिफ़ॉल्ट ब्राउज़र से आयात होने के लिए बाध्य करती है. सक्षम किए जाने पर, यह नीति आयात डॉयलॉग को भी प्रभावित करती है. अक्षम किए जाने पर, सहेजे गए पासवर्ड आयात नहीं किए जाते. यदि इसे सेट नहीं किया जाता है, तो उपयोगकर्ता से आयात करने के लिए पूछा जा सकता है, या आयात स्वतः हो सकता है.</translation> +<translation id="7003334574344702284">अगर यह नीति चालू हो तो, यह सेव किए गए पासवर्ड को पिछले डिफ़ॉल्ट ब्राउज़र से आयात करने के लिए बाध्य करती है. चालू होने पर यह नीति, आयात संबंधी संवाद पर भी असर डालती है. + + अगर बंद हो तो, सेव किए गए पासवर्ड को आयात नहीं किया जाता. + + अगर इसे सेट नहीं किया गया हो तो, उपयोगकर्ता से आयात करने के लिए पूछा जा सकता है या अपने आप आयात किया जा सकता है.</translation> <translation id="7003746348783715221"><ph name="PRODUCT_NAME" /> प्राथमिकताएं</translation> <translation id="7006788746334555276">सामग्री सेटिंग</translation> <translation id="7007671350884342624">यह नीति वह निर्देशिका कॉन्फ़िगर करती है, जिसका उपयोग <ph name="PRODUCT_NAME" /> उपयोगकर्ता का डेटा जमा करने के लिए करेगा. @@ -2103,9 +2121,9 @@ उपयोग किए जा सकने वाले वैरिएबल की सूची देखने के लिए https://www.chromium.org/administrators/policy-list-3/user-data-directory-variables पर जाएं. अगर यह नीति सेट नहीं की जाती है तो, डिफ़ॉल्ट प्रोफ़ाइल पाथ का उपयोग किया जाएगा और उपयोगकर्ता उसे '--disk-cache-dir' कमांड लाइन फ़्लैग की मदद से रद्द कर सकेगा.</translation> -<translation id="7027785306666625591"><ph name="PRODUCT_OS_NAME" /> में पावर प्रबंधन कॉन्फ़िगर करें. +<translation id="7027785306666625591"><ph name="PRODUCT_OS_NAME" /> में पावर प्रबंधन को कॉन्फ़िगर करती है. - ये नीतियां उपयोगकर्ता के कुछ समय तक निष्क्रिय बने रहने पर आपको <ph name="PRODUCT_OS_NAME" /> के व्यवहार करने के तरीके को कॉन्फ़िगर करने देती हैं.</translation> + ये नीतियां यह कॉन्फ़िगर करने में मदद करती हैं कि अगर उपयोगकर्ता कुछ समय तक कोई गतिविधि नहीं करता तो, <ph name="PRODUCT_OS_NAME" /> का बर्ताव कैसा होगा.</translation> <translation id="7040229947030068419">उदाहरण मान:</translation> <translation id="7044883996351280650">Android बैकअप और बहाली सेवा नियंत्रित करती है</translation> <translation id="7049373494483449255">प्रिंट के लिए <ph name="CLOUD_PRINT_NAME" /> में दस्तावेज़ सबमिट करने के लिए <ph name="PRODUCT_NAME" /> को सक्षम करता है. ध्यान दें: यह केवल <ph name="PRODUCT_NAME" /> में <ph name="CLOUD_PRINT_NAME" /> समर्थन को प्रभावित करता है. यह उपयोगकर्ताओं को वेबसाइटों पर प्रिंट कार्य सबमिट करने से नहीं रोकता है. @@ -2113,11 +2131,11 @@ यदि सेटिंग सक्षम है या कॉन्फ़िगर नहीं की गई है, तो उपयोगकर्ता <ph name="PRODUCT_NAME" /> प्रिंट डॉयलॉग से <ph name="CLOUD_PRINT_NAME" /> में प्रिंट कर सकता है. यदि सेटिंग अक्षम है, तो उपयोगकर्ता <ph name="PRODUCT_NAME" /> प्रिंट डॉयलॉग से <ph name="CLOUD_PRINT_NAME" /> में प्रिंट नहीं कर सकता</translation> -<translation id="7053678646221257043">यह नीति सक्षम होने पर वर्तमान डिफ़ॉल्ट ब्राउज़र से बुकमार्क आयातित किए जाने के लिए बाध्य करती है. यदि सक्षम है, तो यह नीति आयात डॉयलॉग को भी प्रभावित कर सकती है. +<translation id="7053678646221257043">अगर यह नीति चालू हो तो, बुकमार्क को मौजूदा डिफ़ॉल्ट ब्राउज़र से लाने के लिए बाध्य करती है. चालू होने पर यह नीति, बुकमार्क लाने के लिए किए जाने वाले संवाद पर भी असर डालती है. - यदि अक्षम है, तो कोई बुकमार्क आयात नहीं किया जाता है. + अगर बंद हो तो, बुकमार्क को लाया नहीं किया जाता. - यदि यह सेट नहीं हो, तो हो सकता है कि उपयोगकर्ता से पूछा जाए कि आयात किया जाए या नहीं, या आयात स्वचालित रूप से हो सकता है.</translation> + अगर इसे सेट नहीं किया गया हो तो, उपयोगकर्ता से बुकमार्क लाने के लिए पूछा जा सकता है या अपने आप लाया जा सकता है.</translation> <translation id="7063895219334505671">इन साइटों पर पॉपअप की अनुमति दें</translation> <translation id="706669471845501145">साइटों को डेस्कटॉप सूचनाएं दिखाने की अनुमति दें</translation> <translation id="7072208053150563108">मशीन से पासवर्ड बदलने की दर</translation> @@ -2131,7 +2149,7 @@ यह नीति उन Windows इंस्टेंस पर उपलब्ध नहीं है जो किसी <ph name="MS_AD_NAME" /> डोमेन से जुड़े हुए नहीं हैं.</translation> <translation id="7079519252486108041">इन साइटों पर पॉपअप अवरुद्ध करें</translation> -<translation id="7085803328069945025">वैसी साइट जिन्हें किसी USB डिवाइस के एक्सेस के लिए उपयोगकर्ता से मंज़ूरी मांगने की अनुमति दी गई है, उनके लिए यूआरएल पैटर्न की सूची तय करने की सुविधा देती है. +<translation id="7085803328069945025">वैसी साइट जिन्हें किसी यूएसबी डिवाइस के एक्सेस के लिए उपयोगकर्ता से मंज़ूरी मांगने की अनुमति दी गई है, उनके लिए यूआरएल पैटर्न की सूची तय करने की सुविधा देती है. अगर इस नीति को नहीं जोड़ा जाता है तो, सभी साइट के लिए वैश्विक डिफ़ॉल्ट मान का इस्तेमाल किया जाएगा. अगर 'DefaultWebUsbGuardSetting' नीति सेट है तो, यह मान इससे लिया जाएगा नहीं तो फिर उपयोगकर्ता के निजी कॉन्फ़िगरेशन का इस्तेमाल किया जाएगा. @@ -2145,13 +2163,13 @@ अगर आप इस सेटिंग को चालू या बंद करते हैं तो, उपयोगकर्ता उसे बदल नहीं सकते या उसे ओवरराइड नहीं कर सकते. अगर नीति सेट नहीं की जाती है तो, उपयोगकर्ता चुन सकता है कि उससे डिवाइस को अनलॉक करने के लिए पासवर्ड मांगा जाए या नहीं.</translation> -<translation id="7115494316187648452">यह नीति तय करती है कि क्या OS लॉगिन पर कोई <ph name="PRODUCT_NAME" /> प्रक्रिया शुरू हुई है और क्या वह पिछले ब्राउज़र के बंद हो जाने पर चलती रहती है, जिससे बैकग्राउंड ऐप्लिकेशन और मौजूदा ब्राउज़िंग सेशन चालू रहें. जिसमें कोई भी सेशन कुकी शामिल है. बैकग्राउंड प्रक्रिया 'सिस्टम ट्रे' में एक आइकॉन दिखाती है और उसे कभी भी वहीं से बंद किया जा सकता है. +<translation id="7115494316187648452">यह नीति तय करती है कि क्या OS लॉगिन पर कोई <ph name="PRODUCT_NAME" /> प्रक्रिया शुरू हुई है और क्या वह पिछले ब्राउज़र के बंद हो जाने पर चलती रहती है, जिससे बैकग्राउंड ऐप्लिकेशन और मौजूदा ब्राउज़िंग सेशन चालू रहें. इसमें कोई भी सेशन कुकी शामिल है. बैकग्राउंड प्रक्रिया 'सिस्टम ट्रे' में एक आइकॉन दिखाती है और उसे वहीं से कभी भी बंद किया जा सकता है. - अगर यह पॉलिसी 'सही' पर सेट होती है तो, बैकग्राउंड मोड चालू किया जाता है और उपयोगकर्ता उसे ब्राउज़र सेटिंग में नियंत्रित नहीं कर सकता है. + अगर यह नीति 'सही' पर सेट होती है तो, बैकग्राउंड मोड चालू हो जाता है और उपयोगकर्ता उसे ब्राउज़र सेटिंग में नियंत्रित नहीं कर सकता. - अगर यह पॉलिसी 'गलत' पर सेट की जाती है तो, बैकग्राउंड मोड बंद कर दिया जाता है और उपयोगकर्ता उसे ब्राउज़र सेटिंग में नियंत्रित नहीं कर सकता है. + अगर यह नीति 'गलत' पर सेट की जाती है तो, बैकग्राउंड मोड बंद हो जाता है और उपयोगकर्ता उसे ब्राउज़र सेटिंग में नियंत्रित नहीं कर सकता. - अगर यह पॉलिसी सेट नहीं की जाती है तो, बैकग्राउंड मोड शुरू में बंद रहता है और उपयोगकर्ता उसे ब्राउज़र सेटिंग में नियंत्रित कर सकता है.</translation> + अगर यह नीति सेट नहीं की जाती है तो, बैकग्राउंड मोड शुरू में बंद रहता है और उपयोगकर्ता उसे ब्राउज़र सेटिंग में नियंत्रित कर सकता है.</translation> <translation id="7126716959063786004">काम का प्रबंधक में प्रक्रियाएं खत्म होना चालू करती है</translation> <translation id="7127892035367404455">टार्गेट वर्शन में रोलबैक करें</translation> <translation id="7128918109610518786">उन ऐप्स पहचानकर्ताओं को सूचीबद्ध करता है जिन्हें <ph name="PRODUCT_OS_NAME" /> द्वारा लॉन्चर बार में पिन किए गए ऐप्स के रूप में दिखाया जाता है. @@ -2169,13 +2187,13 @@ <translation id="7202925763179776247">डाउनलोड से जुड़े प्रतिबंधों की अनुमति दें</translation> <translation id="7207095846245296855">Google सुरक्षित खोज लागू करें</translation> <translation id="7216442368414164495">उपयोगकर्ताओं को सुरक्षित ब्राउज़िंग विस्तारित रिपोर्टिंग की अनुमति देना</translation> -<translation id="7221822638060296742">आपको यह सेट करने देती है कि वेबसाइटों को <ph name="FLASH_PLUGIN_NAME" /> प्लग इन अपने आप चलाने की अनुमति है या नहीं. <ph name="FLASH_PLUGIN_NAME" /> प्लग इन को अपने आप चलाने से सभी वेबसाइट को अनुमति मिल जाएगी या सभी वेबसाइट को अनुमति नहीं मिलेगी. +<translation id="7221822638060296742">यह नीति आपको यह सेट करने देती है कि वेबसाइटों को <ph name="FLASH_PLUGIN_NAME" /> प्लग इन अपने आप चलाने की अनुमति है या नहीं. <ph name="FLASH_PLUGIN_NAME" /> प्लग इन को अपने आप चलाने की अनुमति या तो सभी वेबसाइटों को मिलेगी या किसी को नहीं मिलेगी. - चलाने के लिए क्लिक करने से <ph name="FLASH_PLUGIN_NAME" /> प्लग इन को चलाने की अनुमति मिल जाती है लेकिन उपयोगकर्ता को उसका क्रियान्वयन शुरू करने के लिए प्लेसहोल्डर पर क्लिक करना होगा. + 'चलाने के लिए क्लिक करने' से <ph name="FLASH_PLUGIN_NAME" /> प्लग इन को चलाने की अनुमति मिल जाती है लेकिन उसे चालू करने के लिए उपयोगकर्ता को प्लेसहोल्डर पर क्लिक करना होगा. - अपने आप प्लेबैक की अनुमति सिर्फ़ उन्हीं डोमेन के लिए है जिन्हें <ph name="PLUGINS_ALLOWED_FOR_URLS_POLICY_NAME" /> नीति में खास तौर पर सूची में शामिल किया गया है. अगर आप सभी साइट के लिए अपने आप प्लेबैक की सुविधा चालू करना चाहते हैं तो इस सूची में http://* और https://* जोड़ने पर विचार करें. + अपने आप वीडियो चलने की अनुमति सिर्फ़ उन्हीं डोमेन के लिए है जिन्हें <ph name="PLUGINS_ALLOWED_FOR_URLS_POLICY_NAME" /> नीति में खास तौर पर सूची में शामिल किया गया है. अगर आप सभी साइटों के लिए अपने आप वीडियो चलने की सुविधा चालू करना चाहते हैं तो, इस सूची में http://* और https://* जोड़ें. - अगर यह नीति सेट किए बिना छोड़ दी जाती है, तो उपयोगकर्ता इस सेटिंग को मैन्युअल तरीके से बदल सकेगा.</translation> + अगर यह नीति सेट नहीं है तो, उपयोगकर्ता इस सेटिंग को मैन्युअल तरीके से बदल सकेगा.</translation> <translation id="723103540848640830">लॉक स्क्रीन पिन की सबसे कम लंबाई सेट करती है</translation> <translation id="7234280155140786597">निषिद्ध स्थानीय संदेश सेवा होस्ट के नाम (या * सभी के लिए)</translation> <translation id="7236775576470542603">स्क्रीन मैग्नफाइअर (स्क्रीन पर किसी चीज़ को बड़ा दिखाने वाला) का वह डिफ़ॉल्ट प्रकार सेट करें जिसे लॉग इन स्क्रीन पर चालू किया गया है. @@ -2214,20 +2232,20 @@ यह नीति केवल तभी मान्य होती है अगर 'DefaultSearchProviderEnabled' नीति सक्षम है.</translation> <translation id="7302043767260300182">AC पावर पर चलते समय स्क्रीन लॉक विलंब</translation> -<translation id="7311458740754205918">यदि यह सही पर सेट की हुई है या सेट नहीं की गई है, तो नया टैब पेज उपयोगकर्ता के ब्राउज़िंग इतिहास, रुचियों या स्थान के आधार पर सामग्री के सुझाव दिखा सकता है. +<translation id="7311458740754205918">अगर यह 'सही' पर सेट है या सेट नहीं की गई है तो, 'नया टैब' पेज उपयोगकर्ता के ब्राउज़िंग इतिहास, रुचियों या जगह के आधार पर सामग्री के सुझाव दिखा सकता है. - यदि यह गलत पर सेट की हुई है, तो स्वत: जनरेट होने वाले सामग्री सुझाव, नया टैब पेज पर दिखाए नहीं देते हैं.</translation> + अगर यह 'गलत' पर सेट है तो, अपने आप जनरेट होने वाले सामग्री सुझाव, 'नया टैब' पेज पर दिखाए नहीं देते.</translation> <translation id="7323896582714668701"><ph name="PRODUCT_NAME" /> के लिए कुछ और कमांड लाइन पैरामीटर</translation> -<translation id="7326394567531622570">वाइप करें (मान 2) जैसा ही है, लेकिन यह लॉगिन टोकन सुरक्षित रखने की कोशिश करता है ताकि उपयोगकर्ता को फिर से साइन इन न करना पड़े.</translation> -<translation id="7329842439428490522">बैटरी पावर पर चलते समय, उस समयावधि को निर्दिष्ट करती है जितनी देर तक उपयोगकर्ता कोई भी इनपुट न दे, उसके बाद स्क्रीन बंद हो जाती है. +<translation id="7326394567531622570">'वाइप करें' (मान 2) जैसा ही है लेकिन यह 'लॉगिन टोकन' सुरक्षित रखने की कोशिश करता है ताकि उपयोगकर्ता को फिर से साइन इन न करना पड़े.</translation> +<translation id="7329842439428490522">बैटरी पावर पर चलते समय उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता अगर कोई भी इनपुट नहीं देता है तो, उसके बाद स्क्रीन बंद हो जाती है. - जब यह नीति शून्य से अधिक मान पर सेट की जाती है, तो वह <ph name="PRODUCT_OS_NAME" /> द्वारा स्क्रीन को बंद किए जाने से पहले की उस समयावधि को निर्दिष्ट करती है जिसमें उपयोगकर्ता को प्रयोग में नहीं रहना चाहिए. + जब इस नीति को शून्य से ज़्यादा मान पर सेट किया जाता है तो, यह <ph name="PRODUCT_OS_NAME" /> की ओर से स्क्रीन बंद किए जाने से पहले की उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता कोई गतिविधि नहीं करता. - जब यह नीति शून्य पर सेट की जाती है, तो <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता के प्रयोग में नहीं हो जाने पर स्क्रीन को बंद नहीं करता. + जब इस नीति को शून्य पर सेट किया जाता है तो, उपयोगकर्ता की ओर से कोई गतिविधि नहीं करने के बावजूद <ph name="PRODUCT_OS_NAME" /> स्क्रीन को बंद नहीं करता. - जब यह नीति सेट नहीं की जाती, तो एक डिफ़ॉल्ट समयावधि का उपयोग किया जाता है. + जब यह नीति सेट नहीं की जाती है तो, एक डिफ़ॉल्ट समय सीमा का उपयोग किया जाता है. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए. नीतियों को प्रयोग में नहीं विलंब से कम या उसके बराबर होने के लिए क्लैम्प किया जाता है.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए. मानों को, कोई गतिविधि नहीं में देरी से कम या उसके बराबर पर रखा जाता है.</translation> <translation id="7329968046053403405">यह नीति 'पहचान करने वाले Android ऐप्लिकेशन' के ऐसे खातों का खाता प्रकार तय करती है जिन पर <ph name="HTTP_NEGOTIATE" /> की पहचान करने की सुविधा (जैसे कि Kerberos की पहचान करने की सुविधा) काम करती है. यह जानकारी 'पहचान करने वाले ऐप्लिकेशन' के सप्लायर की तरफ़ से उपलब्ध कराई जानी चाहिए. ज़्यादा जानकारी के लिए https://goo.gl/hajyfN देखें. अगर कोई भी सेटिंग नहीं की जाती है तो, <ph name="HTTP_NEGOTIATE" /> Android पर पहचान करने की सुविधा को बंद कर दिया जाता है.</translation> @@ -2295,11 +2313,11 @@ <translation id="7529144158022474049">स्वतः अपडेट स्कैटर कारक</translation> <translation id="7534199150025803530">इस नीति का Android Google डिस्क ऐप्लिकेशन पर कोई प्रभाव नहीं पड़ता. यदि आप मोबाइल इंटरनेट कनेक्शन पर Google डिस्क का उपयोग रोकना चाहते हैं, तो आपको Android Google डिस्क ऐप्लिकेशन के इंस्टॉलेशन की अनुमति नहीं देनी चाहिए.</translation> <translation id="7547549430720182663">एक बनाएं</translation> -<translation id="7553535237300701827">जब यह नीति सेट की जाती है तो, लॉग इन की पहचान संबंधी प्रक्रिया सेटिंग के मान पर निर्भर करते हुए इनमें से किसी एक तरीके से होगी: +<translation id="7553535237300701827">जब यह नीति सेट की जाती है तो, सेटिंग के मान के आधार पर 'लॉगिन की पहचान से जुड़ी प्रक्रिया' इनमें से एक होगी: - अगर इसे GAIA में सेट किया जाता है तो, लॉग इन सामान्य GAIA पहचान प्रक्रिया के ज़रिए होगा. + अगर इसे GAIA में सेट किया जाता है तो, लॉगिन 'सामान्य GAIA पहचान प्रक्रिया' से होगा. - अगर इसे SAML_INTERSTITIAL में सेट किया जाता है तो, लॉग इन एक ऐसी स्क्रीन दिखाएगा जिसमें उपयोगकर्ता को डिवाइस के नामांकन डोमेन के SAML IdP के ज़रिए पहचान साबित करने के साथ आगे बढ़ने, या सामान्य GAIA लॉग इन प्रक्रिया में वापस जाने का ऑफ़र दिया जाएगा.</translation> + अगर इसे SAML_INTERSTITIAL मेंं सेट किया जाता है तो, लॉगिन एक ऐसी स्क्रीन दिखाएगा जिसमें या तो उपयोगकर्ता को डिवाइस के 'नाम दर्ज करने वाले डोमेन' के SAML IdP के ज़रिए पहचान साबित करके आगे बढ़ने का ऑफ़र दिया जाएगा या फिर 'सामान्य GAIA लॉगिन प्रक्रिया' में वापस जाने का ऑफ़र दिया जाएगा.</translation> <translation id="755951849901630953">सेट नहीं होने या सही पर सेट होने पर <ph name="PRODUCT_NAME" /> में सभी घटकों के लिए घटक के अपडेट चालू करती है. अगर गलत पर सेट किया जाता है, तो घटकों के अपडेट बंद हो जाते हैं. हालांकि, कुछ घटकों पर यह नीति लागू नहीं होती है: ऐसे किसी भी घटक के अपडेट बंद नहीं किए जाते हैं जिसमें एक्ज़ीक्यूटेबल कोड नहीं है या जो ब्राउज़र के व्यवहार में अहम बदलाव नहीं करता है या जो उसकी सुरक्षा के लिए बहुत ज़रूरी है. @@ -2327,7 +2345,11 @@ अगर कोई एक्सटेंशन सूची में नहीं होता है या सूची सेट नहीं की जाती है तो, API (एपीआई) को कॉल नहीं किया जा सकेगा और एक गड़बड़ी कोड मिलेगा.</translation> <translation id="7625444193696794922">उस रिलीज़ चैनल को निर्दिष्ट करती है, जिससे यह डिवाइस लॉक किया जाना चाहिए.</translation> <translation id="7632724434767231364">GSSAPI लाइब्रेरी नाम</translation> -<translation id="7635471475589566552"><ph name="PRODUCT_NAME" /> में ऐप्लिकेशन का स्थान कॉन्फ़िगर करता है और उपयोगकर्ताओं को स्थान बदलने से रोकता है. यदि आप यह सेटिंग सक्षम करते हैं, तो <ph name="PRODUCT_NAME" /> निर्दिष्ट स्थान का उपयोग करता है. यदि कॉन्फ़िगर किया गया स्थान समर्थित नहीं है, तो इसके बजाय 'en-US' का उपयोग किया जाता है. यदि यह सेटिंग अक्षम है या कॉन्फ़िगर नहीं है, तो <ph name="PRODUCT_NAME" /> उपयोगकर्ता द्वारा निर्दिष्ट पसंदीदा स्थान (यदि कॉन्फ़िगर है), सिस्टम स्थान या फ़ॉलबैक स्थान 'en-US' का उपयोग करता है.</translation> +<translation id="7635471475589566552"><ph name="PRODUCT_NAME" /> में ऐप्लिकेशन की स्थान-भाषा कॉन्फ़िगर करता है और उपयोगकर्ताओं को इसे बदलने से रोकता है. + + अगर आप इस सेटिंग को चालू करते हैं तो, <ph name="PRODUCT_NAME" /> बताई गई स्थान-भाषा का उपयोग करता है. अगर कॉन्फ़िगर की गई स्थान-भाषा इस पर काम नहीं करती है तो, इसके बजाय 'en-US' का उपयोग किया जाता है. + + अगर यह सेटिंग बंद है या कॉन्फ़िगर नहीं की गई है तो, <ph name="PRODUCT_NAME" /> या तो उस स्थान-भाषा का इस्तेमाल करता है जिसे उपयोगकर्ता ने तय किया है (अगर कॉन्फ़िगर किया गया है) या फिर, सिस्टम की स्थान-भाषा या फ़ॉलबैक स्थान-भाषा 'en-US' का उपयोग करता है.</translation> <translation id="7641363659597330616">ऐसे डाउनलोड कॉन्फ़िगर करती है जिन्हें <ph name="PRODUCT_NAME" /> पूरी तरह से ब्लॉक कर देगा और उसे इस्तेमाल करने वाले भी सुरक्षा से जुड़े नतीजों में बदलाव नहीं कर पाएंगे. अगर आप इस नीति को सेट करते हैं तो, <ph name="PRODUCT_NAME" /> कुछ खास तरह के डाउनलोड रोक देगा और इस्तेमाल करने वाले लोग सुरक्षा चेतावनियों को नज़रअंदाज़ नहीं कर पाएंगे. @@ -2381,11 +2403,11 @@ इस नीति का उद्देश्य उद्यमों को HTTP/0.9 के मौजूदा सर्वर से बाहर माइग्रेट करने का अवसर देना है और इसे भविष्य में निकाल दिया जाएगा. यदि यह नीति सेट नहीं की जाती है, तो HTTP/0.9 को गैर-डिफ़ॉल्ट पोर्ट पर अक्षम कर दिया जाएगा.</translation> -<translation id="7749402620209366169">दूरस्थ पहुंच होस्ट के लिए किसी उपयोगकर्ता-विशिष्ट पिन के बजाय द्वि-कारक प्रमाणीकरण सक्षम करती है. +<translation id="7749402620209366169">दूर से एक्सेस कर रहे होस्ट के लिए, किसी उपयोगकर्ता के लिए तय खास पिन के बजाय दो तरीकों से पुष्टि को चालू करती है. - यदि यह सेटिंग सक्षम है, तो उपयोगकर्ताओं को किसी होस्ट पर पहुंचने के दौरान कोई मान्य द्वि-कारक कोड प्रदान करना होगा. + अगर यह सेटिंग चालू की जाती है तो, किसी होस्ट को एक्सेस करने के लिए उपयोगकर्ताओं को दो तरीकों से पुष्टि वाला कोई मान्य कोड देना होता है. - यदि यह सेटिंग अक्षम है या सेट नहीं है, तो द्वि-कारक को सक्षम नहीं किया जाएगा और किसी उपयोगकर्ता-विशिष्ट पिन होने का डिफ़ॉल्ट व्यवहार का उपयोग किया जाएगा.</translation> + अगर यह सेटिंग बंद होती है या इसे सेट नहीं किया जाता तो, दो तरीकों से पुष्टि प्रक्रिया को चालू नहीं किया जाएगा और डिफ़ॉल्ट तरीके का इस्तेमाल किया जाएगा. यह तरीका किसी उपयोगकर्ता के लिए तय खास पिन का है.</translation> <translation id="7750991880413385988">नया टैब पेज खोलें</translation> <translation id="7754704193130578113">डाउनलोड करने से पहले प्रत्येक फ़ाइल को सहेजने का स्थान पूछें</translation> <translation id="7761446981238915769">लॉगिन स्क्रीन पर, इंस्टॉल किए गए ऐप्लिकेशन की सूची कॉन्फ़िगर करें</translation> @@ -2531,47 +2553,47 @@ ध्यान दें कि पहले इस नीति को Android पर गलती से चालू कर दिया गया था लेकिन इस कार्यक्षमता ने कभी भी Android पर पूरी तरह से काम नहीं किया.</translation> <translation id="8104962233214241919">इन साइटों के लिए स्वचालित रूप से क्लाइंट प्रमाणपत्रों को चुनें</translation> -<translation id="8112122435099806139">डिवाइस के लिए उपयोग किया जाने वाला घड़ी का प्रारूप निर्दिष्ट करती है. +<translation id="8112122435099806139">डिवाइस के लिए उपयोग किया जाने वाला घड़ी का फ़ॉर्मैट तय करती है. - यह नीति प्रवेश स्क्रीन पर और उपयोगकर्ता सत्रों के लिए डिफ़ॉल्ट के रूप में उपयोग किए जाने वाले घड़ी के प्रारूप को कॉन्फ़िगर करती है. उपयोगकर्ता अभी भी अपने खाते के लिए घड़ी के प्रारूप को ओवरराइड कर सकते हैं. + यह नीति लॉगिन स्क्रीन पर और 'उपयोगकर्ता सत्रों' के लिए डिफ़ॉल्ट के रूप में उपयोग किए जाने वाले घड़ी के फ़ॉर्मैट को कॉन्फ़िगर करती है. उपयोगकर्ता अब भी अपने खाते के लिए घड़ी के फ़ॉर्मैट को ओवरराइड कर सकते हैं. - यदि नीति को सही पर सेट किया जाता है, तो डिवाइस 24 घंटे वाली घड़ी के प्रारूप का उपयोग करेगा. यदि नीति को गलत पर सेट किया जाता है, तो डिवाइस 12 घंटे वाली घड़ी के प्रारूप का उपयोग करेगा. + अगर नीति को 'सही' पर सेट किया जाता है तो, डिवाइस 24 घंटे वाली घड़ी के फ़ॉर्मैट का उपयोग करेगा. अगर नीति को 'गलत' पर सेट किया जाता है तो, डिवाइस 12 घंटे वाली घड़ी के फ़ॉर्मैट का उपयोग करेगा. - यदि इस नीति को सेट नहीं किया जाता है, तो डिवाइस 24 घंटे वाली घड़ी के प्रारूप का उपयोग करेगा.</translation> + अगर इस नीति को सेट नहीं किया जाता है तो, डिवाइस 24 घंटे वाली घड़ी के फ़ॉर्मैट का उपयोग करेगा.</translation> <translation id="8114382167597081590">YouTube पर प्रतिबंधित मोड लागू ना करें</translation> <translation id="8118665053362250806">मीडिया डिस्क संचय आकार सेट करें</translation> <translation id="8124468781472887384">डिवाइस प्रिंटर कॉन्फ़िगरेशन एक्सेस करने की नीति.</translation> -<translation id="8135937294926049787">AC पावर पर चलते समय, उस समयावधि को निर्दिष्ट करती है जितनी देर तक उपयोगकर्ता कोई भी इनपुट न दे, उसके बाद स्क्रीन लॉक हो जाती है. +<translation id="8135937294926049787">एसी पावर पर चलते समय उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता अगर कोई भी इनपुट नहीं देता है तो, उसके बाद स्क्रीन बंद हो जाती है. - जब यह नीति शून्य से अधिक मान पर सेट की जाती है, तो वह <ph name="PRODUCT_OS_NAME" /> द्वारा स्क्रीन को बंद किए जाने से पहले की उस समयावधि को निर्दिष्ट करती है जिसमें उपयोगकर्ता को प्रयोग में नहीं रहना होगा. + जब इस नीति को शून्य से ज़्यादा मान पर सेट किया जाता है तो, यह <ph name="PRODUCT_OS_NAME" /> की ओर से स्क्रीन बंद किए जाने से पहले की उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता कोई गतिविधि नहीं करता. - जब यह नीति शून्य पर सेट की जाती है, तो <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता के प्रयोग में नहीं हो जाने पर स्क्रीन को बंद नहीं करता. + जब इस नीति को शून्य पर सेट किया जाता है तो, उपयोगकर्ता की ओर से कोई गतिविधि नहीं करने के बावजूद <ph name="PRODUCT_OS_NAME" /> स्क्रीन को बंद नहीं करता. - जब यह नीति सेट नहीं की जाती, तो डिफ़ॉल्ट समयावधि का उपयोग किया जाता है. + जब यह नीति सेट नहीं की जाती है तो, एक डिफ़ॉल्ट समय सीमा का उपयोग किया जाता है. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए. मानों को प्रयोग में नहीं विलंब से कम होने के लिए क्लैम्प किया जाता है.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए. मानों को, कोई गतिविधि नहीं में देरी से कम या उसके बराबर पर रखा जाता है.</translation> <translation id="8140204717286305802">नेटवर्क इंटरफ़ेस के प्रकारों और हार्डवेयर पतों सहित उनकी सूची सर्वर को रिपोर्ट करें. यदि नीति गलत पर सेट की गई हो, तो इंटरफ़ेस की रिपोर्ट नहीं की जाएगी.</translation> -<translation id="8141795997560411818">यह नीति उपयोगकर्ता को Android Google डिस्क ऐप्लिकेशन का उपयोग करने से नहीं रोकती. यदि आप Google डिस्क का एक्सेस रोकना चाहते हैं, तो आपको Android Google डिस्क ऐप्लिकेशन के इंस्टॉलेशन की अनुमति देने से भी मना करना चाहिए.</translation> +<translation id="8141795997560411818">यह नीति उपयोगकर्ता को 'Android Google डिस्क ऐप्लिकेशन' का उपयोग करने से नहीं रोकती. अगर आप 'Google डिस्क' का एक्सेस रोकना चाहते हैं तो, आपको 'Android Google डिस्क ऐप्लिकेशन' के इंस्टॉलेशन की अनुमति भी नहीं देनी चाहिए.</translation> <translation id="8146727383888924340">उपयोगकर्ताओं को Chrome OS पंजीकरण के द्वारा ऑफ़र रिडीम करने की अनुमति दें</translation> <translation id="8148785525797916822">जब <ph name="PRODUCT_NAME" /> ऐसे कंप्यूटर या ऑपरेटिंग सिस्टम पर चलाया जा रहा है जो अब समर्थित नहीं है, तो उस समय दिखाई देने वाली चेतावनी को छिपाती है.</translation> -<translation id="8148901634826284024">उच्च कंट्रास्ट मोड वाली पहुंच-योग्यता सुविधा सक्षम करें. +<translation id="8148901634826284024">'हाई कॉन्ट्रास्ट मोड' वाली सुलभता सुविधा चालू करें. - यदि यह नीति सही पर सेट है, तो उच्च कंट्रास्ट मोड हमेशा सक्षम रहेगा. + अगर यह नीति 'सही' पर सेट है तो, 'हाई कॉन्ट्रास्ट मोड' हमेशा चालू रहेगा. - यदि यह नीति गलत पर सेट है, तो उच्च कंट्रास्ट हमेशा अक्षम रहेगा. + अगर यह नीति 'गलत' पर सेट है तो, 'हाई कॉन्ट्रास्ट मोड' हमेशा बंद रहेगा. - यदि आप इस नीति को सेट करते हैं, तो उपयोगकर्ता इसे बदल नहीं सकते या ओवरराइड नहीं कर सकते. + अगर आप इस नीति को सेट करते हैं तो, उपयोगकर्ता इसे बदल नहीं सकते या ओवरराइड नहीं कर सकते. - यदि यह नीति सेट किए बिना छोड़ दी जाती है, तो उच्च कंट्रास्ट आरंभिक रूप से अक्षम हो जाता है लेकिन उपयोगकर्ता द्वारा किसी भी समय सक्षम किया जा सकता है.</translation> -<translation id="815061180603915310">अगर चालू रहने के लिए सेट की जाती है तो, इस पॉलिसी की वजह से प्रोफ़ाइल 'अल्पकालिक मोड' में बदल जाती है. अगर इस पॉलिसी को किसी 'OS पॉलिसी' (जैसे कि Windows पर जीपीओ) के रूप में तय किया जाता है तो यह सिस्टम पर मौजूद हर प्रोफ़ाइल पर लागू होगी; अगर पॉलिसी को 'क्लाउड पॉलिसी' के रूप में सेट किया जाता है तो यह सिर्फ़ किसी प्रबंधित खाते से साइन इन की गई प्रोफ़ाइल पर लागू होगी. + अगर यह नीति सेट नहीं की जाती है तो, 'हाई कॉन्ट्रास्ट मोड' शुरू में बंद होता है लेकिन उपयोगकर्ता इसे किसी भी समय चालू कर सकता है.</translation> +<translation id="815061180603915310">अगर चालू रहने के लिए सेट की जाती है तो, इस नीति की वजह से प्रोफ़ाइल 'अल्पकालिक मोड' में बदल जाती है. अगर इस नीति को किसी 'OS नीति' (जैसे कि Windows पर जीपीओ) के रूप में तय किया जाता है तो यह सिस्टम पर मौजूद हर प्रोफ़ाइल पर लागू होगी; अगर नीति को 'क्लाउड नीति' के रूप में सेट किया जाता है तो यह सिर्फ़ किसी प्रबंधित खाते से साइन इन की गई प्रोफ़ाइल पर लागू होगी. इस मोड में प्रोफ़ाइल डेटा को सिर्फ़ 'उपयोगकर्ता सत्र' की अवधि तक डिस्क पर बनाए रखा जाता है. सुविधाएं, जैसे कि ब्राउज़र इतिहास, एक्सटेंशन और उनका डेटा, वेब डेटा, जैसे कि कुकी और वेब डेटाबेस, ब्राउज़र बंद होने के बाद सेव नहीं रखे जाते हैं. हालांकि इससे उपयोगकर्ता को किसी भी डेटा को डिस्क पर मैन्युअल रूप से डाउनलोड करने, पेज सेव करने या उन्हें प्रिंट करने से नहीं रोका जाता. - अगर उपयोगकर्ता ने 'सिंक की सुविधा' चालू की है तो यह सारा डेटा नियमित प्रोफ़ाइल की तरह ही उसकी सिंक की गई प्रोफ़ाइल में सेव रखा जाता है. अगर खास तौर से पॉलिसी ने बंद नहीं किया है तो, 'गुप्त मोड' भी उपलब्ध होता है. + अगर उपयोगकर्ता ने 'सिंक की सुविधा' चालू की है तो यह सारा डेटा नियमित प्रोफ़ाइल की तरह ही उसकी सिंक की गई प्रोफ़ाइल में सेव रखा जाता है. अगर खास तौर से नीति ने बंद नहीं किया है तो, 'गुप्त मोड' भी उपलब्ध होता है. - अगर पॉलिसी बंद रहने के लिए सेट की जाती है या सेट नहीं की जाती है तो साइन इन करने से नियमित प्रोफ़ाइल खुल जाती हैं.</translation> + अगर नीति बंद रहने के लिए सेट की जाती है या सेट नहीं की जाती है तो साइन इन करने से नियमित प्रोफ़ाइल खुल जाती हैं.</translation> <translation id="8158758865057576716"><ph name="PRODUCT_NAME" /> प्रोफ़ाइल डेटा के लिए रोमिंग कॉपी का निर्माण सक्षम करें.</translation> <translation id="817455428376641507">यूआरएल प्रतिबंध के अपवादों से अलग सूची में मौजूद यूआरएल तक पहुंचने देती है. @@ -2584,14 +2606,14 @@ यह नीति 1000 प्रविष्टियों तक सीमित है; बाद वाली प्रविष्टियों पर ध्यान नहीं दिया जाएगा. अगर यह नीति सेट नहीं है तो, 'URLBlacklist' नीति से पाबंदी वाली सूची में डालने के लिए कोई अपवाद नहीं होंगे.</translation> -<translation id="8176035528522326671">एंटरप्राइज़ उपयोगकर्ता को प्राथमिक रूप से केवल एकाधिक-प्रोफ़ाइल उपयोगकर्ता होने दें (एंटरप्राइज़-प्रबंधित उपयोगकर्ताओं के लिए डिफ़ॉल्ट व्यवहार)</translation> +<translation id="8176035528522326671">'एंटरप्राइज़ उपयोगकर्ता' को सिर्फ़ 'एक से ज़्यादा प्रोफ़ाइल' का प्राथमिक उपयोगकर्ता बनने की अनुमति दें (एंटरप्राइज़-प्रबंधित उपयोगकर्ताओं के लिए डिफ़ॉल्ट व्यवहार)</translation> <translation id="8214600119442850823">पासवर्ड प्रबंधक को कॉन्फ़िगर करती है.</translation> <translation id="8244525275280476362">नीति अमान्यकरण से पहले अधिकतम फ़ेच विलंब</translation> -<translation id="8256688113167012935">अनुरूप डिवाइस-स्थानीय खाते की प्रवेश स्क्रीन पर दिखने वाले खाता नाम <ph name="PRODUCT_OS_NAME" /> को नियंत्रित करता है. +<translation id="8256688113167012935">उस खाता नाम को नियंत्रित करती है जिसे <ph name="PRODUCT_OS_NAME" />, मिलते-जुलते डिवाइस-स्थानीय खाते के लिए लॉग इन स्क्रीन पर दिखाता है. - यदि यह नीति सेट की जाती है, तो प्रवेश स्क्रीन तदनुरूप डिवाइस-स्थानीय खाते के लिए चित्र-आधारित प्रवेश चयनकर्ता में निर्दिष्ट स्ट्रिंग का उपयोग करेगी. + अगर यह नीति सेट की जाती है तो, लॉग इन स्क्रीन मिलते-जुलते डिवाइस-स्थानीय खाते के लिए, तय की गई स्ट्रिंग का इस्तेमाल तस्वीर-आधारित लॉग इन चयनकर्ता में करेगी. - यदि यह नीति सेट किए बिना छोड़ दी जाती है, तो <ph name="PRODUCT_OS_NAME" /> डिवाइस-स्थानीय खाते के ईमेल खाता आईडी का उपयोग प्रवेश स्क्रीन पर प्रदर्शन नाम के रूप में करेगा. + अगर यह नीति सेट किए बिना छोड़ दी जाती है तो, <ph name="PRODUCT_OS_NAME" /> लॉग इन स्क्रीन पर दिखाई देने वाले नाम के रूप में डिवाइस-स्थानीय खाते के ईमेल खाता आईडी का इस्तेमाल करेगा. यह नीति नियमित उपयोगकर्ता खातों के लिए अनदेखी की जाती है.</translation> <translation id="8259375588339409826">क्रोमियम और Google Chrome, दोनों में एक जैसी नीतियां काम करती हैं. कृपया ध्यान रखें कि इस दस्तावेज़ में रिलीज़ नहीं की गई नीतियां शामिल हो सकती हैं (यानी उनकी 'इन पर काम करती हैं' प्रविष्टि का मतलब <ph name="PRODUCT_NAME" /> के किसी ऐसे वर्शन से हो सकता है जिसे अभी तक रिलीज़ नहीं किया गया है) जिन्हें बिना सूचना के बदला या हटाया जा सकता है और जिनके लिए किसी भी तरह की कोई गारंटी नहीं दी जाती है, जिसमें उनकी सुरक्षा और निजता प्रॉपर्टी से जुड़ी कोई गारंटी नहीं देना भी शामिल है. @@ -2632,23 +2654,23 @@ यदि सेट नहीं हो या गलत पर सेट हो, तो उपयोगकर्ता फ़ाइलों को सेल्युलर कनेक्शन के द्वारा Google डिस्क में स्थानान्तरित कर सकेगा.</translation> <translation id="8300992833374611099">यह नियंत्रित करती है कि डेवलपर टूल का इस्तेमाल कहां किया जा सकता है</translation> -<translation id="8312129124898414409">आपको यह सेट करने देती है कि वेबसाइट को कुंजी जेनरेशन का उपयोग करने की अनुमति है या नहीं. कुंजी जेनरेशन का उपयोग करने की अनुमति या तो सभी वेबसाइट के लिए हो सकती है या सभी वेबसाइट के लिए अस्वीकृत की जा सकती है. +<translation id="8312129124898414409">यह सेट करने देती है कि वेबसाइटों को कुंजी जनरेट करने की अनुमति है या नहीं. कुंजी जनरेट करने की अनुमति या तो सभी साइटों के लिए दी जा सकती है या फिर सभी साइटों के लिए खारिज की जा सकती है. - यदि यह पॉलिसी सेट किए बिना छोड़ दी जाती है, तो 'BlockKeygen' का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> -<translation id="8329984337216493753">यह नीति केवल रिटेल मोड में सक्रिय है. + अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, 'BlockKeygen' का उपयोग किया जाएगा और उपयोगकर्ता इसमें बदलाव कर सकेंगे.</translation> +<translation id="8329984337216493753">यह नीति केवल 'रीटेल मोड' में चालू है. - जब DeviceIdleLogoutTimeout निर्दिष्ट किया जाता है तो नीति काउंट डाउन टाइमर के साथ चेतावनी बॉक्स की अवधि परिभाषित करती है जिसे लॉग आउट करने से पहले उपयोगकर्ता को दिखाया जाता है. + जब DeviceIdleLogoutTimeout तय किया जाता है तो यह नीति 'काउंट डाउन टाइमर' के साथ चेतावनी बॉक्स की अवधि तय करती है जिसे उपयोगकर्ता को लॉग आउट करने से पहले दिखाया जाता है. - नीति मान मिलीसेकंड में निर्दिष्ट होना चाहिए.</translation> + नीति मान मिलीसेकंड में तय होना चाहिए.</translation> <translation id="8339420913453596618">दूसरा तरीका अक्षम है</translation> <translation id="8344454543174932833">पहली बार चलाने पर सामान्य ब्राउज़र से बुकमार्क आयात करें</translation> <translation id="8359734107661430198">02/09/2008 से ExampleDeprecatedFeature API (एपीआई) चालू है</translation> <translation id="8369602308428138533">AC पावर पर चलते समय स्क्रीन बंद विलंब</translation> <translation id="8382184662529825177">डिवाइस के लिए सामग्री सुरक्षा के लिए दूरस्थ अनुप्रमाणन के उपयोग को सक्षम करें</translation> <translation id="838870586332499308">डेटा रोमिंग सक्षम करें</translation> -<translation id="8390049129576938611"><ph name="PRODUCT_NAME" /> में पहले से शामिल PDF व्यूअर को बंद करती है. इसके बजाय यह इसे डाउनलोड के रूप में देखती है और इस्तेमाल करने वाले व्यक्ति को डिफ़ॉल्ट ऐप्लिकेशन से PDF फ़ाइलें खोलने की अनुमति देती है. +<translation id="8390049129576938611">यह नीति <ph name="PRODUCT_NAME" /> में 'इंटरनल PDF व्यूअर' बंद करती है. इसके बजाय यह इसे डाउनलोड के रूप में देखता है और उपयोगकर्ता को डिफ़ॉल्ट ऐप्लिकेशन से PDF फ़ाइलें खोलने की अनुमति देता है. - अगर यह नीति सेट नहीं की जाती है या बंद होती है तो, PDF फ़ाइलों को खोलने के लिए तब तक PDF प्लग इन का इस्तेमाल किया जाएगा, जब तक कि इस्तेमाल करने वाला व्यक्ति इसे बंद नहीं कर देता.</translation> + अगर यह नीति सेट नहीं की जाती है या बंद होती है तो, PDF फ़ाइलों को खोलने के लिए तब तक 'PDF प्लग इन' का उपयोग किया जाएगा जब तक कि उपयोगकर्ता इसे बंद नहीं कर देता.</translation> <translation id="8402079500086185021">PDF फ़ाइलों को हमेशा दूसरे टूल/ऐप्लिकेशन में खोलें</translation> <translation id="8412312801707973447">क्या ऑनलाइन OCSP/CRL जाँचें निष्पादित की जा रही हैं</translation> <translation id="8417305981081876834">लॉक स्क्रीन पिन की सबसे ज़्यादा लंबाई सेट करती है</translation> @@ -2657,13 +2679,13 @@ <translation id="8426231401662877819">स्क्रीन को घड़ी की दिशा में 90 डिग्री घुमाएं</translation> <translation id="8433423491036718210">वे एंटरप्राइज़ लॉगिन यूआरएल की सूची कॉन्फ़िगर करें जिनमें पासवर्ड सुरक्षा सेवा को पासवर्ड की फ़िंगरप्रिंट कैप्चर करनी चाहिए.</translation> <translation id="8451988835943702790">मुख्यपेज के रूप में नया टैब पेज का उपयोग करें</translation> -<translation id="8459216513698220096">बताती है कि कंप्यूटर GPO से उपयोगकर्ता नीति को प्रोसेस करना है या नहीं और अगर करना है, तो कैसे करना है. +<translation id="8459216513698220096">यह नीति बताती है कि कंप्यूटर जीपीओ के ज़रिए उपयोगकर्ता नीति को प्रोसेस करना है या नहीं और अगर करना है तो, कैसे करना है. - अगर नीति 'डिफ़ॉल्ट' पर सेट की जाती है या सेट नहीं की जाती है, तो उपयोगकर्ता नीति सिर्फ़ उपयोगकर्ता GPO से पढ़ी जाती है (कंप्यूटर GPO पर ध्यान नहीं दिया जाता है). + अगर नीति 'डिफ़ॉल्ट' पर सेट की जाती है या सेट नहीं की जाती है तो, उपयोगकर्ता नीति सिर्फ़ उपयोगकर्ता जीपीओ से पढ़ी जाती है (कंप्यूटर जीपीओ को अनदेखा किया जाता है). - अगर नीति 'एक बनाएं' पर सेट की जाती है, तो उपयोगकर्ता GPO में मौजूद उपयोगकर्ता नीति को कंप्यूटर GPO की उपयोगकर्ता नीति के साथ एक कर दिया जाता है (कंप्यूटर GPO को प्राथमिकता मिलती है). + अगर नीति 'साथ मिलाएं' पर सेट की जाती है तो, उपयोगकर्ता जीपीओ में मौजूद उपयोगकर्ता नीति को कंप्यूटर जीपीओ की उपयोगकर्ता नीति के साथ मिला दिया जाता है (कंप्यूटर जीपीओ को प्राथमिकता मिलती है). - अगर नीति 'बदलें' पर सेट की जाती है, तो उपयोगकर्ता GPO में मौजूद उपयोगकर्ता नीति को कंप्यूटर GPO की उपयोगकर्ता नीति से बदल दिया जाता है (उपयोगकर्ता GPO पर ध्यान नहीं दिया जाता है).</translation> + अगर नीति 'बदलें' पर सेट की जाती है तो, उपयोगकर्ता जीपीओ में मौजूद उपयोगकर्ता नीति को कंप्यूटर जीपीओ की उपयोगकर्ता नीति से बदल दिया जाता है (उपयोगकर्ता जीपीओ को अनदेखा किया जाता है).</translation> <translation id="8465065632133292531">POST का इस्तेमाल करने वाले इंस्टैंट यूआरएल के पैरामीटर</translation> <translation id="847472800012384958">किसी भी साइट को पॉपअप दिखाने की अनुमति न दें</translation> <translation id="8477885780684655676">TLS 1.0</translation> @@ -2684,7 +2706,7 @@ "1412.24.34": सिर्फ़ इस खास वर्शन में अपडेट करें चेतावनी: वर्शन प्रतिबंधों को कॉन्फ़िगर करने का सुझाव नहीं दिया जाता है क्योंकि वे उपयोगकर्ताओं को सॉफ़्टवेयर अपडेट और महत्वपूर्ण सुरक्षा सुधार पाने से रोक सकते हैं. अपडेट को किसी खास वर्शन के शुरुआती हिस्से तक सीमित करने से उपयोगकर्ता खतरे में पड़ सकता है.</translation> -<translation id="8519264904050090490">प्रबंधित उपयोगकर्ता मैन्युअल अपवाद URL</translation> +<translation id="8519264904050090490">प्रबंधित उपयोगकर्ता मैन्युअल अपवाद यूआरएल</translation> <translation id="8538235451413605457"><ph name="PRODUCT_NAME" /> के सबसे कम अनुमति वाले वर्शन संबंधी ज़रूरतों को कॉन्फ़िगर करती है. नीचे दिए गए वर्शन पुराने माने जाते हैं और डिवाइस तब तक उपयोगकर्ता को साइन इन की अनुमति नहीं देता जब तक कि ऑपरेटिंग सिस्टम को अपडेट नहीं कर लिया जाता. अगर उपयोगकर्ता सत्र के दौरान मौजूदा सत्र पुराना हो जाता है तो, उपयोगकर्ता को जबरन साइन आउट कर दिया जाएगा. @@ -2700,7 +2722,7 @@ अगर इस नीति का इस्तेमाल किया जाता है, तो उपयोगकर्ता को इस नीति की सूची में शामिल आईडी को छोड़कर सभी प्रिंटर उपलब्ध कराए जाते हैं. आईडी, <ph name="BULK_PRINTERS_POLICY" /> में बताई गई फ़ाइल के "id" या "guid" फ़ील्ड के मुताबिक होने चाहिए. </translation> -<translation id="8587229956764455752">नए उपयोगकर्ता खातों के निर्माण की अनुमति दें</translation> +<translation id="8587229956764455752">नए उपयोगकर्ता खातों को बनाने की अनुमति दें</translation> <translation id="8598350264853261122">अगर नीति 'गलत' पर सेट की जाती है तो, उन उपयोगकर्ताओं को एआरसी का इस्तेमाल नहीं करने दिया जाएगा जो इससे जुड़े नहीं हैं. अगर नीति सेट नहीं की जाती है या 'सही' पर सेट की जाती है तो, सभी उपयोगकर्ता एआरसी का इस्तेमाल कर सकते हैं (जब तक कि एआरसी को किसी और तरीके से बंद नहीं कर दिया जाता). @@ -2734,19 +2756,19 @@ <translation id="8704831857353097849">अक्षम प्लग इन की सूची</translation> <translation id="8711086062295757690">कीवर्ड निर्दिष्ट करती है, जो इस प्रदाता के लिए खोज ट्रिगर करने के लिए खोज वाली पट्टी में उपयोग किया गया शॉर्टकट है. यह नीति वैकल्पिक है. यदि यह सेट नहीं है, तो कोई भी कीवर्ड खोज प्रदाता को सक्रिय नहीं कर सकेगा. इस नीति पर केवल तब ही विचार किया जाता है जबकि 'DefaultSearchProviderEnabled' नीति सक्षम है.</translation> <translation id="8731693562790917685">सामग्री सेटिंग आपको विशिष्ट प्रकार की सामग्रियों (उदाहरण के लिए कुकी, चित्र या JavaScript) को प्रबंधित करने के बारे में विवरण देने की सुविधा देती है.</translation> -<translation id="8733448613597049197"><ph name="PRODUCT_NAME" /> की सुरक्षित ब्राउज़िंग अतिरिक्त रिपोर्टिंग को चालू करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. +<translation id="8733448613597049197">यह नीति <ph name="PRODUCT_NAME" /> की 'सुरक्षित ब्राउज़िंग' की 'एक्सटेंडेट रिपोर्टिंग' सुविधा चालू करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. - अतिरिक्त रिपोर्टिंग खतरनाक ऐप्लिकेशन और साइटों का पता लगाने में मदद करने के लिए Google सर्वर को कुछ सिस्टम जानकारी और पेज सामग्री भेजती है. + 'एक्सटेंडेट रिपोर्टिंग' खतरनाक ऐप्लिकेशन और साइटों का पता लगाने में मदद करने के लिए 'Google सर्वर' को कुछ 'सिस्टम जानकारी' और 'पेज सामग्री' भेजती है. - अगर सेटिंग सही पर सेट की गई है, तो रिपोर्ट बनाई जाएंगी और ज़रूरत होने पर भेजी जाएंगी (यानी जब सुरक्षा में कोई हस्तक्षेप दिखाई देता है). + अगर सेटिंग 'सही' पर सेट है तो, रिपोर्ट बनाई जाएंगी और ज़रूरत होने पर भेजी जाएंगी (यानी जब सुरक्षा में कोई गड़बड़ दिखाई देती है). - अगर सेटिंग गलत पर सेट की गई है, तो रिपोर्ट कभी भी नहीं भेजी जाएंगी. + अगर सेटिंग 'गलत' पर सेट है तो, रिपोर्ट कभी भी नहीं भेजी जाएंगी. - अगर इस नीति को सही या गलत पर सेट किया गया है, तो उपयोगकर्ता सेटिंग को बदल नहीं सकेगा. + अगर यह नीति 'सही' या 'गलत' पर सेट है तो, उपयोगकर्ता सेटिंग को बदल नहीं सकेगा. - अगर इस नीति को सेट नहीं किया गया है, तो उपयोगकर्ता सेटिंग बदल सकेगा और यह तय कर सकेगा कि रिपोर्ट भेजी जानी हैं या नहीं. + अगर यह नीति सेट नहीं है तो, उपयोगकर्ता सेटिंग बदल सकेगा और यह तय कर सकेगा कि रिपोर्ट भेजी जाएं या नहीं. - सुरक्षित ब्राउज़िंग के बारे में ज़्यादा जानकारी के लिए https://developers.google.com/safe-browsing देखें.</translation> + 'सुरक्षित ब्राउज़िंग' के बारे में ज़्यादा जानकारी के लिए https://developers.google.com/safe-browsing देखें.</translation> <translation id="8736538322216687231">न्यूनतम YouTube प्रतिबंधित मोड लागू करें</translation> <translation id="8749370016497832113"><ph name="PRODUCT_NAME" /> में ब्राउज़र इतिहास और डाउनलोड इतिहास को हटाना सक्षम करती है तथा उपयोगकर्ताओं को इस सेटिंग को बदलने से रोकती है. @@ -2775,12 +2797,12 @@ <translation id="8818768076343557335">सेल्युलर के अलावा किसी भी नेटवर्क पर नेटवर्क कार्रवाइयों का पूर्वानुमान लगाएं. (50 में बहिष्कृत, 52 में निकाले गए. 52 के बाद, यदि मान 1 सेट किया गया है, तो उसे 0 के रूप में माना जाएगा - किसी भी नेटवर्क कनेक्शन पर नेटवर्क कार्रवाइयों का पूर्वानुमान लगाएं.)</translation> <translation id="8825782996899863372">फ़िशिंग पेज पर पासवर्ड का फिर से इस्तेमाल होने पर पासवर्ड सुरक्षा की ओर से चेतावनी ट्रिगर की गई है</translation> -<translation id="8828766846428537606"><ph name="PRODUCT_NAME" /> में डिफ़ॉल्ट होम पेज को कॉन्फ़िगर करती है और उपयोगकर्ताओं को इसे बदलने से रोकती है. +<translation id="8828766846428537606"><ph name="PRODUCT_NAME" /> में डिफ़ॉल्ट होम पेज कॉन्फ़िगर करती है और उपयोगकर्ताओं को इसे बदलने से रोकती है. उपयोगकर्ताओं की होम पेज सेटिंग सिर्फ़ तभी पूरी तरह से लॉक की जाएगी, जब आप या तो होम पेज को नया टैब पेज बनाने के लिए चुनते हैं, या उसे यूआरएल के रूप में सेट करते हैं और होम पेज यूआरएल बताते हैं. अगर आप होम पेज यूआरएल नहीं बताते हैं, तब भी उपयोगकर्ता 'chrome://newtab' बताकर होम पेज को नए टैब पेज के रूप में सेट कर सकेंगे.</translation> <translation id="8833109046074170275">डिफ़ॉल्ट GAIA प्रवाह के द्वारा प्रमाणीकरण</translation> -<translation id="8838303810937202360"><ph name="PRODUCT_OS_NAME" /> ऐप्लिकेशन और एक्सटेंशन की कैश मेमोरी सेव करता है ताकि किसी एक डिवाइस पर एक से ज़्यादा उपयोगकर्ताओं को उन ऐप्लिकेशन और एक्सटेंशन को बार-बार डाउनलोड करने की ज़रूरत न पड़े. - अगर यह नीति कॉन्फ़िगर नहीं है या मान एक एमबी से कम है तो, <ph name="PRODUCT_OS_NAME" /> कैश मेमोरी सेव करने के लिए डिफ़ॉल्ट आकार का उपयोग करेगा.</translation> +<translation id="8838303810937202360"><ph name="PRODUCT_OS_NAME" /> ऐप्लिकेशन और एक्सटेंशन को कैश मेमोरी में सेव करता है ताकि किसी एक डिवाइस पर एक से ज़्यादा उपयोगकर्ताओं को उन ऐप्लिकेशन और एक्सटेंशन को बार-बार डाउनलोड करने की ज़रूरत न पड़े. + अगर यह नीति कॉन्फ़िगर नहीं है या मान एक एमबी से कम है तो, <ph name="PRODUCT_OS_NAME" /> कैश के डिफ़ॉल्ट आकार का उपयोग करेगा.</translation> <translation id="8858642179038618439">बलपूर्वक YouTube सुरक्षित मोड</translation> <translation id="8860342862142842017">subjectPublicKeyInfo हैश की सूची के लिए 'प्रमाणपत्र पारदर्शिता' लागू किया जाना बंद करें</translation> <translation id="8864975621965365890"><ph name="PRODUCT_FRAME_NAME" /> द्वारा किसी साइट को रेंडर किए जाने पर दिखाई देने वाले टर्नडाउन संकेत को छिपा देती है.</translation> @@ -2810,20 +2832,20 @@ इस समय इन भाषाओं के लिए यह सुविधा मौजूद है: af, bg, ca, cs, da, de, el, en-AU, en-CA, en-GB, en-US, es, es-419, es-AR, es-ES, es-MX, es-US, et, fa, fo, fr, he, hi, hr, hu, id, it, ko, lt, lv, nb, nl, pl, pt-BR, pt-PT, ro, ru, sh, sk, sl, sq, sr, sv, ta, tg, tr, uk, vi.</translation> <translation id="8906768759089290519">मेहमान मोड सक्षम करें</translation> -<translation id="8908294717014659003">आपको यह सेट करने की सुविधा देती है कि वेबसाइटों को मीडिया कैप्चर डिवाइस तक पहुंचने की अनुमति है या नहीं. मीडिया कैप्चर डिवाइस तक पहुंच की अनुमति डिफ़ॉल्ट रूप से दी जा सकती है, या यदि कोई वेबसाइट मीडिया कैप्चर डिवाइस तक पहुंचना चाहती है, तो हर बार उपयोगकर्ता से पूछा जा सकता है. +<translation id="8908294717014659003">यह सेट करने की सुविधा देती है कि वेबसाइटों को मीडिया कैप्चर डिवाइस का एक्सेस करने की अनुमति है या नहीं. मीडिया कैप्चर डिवाइस के एक्सेस की अनुमति डिफ़ॉल्ट रूप से दी जा सकती है, या जब भी कोई वेबसाइट मीडिया कैप्चर डिवाइस का एक्सेस पाना चाहेगी तब-तब उपयोगकर्ता से पूछा जा सकता है. - यदि यह नीति सेट किए बिना छोड़ दी जाती है, तो 'PromptOnAccess' का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> -<translation id="8909280293285028130">AC पावर पर चलते समय, उस समयावधि को निर्दिष्ट करती है जितनी देर तक उपयोगकर्ता कोई भी इनपुट न दे, उसके बाद स्क्रीन लॉक हो जाती है. + अगर यह नीति सेट किए बिना छोड़ दी जाती है तो, 'PromptOnAccess' का उपयोग किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> +<translation id="8909280293285028130">एसी पावर पर चलते समय उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता अगर कोई भी इनपुट नहीं देता है तो, उसके बाद स्क्रीन बंद हो जाती है. - जब इस नीति को शून्य से अधिक के मान पर सेट किया जाता है, तो यह <ph name="PRODUCT_OS_NAME" /> द्वारा स्क्रीन को लॉक किए जाने से पहले की उस समयावधि को निर्दिष्ट करती है जिसमें उपयोगकर्ता को प्रयोग में नहीं रहना होगा. + जब इस नीति को शून्य से ज़्यादा मान पर सेट किया जाता है तो, यह <ph name="PRODUCT_OS_NAME" /> की ओर से स्क्रीन बंद किए जाने से पहले की उस समय सीमा के बारे में बताती है, जितनी देर तक उपयोगकर्ता कोई गतिविधि नहीं करता. - जब इस नीति को शून्य पर सेट किया जाता है, तो उपयोगकर्ता के प्रयोग में नहीं हो जाने पर <ph name="PRODUCT_OS_NAME" /> स्क्रीन को लॉक नहीं करता. + जब इस नीति को शून्य पर सेट किया जाता है तो, उपयोगकर्ता की ओर से कोई गतिविधि नहीं करने के बावजूद <ph name="PRODUCT_OS_NAME" /> स्क्रीन को बंद नहीं करता. - जब इस नीति को सेट नहीं किया जाता, तो एक डिफ़ॉल्ट समयावधि का उपयोग किया जाता है. + जब यह नीति सेट नहीं की जाती है तो, एक डिफ़ॉल्ट समय सीमा का उपयोग किया जाता है. - प्रयोग में नहीं रहने पर स्क्रीन को लॉक करने का सुझाए गए तरीका निलंबन पर स्क्रीन लॉक करना और प्रयोग में नहीं विलंब के बाद <ph name="PRODUCT_OS_NAME" /> को निलंबित करने देना है. इस नीति का उपयोग केवल तभी किया जाना चाहिए जब स्क्रीन लॉकिंग, निलंबन से उपयुक्त समयावधि से पहले हो या जब प्रयोग में नहीं रहने पर निलंबन बिल्कुल भी आवश्यक न हो. + गतिविधि नहीं करने पर स्क्रीन को बंद करने का सुझाया गया तरीका यह है कि निलंबन पर स्क्रीन को बंद किया जाए और गतिविधि नहीं करने में देरी के बाद <ph name="PRODUCT_OS_NAME" /> को निलंबित करने दिया जाए. इस नीति का उपयोग सिर्फ़ तभी किया जाना चाहिए जब स्क्रीन को बंद करना, निलंबन से काफ़ी समय पहले सामने आए या गतिविधि नहीं करने पर निलंबित किया जाना बिल्कुल भी ज़रूरी न हो. - नीति का मान मिलीसेकंड में निर्दिष्ट किया जाना चाहिए. मानों को प्रयोग में नहीं विलंब से कम होने के लिए क्लैम्प किया जाता है.</translation> + नीति का मान मिलीसेकंड में तय किया जाना चाहिए. मानों को, कोई गतिविधि नहीं में देरी से कम या उसके बराबर पर रखा जाता है.</translation> <translation id="891435090623616439">JSON स्ट्रिंग के रूप में एन्कोड किया गया है, विवरण के लिए <ph name="COMPLEX_POLICIES_URL" /> देखें</translation> <translation id="8934944553121392674">यह नियंत्रित करती है कि <ph name="DEVICE_PRINTERS_POLICY" /> से कौन-कौनसे प्रिंटर उपयोगकर्ताओं के लिए उपलब्ध हैं. @@ -2836,15 +2858,15 @@ सही पर सेट होने पर या सेट नहीं की गई होने पर, सिंक सहमति दिखाई जाएगी.</translation> <translation id="8947415621777543415">डिवाइस स्थान की रिपोर्ट करें</translation> <translation id="8951350807133946005">डिस्क संचय निर्देशिका सेट करें</translation> -<translation id="8952317565138994125">Google की ओर से होस्ट की जाने वाली सिंक्रनाइज़ेशन सेवाओं का उपयोग करके <ph name="PRODUCT_NAME" /> में डेटा सिंक्रनाइज़ेशन को बंद करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. +<translation id="8952317565138994125">यह नीति Google की ओर से होस्ट की जाने वाली सिंक सेवाओं का उपयोग करके <ph name="PRODUCT_NAME" /> में डेटा सिंक को बंद करती है और उपयोगकर्ताओं को यह सेटिंग बदलने से रोकती है. - अगर आप इस सेटिंग को चालू करते हैं तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में इस सेटिंग को बदल या रद्द नहीं कर सकते. + अगर आप इस सेटिंग को चालू करते हैं तो, उपयोगकर्ता <ph name="PRODUCT_NAME" /> में इस सेटिंग को बदल नहीं सकते या ओवरराइड नहीं कर सकते. - अगर इस नीति को सेट किए बिना छोड़ दिया जाता है तो, उपयोगकर्ता के लिए Google सिंक सेवा मौजूद रहेगी और इसका उपयोग करना या नहीं करना उपयोगकर्ता पर निर्भर करेगा. + अगर यह नीति सेट नहीं की जाती है तो, उपयोगकर्ता को इसका इस्तेमाल करने या नहीं करने का विकल्प देने के लिए 'Google सिंक' सेवा उपलब्ध होगी. - Google सिंक को पूरी तरह से बंद करने के लिए, यह सुझाव दिया जाता है कि आप Google Admin console में 'Google सिंक' सेवा को बंद करें. + 'Google सिंक' को पूरी तरह से बंद करने के लिए, यह सुझाव दिया जाता है कि आप 'Google एडमिन कंसोल' में 'Google सिंक' सेवा को बंद करें. - जब <ph name="ROAMING_PROFILE_SUPPORT_ENABLED_POLICY_NAME" /> नीति चालू होती है तब इस नीति को चालू नहीं किया जाना चाहिए क्योंकि वह सुविधा काम से जुड़ी एक ही तरह की क्लाइंट साइड शेयर करती है. ऐसी स्थिति में, Google की ओर से होस्ट किया जाने वाला सिंक्रनाइज़ेशन पूरी तरह से बंद हो जाता है.</translation> + जब <ph name="ROAMING_PROFILE_SUPPORT_ENABLED_POLICY_NAME" /> नीति 'चालू' पर सेट होती है तो, इस नीति को चालू नहीं करना चाहिए क्योंकि वह सुविधा वही क्लाइंट साइड फ़ंक्शन शेयर करती है. ऐसे मामले में Google की ओर से होस्ट किया जाने वाला सिंक पूरी तरह से बंद रहता है.</translation> <translation id="8955719471735800169">शीर्ष पर वापस जाएं</translation> <translation id="8959992920425111821">डिफ़ॉल्ट कॉन्फ़िगरेशन</translation> <translation id="8960850473856121830">इस सूची के पैटर्न का मिलान अनुरोध करने वाले यूआरएल के सुरक्षा @@ -2864,13 +2886,13 @@ अगर यह सेटिंग बंद होगी या सेट नहीं की गई होगी, तो पासवर्ड सुरक्षा सेवा सिर्फ़ https://accounts.google.com पर पासवर्ड का फ़िंगरप्रिंट कैप्चर करेगी. यह नीति ऐसे Windows इंस्टेंस पर उपलब्ध नहीं है जो किसी <ph name="MS_AD_NAME" /> डोमेन से जुड़े हुए नहीं हैं.</translation> <translation id="9035964157729712237">प्रतिबंधित सूची से मुक्त किए जाने वाले विस्तार ID</translation> -<translation id="9042911395677044526">प्रति उपयोगकर्ता पर <ph name="PRODUCT_OS_NAME" /> डिवाइस लागू करने के लिए नेटवर्क कॉन्फ़िगरेशन पुश करने दें. नेटवर्क कॉन्फ़िगरेशन <ph name="ONC_SPEC_URL" /> पर वर्णित आपेन नेटवर्क कॉन्फ़िगरेशन स्वरूप द्वारा परिभाषित JSON-स्वरूपित स्ट्रिंग है</translation> +<translation id="9042911395677044526">यह नीति, हर उपयोगकर्ता पर <ph name="PRODUCT_OS_NAME" /> डिवाइस लागू करने के लिए नेटवर्क कॉन्फ़िगरेशन पुश करने देती है. नेटवर्क कॉन्फ़िगरेशन, जेएसओएन के फ़ॉर्मैट की स्ट्रिंग है जिसे 'ओपन नेटवर्क कॉन्फ़िगरेशन' ने तय किया है जो <ph name="ONC_SPEC_URL" /> पर बताया गया है.</translation> <translation id="9084985621503260744">निर्दिष्ट करें कि वीडियो गतिविधि पावर प्रबंधन को प्रभावित करती है या नहीं</translation> -<translation id="9085839450090699752">आपको मिलीसेकंड में वह समय सीमा सेट करने देती है, जिसके दौरान उपयोगकर्ताओं को सूचना दी जाएगी कि <ph name="PRODUCT_NAME" /> को फिर से लॉन्च किया जाना चाहिए या बाकी बचे अपडेट को लागू करने के लिए <ph name="PRODUCT_OS_NAME" /> डिवाइस को रीस्टार्ट किया जाना चाहिए. +<translation id="9085839450090699752">यह नीति आपको वह समयावधि मिलीसेकंड में सेट करने देती है, जिसके दौरान उपयोगकर्ताओं को सूचना दी जाती है कि <ph name="PRODUCT_NAME" /> को फिर से लॉन्च करना चाहिए या बाकी बचे अपडेट को लागू करने के लिए <ph name="PRODUCT_OS_NAME" /> डिवाइस को रीस्टार्ट करना चाहिए. - इस समय सीमा के दौरान, उपयोगकर्ता को अपडेट की ज़रूरत के बारे में बार-बार जानकारी दी जाएगी. <ph name="PRODUCT_OS_NAME" /> डिवाइसों के लिए, कोई अपग्रेड मिलने पर सिस्टम ट्रे में रीस्टार्ट की सूचना दिखाई देती है. सूचना की आधी समय सीमा निकल जाने पर इस सूचना का रंग बदल जाता है और सूचना की समय सीमा पूरी हो जाने पर उसका रंग फिर से बदल जाता है. <ph name="PRODUCT_NAME" /> ब्राउज़रों के लिए, ऐप्लिकेशन मेन्यू में यह बताने के लिए बदलाव हो जाता है कि सूचना की एक-तिहाई समय सीमा निकल जाने पर फिर से लॉन्च करना ज़रूरी है. सूचना की दो-तिहाई समय सीमा निकल जाने पर इस सूचना का रंग बदल जाता है और सूचना की समय सीमा पूरी हो जाने पर उसका रंग फिर से बदल जाता है. ब्राउज़रों के लिए <ph name="RELAUNCH_NOTIFICATION_POLICY_NAME" /> के ज़रिए अलग से चालू की गई सूचनाएं इसी शेड्यूल को फ़ॉलो करती हैं. + इस समयावधि के दौरान, उपयोगकर्ता को अपडेट की ज़रूरत के बारे में बार-बार जानकारी दी जाएगी. <ph name="PRODUCT_OS_NAME" /> डिवाइसों के लिए, कोई अपग्रेड मिलने पर 'सिस्टम ट्रे' में रीस्टार्ट की सूचना दिखाई देती है. सूचना की आधी अवधि निकल जाने पर इस सूचना का रंग बदल जाता है और सूचना की अवधि पूरी हो जाने पर उसका रंग फिर से बदल जाता है. <ph name="PRODUCT_NAME" /> ब्राउज़रों के लिए, ऐप्लिकेशन मेन्यू में यह बताने के लिए बदलाव हो जाता है कि सूचना की एक तिहाई अवधि निकल जाने पर फिर से लॉन्च करना ज़रूरी है. सूचना की दो तिहाई अवधि निकल जाने पर इस सूचना का रंग बदल जाता है और सूचना की अवधि पूरी हो जाने पर उसका रंग फिर से बदल जाता है. ब्राउज़रों के लिए <ph name="RELAUNCH_NOTIFICATION_POLICY_NAME" /> नीति ने अलग से जो सूचनाएं चालू की हैं, वे इसी शेड्यूल को फ़ॉलो करती हैं. - अगर सेट न हो तो, <ph name="PRODUCT_OS_NAME" /> डिवाइसों के लिए 345600000 मिलीसेकंड (चार दिनों) की डिफ़ॉल्ट समय सीमा और ब्राउज़रों के लिए 604800000 मिलीसेकंड (एक हफ़्ते) की समय सीमा का इस्तेमाल किया जाता है.</translation> + यह नीति अगर सेट न हो तो, <ph name="PRODUCT_OS_NAME" /> डिवाइसों के लिए 345600000 मिलीसेकंड (चार दिनों) की डिफ़ॉल्ट अवधि और ब्राउज़रों के लिए 604800000 मिलीसेकंड (एक हफ़्ते) की अवधि का इस्तेमाल किया जाता है.</translation> <translation id="9088433379343318874">निगरानी में रखा गया उपयोगकर्ता सामग्री प्रदाता को सक्षम करें</translation> <translation id="9088444059179765143">स्वचालित समयक्षेत्र की पहचान विधि को कॉन्फ़िगर करें</translation> <translation id="9096086085182305205">प्रमाणीकरण सर्वर श्वेतसूची</translation> @@ -2878,9 +2900,9 @@ <translation id="9105265795073104888">Android ऐप्लिकेशन को प्रॉक्सी कॉन्फ़िगरेशन विकल्पों का सबसेट ही उपलब्ध कराया जाता है. Android ऐप्लिकेशन स्वैच्छिक रूप से प्रॉक्सी का उपयोग करना चुन सकते हैं. आप उन्हें किसी प्रॉक्सी का उपयोग करने के लिए मजबूर नहीं कर सकते हैं.</translation> <translation id="9106865192244721694">इन साइटों पर WebUSB की मंज़ूरी दें</translation> <translation id="9112727953998243860">एंटरप्राइज़ प्रिंटर कॉन्फ़िगरेशन फ़ाइल</translation> -<translation id="9112897538922695510">आपको प्रोटोकॉल प्रबंधकों की सूची रजिस्टर करवाने देती है. यह एक ऐसी नीति ही हो सकती है जो सुझाई गई हो. प्रॉपर्टी के |protocol| को सिर्फ़ 'mailto' जैसी स्कीम पर और |url| को स्कीम का प्रबंधन करने वाले ऐप्लिकेशन के यूआरएल पैटर्न पर ही सेट किया जा सकता है. पैटर्न में '%s' शामिल हो सकता है. अगर यह मौजूद होगा तो उसे प्रबंधित यूआरएल से बदल जिया जाएगा. +<translation id="9112897538922695510">आपको प्रोटोकॉल प्रबंधकों की सूची रजिस्टर करवाने देती है. यह सिर्फ़ एक ऐसी नीति हो सकती है जो सुझाई गई हो. प्रॉपर्टी के |protocol| को सिर्फ़ 'mailto' जैसी स्कीम पर और |url| को स्कीम का प्रबंधन करने वाले ऐप्लिकेशन के यूआरएल पैटर्न पर ही सेट किया जा सकता है. पैटर्न में '%s' शामिल हो सकता है. अगर यह मौजूद होगा तो उसे प्रबंधित यूआरएल से बदल जिया जाएगा. - नीति के तहत रजिस्टर किए गए प्रोटोकॉल प्रबंधक, उपयोगकर्ता के रजिस्टर कराए गए प्रोटोकॉल प्रबंधकों के साथ मिला दिए जाते हैं. उपयोगकर्ता, नए डिफ़ॉल्ट प्रबंधक को इंस्टॉल करके नीति के तहत इंस्टॉल किए गए प्रोटोकॉल प्रबंधकों को ओवरराइड कर सकता है, लेकिन नीति के तहत रजिस्टर कराए गए प्रोटोकॉल प्रबंधक को निकाल नहीं सकता.</translation> + नीति के तहत रजिस्टर किए गए प्रोटोकॉल प्रबंधक, उपयोगकर्ता के रजिस्टर कराए गए प्रोटोकॉल प्रबंधकों के साथ मिला दिए जाते हैं. उपयोगकर्ता, नए डिफ़ॉल्ट प्रबंधक को इंस्टॉल करके नीति के तहत इंस्टॉल किए गए प्रोटोकॉल प्रबंधकों को रद्द कर सकता है, लेकिन नीति के तहत रजिस्टर कराए गए प्रोटोकॉल प्रबंधक को हटा नहीं सकता.</translation> <translation id="9123211093995421438">यह <ph name="PRODUCT_OS_NAME" /> उपलब्धियों की ऐसी कम से कम संख्या तय करती है जिसके लिए किसी भी समय स्थिर वर्शन से रोलबैक शुरू करने की मंज़ूरी दी जानी चाहिए. डिफ़ॉल्ट, उपभोक्ता के लिए 0 है, एंटरप्राइज़ के नाम दर्ज किए हुए डिवाइस के लिए 4 (लगभग एक साल में आधे) है. @@ -2893,13 +2915,13 @@ वास्तविक रोलबैक की संभावनाएं बोर्ड और जटिल जोखिम पैच पर भी निर्भर हो सकती हैं.</translation> <translation id="913195841488580904">URL की सूची तक एक्सेस रोकें</translation> <translation id="9135033364005346124"><ph name="CLOUD_PRINT_NAME" /> प्रॉक्सी सक्षम करें</translation> -<translation id="9136253551939494882">लॉक स्क्रीन को अनलॉक करने के लिए उपयोगकर्ता झटपट अनलॉक करने के किन मोड को कॉन्फ़िगर कर सकता है और किन मोड का उपयोग कर सकता है, इसे एक सूची नियंत्रित करती है. +<translation id="9136253551939494882">लॉक स्क्रीन को अनलॉक करने के लिए उपयोगकर्ता 'झटपट अनलॉक' करने के किन मोड को कॉन्फ़िगर कर सकता है और किन मोड का उपयोग कर सकता है, इसे एक सूची नियंत्रित करती है. - यह मान, स्ट्रिंग की एक सूची होता है; सूची के मान्य आइटम इस प्रकार हैं: "सभी", "पिन". सूची में "सभी" जोड़ने का मतलब यह होता है कि झटपट अनलॉक करने का हर मोड उपयोगकर्ता के लिए उपलब्ध है, जिसमें आने वाले समय में लागू होने वाले मोड शामिल हैं. नहीं तो, सिर्फ़ सूची में मौजूद झटपट अनलॉक करने के मोड ही उपलब्ध होंगे. + यह मान, स्ट्रिंग की एक सूची होता है; सूची के मान्य आइटम ये हैं: "सभी", "पिन". सूची में "सभी" जोड़ने का मतलब यह होता है कि 'झटपट अनलॉक' करने का हर मोड उपयोगकर्ता के लिए उपलब्ध है, जिसमें आने वाले समय में लागू होने वाले मोड शामिल हैं. नहीं तो, सिर्फ़ सूची में मौजूद 'झटपट अनलॉक' करने के मोड उपलब्ध होंगे. - उदाहरण के लिए, झटपट अनलॉक करने के हर मोड को अनुमति देने के लिए, ["सभी"] का उपयोग करें. सिर्फ़ 'पिन अनलॉक' की अनुमति देने के लिए, ["पिन"] का उपयोग करें. झटपट अनलॉक करने के सभी मोड बंद करने के लिए , [] का उपयोग करें. + उदाहरण के लिए, 'झटपट अनलॉक' करने के हर मोड को अनुमति देने के लिए, ["सभी"] का उपयोग करें. सिर्फ़ 'पिन अनलॉक' की अनुमति देने के लिए, ["पिन"] का उपयोग करें. 'झटपट अनलॉक' करने के सभी मोड बंद करने के लिए, [] का उपयोग करें. - डिफ़ॉल्ट रूप से, प्रबंधित डिवाइस के लिए झटपट अनलॉक करने का कोई मोड उपलब्ध नहीं होता है.</translation> + डिफ़ॉल्ट रूप से, प्रबंधित डिवाइस के लिए 'झटपट अनलॉक' करने का कोई मोड उपलब्ध नहीं होता.</translation> <translation id="9136399279941091445">तय की गई डिवाइस नीतियां रिलीज़ किए जाने पर बंद रहने के समय के अंतराल</translation> <translation id="9147029539363974059">व्यवस्थापकों को सिस्टम लॉग की निगरानी करने देने के लिए, प्रबंधन सर्वर को सिस्टम लॉग भेजें. @@ -2907,25 +2929,25 @@ यदि इस पॉलिसी को सत्य पर सेट किया जाता है, तो सिस्टम लॉग भेजे जाएंगे. यदि असत्य सेट किया जाता है या सेट नहीं किया जाता है, तो फिर कोई भी सिस्टम लॉग नहीं भेजा जाएगा.</translation> <translation id="9150416707757015439">यह नीति अनुचित है. कृपया, इसके बजाय IncognitoModeAvailability का उपयोग करें. <ph name="PRODUCT_NAME" /> में गुप्त मोड सक्षम करता है. यदि यह सेटिंग सक्षम की जाती है या कॉन्फ़िगर नहीं की जाती है, तो उपयोगकर्ता गुप्त मोड में वेब पेज खोल सकते हैं. यदि यह सेटिंग अक्षम होती है, तो उपयोगकर्ता गुप्त मोड में वेब पेज नहीं खोल सकते. यदि इस नीति को बिना सेट किए छोड़ दिया जाता है, तो यह सक्षम हो जाएगी और उपयोगकर्ता गुप्त मोड का उपयोग कर सकेंगे.</translation> -<translation id="915194831143859291">अगर यह पॉलिसी फ़र्ज़ी पर सेट होती है या कॉन्फ़िगर नहीं की जाती है, तो <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता को डिवाइस को बंद करने देगा. - अगर यह पॉलिसी सही पर सेट होती है, तो <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता से डिवाइस को बंद करने पर एक रीबूट ट्रिगर करेगा. <ph name="PRODUCT_OS_NAME" /> यूज़र इंटरफ़ेस (यूआई) में शटडाउन बटन की सभी घटनाओं को रीबूट बटनों से बदल देता है. अगर उपयोगकर्ता पावर बटन का उपयोग करके डिवाइस को बंद कर देता है, तो वह अपने आप बूट नहीं होगा, भले ही पॉलिसी हो.</translation> +<translation id="915194831143859291">अगर यह नीति 'गलत' पर सेट है या कॉन्फ़िगर नहीं है तो, <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता को डिवाइस बंद करने देगा. + अगर यह नीति 'सही' पर सेट है तो, <ph name="PRODUCT_OS_NAME" /> उपयोगकर्ता के डिवाइस को बंद करने पर उसे फिर से चालू (रीबूट) कर देगा. <ph name="PRODUCT_OS_NAME" /> यूज़र इंटरफ़ेस (यूआई) में हर बार 'शटडाउन बटन' को 'रीबूट बटन' से बदल देता है. अगर उपयोगकर्ता 'पावर बटन' से डिवाइस को बंद कर देता है तो, वह अपने आप चालू नहीं होगा, भले ही नीति चालू हो.</translation> <translation id="9158929520101169054">ब्राउज़र के अंदर एक से ज़्यादा साइन-इन की अनुमति दें</translation> -<translation id="9165792353046089850">यह सेट करने की सुविधा देती है कि वेबसाइटों को कनेक्ट किए हुए USB डिवाइसों का एक्सेस पाने की मंज़ूरी है या नहीं. एक्सेस पूरी तरह ब्लॉक किया जा सकता है या कोई वेबसाइट कनेक्ट किए हुए USB डिवाइस का एक्सेस पाना चाहती है तो, हर बार उपयोगकर्ता से पूछा जा सकता है. +<translation id="9165792353046089850">आपको यह सेट करने देती है कि वेबसाइटों को कनेक्ट किए हुए यूएसबी डिवाइसों का एक्सेस पाने की मंज़ूरी है या नहीं. एक्सेस पर पूरी तरह रोक लगाई जा सकती है या जब भी कोई वेबसाइट कनेक्ट किए हुए यूएसबी डिवाइस का एक्सेस पाना चाहेगी तो, हर बार उपयोगकर्ता से पूछा जा सकता है. - 'WebUsbAskForUrls' और 'WebUsbBlockedForUrls' नीतियों का इस्तेमाल करके, किन्हीं खास यूआरएल पैटर्न के लिए इस नीति को रद्द किया जा सकता है. + इस नीति को 'WebUsbAskForUrls' और 'WebUsbBlockedForUrls' नीतियों का इस्तेमाल करके खास यूआरएल पैटर्न के लिए रद्द किया जा सकता है. अगर यह नीति सेट किए बिना छोड़ दी जाती है तो, '3' का इस्तेमाल किया जाएगा और उपयोगकर्ता उसे बदल सकेगा.</translation> <translation id="9167719789236691545"><ph name="PRODUCT_OS_NAME" /> फ़ाइल ऐप्लिकेशन में डिस्क को बंद करती है</translation> <translation id="9187743794267626640">बाहरी मेमोरी की माउंटिंग बंद करें</translation> -<translation id="9197740283131855199">मंद होने के बाद उपयोगकर्ता के सक्रिय होने पर, मंद स्क्रीन विलंब को मापने वाला प्रतिशत</translation> +<translation id="9197740283131855199">स्क्रीन की रोशनी कम होने के बाद उपयोगकर्ता कोई गतिविधि करता है तो, स्क्रीन की रोशनी कितनी देर में कम हो, इस समय को स्केल करने (घटाने या बढ़ाने) का प्रतिशत.</translation> <translation id="9200828125069750521">POST इस्तेमाल करने वाले इमेज यूआरएल के लिए पैरामीटर</translation> -<translation id="9210953373038593554">SAML लॉगिन के लिए प्रमाणीकरण का प्रकार कॉन्फ़िगर करती है. +<translation id="9210953373038593554">यह नीति, SAML लॉगिन के लिए 'पहचान करने का प्रकार' कॉन्फ़िगर करती है. - जब यह नीति सेट नहीं की जाती है या इसे डिफ़ॉल्ट (मान 0) पर सेट किया जाता है, तो ब्राउज़र दूसरे कारकों के मुताबिक SAML लॉगिन का व्यवहार तय करता है. ज़्यादातर बुनियादी मामलों में, उपयोगकर्ता प्रमाणीकरण और कैश किए गए उपयोगकर्ता डेटा की सुरक्षा उन पासवर्ड पर आधारित होती है जिन्हें उपयोगकर्ता मैन्युअल रूप से डालते हैं. + जब यह नीति सेट नहीं की जाती है या इसे 'डिफ़ॉल्ट' (मान 0) पर सेट किया जाता है तो, ब्राउज़र दूसरे फ़ैक्टर के मुताबिक SAML लॉगिन का व्यवहार तय करता है. ज़्यादातर बुनियादी मामलों में, उपयोगकर्ता की पहचान और कैश किए गए 'उपयोगकर्ता डेटा' की सुरक्षा उन पासवर्ड पर आधारित होती है जिन्हें उपयोगकर्ता मैन्युअल रूप से डालते हैं. - जब इस नीति को ClientCertificate (मान 1) पर सेट किया जाता है, तो SAML के ज़रिए लॉग इन करने वाले नए जोड़े गए उपयोगकर्ताओं के लिए क्लाइंट प्रमाणपत्र के प्रमाणीकरण का इस्तेमाल किया जाता है. ऐसे उपयोगकर्ताओं के लिए किसी पासवर्ड का इस्तेमाल नहीं किया जाता है और उनका कैश किया गया स्थानीय डेटा उससे जुड़ी क्रिप्टोग्राफ़िक कुंजियों का इस्तेमाल करके सुरक्षित किया जाता है. उदाहरण के लिए, यह सेटिंग स्मार्ट कार्ड आधारित उपयोगकर्ता प्रमाणीकरण कॉन्फ़िगर करने देती है (ध्यान रखें कि स्मार्ट कार्ड मिडिलवेयर ऐप्लिकेशन DeviceLoginScreenAppInstallList नीति के ज़रिए इंस्टॉल होने चाहिए). + जब इस नीति को ClientCertificate (मान 1) पर सेट किया जाता है तो, SAML के ज़रिए लॉग इन करने वाले नए जोड़े गए उपयोगकर्ताओं की पहचान 'क्लाइंट प्रमाणपत्र' से की जाती है. ऐसे उपयोगकर्ताओं के लिए किसी पासवर्ड का इस्तेमाल नहीं किया जाता और उनका कैश किया गया 'स्थानीय डेटा' उससे जुड़ी 'क्रिप्टोग्राफ़िक की' का इस्तेमाल करके सुरक्षित किया जाता है. उदाहरण के लिए, यह सेटिंग, स्मार्ट कार्ड के आधार पर उपयोगकर्ता की पहचान कॉन्फ़िगर करने देती है (ध्यान रखें कि स्मार्ट कार्ड मिडिलवेयर ऐप्लिकेशन, DeviceLoginScreenAppInstallList नीति के ज़रिए इंस्टॉल होने चाहिए). - इस नीति का असर सिर्फ़ उन उपयोगकर्ताओं पर पड़ता है जो SAML का इस्तेमाल करके प्रमाणीकरण करते हैं.</translation> + इस नीति का असर सिर्फ़ उन उपयोगकर्ताओं पर पड़ता है जो पहचान की पुष्टि के लिए SAML का इस्तेमाल करते हैं.</translation> <translation id="9213347477683611358">अगर किसी भी उपयोगकर्ता ने अभी तक डिवाइस में साइन इन नहीं किया है तो, लॉगिन स्क्रीन पर दिखाई गई डिवाइस-लेवल वॉलपेपर इमेज को कॉन्फ़िगर करें. नीति को वह यूआरएल तय करके सेट किया जाता है, जिससे 'Chrome OS डिवाइस' वॉलपेपर इमेज डाउनलोड कर सकता है. डाउनलोड पूरा और सही तरह से हुआ है इसकी पुष्टि करने के लिए क्रिप्टोग्राफ़िक हैश का इस्तेमाल किया जाता है. इमेज जेपीईजी फ़ॉर्मैट में होनी चाहिए, उसकी फ़ाइल का आकार 16MB से ज़्यादा नहीं होना चाहिए. 'पहचान करने की किसी प्रक्रिया' के बिना यूआरएल का एक्सेस होना चाहिए. वॉलपेपर इमेज को डाउनलोड करके कैश के तौर पर सेव किया जाता है. कभी भी यूआरएल या हैश के बदले जाने पर, इसे फिर से डाउलनोड किया जा सकेगा. नीति को एक ऐसी स्ट्रिंग के रूप में तय करना चाहिए, जो यूआरएल और हैश को जेएसओएन (जेसन) फ़ॉर्मैट, उदाहरण के लिए, @@ -2936,6 +2958,7 @@ अगर डिवाइस वॉलपेपर नीति सेट हो और डिवाइस में किसी भी उपयोगकर्ता ने साइन इन न किया हो तो, 'Chrome OS डिवाइस' वॉलपेपर इमेज को डाउनलोड करके लॉग इन स्क्रीन पर उसका उपयोग करेगा. उपयोगकर्ता के साइन इन करने के बाद, उपयोगकर्ता की वॉलपेपर नीति लागू हो जाती है. + अगर डिवाइस वॉलपेपर नीति सेट न हो और उपयोगकर्ता की वॉलपेपर नीति सेट हो तो, क्या दिखाया जाए, यह उपयोगकर्ता की वॉलपेपर नीति से तय किया जाता है.</translation> <translation id="9217154963008402249">नेटवर्क पैकेट मॉनीटर करने की आवृत्ति</translation> <translation id="922540222991413931">एक्सटेंशन, ऐप्लिकेशन और उपयोगकर्ता स्क्रिप्ट को इंस्टॉल करने की मंज़ूरी देने वाले स्रोतों को कॉन्फ़िगर करती है</translation>
diff --git a/components/policy/resources/policy_templates_pt-PT.xtb b/components/policy/resources/policy_templates_pt-PT.xtb index ac1cd5f2..24f31088 100644 --- a/components/policy/resources/policy_templates_pt-PT.xtb +++ b/components/policy/resources/policy_templates_pt-PT.xtb
@@ -218,7 +218,7 @@ Esta política deve estar definida para um URL a partir do qual o <ph name="PRODUCT_OS_NAME" /> possa transferir os Termos de Utilização. Os Termos de Utilização devem estar no formato de texto simples, com o tipo de MIME texto/simples. Não é permitida qualquer marcação.</translation> <translation id="1750315445671978749">Bloquear todas as transferências</translation> <translation id="1781356041596378058">Esta política também controla o acesso às Opções de programador do Android. Se definir esta política como verdadeira, os utilizadores não poderão aceder às Opções de programador. Se definir esta política como falsa ou se não a definir, os utilizadores podem aceder às Opções de programador ao tocar sete vezes no número da compilação na aplicação de definições do Android.</translation> -<translation id="178832255504524723">Configure o URL de alteração da palavra-passe (apenas para esquemas HTTP e HTTPS). O serviço de proteção por palavra-passe envia os utilizadores para este URL para alterarem as respetivas palavras-passe se tiverem sido alvo de phishing. +<translation id="178832255504524723">Configure o URL de alteração da palavra-passe (só funciona em HTTP e HTTPS). O serviço de proteção por palavra-passe envia os utilizadores para este URL para alterarem as respetivas palavras-passe se tiverem sido alvo de phishing. Para que o <ph name="PRODUCT_NAME" /> capture a nova impressão digital da palavra-passe corretamente nesta página de alteração da palavra-passe, certifique-se de que a sua página de início de sessão de alteração da palavra-passe segue as diretrizes apresentadas em https://www.chromium.org/developers/design-documents/create-amazing-password-forms. Se esta definição estiver ativada, o serviço de proteção por palavra-passe envia os utilizadores para este URL para alterarem as respetivas palavras-passe se tiverem sido alvo de phishing. @@ -2434,7 +2434,7 @@ <translation id="8102913158860568230">Predefinição da transmissão em sequência de multimédia</translation> <translation id="8104186956182795918">Permite definir se os Websites têm autorização para apresentar imagens. A apresentação de imagens pode ser autorizada ou negada para todos os Websites. - Se esta política não for definida, é utilizada a definição "AllowImages" e o utilizador pode alterá-la. + Se esta política não for definida, a política "AllowImages" é utilizada e o utilizador pode alterá-la. Tenha em atenção que, embora esta política tenha sido ativada por engano anteriormente no Android, a funcionalidade nunca foi totalmente suportada no Android.</translation> <translation id="8104962233214241919">Selecionar automaticamente certificados de cliente para estes Web sites</translation>
diff --git a/components/policy/resources/policy_templates_vi.xtb b/components/policy/resources/policy_templates_vi.xtb index 78db585..c8961bb 100644 --- a/components/policy/resources/policy_templates_vi.xtb +++ b/components/policy/resources/policy_templates_vi.xtb
@@ -2381,7 +2381,7 @@ Nếu cài đặt này được bật thì người dùng phải cung cấp mã xác thực hai bước hợp lệ khi truy cập vào máy chủ. Nếu cài đặt này bị tắt hoặc không được đặt thì tính năng xác thực hai bước sẽ không được bật và hành vi mặc định là có mã PIN do người dùng xác định sẽ được sử dụng.</translation> -<translation id="7750991880413385988">Mở trang tab mới</translation> +<translation id="7750991880413385988">Mở trang Tab mới</translation> <translation id="7754704193130578113">Hỏi vị trí lưu từng tệp trước khi tải xuống</translation> <translation id="7761446981238915769">Định cấu hình danh sách ứng dụng đã cài đặt trên màn hình đăng nhập</translation> <translation id="7761526206824804472">Đặt một hoặc nhiều ngôn ngữ được đề xuất cho phiên công khai, nhờ đó cho phép người dùng dễ dàng chọn một trong các ngôn ngữ này.
diff --git a/components/previews/content/previews_content_util.cc b/components/previews/content/previews_content_util.cc index a06729a0..48113ed 100644 --- a/components/previews/content/previews_content_util.cc +++ b/components/previews/content/previews_content_util.cc
@@ -101,21 +101,25 @@ return content::PREVIEWS_OFF; } - NOTREACHED() << previews_state; - return previews_state; + DCHECK(previews_state == content::PREVIEWS_OFF || + previews_state == content::PREVIEWS_UNSPECIFIED); + return content::PREVIEWS_OFF; } previews::PreviewsType GetMainFramePreviewsType( content::PreviewsState previews_state) { - if (previews_state & content::SERVER_LITE_PAGE_ON) { + if (previews_state & content::SERVER_LITE_PAGE_ON) return previews::PreviewsType::LITE_PAGE; - } else if (previews_state & content::SERVER_LOFI_ON) { + if (previews_state & content::SERVER_LOFI_ON) return previews::PreviewsType::LOFI; - } else if (previews_state & content::NOSCRIPT_ON) { + if (previews_state & content::NOSCRIPT_ON) return previews::PreviewsType::NOSCRIPT; - } else if (previews_state & content::CLIENT_LOFI_ON) { + if (previews_state & content::CLIENT_LOFI_ON) return previews::PreviewsType::LOFI; - } + + DCHECK_EQ(content::PREVIEWS_UNSPECIFIED, + previews_state & ~content::CLIENT_LOFI_AUTO_RELOAD & + ~content::PREVIEWS_NO_TRANSFORM & ~content::PREVIEWS_OFF); return previews::PreviewsType::NONE; }
diff --git a/components/previews/core/BUILD.gn b/components/previews/core/BUILD.gn index 29af751..438ae14 100644 --- a/components/previews/core/BUILD.gn +++ b/components/previews/core/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "blacklist_data.cc", "blacklist_data.h", + "opt_out_blacklist.cc", + "opt_out_blacklist.h", "previews_amp_converter.cc", "previews_amp_converter.h", "previews_black_list.cc", @@ -44,6 +46,7 @@ source_set("unit_tests") { testonly = true sources = [ + "opt_out_blacklist_unittest.cc", "previews_amp_converter_unittest.cc", "previews_black_list_item_unittest.cc", "previews_black_list_unittest.cc",
diff --git a/components/previews/core/opt_out_blacklist.cc b/components/previews/core/opt_out_blacklist.cc new file mode 100644 index 0000000..4365b94 --- /dev/null +++ b/components/previews/core/opt_out_blacklist.cc
@@ -0,0 +1,223 @@ +// 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/previews/core/opt_out_blacklist.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/metrics/histogram.h" +#include "base/optional.h" +#include "base/strings/stringprintf.h" +#include "base/time/clock.h" +#include "components/previews/core/previews_black_list_delegate.h" +#include "components/previews/core/previews_black_list_item.h" +#include "components/previews/core/previews_opt_out_store.h" +#include "url/gurl.h" + +namespace previews { + +OptOutBlacklist::OptOutBlacklist( + std::unique_ptr<PreviewsOptOutStore> opt_out_store, + base::Clock* clock, + PreviewsBlacklistDelegate* blacklist_delegate) + : loaded_(false), + opt_out_store_(std::move(opt_out_store)), + clock_(clock), + blacklist_delegate_(blacklist_delegate), + weak_factory_(this) { + DCHECK(blacklist_delegate_); +} + +OptOutBlacklist::~OptOutBlacklist() = default; + +void OptOutBlacklist::Init() { + DCHECK(!loaded_); + DCHECK(!blacklist_data_); + base::TimeDelta duration; + size_t history = 0; + int threshold = 0; + + std::unique_ptr<BlacklistData::Policy> session_policy; + if (ShouldUseSessionPolicy(&duration, &history, &threshold)) { + session_policy = + std::make_unique<BlacklistData::Policy>(duration, history, threshold); + } + + std::unique_ptr<BlacklistData::Policy> persistent_policy; + if (ShouldUsePersistentPolicy(&duration, &history, &threshold)) { + persistent_policy = + std::make_unique<BlacklistData::Policy>(duration, history, threshold); + } + + size_t max_hosts = 0; + std::unique_ptr<BlacklistData::Policy> host_policy; + if (ShouldUseHostPolicy(&duration, &history, &threshold, &max_hosts)) { + host_policy = + std::make_unique<BlacklistData::Policy>(duration, history, threshold); + } + + std::unique_ptr<BlacklistData::Policy> type_policy; + if (ShouldUseTypePolicy(&duration, &history, &threshold)) { + type_policy = + std::make_unique<BlacklistData::Policy>(duration, history, threshold); + } + + auto blacklist_data = std::make_unique<BlacklistData>( + std::move(session_policy), std::move(persistent_policy), + std::move(host_policy), std::move(type_policy), max_hosts, + GetAllowedTypes()); + + if (opt_out_store_) { + opt_out_store_->LoadBlackList( + std::move(blacklist_data), + base::BindOnce(&OptOutBlacklist::LoadBlackListDone, + weak_factory_.GetWeakPtr())); + } else { + LoadBlackListDone(std::move(blacklist_data)); + } +} + +base::Time OptOutBlacklist::AddEntry(const std::string& host_name, + bool opt_out, + int type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + base::Time now = clock_->Now(); + + // If the |blacklist_data| has been loaded from |opt_out_store_|, synchronous + // operations will be accurate. Otherwise, queue the task to run + // asynchronously. + if (loaded_) { + AddEntrySync(host_name, opt_out, type, now); + } else { + QueuePendingTask(base::BindOnce(&OptOutBlacklist::AddEntrySync, + base::Unretained(this), host_name, opt_out, + type, now)); + } + + return now; +} + +void OptOutBlacklist::AddEntrySync(const std::string& host_name, + bool opt_out, + int type, + base::Time time) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(loaded_); + + bool host_was_blacklisted = + blacklist_data_->IsHostBlacklisted(host_name, time); + bool user_was_blacklisted = blacklist_data_->IsUserOptedOutInGeneral(time); + blacklist_data_->AddEntry(host_name, opt_out, type, time, false); + + if (!host_was_blacklisted && + blacklist_data_->IsHostBlacklisted(host_name, time)) { + // Notify |blacklist_delegate_| about a new blacklisted host. + blacklist_delegate_->OnNewBlacklistedHost(host_name, time); + } + + if (user_was_blacklisted != blacklist_data_->IsUserOptedOutInGeneral(time)) { + // Notify |blacklist_delegate_| about a new blacklisted host. + blacklist_delegate_->OnUserBlacklistedStatusChange( + blacklist_data_->IsUserOptedOutInGeneral(time)); + } + + if (!opt_out_store_) + return; + opt_out_store_->AddEntry(opt_out, host_name, type, time); +} + +BlacklistReason OptOutBlacklist::IsLoadedAndAllowed( + const std::string& host_name, + int type, + bool ignore_long_term_black_list_rules, + std::vector<BlacklistReason>* passed_reasons) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!loaded_) + return BlacklistReason::kBlacklistNotLoaded; + passed_reasons->push_back(BlacklistReason::kBlacklistNotLoaded); + + return blacklist_data_->IsAllowed(host_name, type, + ignore_long_term_black_list_rules, + clock_->Now(), passed_reasons); +} + +void OptOutBlacklist::ClearBlackList(base::Time begin_time, + base::Time end_time) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_LE(begin_time, end_time); + // If the |blacklist_data| has been loaded from |opt_out_store_|, + // synchronous operations will be accurate. Otherwise, queue the task to run + // asynchronously. + if (loaded_) { + ClearBlackListSync(begin_time, end_time); + } else { + QueuePendingTask(base::BindOnce(&OptOutBlacklist::ClearBlackListSync, + base::Unretained(this), begin_time, + end_time)); + } +} + +void OptOutBlacklist::ClearBlackListSync(base::Time begin_time, + base::Time end_time) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(loaded_); + DCHECK_LE(begin_time, end_time); + + // Clear the in-memory rules entirely. + blacklist_data_->ClearData(); + loaded_ = false; + + // Notify |blacklist_delegate_| that the blacklist is cleared. + blacklist_delegate_->OnBlacklistCleared(clock_->Now()); + + // Delete relevant entries and reload the blacklist into memory. + if (opt_out_store_) { + opt_out_store_->ClearBlackList(begin_time, end_time); + opt_out_store_->LoadBlackList( + std::move(blacklist_data_), + base::BindOnce(&OptOutBlacklist::LoadBlackListDone, + weak_factory_.GetWeakPtr())); + } else { + LoadBlackListDone(std::move(blacklist_data_)); + } +} + +void OptOutBlacklist::QueuePendingTask(base::OnceClosure callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!loaded_); + DCHECK(!callback.is_null()); + pending_callbacks_.push(std::move(callback)); +} + +void OptOutBlacklist::LoadBlackListDone( + std::unique_ptr<BlacklistData> blacklist_data) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(blacklist_data); + DCHECK(!loaded_); + DCHECK(!blacklist_data_); + loaded_ = true; + blacklist_data_ = std::move(blacklist_data); + + // Notify |blacklist_delegate_| on current user blacklisted status. + blacklist_delegate_->OnUserBlacklistedStatusChange( + blacklist_data_->IsUserOptedOutInGeneral(clock_->Now())); + + // Notify the |blacklist_delegate_| on historical blacklisted hosts. + for (const auto& entry : blacklist_data_->black_list_item_host_map()) { + if (blacklist_data_->IsHostBlacklisted(entry.first, clock_->Now())) { + blacklist_delegate_->OnNewBlacklistedHost( + entry.first, entry.second.most_recent_opt_out_time().value()); + } + } + + // Run all pending tasks. |loaded_| may change if ClearBlackList is queued. + while (pending_callbacks_.size() > 0 && loaded_) { + std::move(pending_callbacks_.front()).Run(); + pending_callbacks_.pop(); + } +} + +} // namespace previews
diff --git a/components/previews/core/opt_out_blacklist.h b/components/previews/core/opt_out_blacklist.h new file mode 100644 index 0000000..f5d9ff12 --- /dev/null +++ b/components/previews/core/opt_out_blacklist.h
@@ -0,0 +1,183 @@ +// 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 COMPONENTS_PREVIEWS_CORE_OPT_OUT_BLACKLIST_H_ +#define COMPONENTS_PREVIEWS_CORE_OPT_OUT_BLACKLIST_H_ + +#include <stdint.h> + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/containers/queue.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "base/sequence_checker.h" +#include "base/time/time.h" +#include "components/previews/core/blacklist_data.h" + +namespace base { +class Clock; +} + +namespace previews { + +class BlacklistData; +class PreviewsBlacklistDelegate; +class PreviewsOptOutStore; + +class OptOutBlacklist { + public: + // |opt_out_store| is the backing store to retrieve and store blacklist + // information, and can be null. When |opt_out_store| is null, the in-memory + // data will be immediately loaded to empty. If |opt_out_store| is non-null, + // it will be used to load the in-memory map asynchronously. + // |blacklist_delegate| is a single object listening for blacklist events, and + // it is guaranteed to outlive the life time of |this|. + OptOutBlacklist(std::unique_ptr<PreviewsOptOutStore> opt_out_store, + base::Clock* clock, + PreviewsBlacklistDelegate* blacklist_delegate); + virtual ~OptOutBlacklist(); + + // Creates the BlacklistData that backs the blacklist. + void Init(); + + // Asynchronously deletes all entries in the in-memory blacklist. Informs + // the backing store to delete entries between |begin_time| and |end_time|, + // and reloads entries into memory from the backing store. If the embedder + // passed in a null store, resets all history in the in-memory blacklist. + void ClearBlackList(base::Time begin_time, base::Time end_time); + + // Asynchronously adds a new navigation to to the in-memory blacklist and + // backing store. |opt_out| is whether the user opted out of the action. If + // the in memory map has reached the max number of hosts allowed, and + // |host_name| is a new host, a host will be evicted based on recency of the + // hosts most recent opt out. It returns the time used for recording the + // moment when the navigation is added for logging. + base::Time AddEntry(const std::string& host_name, bool opt_out, int type); + + // Synchronously determines if the action should be allowed for |host_name| + // and |type|. Returns the reason the blacklist disallowed the action, or + // kAllowed if the preview is allowed. Record checked reasons in + // |passed_reasons|. |ignore_long_term_black_list_rules| will cause session, + // type, and host rules, but the session rule will still be queried. + BlacklistReason IsLoadedAndAllowed( + const std::string& host_name, + int type, + bool ignore_long_term_black_list_rules, + std::vector<BlacklistReason>* passed_reasons) const; + + protected: + // Whether the session rule should be enabled. |duration| specifies how long a + // user remains blacklisted. |history| specifies how many entries should be + // evaluated; |threshold| specifies how many opt outs would cause + // blacklisting. I.e., the most recent |history| are looked at and if + // |threshold| (or more) of them are opt outs, the user is considered + // blacklisted unless the most recent opt out was longer than |duration| ago. + // This rule only considers entries within this session (it does not use the + // data that was persisted in previous sessions). When the blacklist is + // cleared, this rule is reset as if it were a new session. Queried in Init(). + virtual bool ShouldUseSessionPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const = 0; + + // Whether the persistent rule should be enabled. |duration| specifies how + // long a user remains blacklisted. |history| specifies how many entries + // should be evaluated; |threshold| specifies how many opt outs would cause + // blacklisting. I.e., the most recent |history| are looked at and if + // |threshold| (or more) of them are opt outs, the user is considered + // blacklisted unless the most recent opt out was longer than |duration| ago. + // Queried in Init(). + virtual bool ShouldUsePersistentPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const = 0; + + // Whether the host rule should be enabled. |duration| specifies how long a + // host remains blacklisted. |history| specifies how many entries should be + // evaluated per host; |threshold| specifies how many opt outs would cause + // blacklisting. I.e., the most recent |history| entries per host are looked + // at and if |threshold| (or more) of them are opt outs, the host is + // considered blacklisted unless the most recent opt out was longer than + // |duration| ago. |max_hosts| will limit the number of hosts stored in this + // class when non-zero. + // Queried in Init(). + virtual bool ShouldUseHostPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold, + size_t* max_hosts) const = 0; + + // Whether the type rule should be enabled. |duration| specifies how long a + // type remains blacklisted. |history| specifies how many entries should be + // evaluated per type; |threshold| specifies how many opt outs would cause + // blacklisting. + // I.e., the most recent |history| entries per type are looked at and if + // |threshold| (or more) of them are opt outs, the type is considered + // blacklisted unless the most recent opt out was longer than |duration| ago. + // Queried in Init(). + virtual bool ShouldUseTypePolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const = 0; + + // The allowed types and what version they are. Should be empty unless the + // caller will not be using the blacklist in the session. It is used to remove + // stale entries from the database and to DCHECK that other methods are not + // using disallowed types. Queried in Init(). + virtual BlacklistData::AllowedTypesAndVersions GetAllowedTypes() const = 0; + + private: + // Synchronous version of AddEntry method. |time| is the time + // stamp of when the navigation was determined to be an opt-out or non-opt + // out. + void AddEntrySync(const std::string& host_name, + bool opt_out, + int type, + base::Time time); + + // Synchronous version of ClearBlackList method. + void ClearBlackListSync(base::Time begin_time, base::Time end_time); + + // Callback passed to the backing store when loading black list information. + // Takes ownership of |blacklist_data|. + void LoadBlackListDone(std::unique_ptr<BlacklistData> blacklist_data); + + // Called while waiting for the blacklist to be loaded from the backing + // store. + // Enqueues a task to run when when loading blacklist information has + // completed. Maintains the order that tasks were called in. + void QueuePendingTask(base::OnceClosure callback); + + // An in-memory representation of the various rules of the blacklist. This is + // null while reading from the backing store. + std::unique_ptr<BlacklistData> blacklist_data_; + + // Whether the blacklist is done being loaded from the backing store. + bool loaded_; + + // The backing store of the blacklist information. + std::unique_ptr<PreviewsOptOutStore> opt_out_store_; + + // Callbacks to be run after loading information from the backing store has + // completed. + base::queue<base::OnceClosure> pending_callbacks_; + + base::Clock* clock_; + + // The delegate listening to this blacklist. |blacklist_delegate_| lifetime is + // guaranteed to outlive |this|. + PreviewsBlacklistDelegate* blacklist_delegate_; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<OptOutBlacklist> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(OptOutBlacklist); +}; + +} // namespace previews + +#endif // COMPONENTS_PREVIEWS_CORE_OPT_OUT_BLACKLIST_H_
diff --git a/components/previews/core/opt_out_blacklist_unittest.cc b/components/previews/core/opt_out_blacklist_unittest.cc new file mode 100644 index 0000000..b24fd36b --- /dev/null +++ b/components/previews/core/opt_out_blacklist_unittest.cc
@@ -0,0 +1,1191 @@ +// 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/previews/core/opt_out_blacklist.h" + +#include <algorithm> +#include <map> +#include <memory> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/simple_test_clock.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "components/previews/core/previews_black_list_delegate.h" +#include "components/previews/core/previews_black_list_item.h" +#include "components/previews/core/previews_opt_out_store.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace previews { + +namespace { + +const char kTestHost1[] = "testhost1.com"; +const char kTestHost2[] = "testhost2.com"; + +// Mock class to test that OptOutBlacklist notifies the delegate with correct +// events (e.g. New host blacklisted, user blacklisted, and blacklist cleared). +class TestPreviewsBlacklistDelegate : public PreviewsBlacklistDelegate { + public: + TestPreviewsBlacklistDelegate() + : user_blacklisted_(false), + blacklist_cleared_(false), + blacklist_cleared_time_(base::Time::Now()) {} + + // PreviewsBlacklistDelegate: + void OnNewBlacklistedHost(const std::string& host, base::Time time) override { + blacklisted_hosts_[host] = time; + } + void OnUserBlacklistedStatusChange(bool blacklisted) override { + user_blacklisted_ = blacklisted; + } + void OnBlacklistCleared(base::Time time) override { + blacklist_cleared_ = true; + blacklist_cleared_time_ = time; + } + + // Gets the set of blacklisted hosts recorded. + const std::unordered_map<std::string, base::Time>& blacklisted_hosts() const { + return blacklisted_hosts_; + } + + // Gets the state of user blacklisted status. + bool user_blacklisted() const { return user_blacklisted_; } + + // Gets the state of blacklisted cleared status of |this| for testing. + bool blacklist_cleared() const { return blacklist_cleared_; } + + // Gets the event time of blacklist is as cleared. + base::Time blacklist_cleared_time() const { return blacklist_cleared_time_; } + + private: + // The user blacklisted status of |this| blacklist_delegate. + bool user_blacklisted_; + + // Check if the blacklist is notified as cleared on |this| blacklist_delegate. + bool blacklist_cleared_; + + // The time when blacklist is cleared. + base::Time blacklist_cleared_time_; + + // |this| blacklist_delegate's collection of blacklisted hosts. + std::unordered_map<std::string, base::Time> blacklisted_hosts_; +}; + +class TestPreviewsOptOutStore : public PreviewsOptOutStore { + public: + TestPreviewsOptOutStore() : clear_blacklist_count_(0) {} + ~TestPreviewsOptOutStore() override {} + + int clear_blacklist_count() { return clear_blacklist_count_; } + + void SetBlacklistData(std::unique_ptr<BlacklistData> data) { + data_ = std::move(data); + } + + private: + // PreviewsOptOutStore implementation: + void AddEntry(bool opt_out, + const std::string& host_name, + int type, + base::Time now) override {} + + void LoadBlackList(std::unique_ptr<BlacklistData> blacklist_data, + LoadBlackListCallback callback) override { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(std::move(callback), + data_ ? std::move(data_) : std::move(blacklist_data))); + } + + void ClearBlackList(base::Time begin_time, base::Time end_time) override { + ++clear_blacklist_count_; + } + + int clear_blacklist_count_; + + std::unique_ptr<BlacklistData> data_; +}; + +class TestOptOutBlacklist : public OptOutBlacklist { + public: + TestOptOutBlacklist(std::unique_ptr<PreviewsOptOutStore> opt_out_store, + base::Clock* clock, + PreviewsBlacklistDelegate* blacklist_delegate) + : OptOutBlacklist(std::move(opt_out_store), clock, blacklist_delegate) {} + ~TestOptOutBlacklist() override {} + + void SetSessionRule(std::unique_ptr<BlacklistData::Policy> policy) { + session_policy_ = std::move(policy); + } + + void SetPersistentRule(std::unique_ptr<BlacklistData::Policy> policy) { + persistent_policy_ = std::move(policy); + } + + void SetHostRule(std::unique_ptr<BlacklistData::Policy> policy, + size_t max_hosts) { + host_policy_ = std::move(policy); + max_hosts_ = max_hosts; + } + + void SetTypeRule(std::unique_ptr<BlacklistData::Policy> policy) { + type_policy_ = std::move(policy); + } + + void SetAllowedTypes(BlacklistData::AllowedTypesAndVersions allowed_types) { + allowed_types_ = std::move(allowed_types); + } + + private: + bool ShouldUseSessionPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const override { + if (!session_policy_) + return false; + *duration = session_policy_->duration; + *history = session_policy_->history; + *threshold = session_policy_->threshold; + + return true; + } + + bool ShouldUsePersistentPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const override { + if (!persistent_policy_) + return false; + *duration = persistent_policy_->duration; + *history = persistent_policy_->history; + *threshold = persistent_policy_->threshold; + + return true; + } + + bool ShouldUseHostPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold, + size_t* max_hosts) const override { + if (!host_policy_) + return false; + *duration = host_policy_->duration; + *history = host_policy_->history; + *threshold = host_policy_->threshold; + *max_hosts = max_hosts_; + + return true; + } + + bool ShouldUseTypePolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const override { + if (!type_policy_) + return false; + *duration = type_policy_->duration; + *history = type_policy_->history; + *threshold = type_policy_->threshold; + + return true; + } + + BlacklistData::AllowedTypesAndVersions GetAllowedTypes() const override { + return allowed_types_; + } + + std::unique_ptr<BlacklistData::Policy> session_policy_; + std::unique_ptr<BlacklistData::Policy> persistent_policy_; + std::unique_ptr<BlacklistData::Policy> host_policy_; + std::unique_ptr<BlacklistData::Policy> type_policy_; + + size_t max_hosts_ = 0; + + BlacklistData::AllowedTypesAndVersions allowed_types_; +}; + +class OptOutBlacklistTest : public testing::Test { + public: + OptOutBlacklistTest() {} + ~OptOutBlacklistTest() override {} + + void StartTest(bool null_opt_out_store) { + std::unique_ptr<TestPreviewsOptOutStore> opt_out_store = + null_opt_out_store ? nullptr + : std::make_unique<TestPreviewsOptOutStore>(); + opt_out_store_ = opt_out_store.get(); + + black_list_ = std::make_unique<TestOptOutBlacklist>( + std::move(opt_out_store), &test_clock_, &blacklist_delegate_); + if (session_policy_) { + black_list_->SetSessionRule(std::move(session_policy_)); + } + if (persistent_policy_) { + black_list_->SetPersistentRule(std::move(persistent_policy_)); + } + if (host_policy_) { + black_list_->SetHostRule(std::move(host_policy_), max_hosts_); + } + if (type_policy_) { + black_list_->SetTypeRule(std::move(type_policy_)); + } + + black_list_->SetAllowedTypes(std::move(allowed_types_)); + black_list_->Init(); + + start_ = test_clock_.Now(); + + passed_reasons_ = {}; + } + + void SetSessionRule(std::unique_ptr<BlacklistData::Policy> policy) { + session_policy_ = std::move(policy); + } + + void SetPersistentRule(std::unique_ptr<BlacklistData::Policy> policy) { + persistent_policy_ = std::move(policy); + } + + void SetHostRule(std::unique_ptr<BlacklistData::Policy> policy, + size_t max_hosts) { + host_policy_ = std::move(policy); + max_hosts_ = max_hosts; + } + + void SetTypeRule(std::unique_ptr<BlacklistData::Policy> policy) { + type_policy_ = std::move(policy); + } + + void SetAllowedTypes(BlacklistData::AllowedTypesAndVersions allowed_types) { + allowed_types_ = std::move(allowed_types); + } + + protected: + base::MessageLoop loop_; + + // Observer to |black_list_|. + TestPreviewsBlacklistDelegate blacklist_delegate_; + + base::SimpleTestClock test_clock_; + TestPreviewsOptOutStore* opt_out_store_; + base::Time start_; + + std::unique_ptr<TestOptOutBlacklist> black_list_; + std::vector<BlacklistReason> passed_reasons_; + + private: + std::unique_ptr<BlacklistData::Policy> session_policy_; + std::unique_ptr<BlacklistData::Policy> persistent_policy_; + std::unique_ptr<BlacklistData::Policy> host_policy_; + std::unique_ptr<BlacklistData::Policy> type_policy_; + + size_t max_hosts_ = 0; + + BlacklistData::AllowedTypesAndVersions allowed_types_; + + DISALLOW_COPY_AND_ASSIGN(OptOutBlacklistTest); +}; + +TEST_F(OptOutBlacklistTest, HostBlackListNoStore) { + // Tests the black list behavior when a null OptOutStore is passed in. + auto host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 2); + SetHostRule(std::move(host_policy), 5); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost1, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, true, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost2, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost2, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, true, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost2, false, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost2, false, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost2, false, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, true, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + + black_list_->ClearBlackList(start_, test_clock_.Now()); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); +} + +TEST_F(OptOutBlacklistTest, TypeBlackListWithStore) { + // Tests the black list behavior when a non-null OptOutStore is passed in. + + auto type_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 2); + SetTypeRule(std::move(type_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + allowed_types.insert({2, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(false /* null_opt_out */); + + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost1, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, true, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost1, true, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost1, false, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, false, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, false, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + EXPECT_EQ(0, opt_out_store_->clear_blacklist_count()); + black_list_->ClearBlackList(start_, base::Time::Now()); + EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); + + EXPECT_EQ( + BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); +} + +TEST_F(OptOutBlacklistTest, TypeBlackListNoStore) { + // Tests the black list behavior when a null OptOutStore is passed in. + auto type_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 2); + SetTypeRule(std::move(type_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + allowed_types.insert({2, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost1, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, true, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost1, true, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, true, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + black_list_->AddEntry(kTestHost1, false, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, false, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, false, 2); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfType, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, true, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); + + black_list_->ClearBlackList(start_, test_clock_.Now()); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 2, false, &passed_reasons_)); +} + +TEST_F(OptOutBlacklistTest, HostIndifferentBlacklist) { + // Tests the black list behavior when a null OptOutStore is passed in. + const std::string hosts[] = { + "url_0.com", "url_1.com", "url_2.com", "url_3.com", + }; + + int host_indifferent_threshold = 4; + + auto persistent_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, host_indifferent_threshold); + SetPersistentRule(std::move(persistent_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[0], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[1], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[2], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[3], 1, false, &passed_reasons_)); + + for (int i = 0; i < host_indifferent_threshold; i++) { + black_list_->AddEntry(hosts[i], true, 1); + EXPECT_EQ( + i != 3 ? BlacklistReason::kAllowed + : BlacklistReason::kUserOptedOutInGeneral, + black_list_->IsLoadedAndAllowed(hosts[0], 1, false, &passed_reasons_)); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + } + + EXPECT_EQ( + BlacklistReason::kUserOptedOutInGeneral, + black_list_->IsLoadedAndAllowed(hosts[0], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutInGeneral, + black_list_->IsLoadedAndAllowed(hosts[1], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutInGeneral, + black_list_->IsLoadedAndAllowed(hosts[2], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutInGeneral, + black_list_->IsLoadedAndAllowed(hosts[3], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[3], 1, true, &passed_reasons_)); + + black_list_->AddEntry(hosts[3], false, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + // New non-opt-out entry will cause these to be allowed now. + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[0], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[1], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[2], 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(hosts[3], 1, false, &passed_reasons_)); +} + +TEST_F(OptOutBlacklistTest, QueueBehavior) { + // Tests the black list asynchronous queue behavior. Methods called while + // loading the opt-out store are queued and should run in the order they were + // queued. + + std::vector<bool> test_opt_out{true, false}; + + for (auto opt_out : test_opt_out) { + auto host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 2); + SetHostRule(std::move(host_policy), 5); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(false /* null_opt_out */); + + EXPECT_EQ(BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, + &passed_reasons_)); + black_list_->AddEntry(kTestHost1, opt_out, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, opt_out, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + EXPECT_EQ(BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, + &passed_reasons_)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(opt_out ? BlacklistReason::kUserOptedOutOfHost + : BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, + &passed_reasons_)); + black_list_->AddEntry(kTestHost1, opt_out, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, opt_out, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + EXPECT_EQ(0, opt_out_store_->clear_blacklist_count()); + black_list_->ClearBlackList( + start_, test_clock_.Now() + base::TimeDelta::FromSeconds(1)); + EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); + black_list_->AddEntry(kTestHost2, opt_out, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost2, opt_out, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); + + EXPECT_EQ(BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, + &passed_reasons_)); + EXPECT_EQ(opt_out ? BlacklistReason::kUserOptedOutOfHost + : BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, + &passed_reasons_)); + } +} + +TEST_F(OptOutBlacklistTest, MaxHosts) { + // Test that the black list only stores n hosts, and it stores the correct n + // hosts. + const std::string test_host_3("host3.com"); + const std::string test_host_4("host4.com"); + const std::string test_host_5("host5.com"); + + auto host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 1u, 1); + SetHostRule(std::move(host_policy), 2); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + black_list_->AddEntry(kTestHost1, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost2, false, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(test_host_3, false, 1); + // kTestHost1 should stay in the map, since it has an opt out time. + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(test_host_3, 1, false, &passed_reasons_)); + + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(test_host_4, true, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(test_host_5, true, 1); + // test_host_4 and test_host_5 should remain in the map, but host should be + // evicted. + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(test_host_4, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(test_host_5, 1, false, &passed_reasons_)); +} + +TEST_F(OptOutBlacklistTest, SingleOptOut) { + // Test that when a user opts out of a preview, previews won't be shown until + // |single_opt_out_duration| has elapsed. + int single_opt_out_duration = 5; + const std::string test_host_3("host3.com"); + + auto session_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromSeconds(single_opt_out_duration), 1u, 1); + SetSessionRule(std::move(session_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + black_list_->AddEntry(kTestHost1, false, 1); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(test_host_3, 1, false, &passed_reasons_)); + + test_clock_.Advance( + base::TimeDelta::FromSeconds(single_opt_out_duration + 1)); + + black_list_->AddEntry(kTestHost2, true, 1); + EXPECT_EQ( + BlacklistReason::kUserOptedOutInSession, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutInSession, + black_list_->IsLoadedAndAllowed(test_host_3, 1, false, &passed_reasons_)); + + test_clock_.Advance( + base::TimeDelta::FromSeconds(single_opt_out_duration - 1)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutInSession, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kUserOptedOutInSession, + black_list_->IsLoadedAndAllowed(test_host_3, 1, false, &passed_reasons_)); + + test_clock_.Advance( + base::TimeDelta::FromSeconds(single_opt_out_duration + 1)); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost2, 1, false, &passed_reasons_)); + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(test_host_3, 1, false, &passed_reasons_)); +} + +TEST_F(OptOutBlacklistTest, ClearingBlackListClearsRecentNavigation) { + // Tests that clearing the black list for a long amount of time (relative to + // "single_opt_out_duration_in_seconds") resets the blacklist's recent opt out + // rule. + + auto session_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromSeconds(5), 1u, 1); + SetSessionRule(std::move(session_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(false /* null_opt_out */); + + black_list_->AddEntry(kTestHost1, true /* opt_out */, 1); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->ClearBlackList(start_, test_clock_.Now()); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); +} + +TEST_F(OptOutBlacklistTest, ObserverIsNotifiedOnHostBlacklisted) { + // Tests the black list behavior when a null OptOutStore is passed in. + + auto host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 2); + SetHostRule(std::move(host_policy), 5); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + + // Observer is not notified as blacklisted when the threshold does not met. + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 1); + base::RunLoop().RunUntilIdle(); + EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(0)); + + // Observer is notified as blacklisted when the threshold is met. + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 1); + base::RunLoop().RunUntilIdle(); + const base::Time blacklisted_time = test_clock_.Now(); + EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(1)); + EXPECT_EQ(blacklisted_time, + blacklist_delegate_.blacklisted_hosts().find(kTestHost1)->second); + + // Observer is not notified when the host is already blacklisted. + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(kTestHost1, true, 1); + base::RunLoop().RunUntilIdle(); + EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(1)); + EXPECT_EQ(blacklisted_time, + blacklist_delegate_.blacklisted_hosts().find(kTestHost1)->second); + + // Observer is notified when blacklist is cleared. + EXPECT_FALSE(blacklist_delegate_.blacklist_cleared()); + + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->ClearBlackList(start_, test_clock_.Now()); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(blacklist_delegate_.blacklist_cleared()); + EXPECT_EQ(test_clock_.Now(), blacklist_delegate_.blacklist_cleared_time()); +} + +TEST_F(OptOutBlacklistTest, ObserverIsNotifiedOnUserBlacklisted) { + // Tests the black list behavior when a null OptOutStore is passed in. + const std::string hosts[] = { + "url_0.com", "url_1.com", "url_2.com", "url_3.com", + }; + + int host_indifferent_threshold = 4; + + auto persistent_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(30), 4u, host_indifferent_threshold); + SetPersistentRule(std::move(persistent_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + // Initially no host is blacklisted, and user is not blacklisted. + EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(0)); + EXPECT_FALSE(blacklist_delegate_.user_blacklisted()); + + for (int i = 0; i < host_indifferent_threshold; ++i) { + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(hosts[i], true, 1); + base::RunLoop().RunUntilIdle(); + + EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(0)); + // Observer is notified when number of recently opt out meets + // |host_indifferent_threshold|. + EXPECT_EQ(i >= host_indifferent_threshold - 1, + blacklist_delegate_.user_blacklisted()); + } + + // Observer is notified when the user is no longer blacklisted. + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + black_list_->AddEntry(hosts[3], false, 1); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(blacklist_delegate_.user_blacklisted()); +} + +TEST_F(OptOutBlacklistTest, ObserverIsNotifiedWhenLoadBlacklistDone) { + int host_indifferent_threshold = 4; + size_t host_indifferent_history = 4u; + auto persistent_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(30), host_indifferent_history, + host_indifferent_threshold); + SetPersistentRule(std::move(persistent_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(false /* null_opt_out */); + + allowed_types.clear(); + allowed_types[0] = 0; + std::unique_ptr<BlacklistData> data = std::make_unique<BlacklistData>( + nullptr, + std::make_unique<BlacklistData::Policy>(base::TimeDelta::FromSeconds(365), + host_indifferent_history, + host_indifferent_threshold), + nullptr, nullptr, 0, std::move(allowed_types)); + base::SimpleTestClock test_clock; + + for (int i = 0; i < host_indifferent_threshold; ++i) { + test_clock.Advance(base::TimeDelta::FromSeconds(1)); + data->AddEntry(kTestHost1, true, 0, test_clock.Now(), true); + } + + std::unique_ptr<TestPreviewsOptOutStore> opt_out_store = + std::make_unique<TestPreviewsOptOutStore>(); + opt_out_store->SetBlacklistData(std::move(data)); + + EXPECT_FALSE(blacklist_delegate_.user_blacklisted()); + allowed_types.clear(); + allowed_types[1] = 0; + auto black_list = std::make_unique<TestOptOutBlacklist>( + std::move(opt_out_store), &test_clock, &blacklist_delegate_); + black_list->SetAllowedTypes(std::move(allowed_types)); + + persistent_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(30), host_indifferent_history, + host_indifferent_threshold); + black_list->SetPersistentRule(std::move(persistent_policy)); + + black_list->Init(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(blacklist_delegate_.user_blacklisted()); +} + +TEST_F(OptOutBlacklistTest, ObserverIsNotifiedOfHistoricalBlacklistedHosts) { + // Tests the black list behavior when a non-null OptOutStore is passed in. + int host_indifferent_threshold = 2; + size_t host_indifferent_history = 4u; + auto host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), host_indifferent_history, + host_indifferent_threshold); + SetHostRule(std::move(host_policy), 5); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(false /* null_opt_out */); + + base::SimpleTestClock test_clock; + + allowed_types.clear(); + allowed_types[static_cast<int>(1)] = 0; + std::unique_ptr<BlacklistData> data = std::make_unique<BlacklistData>( + nullptr, nullptr, + std::make_unique<BlacklistData::Policy>(base::TimeDelta::FromDays(365), + host_indifferent_history, + host_indifferent_threshold), + nullptr, 2, std::move(allowed_types)); + + test_clock.Advance(base::TimeDelta::FromSeconds(1)); + data->AddEntry(kTestHost1, true, static_cast<int>(1), test_clock.Now(), true); + test_clock.Advance(base::TimeDelta::FromSeconds(1)); + data->AddEntry(kTestHost1, true, static_cast<int>(1), test_clock.Now(), true); + base::Time blacklisted_time = test_clock.Now(); + + base::RunLoop().RunUntilIdle(); + std::vector<BlacklistReason> reasons; + EXPECT_NE(BlacklistReason::kAllowed, + data->IsAllowed(kTestHost1, static_cast<int>(1), false, + test_clock.Now(), &reasons)); + + // Host |url_b| is not blacklisted. + test_clock.Advance(base::TimeDelta::FromSeconds(1)); + data->AddEntry(kTestHost2, true, static_cast<int>(1), test_clock.Now(), true); + + std::unique_ptr<TestPreviewsOptOutStore> opt_out_store = + std::make_unique<TestPreviewsOptOutStore>(); + opt_out_store->SetBlacklistData(std::move(data)); + + allowed_types.clear(); + allowed_types[static_cast<int>(1)] = 0; + auto black_list = std::make_unique<TestOptOutBlacklist>( + std::move(opt_out_store), &test_clock, &blacklist_delegate_); + black_list->SetAllowedTypes(std::move(allowed_types)); + + host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(30), host_indifferent_history, + host_indifferent_threshold); + black_list->SetPersistentRule(std::move(host_policy)); + + black_list->Init(); + + base::RunLoop().RunUntilIdle(); + + ASSERT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(1)); + EXPECT_EQ(blacklisted_time, + blacklist_delegate_.blacklisted_hosts().find(kTestHost1)->second); +} + +TEST_F(OptOutBlacklistTest, PassedReasonsWhenBlacklistDataNotLoaded) { + // Test that IsLoadedAndAllow, push checked BlacklistReasons to the + // |passed_reasons| vector. + + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + StartTest(false /* null_opt_out */); + + EXPECT_EQ( + BlacklistReason::kBlacklistNotLoaded, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + + EXPECT_EQ(0UL, passed_reasons_.size()); +} + +TEST_F(OptOutBlacklistTest, PassedReasonsWhenUserRecentlyOptedOut) { + // Test that IsLoadedAndAllow, push checked BlacklistReasons to the + // |passed_reasons| vector. + + auto session_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromSeconds(5), 1u, 1); + SetSessionRule(std::move(session_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + black_list_->AddEntry(kTestHost1, true, 1); + EXPECT_EQ( + BlacklistReason::kUserOptedOutInSession, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + EXPECT_EQ(1UL, passed_reasons_.size()); + EXPECT_EQ(BlacklistReason::kBlacklistNotLoaded, passed_reasons_[0]); +} + +TEST_F(OptOutBlacklistTest, PassedReasonsWhenUserBlacklisted) { + // Test that IsLoadedAndAllow, push checked BlacklistReasons to the + // |passed_reasons| vector. + const std::string hosts[] = { + "http://www.url_0.com", "http://www.url_1.com", "http://www.url_2.com", + "http://www.url_3.com", + }; + + auto session_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromSeconds(1), 1u, 1); + SetSessionRule(std::move(session_policy)); + auto persistent_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 4); + SetPersistentRule(std::move(persistent_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + test_clock_.Advance(base::TimeDelta::FromSeconds(1)); + + for (auto host : hosts) { + black_list_->AddEntry(host, true, 1); + } + + test_clock_.Advance(base::TimeDelta::FromSeconds(2)); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutInGeneral, + black_list_->IsLoadedAndAllowed(hosts[0], 1, false, &passed_reasons_)); + + BlacklistReason expected_reasons[] = { + BlacklistReason::kBlacklistNotLoaded, + BlacklistReason::kUserOptedOutInSession, + }; + EXPECT_EQ(base::size(expected_reasons), passed_reasons_.size()); + for (size_t i = 0; i < passed_reasons_.size(); i++) { + EXPECT_EQ(expected_reasons[i], passed_reasons_[i]); + } +} + +TEST_F(OptOutBlacklistTest, PassedReasonsWhenHostBlacklisted) { + // Test that IsLoadedAndAllow, push checked BlacklistReasons to the + // |passed_reasons| vector. + + auto session_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(5), 3u, 3); + SetSessionRule(std::move(session_policy)); + auto persistent_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 4); + SetPersistentRule(std::move(persistent_policy)); + auto host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(30), 4u, 2); + SetHostRule(std::move(host_policy), 2); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + black_list_->AddEntry(kTestHost1, true, 1); + black_list_->AddEntry(kTestHost1, true, 1); + + EXPECT_EQ( + BlacklistReason::kUserOptedOutOfHost, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + + BlacklistReason expected_reasons[] = { + BlacklistReason::kBlacklistNotLoaded, + BlacklistReason::kUserOptedOutInSession, + BlacklistReason::kUserOptedOutInGeneral, + }; + EXPECT_EQ(base::size(expected_reasons), passed_reasons_.size()); + for (size_t i = 0; i < passed_reasons_.size(); i++) { + EXPECT_EQ(expected_reasons[i], passed_reasons_[i]); + } +} + +TEST_F(OptOutBlacklistTest, PassedReasonsWhenAllowed) { + // Test that IsLoadedAndAllow, push checked BlacklistReasons to the + // |passed_reasons| vector. + + auto session_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromSeconds(1), 1u, 1); + SetSessionRule(std::move(session_policy)); + auto persistent_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(365), 4u, 4); + SetPersistentRule(std::move(persistent_policy)); + auto host_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(30), 4u, 4); + SetHostRule(std::move(host_policy), 1); + auto type_policy = std::make_unique<BlacklistData::Policy>( + base::TimeDelta::FromDays(30), 4u, 4); + SetTypeRule(std::move(type_policy)); + BlacklistData::AllowedTypesAndVersions allowed_types; + allowed_types.insert({1, 0}); + SetAllowedTypes(std::move(allowed_types)); + + StartTest(true /* null_opt_out */); + + EXPECT_EQ( + BlacklistReason::kAllowed, + black_list_->IsLoadedAndAllowed(kTestHost1, 1, false, &passed_reasons_)); + + BlacklistReason expected_reasons[] = { + BlacklistReason::kBlacklistNotLoaded, + BlacklistReason::kUserOptedOutInSession, + BlacklistReason::kUserOptedOutInGeneral, + BlacklistReason::kUserOptedOutOfHost, + BlacklistReason::kUserOptedOutOfType, + }; + EXPECT_EQ(base::size(expected_reasons), passed_reasons_.size()); + for (size_t i = 0; i < passed_reasons_.size(); i++) { + EXPECT_EQ(expected_reasons[i], passed_reasons_[i]); + } +} + +} // namespace + +} // namespace previews
diff --git a/components/previews/core/previews_black_list.cc b/components/previews/core/previews_black_list.cc index 65ecb77..4e2a182 100644 --- a/components/previews/core/previews_black_list.cc +++ b/components/previews/core/previews_black_list.cc
@@ -10,7 +10,6 @@ #include "base/optional.h" #include "base/strings/stringprintf.h" #include "base/time/clock.h" -#include "components/previews/core/previews_black_list_item.h" #include "components/previews/core/previews_experiments.h" #include "url/gurl.h" @@ -20,7 +19,6 @@ PreviewsEligibilityReason BlacklistReasonToPreviewsReason( BlacklistReason reason) { - // TODO(ryansturm): Blacklist split -- In derived class. switch (reason) { case BlacklistReason::kBlacklistNotLoaded: return PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED; @@ -45,77 +43,24 @@ base::Clock* clock, PreviewsBlacklistDelegate* blacklist_delegate, BlacklistData::AllowedTypesAndVersions allowed_types) - : loaded_(false), - opt_out_store_(std::move(opt_out_store)), - clock_(clock), - blacklist_delegate_(blacklist_delegate), - allowed_types_(std::move(allowed_types)), - weak_factory_(this) { - // TODO(ryansturm): Blacklist split -- In derived class. - DCHECK(blacklist_delegate_); + : OptOutBlacklist(std::move(opt_out_store), clock, blacklist_delegate), + allowed_types_(std::move(allowed_types)) { + DCHECK(blacklist_delegate); Init(); } -void PreviewsBlackList::Init() { - // TODO(ryansturm): Blacklist split -- In base class. - - base::TimeDelta duration; - size_t history = 0; - int threshold = 0; - - std::unique_ptr<BlacklistData::Policy> session_policy; - if (ShouldUseSessionPolicy(&duration, &history, &threshold)) { - session_policy = - std::make_unique<BlacklistData::Policy>(duration, history, threshold); - } - - std::unique_ptr<BlacklistData::Policy> persistent_policy; - if (ShouldUsePersistentPolicy(&duration, &history, &threshold)) { - persistent_policy = - std::make_unique<BlacklistData::Policy>(duration, history, threshold); - } - - size_t max_hosts = 0; - std::unique_ptr<BlacklistData::Policy> host_policy; - if (ShouldUseHostPolicy(&duration, &history, &threshold, &max_hosts)) { - host_policy = - std::make_unique<BlacklistData::Policy>(duration, history, threshold); - } - - std::unique_ptr<BlacklistData::Policy> type_policy; - if (ShouldUseTypePolicy(&duration, &history, &threshold)) { - type_policy = - std::make_unique<BlacklistData::Policy>(duration, history, threshold); - } - - auto blacklist_data = std::make_unique<BlacklistData>( - std::move(session_policy), std::move(persistent_policy), - std::move(host_policy), std::move(type_policy), max_hosts, - GetAllowedTypes()); - - if (opt_out_store_) { - opt_out_store_->LoadBlackList( - std::move(blacklist_data), - base::BindOnce(&PreviewsBlackList::LoadBlackListDone, - weak_factory_.GetWeakPtr())); - } else { - LoadBlackListDone(std::move(blacklist_data)); - } -} - bool PreviewsBlackList::ShouldUseSessionPolicy(base::TimeDelta* duration, size_t* history, int* threshold) const { - // TODO(ryansturm): Blacklist split -- In derived class. *duration = params::SingleOptOutDuration(); *history = 1; *threshold = 1; return true; } + bool PreviewsBlackList::ShouldUsePersistentPolicy(base::TimeDelta* duration, size_t* history, int* threshold) const { - // TODO(ryansturm): Blacklist split -- In derived class. *history = params::MaxStoredHistoryLengthForHostIndifferentBlackList(); *threshold = params::HostIndifferentBlackListOptOutThreshold(); *duration = params::HostIndifferentBlackListPerHostDuration(); @@ -125,7 +70,6 @@ size_t* history, int* threshold, size_t* max_hosts) const { - // TODO(ryansturm): Blacklist split -- In derived class. *max_hosts = params::MaxInMemoryHostsInBlackList(); *history = params::MaxStoredHistoryLengthForPerHostBlackList(); *threshold = params::PerHostBlackListOptOutThreshold(); @@ -135,13 +79,11 @@ bool PreviewsBlackList::ShouldUseTypePolicy(base::TimeDelta* duration, size_t* history, int* threshold) const { - // TODO(ryansturm): Blacklist split -- In derived class. return false; } -const BlacklistData::AllowedTypesAndVersions& -PreviewsBlackList::GetAllowedTypes() const { - // TODO(ryansturm): Blacklist split -- In derived class. +BlacklistData::AllowedTypesAndVersions PreviewsBlackList::GetAllowedTypes() + const { return allowed_types_; } @@ -150,8 +92,6 @@ base::Time PreviewsBlackList::AddPreviewNavigation(const GURL& url, bool opt_out, PreviewsType type) { - // TODO(ryansturm): Blacklist split -- In derived class. - DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(url.has_host()); base::BooleanHistogram::FactoryGet( @@ -160,59 +100,7 @@ base::HistogramBase::kUmaTargetedHistogramFlag) ->Add(opt_out); - return AddEntry(url.host(), opt_out, static_cast<int>(type)); -} - -base::Time PreviewsBlackList::AddEntry(const std::string& host_name, - bool opt_out, - int type) { - // TODO(ryansturm): Blacklist split -- In base class. - DCHECK(thread_checker_.CalledOnValidThread()); - - base::Time now = clock_->Now(); - - // If the |blacklist_data| has been loaded from |opt_out_store_|, synchronous - // operations will be accurate. Otherwise, queue the task to run - // asynchronously. - if (loaded_) { - AddEntrySync(host_name, opt_out, type, now); - } else { - QueuePendingTask(base::BindOnce(&PreviewsBlackList::AddEntrySync, - base::Unretained(this), host_name, opt_out, - type, now)); - } - - return now; -} - -void PreviewsBlackList::AddEntrySync(const std::string& host_name, - bool opt_out, - int type, - base::Time time) { - // TODO(ryansturm): Blacklist split -- In base class. - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(loaded_); - - bool host_was_blacklisted = - blacklist_data_->IsHostBlacklisted(host_name, time); - bool user_was_blacklisted = blacklist_data_->IsUserOptedOutInGeneral(time); - blacklist_data_->AddEntry(host_name, opt_out, type, time, false); - - if (!host_was_blacklisted && - blacklist_data_->IsHostBlacklisted(host_name, time)) { - // Notify |blacklist_delegate_| about a new blacklisted host. - blacklist_delegate_->OnNewBlacklistedHost(host_name, time); - } - - if (user_was_blacklisted != blacklist_data_->IsUserOptedOutInGeneral(time)) { - // Notify |blacklist_delegate_| about a new blacklisted host. - blacklist_delegate_->OnUserBlacklistedStatusChange( - blacklist_data_->IsUserOptedOutInGeneral(time)); - } - - if (!opt_out_store_) - return; - opt_out_store_->AddEntry(opt_out, host_name, type, time); + return OptOutBlacklist::AddEntry(url.host(), opt_out, static_cast<int>(type)); } PreviewsEligibilityReason PreviewsBlackList::IsLoadedAndAllowed( @@ -220,12 +108,10 @@ PreviewsType type, bool ignore_long_term_black_list_rules, std::vector<PreviewsEligibilityReason>* passed_reasons) const { - // TODO(ryansturm): Blacklist split -- In derived class. - DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(url.has_host()); std::vector<BlacklistReason> passed_blacklist_reasons; - BlacklistReason reason = IsLoadedAndAllowed( + BlacklistReason reason = OptOutBlacklist::IsLoadedAndAllowed( url.host(), static_cast<int>(type), ignore_long_term_black_list_rules, &passed_blacklist_reasons); for (auto passed_reason : passed_blacklist_reasons) { @@ -235,99 +121,4 @@ return BlacklistReasonToPreviewsReason(reason); } -BlacklistReason PreviewsBlackList::IsLoadedAndAllowed( - const std::string& host_name, - int type, - bool ignore_long_term_black_list_rules, - std::vector<BlacklistReason>* passed_reasons) const { - // TODO(ryansturm): Blacklist split -- In base class. - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!loaded_) - return BlacklistReason::kBlacklistNotLoaded; - passed_reasons->push_back(BlacklistReason::kBlacklistNotLoaded); - - return blacklist_data_->IsAllowed(host_name, type, - ignore_long_term_black_list_rules, - clock_->Now(), passed_reasons); -} - -void PreviewsBlackList::ClearBlackList(base::Time begin_time, - base::Time end_time) { - // TODO(ryansturm): Blacklist split -- In base class. - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_LE(begin_time, end_time); - // If the |blacklist_data| has been loaded from |opt_out_store_|, - // synchronous operations will be accurate. Otherwise, queue the task to run - // asynchronously. - if (loaded_) { - ClearBlackListSync(begin_time, end_time); - } else { - QueuePendingTask(base::BindOnce(&PreviewsBlackList::ClearBlackListSync, - base::Unretained(this), begin_time, - end_time)); - } -} - -void PreviewsBlackList::ClearBlackListSync(base::Time begin_time, - base::Time end_time) { - // TODO(ryansturm): Blacklist split -- In base class. - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(loaded_); - DCHECK_LE(begin_time, end_time); - - // Clear the in-memory rules entirely. - blacklist_data_->ClearData(); - loaded_ = false; - - // Notify |blacklist_delegate_| that the blacklist is cleared. - blacklist_delegate_->OnBlacklistCleared(clock_->Now()); - - // Delete relevant entries and reload the blacklist into memory. - if (opt_out_store_) { - opt_out_store_->ClearBlackList(begin_time, end_time); - opt_out_store_->LoadBlackList( - std::move(blacklist_data_), - base::BindOnce(&PreviewsBlackList::LoadBlackListDone, - weak_factory_.GetWeakPtr())); - } else { - LoadBlackListDone(std::move(blacklist_data_)); - } -} - -void PreviewsBlackList::QueuePendingTask(base::OnceClosure callback) { - // TODO(ryansturm): Blacklist split -- In base class. - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!loaded_); - DCHECK(!callback.is_null()); - pending_callbacks_.push(std::move(callback)); -} - -void PreviewsBlackList::LoadBlackListDone( - std::unique_ptr<BlacklistData> blacklist_data) { - // TODO(ryansturm): Blacklist split -- In base class. - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(blacklist_data); - loaded_ = true; - blacklist_data_ = std::move(blacklist_data); - - // Notify |blacklist_delegate_| on current user blacklisted status. - blacklist_delegate_->OnUserBlacklistedStatusChange( - blacklist_data_->IsUserOptedOutInGeneral(clock_->Now())); - - // Notify the |blacklist_delegate_| on historical blacklisted hosts. - for (const auto& entry : blacklist_data_->black_list_item_host_map()) { - if (blacklist_data_->IsHostBlacklisted(entry.first, clock_->Now())) { - blacklist_delegate_->OnNewBlacklistedHost( - entry.first, entry.second.most_recent_opt_out_time().value()); - } - } - - // Run all pending tasks. |loaded_| may change if ClearBlackList is queued. - while (pending_callbacks_.size() > 0 && loaded_) { - std::move(pending_callbacks_.front()).Run(); - pending_callbacks_.pop(); - } -} - } // namespace previews
diff --git a/components/previews/core/previews_black_list.h b/components/previews/core/previews_black_list.h index fef830f..ef28eec 100644 --- a/components/previews/core/previews_black_list.h +++ b/components/previews/core/previews_black_list.h
@@ -13,13 +13,10 @@ #include <vector> #include "base/callback.h" -#include "base/containers/queue.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "base/threading/thread_checker.h" #include "base/time/time.h" -#include "components/previews/core/blacklist_data.h" +#include "components/previews/core/opt_out_blacklist.h" #include "components/previews/core/previews_black_list_delegate.h" #include "components/previews/core/previews_experiments.h" #include "components/previews/core/previews_opt_out_store.h" @@ -78,19 +75,13 @@ // browsing history), domains are reported as black listed. The list stores no // more than previews::params::MaxInMemoryHostsInBlackList hosts in-memory, // which defaults to 100. -class PreviewsBlackList { +class PreviewsBlackList : public OptOutBlacklist { public: - // |opt_out_store| is the backing store to retrieve and store black list - // information, and can be null. When |opt_out_store| is null, the in-memory - // map will be immediately loaded to empty. If |opt_out_store| is non-null, - // it will be used to load the in-memory map asynchronously. - // |blacklist_delegate| is a single object listening for blacklist events, and - // it is guaranteed to overlive the life time of |this|. PreviewsBlackList(std::unique_ptr<PreviewsOptOutStore> opt_out_store, base::Clock* clock, PreviewsBlacklistDelegate* blacklist_delegate, BlacklistData::AllowedTypesAndVersions allowed_types); - virtual ~PreviewsBlackList(); + ~PreviewsBlackList() override; // Asynchronously adds a new navigation to to the in-memory black list and // backing store. |opt_out| is whether the user opted out of the preview or @@ -113,139 +104,26 @@ bool ignore_long_term_black_list_rules, std::vector<PreviewsEligibilityReason>* passed_reasons) const; - // Asynchronously deletes all entries in the in-memory black list. Informs - // the backing store to delete entries between |begin_time| and |end_time|, - // and reloads entries into memory from the backing store. If the embedder - // passed in a null store, resets all history in the in-memory black list. - void ClearBlackList(base::Time begin_time, base::Time end_time); - - private: - // Synchronous version of AddEntry method. |time| is the time - // stamp of when the navigation was determined to be an opt-out or non-opt - // out. - void AddEntrySync(const std::string& host_name, - bool opt_out, - int type, - base::Time time); - - // Creates the BlacklistData that backs the blacklist. - void Init(); - - // Synchronous version of ClearBlackList method. - void ClearBlackListSync(base::Time begin_time, base::Time end_time); - - // Callback passed to the backing store when loading black list information. - // Moves the |black_list_item_map| and |host_indifferent_black_list_item| into - // the in-memory black list and runs any outstanding tasks. - void LoadBlackListDone(std::unique_ptr<BlacklistData> blacklist_data); - - // Synchronously determines if |host_name| should be allowed to show previews. - // Returns the reason the blacklist disallowed the preview, or - // PreviewsEligibilityReason::ALLOWED if the preview is allowed. Record - // checked reasons in |passed_reasons|. - BlacklistReason IsLoadedAndAllowed( - const std::string& host_name, - int type, - bool ignore_long_term_black_list_rules, - std::vector<BlacklistReason>* passed_reasons) const; - - // Whether the session rule should be enabled. |duration| specifies how long a - // user remains blacklisted. |history| specifies how many entries should be - // evaluated; |threshold| specifies how many opt outs would cause - // blacklisting. I.e., the most recent |history| are looked at and if - // |threshold| (or more) of them are opt outs, the user is considered - // blacklisted unless the most recent opt out was longer than |duration| ago. - // This rule only considers entries within this session (it does not use the - // data that was persisted in previous sessions). When the blacklist is - // cleared, this rule is reset as if it were a new session. Queried in Init(). + protected: + // OptOutBlacklist (virtual for testing): bool ShouldUseSessionPolicy(base::TimeDelta* duration, size_t* history, - int* threshold) const; - - // Whether the persistent rule should be enabled. |duration| specifies how - // long a user remains blacklisted. |history| specifies how many entries - // should be evaluated; |threshold| specifies how many opt outs would cause - // blacklisting. I.e., the most recent |history| are looked at and if - // |threshold| (or more) of them are opt outs, the user is considered - // blacklisted unless the most recent opt out was longer than |duration| ago. - // Queried in Init(). + int* threshold) const override; bool ShouldUsePersistentPolicy(base::TimeDelta* duration, size_t* history, - int* threshold) const; - - // Whether the host rule should be enabled. |duration| specifies how long a - // host remains blacklisted. |history| specifies how many entries should be - // evaluated per host; |threshold| specifies how many opt outs would cause - // blacklisting. I.e., the most recent |history| entries per host are looked - // at and if |threshold| (or more) of them are opt outs, the host is - // considered blacklisted unless the most recent opt out was longer than - // |duration| ago. |max_hosts| will limit the number of hosts stored in this - // class when non-zero. - // Queried in Init(). + int* threshold) const override; bool ShouldUseHostPolicy(base::TimeDelta* duration, size_t* history, int* threshold, - size_t* max_hosts) const; - - // Whether the type rule should be enabled. |duration| specifies how long a - // type remains blacklisted. |history| specifies how many entries should be - // evaluated per type; |threshold| specifies how many opt outs would cause - // blacklisting. - // I.e., the most recent |history| entries per type are looked at and if - // |threshold| (or more) of them are opt outs, the type is considered - // blacklisted unless the most recent opt out was longer than |duration| ago. - // Queried in Init(). + size_t* max_hosts) const override; bool ShouldUseTypePolicy(base::TimeDelta* duration, size_t* history, - int* threshold) const; + int* threshold) const override; + BlacklistData::AllowedTypesAndVersions GetAllowedTypes() const override; - // The allowed types and what version they are. Should be empty unless the - // caller will not be using the blacklist in the session. It is used to remove - // stale entries from the database and to DCHECK that other methods are not - // using disallowed types. Queried in Init(). - const BlacklistData::AllowedTypesAndVersions& GetAllowedTypes() const; - - // Asynchronously adds a new navigation to to the in-memory black list and - // backing store. |opt_out| is whether the user opted out of the preview or - // navigated away from the page without opting out. If the in memory map has - // reached the max number of hosts allowed, and |url| is a new host, a host - // will be evicted based on recency of the hosts most recent opt out. It - // returns the time used for recording the moment when the navigation is added - // for logging. - base::Time AddEntry(const std::string& host_name, bool opt_out, int type); - - // Called while waiting for the black list to be loaded from the backing - // store. - // Enqueues a task to run when when loading black list information has - // completed. Maintains the order that tasks were called in. - void QueuePendingTask(base::OnceClosure callback); - - // An in-memory representation of the various rules of the blacklist. This is - // null while reading from the backing store. - std::unique_ptr<BlacklistData> blacklist_data_; - - // Whether the black list is done being loaded from the backing store. - bool loaded_; - - // The backing store of the black list information. - std::unique_ptr<PreviewsOptOutStore> opt_out_store_; - - // Callbacks to be run after loading information from the backing store has - // completed. - base::queue<base::OnceClosure> pending_callbacks_; - - base::Clock* clock_; - - // The delegate listening to this blacklist. |blacklist_delegate_| lifetime is - // guaranteed to overlive |this|. - PreviewsBlacklistDelegate* blacklist_delegate_; - + private: const BlacklistData::AllowedTypesAndVersions allowed_types_; - base::ThreadChecker thread_checker_; - - base::WeakPtrFactory<PreviewsBlackList> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(PreviewsBlackList); };
diff --git a/components/previews/core/previews_black_list_unittest.cc b/components/previews/core/previews_black_list_unittest.cc index c7c4bdd2..737617b 100644 --- a/components/previews/core/previews_black_list_unittest.cc +++ b/components/previews/core/previews_black_list_unittest.cc
@@ -39,84 +39,53 @@ // events (e.g. New host blacklisted, user blacklisted, and blacklist cleared). class TestPreviewsBlacklistDelegate : public PreviewsBlacklistDelegate { public: - TestPreviewsBlacklistDelegate() - : user_blacklisted_(false), - blacklist_cleared_(false), - blacklist_cleared_time_(base::Time::Now()) {} + TestPreviewsBlacklistDelegate() {} // PreviewsBlacklistDelegate: void OnNewBlacklistedHost(const std::string& host, base::Time time) override { - blacklisted_hosts_[host] = time; } void OnUserBlacklistedStatusChange(bool blacklisted) override { - user_blacklisted_ = blacklisted; } void OnBlacklistCleared(base::Time time) override { - blacklist_cleared_ = true; - blacklist_cleared_time_ = time; } - - // Gets the set of blacklisted hosts recorded. - const std::unordered_map<std::string, base::Time>& blacklisted_hosts() const { - return blacklisted_hosts_; - } - - // Gets the state of user blacklisted status. - bool user_blacklisted() const { return user_blacklisted_; } - - // Gets the state of blacklisted cleared status of |this| for testing. - bool blacklist_cleared() const { return blacklist_cleared_; } - - // Gets the event time of blacklist is as cleared. - base::Time blacklist_cleared_time() const { return blacklist_cleared_time_; } - - private: - // The user blacklisted status of |this| blacklist_delegate. - bool user_blacklisted_; - - // Check if the blacklist is notified as cleared on |this| blacklist_delegate. - bool blacklist_cleared_; - - // The time when blacklist is cleared. - base::Time blacklist_cleared_time_; - - // |this| blacklist_delegate's collection of blacklisted hosts. - std::unordered_map<std::string, base::Time> blacklisted_hosts_; }; -class TestPreviewsOptOutStore : public PreviewsOptOutStore { +class TestPreviewsBlackList : public PreviewsBlackList { public: - TestPreviewsOptOutStore() : clear_blacklist_count_(0) {} - ~TestPreviewsOptOutStore() override {} + TestPreviewsBlackList(std::unique_ptr<PreviewsOptOutStore> opt_out_store, + base::Clock* clock, + PreviewsBlacklistDelegate* blacklist_delegate, + BlacklistData::AllowedTypesAndVersions allowed_types) + : PreviewsBlackList(std::move(opt_out_store), + clock, + blacklist_delegate, + allowed_types) {} + ~TestPreviewsBlackList() override {} - int clear_blacklist_count() { return clear_blacklist_count_; } - - void SetBlacklistData(std::unique_ptr<BlacklistData> data) { - data_ = std::move(data); + bool ShouldUseSessionPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const override { + return PreviewsBlackList::ShouldUseSessionPolicy(duration, history, + threshold); } - - private: - // PreviewsOptOutStore implementation: - void AddEntry(bool opt_out, - const std::string& host_name, - int type, - base::Time now) override {} - - void LoadBlackList(std::unique_ptr<BlacklistData> blacklist_data, - LoadBlackListCallback callback) override { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), - data_ ? std::move(data_) : std::move(blacklist_data))); + bool ShouldUsePersistentPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const override { + return PreviewsBlackList::ShouldUsePersistentPolicy(duration, history, + threshold); } - - void ClearBlackList(base::Time begin_time, base::Time end_time) override { - ++clear_blacklist_count_; + bool ShouldUseHostPolicy(base::TimeDelta* duration, + size_t* history, + int* threshold, + size_t* max_hosts) const override { + return PreviewsBlackList::ShouldUseHostPolicy(duration, history, threshold, + max_hosts); } - - int clear_blacklist_count_; - - std::unique_ptr<BlacklistData> data_; + bool ShouldUseTypePolicy(base::TimeDelta* duration, + size_t* history, + int* threshold) const override { + return PreviewsBlackList::ShouldUseTypePolicy(duration, history, threshold); + } }; class PreviewsBlackListTest : public testing::Test { @@ -126,7 +95,7 @@ void TearDown() override { variations::testing::ClearAllVariationParams(); } - void StartTest(bool null_opt_out) { + void StartTest() { if (params_.size() > 0) { ASSERT_TRUE(variations::AssociateVariationParams("ClientSidePreviews", "Enabled", params_)); @@ -134,16 +103,11 @@ "Enabled")); params_.clear(); } - std::unique_ptr<TestPreviewsOptOutStore> opt_out_store = - null_opt_out ? nullptr : std::make_unique<TestPreviewsOptOutStore>(); - opt_out_store_ = opt_out_store.get(); BlacklistData::AllowedTypesAndVersions allowed_types; allowed_types[static_cast<int>(PreviewsType::OFFLINE)] = 0; - black_list_ = std::make_unique<PreviewsBlackList>( - std::move(opt_out_store), &test_clock_, &blacklist_delegate_, - std::move(allowed_types)); - start_ = test_clock_.Now(); + black_list_ = std::make_unique<TestPreviewsBlackList>( + nullptr, &test_clock_, &blacklist_delegate_, std::move(allowed_types)); passed_reasons_ = {}; } @@ -173,6 +137,11 @@ base::IntToString(duration_in_days); } + void SetHostIndifferentDurationParam(int duration_in_days) { + params_["host_indifferent_black_list_duration_in_days"] = + base::IntToString(duration_in_days); + } + void SetSingleOptOutDurationParam(int single_opt_out_duration) { params_["single_opt_out_duration_in_seconds"] = base::IntToString(single_opt_out_duration); @@ -183,26 +152,6 @@ base::IntToString(max_hosts_in_blacklist); } - // Adds an opt out and either clears the black list for a time either longer - // or shorter than the single opt out duration parameter depending on - // |short_time|. - void RunClearingBlackListTest(const GURL& url) { - const size_t host_indifferent_history = 1; - const int single_opt_out_duration = 5; - SetHostDurationParam(365); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetSingleOptOutDurationParam(single_opt_out_duration); - - StartTest(false /* null_opt_out */); - - black_list_->AddPreviewNavigation(url, true /* opt_out */, - PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->ClearBlackList(start_, test_clock_.Now()); - base::RunLoop().RunUntilIdle(); - } - protected: base::MessageLoop loop_; @@ -210,484 +159,21 @@ TestPreviewsBlacklistDelegate blacklist_delegate_; base::SimpleTestClock test_clock_; - TestPreviewsOptOutStore* opt_out_store_; - base::Time start_; std::map<std::string, std::string> params_; base::FieldTrialList field_trial_list_; - std::unique_ptr<PreviewsBlackList> black_list_; + std::unique_ptr<TestPreviewsBlackList> black_list_; std::vector<PreviewsEligibilityReason> passed_reasons_; private: DISALLOW_COPY_AND_ASSIGN(PreviewsBlackListTest); }; -TEST_F(PreviewsBlackListTest, PerHostBlackListNoStore) { - // Tests the black list behavior when a null OptOutStore is passed in. - const GURL url_a("http://www.url_a.com"); - const GURL url_b("http://www.url_b.com"); - - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - SetHostHistoryParam(4); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostThresholdParam(2); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(true /* null_opt_out */); - - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - black_list_->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, true, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, true, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, true, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - black_list_->ClearBlackList(start_, test_clock_.Now()); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); -} - -TEST_F(PreviewsBlackListTest, PerHostBlackListWithStore) { - // Tests the black list behavior when a non-null OptOutStore is passed in. - const GURL url_a1("http://www.url_a.com/a1"); - const GURL url_a2("http://www.url_a.com/a2"); - const GURL url_b("http://www.url_b.com"); - - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - SetHostHistoryParam(4); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostThresholdParam(2); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(false /* null_opt_out */); - - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - black_list_->AddPreviewNavigation(url_a1, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_a1, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE, true, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - EXPECT_EQ(0, opt_out_store_->clear_blacklist_count()); - black_list_->ClearBlackList(start_, base::Time::Now()); - EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); - - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); -} - -TEST_F(PreviewsBlackListTest, HostIndifferentBlackList) { - // Tests the black list behavior when a null OptOutStore is passed in. - const GURL urls[] = { - GURL("http://www.url_0.com"), GURL("http://www.url_1.com"), - GURL("http://www.url_2.com"), GURL("http://www.url_3.com"), - }; - - // Per host blacklisting should have no effect with the following params. - const size_t per_host_history = 1; - const size_t host_indifferent_history = 4; - const size_t host_indifferent_threshold = host_indifferent_history; - SetHostHistoryParam(per_host_history); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostThresholdParam(per_host_history + 1); - SetHostIndifferentThresholdParam(host_indifferent_threshold); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(true /* null_opt_out */); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE, - false, &passed_reasons_)); - - for (size_t i = 0; i < host_indifferent_threshold; i++) { - black_list_->AddPreviewNavigation(urls[i], true, PreviewsType::OFFLINE); - EXPECT_EQ(i != 3 ? PreviewsEligibilityReason::ALLOWED - : PreviewsEligibilityReason::USER_BLACKLISTED, - black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE, - false, &passed_reasons_)); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - } - - EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED, - black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED, - black_list_->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED, - black_list_->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED, - black_list_->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE, - true, &passed_reasons_)); - - black_list_->AddPreviewNavigation(urls[3], false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - // New non-opt-out entry will cause these to be allowed now. - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE, - false, &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE, - false, &passed_reasons_)); -} - -TEST_F(PreviewsBlackListTest, QueueBehavior) { - // Tests the black list asynchronous queue behavior. Methods called while - // loading the opt-out store are queued and should run in the order they were - // queued. - const GURL url("http://www.url.com"); - const GURL url2("http://www.url2.com"); - - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - std::vector<bool> test_opt_out{true, false}; - - for (auto opt_out : test_opt_out) { - StartTest(false /* null_opt_out */); - - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(opt_out ? PreviewsEligibilityReason::HOST_BLACKLISTED - : PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(0, opt_out_store_->clear_blacklist_count()); - black_list_->ClearBlackList( - start_, test_clock_.Now() + base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); - black_list_->AddPreviewNavigation(url2, opt_out, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url2, opt_out, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, opt_out_store_->clear_blacklist_count()); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(opt_out ? PreviewsEligibilityReason::HOST_BLACKLISTED - : PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url2, PreviewsType::OFFLINE, - false, &passed_reasons_)); - } -} - -TEST_F(PreviewsBlackListTest, MaxHosts) { - // Test that the black list only stores n hosts, and it stores the correct n - // hosts. - const GURL url_a("http://www.url_a.com"); - const GURL url_b("http://www.url_b.com"); - const GURL url_c("http://www.url_c.com"); - const GURL url_d("http://www.url_d.com"); - const GURL url_e("http://www.url_e.com"); - - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - const size_t stored_history_length = 1; - SetHostHistoryParam(stored_history_length); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetMaxHostInBlackListParam(2); - SetHostThresholdParam(stored_history_length); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(true /* null_opt_out */); - - black_list_->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_c, false, PreviewsType::OFFLINE); - // url_a should stay in the map, since it has an opt out time. - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_d, true, PreviewsType::OFFLINE); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_e, true, PreviewsType::OFFLINE); - // url_d and url_e should remain in the map, but url_a should be evicted. - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_d, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url_e, PreviewsType::OFFLINE, false, - &passed_reasons_)); -} - -TEST_F(PreviewsBlackListTest, SingleOptOut) { - // Test that when a user opts out of a preview, previews won't be shown until - // |single_opt_out_duration| has elapsed. - const GURL url_a("http://www.url_a.com"); - const GURL url_b("http://www.url_b.com"); - const GURL url_c("http://www.url_c.com"); - - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - const int single_opt_out_duration = 5; - SetHostHistoryParam(1); - SetHostIndifferentHistoryParam(2); - SetHostDurationParam(365); - SetMaxHostInBlackListParam(10); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetSingleOptOutDurationParam(single_opt_out_duration); - - StartTest(true /* null_opt_out */); - - black_list_->AddPreviewNavigation(url_a, false, PreviewsType::OFFLINE); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - test_clock_.Advance( - base::TimeDelta::FromSeconds(single_opt_out_duration + 1)); - - black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE); - EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - test_clock_.Advance( - base::TimeDelta::FromSeconds(single_opt_out_duration - 1)); - - EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - test_clock_.Advance( - base::TimeDelta::FromSeconds(single_opt_out_duration + 1)); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE, false, - &passed_reasons_)); -} - TEST_F(PreviewsBlackListTest, AddPreviewUMA) { base::HistogramTester histogram_tester; const GURL url("http://www.url.com"); - StartTest(false /* null_opt_out */); + StartTest(); black_list_->AddPreviewNavigation(url, false, PreviewsType::OFFLINE); histogram_tester.ExpectUniqueSample("Previews.OptOut.UserOptedOut.Offline", 0, @@ -697,356 +183,72 @@ 1); } -TEST_F(PreviewsBlackListTest, ClearingBlackListClearsRecentNavigation) { - // Tests that clearing the black list for a long amount of time (relative to - // "single_opt_out_duration_in_seconds") resets the blacklist's recent opt out - // rule. - const GURL url("http://www.url.com"); - RunClearingBlackListTest(url); +TEST_F(PreviewsBlackListTest, SessionParams) { + int duration_seconds = 5; + SetSingleOptOutDurationParam(duration_seconds); - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); + StartTest(); + + base::TimeDelta duration; + size_t history = 0; + int threshold = 0; + + EXPECT_TRUE( + black_list_->ShouldUseSessionPolicy(&duration, &history, &threshold)); + EXPECT_EQ(base::TimeDelta::FromSeconds(duration_seconds), duration); + EXPECT_EQ(1u, history); + EXPECT_EQ(1, threshold); } -TEST_F(PreviewsBlackListTest, ObserverIsNotifiedOnHostBlacklisted) { - // Tests the black list behavior when a null OptOutStore is passed in. - const GURL url_("http://www.url_.com"); +TEST_F(PreviewsBlackListTest, PersistentParams) { + int duration_days = 5; + size_t expected_history = 6; + int expected_threshold = 4; + SetHostIndifferentThresholdParam(expected_threshold); + SetHostIndifferentHistoryParam(expected_history); + SetHostIndifferentDurationParam(duration_days); - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - SetHostHistoryParam(4); - SetHostThresholdParam(2); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); + StartTest(); - StartTest(true /* null_opt_out */); + base::TimeDelta duration; + size_t history = 0; + int threshold = 0; - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url_, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - // Observer is not notified as blacklisted when the threshold does not met. - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_, true, PreviewsType::OFFLINE); - base::RunLoop().RunUntilIdle(); - EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(0)); - - // Observer is notified as blacklisted when the threshold is met. - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_, true, PreviewsType::OFFLINE); - base::RunLoop().RunUntilIdle(); - const base::Time blacklisted_time = test_clock_.Now(); - EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(1)); - EXPECT_EQ(blacklisted_time, - blacklist_delegate_.blacklisted_hosts().find(url_.host())->second); - - // Observer is not notified when the host is already blacklisted. - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(url_, true, PreviewsType::OFFLINE); - base::RunLoop().RunUntilIdle(); - EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(1)); - EXPECT_EQ(blacklisted_time, - blacklist_delegate_.blacklisted_hosts().find(url_.host())->second); - - // Observer is notified when blacklist is cleared. - EXPECT_FALSE(blacklist_delegate_.blacklist_cleared()); - - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->ClearBlackList(start_, test_clock_.Now()); - base::RunLoop().RunUntilIdle(); - - EXPECT_TRUE(blacklist_delegate_.blacklist_cleared()); - EXPECT_EQ(test_clock_.Now(), blacklist_delegate_.blacklist_cleared_time()); + EXPECT_TRUE( + black_list_->ShouldUsePersistentPolicy(&duration, &history, &threshold)); + EXPECT_EQ(base::TimeDelta::FromDays(duration_days), duration); + EXPECT_EQ(expected_history, history); + EXPECT_EQ(expected_threshold, threshold); } -TEST_F(PreviewsBlackListTest, ObserverIsNotifiedOnUserBlacklisted) { - // Tests the black list behavior when a null OptOutStore is passed in. - const GURL urls[] = { - GURL("http://www.url_0.com"), GURL("http://www.url_1.com"), - GURL("http://www.url_2.com"), GURL("http://www.url_3.com"), - }; +TEST_F(PreviewsBlackListTest, HostParams) { + int duration_days = 5; + size_t expected_history = 6; + int expected_threshold = 4; + size_t expected_max_hosts = 11; + SetHostThresholdParam(expected_threshold); + SetHostHistoryParam(expected_history); + SetHostDurationParam(duration_days); + SetMaxHostInBlackListParam(expected_max_hosts); - // Per host blacklisting should have no effect with the following params. - const size_t per_host_history = 1; - const size_t host_indifferent_history = 4; - const size_t host_indifferent_threshold = host_indifferent_history; - SetHostHistoryParam(per_host_history); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostThresholdParam(per_host_history + 1); - SetHostIndifferentThresholdParam(host_indifferent_threshold); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); + StartTest(); - StartTest(true /* null_opt_out */); + base::TimeDelta duration; + size_t history = 0; + int threshold = 0; + size_t max_hosts = 0; - // Initially no host is blacklisted, and user is not blacklisted. - EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(0)); - EXPECT_FALSE(blacklist_delegate_.user_blacklisted()); - - for (size_t i = 0; i < host_indifferent_threshold; ++i) { - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(urls[i], true, PreviewsType::OFFLINE); - base::RunLoop().RunUntilIdle(); - - EXPECT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(0)); - // Observer is notified when number of recently opt out meets - // |host_indifferent_threshold|. - EXPECT_EQ(i >= host_indifferent_threshold - 1, - blacklist_delegate_.user_blacklisted()); - } - - // Observer is notified when the user is no longer blacklisted. - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - black_list_->AddPreviewNavigation(urls[3], false, PreviewsType::OFFLINE); - base::RunLoop().RunUntilIdle(); - - EXPECT_FALSE(blacklist_delegate_.user_blacklisted()); + EXPECT_TRUE(black_list_->ShouldUseHostPolicy(&duration, &history, &threshold, + &max_hosts)); + EXPECT_EQ(base::TimeDelta::FromDays(duration_days), duration); + EXPECT_EQ(expected_history, history); + EXPECT_EQ(expected_threshold, threshold); + EXPECT_EQ(expected_max_hosts, max_hosts); } -TEST_F(PreviewsBlackListTest, ObserverIsNotifiedWhenLoadBlacklistDone) { - const GURL url_a1("http://www.url_a.com/a1"); - const GURL url_a2("http://www.url_a.com/a2"); - - // Per host blacklisting should have no effect with the following params. - const size_t per_host_history = 1; - const size_t host_indifferent_history = 4; - const size_t host_indifferent_threshold = host_indifferent_history; - SetHostHistoryParam(per_host_history); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostThresholdParam(per_host_history + 1); - SetHostIndifferentThresholdParam(host_indifferent_threshold); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(false /* null_opt_out */); - - BlacklistData::AllowedTypesAndVersions allowed_types; - allowed_types[0] = 0; - std::unique_ptr<BlacklistData> data = std::make_unique<BlacklistData>( - nullptr, - std::make_unique<BlacklistData::Policy>(base::TimeDelta::FromSeconds(365), - host_indifferent_history, - host_indifferent_threshold), - nullptr, nullptr, 0, std::move(allowed_types)); - base::SimpleTestClock test_clock; - - for (size_t i = 0; i < host_indifferent_threshold; ++i) { - test_clock.Advance(base::TimeDelta::FromSeconds(1)); - data->AddEntry("blah", true, 0, test_clock.Now(), true); - } - - std::unique_ptr<TestPreviewsOptOutStore> opt_out_store = - std::make_unique<TestPreviewsOptOutStore>(); - opt_out_store->SetBlacklistData(std::move(data)); - - EXPECT_FALSE(blacklist_delegate_.user_blacklisted()); - allowed_types.clear(); - allowed_types[static_cast<int>(PreviewsType::OFFLINE)] = 0; - auto black_list = - std::make_unique<PreviewsBlackList>(std::move(opt_out_store), &test_clock, - &blacklist_delegate_, allowed_types); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(blacklist_delegate_.user_blacklisted()); -} - -TEST_F(PreviewsBlackListTest, ObserverIsNotifiedOfHistoricalBlacklistedHosts) { - // Tests the black list behavior when a non-null OptOutStore is passed in. - const GURL url_a("http://www.url_a.com"); - const GURL url_b("http://www.url_b.com"); - - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - SetHostThresholdParam(2); - SetHostHistoryParam(4); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(false /* null_opt_out */); - - base::SimpleTestClock test_clock; - - BlacklistData::AllowedTypesAndVersions allowed_types; - allowed_types[static_cast<int>(PreviewsType::OFFLINE)] = 0; - std::unique_ptr<BlacklistData> data = std::make_unique<BlacklistData>( - nullptr, nullptr, - std::make_unique<BlacklistData::Policy>( - params::PerHostBlackListDuration(), - params::MaxStoredHistoryLengthForPerHostBlackList(), - params::PerHostBlackListOptOutThreshold()), - nullptr, params::MaxInMemoryHostsInBlackList(), std::move(allowed_types)); - - test_clock.Advance(base::TimeDelta::FromSeconds(1)); - data->AddEntry(url_a.host(), true, static_cast<int>(PreviewsType::OFFLINE), - test_clock.Now(), true); - test_clock.Advance(base::TimeDelta::FromSeconds(1)); - data->AddEntry(url_a.host(), true, static_cast<int>(PreviewsType::OFFLINE), - test_clock.Now(), true); - base::Time blacklisted_time = test_clock.Now(); - - base::RunLoop().RunUntilIdle(); - std::vector<BlacklistReason> reasons; - EXPECT_NE( - BlacklistReason::kAllowed, - data->IsAllowed(url_a.host(), static_cast<int>(PreviewsType::OFFLINE), - false, test_clock.Now(), &reasons)); - - // Host |url_b| is not blacklisted. - test_clock.Advance(base::TimeDelta::FromSeconds(1)); - data->AddEntry(url_b.host(), true, static_cast<int>(PreviewsType::OFFLINE), - test_clock.Now(), true); - - std::unique_ptr<TestPreviewsOptOutStore> opt_out_store = - std::make_unique<TestPreviewsOptOutStore>(); - opt_out_store->SetBlacklistData(std::move(data)); - - allowed_types.clear(); - allowed_types[static_cast<int>(PreviewsType::OFFLINE)] = 0; - auto black_list = std::make_unique<PreviewsBlackList>( - std::move(opt_out_store), &test_clock, &blacklist_delegate_, - std::move(allowed_types)); - base::RunLoop().RunUntilIdle(); - - ASSERT_THAT(blacklist_delegate_.blacklisted_hosts(), ::testing::SizeIs(1)); - EXPECT_EQ(blacklisted_time, - blacklist_delegate_.blacklisted_hosts().find(url_a.host())->second); -} - -TEST_F(PreviewsBlackListTest, PassedReasonsWhenBlacklistDataNotLoaded) { - // Test that IsLoadedAndAllow, push checked PreviewsEligibilityReasons to the - // |passed_reasons| vector. - const GURL url("http://www.url_.com/"); - StartTest(false /* null_opt_out */); - - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - EXPECT_EQ(0UL, passed_reasons_.size()); -} - -TEST_F(PreviewsBlackListTest, PassedReasonsWhenUserRecentlyOptedOut) { - // Test that IsLoadedAndAllow, push checked PreviewsEligibilityReasons to the - // |passed_reasons| vector. - const GURL url("http://www.url_.com/"); - StartTest(true /* null_opt_out */); - - black_list_->AddPreviewNavigation(url, true, PreviewsType::OFFLINE); - EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - EXPECT_EQ(1UL, passed_reasons_.size()); - EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - passed_reasons_[0]); -} - -TEST_F(PreviewsBlackListTest, PassedReasonsWhenUserBlacklisted) { - // Test that IsLoadedAndAllow, push checked PreviewsEligibilityReasons to the - // |passed_reasons| vector. - const GURL urls[] = { - GURL("http://www.url_0.com"), GURL("http://www.url_1.com"), - GURL("http://www.url_2.com"), GURL("http://www.url_3.com"), - }; - - // Per host blacklisting should have no effect with the following params. - const size_t per_host_history = 1; - const size_t host_indifferent_history = 4; - const size_t host_indifferent_threshold = host_indifferent_history; - SetHostHistoryParam(per_host_history); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostThresholdParam(per_host_history + 1); - SetHostIndifferentThresholdParam(host_indifferent_threshold); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(true /* null_opt_out */); - test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - - for (auto url : urls) { - black_list_->AddPreviewNavigation(url, true, PreviewsType::OFFLINE); - } - - EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED, - black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE, - false, &passed_reasons_)); - - PreviewsEligibilityReason expected_reasons[] = { - PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - }; - EXPECT_EQ(2UL, passed_reasons_.size()); - for (size_t i = 0; i < passed_reasons_.size(); i++) { - EXPECT_EQ(expected_reasons[i], passed_reasons_[i]); - } -} - -TEST_F(PreviewsBlackListTest, PassedReasonsWhenHostBlacklisted) { - // Test that IsLoadedAndAllow, push checked PreviewsEligibilityReasons to the - // |passed_reasons| vector. - const GURL url("http://www.url_a.com"); - - // Host indifferent blacklisting should have no effect with the following - // params. - const size_t host_indifferent_history = 1; - SetHostHistoryParam(4); - SetHostIndifferentHistoryParam(host_indifferent_history); - SetHostThresholdParam(2); - SetHostIndifferentThresholdParam(host_indifferent_history + 1); - SetHostDurationParam(365); - // Disable single opt out by setting duration to 0. - SetSingleOptOutDurationParam(0); - - StartTest(true /* null_opt_out */); - - black_list_->AddPreviewNavigation(url, true, PreviewsType::OFFLINE); - black_list_->AddPreviewNavigation(url, true, PreviewsType::OFFLINE); - - EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - PreviewsEligibilityReason expected_reasons[] = { - PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - PreviewsEligibilityReason::USER_BLACKLISTED, - }; - EXPECT_EQ(3UL, passed_reasons_.size()); - for (size_t i = 0; i < passed_reasons_.size(); i++) { - EXPECT_EQ(expected_reasons[i], passed_reasons_[i]); - } -} - -TEST_F(PreviewsBlackListTest, PassedReasonsWhenAllowed) { - // Test that IsLoadedAndAllow, push checked PreviewsEligibilityReasons to the - // |passed_reasons| vector. - const GURL url("http://www.url.com"); - StartTest(true /* null_opt_out */); - - EXPECT_EQ(PreviewsEligibilityReason::ALLOWED, - black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE, false, - &passed_reasons_)); - - PreviewsEligibilityReason expected_reasons[] = { - PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED, - PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT, - PreviewsEligibilityReason::USER_BLACKLISTED, - PreviewsEligibilityReason::HOST_BLACKLISTED, - }; - EXPECT_EQ(4UL, passed_reasons_.size()); - for (size_t i = 0; i < passed_reasons_.size(); i++) { - EXPECT_EQ(expected_reasons[i], passed_reasons_[i]); - } +TEST_F(PreviewsBlackListTest, TypeParams) { + StartTest(); + EXPECT_FALSE(black_list_->ShouldUseTypePolicy(nullptr, nullptr, nullptr)); } } // namespace
diff --git a/components/safe_browsing/browser/threat_details.cc b/components/safe_browsing/browser/threat_details.cc index 8a2007f8..de38dfd 100644 --- a/components/safe_browsing/browser/threat_details.cc +++ b/components/safe_browsing/browser/threat_details.cc
@@ -15,6 +15,7 @@ #include "base/bind.h" #include "base/lazy_instance.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "components/history/core/browser/history_service.h" #include "components/safe_browsing/base_ui_manager.h" @@ -91,7 +92,8 @@ return ClientSafeBrowsingReportRequest::URL_CLIENT_SIDE_MALWARE; case SB_THREAT_TYPE_AD_SAMPLE: return ClientSafeBrowsingReportRequest::AD_SAMPLE; - case SB_THREAT_TYPE_PASSWORD_REUSE: + case SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE: + case SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: return ClientSafeBrowsingReportRequest::URL_PASSWORD_PROTECTION_PHISHING; case SB_THREAT_TYPE_SUSPICIOUS_SITE: return ClientSafeBrowsingReportRequest::URL_SUSPICIOUS; @@ -251,8 +253,7 @@ const HTMLElement& element = *element_iter->second; // Delete any elements that we do not want to keep. - if (std::find(ids_to_keep.begin(), ids_to_keep.end(), element.id()) == - ids_to_keep.end()) { + if (!base::ContainsValue(ids_to_keep, element.id())) { if (element.has_resource_id()) { const std::string& resource_url = resource_id_to_url[element.resource_id()];
diff --git a/components/safe_browsing/db/v4_get_hash_protocol_manager.cc b/components/safe_browsing/db/v4_get_hash_protocol_manager.cc index e3589ea..85c42051 100644 --- a/components/safe_browsing/db/v4_get_hash_protocol_manager.cc +++ b/components/safe_browsing/db/v4_get_hash_protocol_manager.cc
@@ -531,8 +531,7 @@ ThreatMetadata md; for (const FullHashInfo& full_hash_info : full_hash_infos) { DCHECK_EQ(GetChromeUrlApiId(), full_hash_info.list_id); - DCHECK(std::find(full_hashes.begin(), full_hashes.end(), - full_hash_info.full_hash) != full_hashes.end()); + DCHECK(base::ContainsValue(full_hashes, full_hash_info.full_hash)); md.api_permissions.insert(full_hash_info.metadata.api_permissions.begin(), full_hash_info.metadata.api_permissions.end()); }
diff --git a/components/safe_browsing/db/v4_protocol_manager_util.h b/components/safe_browsing/db/v4_protocol_manager_util.h index 53033ae3..e89a204 100644 --- a/components/safe_browsing/db/v4_protocol_manager_util.h +++ b/components/safe_browsing/db/v4_protocol_manager_util.h
@@ -129,14 +129,17 @@ // DEPRECATED. Url detected by password protection service. DEPRECATED_SB_THREAT_TYPE_URL_PASSWORD_PROTECTION_PHISHING, - // Password reuse detected on low reputation page, - SB_THREAT_TYPE_PASSWORD_REUSE, + // Chrome sign in password reuse detected on low reputation page, + SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE, // A sample of an ad was collected SB_THREAT_TYPE_AD_SAMPLE, // The page loaded a resource from the Suspicious Site list. SB_THREAT_TYPE_SUSPICIOUS_SITE, + + // Enterprise password reuse detected on low reputation page, + SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE, }; using SBThreatTypeSet = base::flat_set<SBThreatType>;
diff --git a/components/safe_browsing/password_protection/mock_password_protection_service.h b/components/safe_browsing/password_protection/mock_password_protection_service.h index 763e58fb..8caf27d 100644 --- a/components/safe_browsing/password_protection/mock_password_protection_service.h +++ b/components/safe_browsing/password_protection/mock_password_protection_service.h
@@ -38,15 +38,15 @@ MOCK_METHOD0(OnPolicySpecifiedPasswordChanged, void()); MOCK_METHOD1(MaybeLogPasswordReuseDetectedEvent, void(content::WebContents*)); MOCK_METHOD1(UserClickedThroughSBInterstitial, bool(content::WebContents*)); - MOCK_METHOD1(ShowInterstitial, void(content::WebContents*)); + MOCK_METHOD2(ShowInterstitial, + void(content::WebContents*, ReusedPasswordType)); MOCK_METHOD2(IsPingingEnabled, bool(LoginReputationClientRequest::TriggerType, RequestOutcome*)); MOCK_METHOD3(ShowModalWarning, void(content::WebContents*, const std::string&, - LoginReputationClientRequest::PasswordReuseEvent:: - ReusedPasswordType)); + ReusedPasswordType)); MOCK_METHOD2(UpdateSecurityState, void(safe_browsing::SBThreatType, content::WebContents*)); MOCK_METHOD2(RemoveUnhandledSyncPasswordReuseOnURLsDeleted, @@ -60,19 +60,15 @@ void(content::WebContents*, PasswordProtectionService::RequestOutcome, const safe_browsing::LoginReputationClientResponse*)); - MOCK_METHOD3(OnUserAction, - void(content::WebContents*, WarningUIType, WarningAction)); - MOCK_METHOD4( MaybeStartPasswordFieldOnFocusRequest, void(content::WebContents*, const GURL&, const GURL&, const GURL&)); - MOCK_METHOD5( - MaybeStartProtectedPasswordEntryRequest, - void(content::WebContents*, - const GURL&, - LoginReputationClientRequest::PasswordReuseEvent::ReusedPasswordType, - const std::vector<std::string>&, - bool)); + MOCK_METHOD5(MaybeStartProtectedPasswordEntryRequest, + void(content::WebContents*, + const GURL&, + ReusedPasswordType, + const std::vector<std::string>&, + bool)); private: DISALLOW_COPY_AND_ASSIGN(MockPasswordProtectionService);
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc index 26b3467..3431d76c 100644 --- a/components/safe_browsing/password_protection/password_protection_request.cc +++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -43,6 +43,10 @@ "PasswordProtection.Verdict.SyncPasswordEntry"; const char kProtectedPasswordEntryVerdictHistogram[] = "PasswordProtection.Verdict.ProtectedPasswordEntry"; +const char kEnterprisePasswordEntryVerdictHistogram[] = + "PasswordProtection.Verdict.NonGaiaEnterprisePasswordEntry"; +const char kGSuiteSyncPasswordEntryVerdictHistogram[] = + "PasswordProtection.Verdict.GSuiteSyncPasswordEntry"; PasswordProtectionRequest::PasswordProtectionRequest( WebContents* web_contents, @@ -339,16 +343,14 @@ std::unique_ptr<LoginReputationClientResponse> response) { DCHECK_CURRENTLY_ON(BrowserThread::UI); tracker_.TryCancelAll(); - bool matches_sync_password = - reused_password_type_ == - LoginReputationClientRequest::PasswordReuseEvent::SIGN_IN_PASSWORD; if (trigger_type_ == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) { UMA_HISTOGRAM_ENUMERATION(kPasswordOnFocusRequestOutcomeHistogram, outcome, PasswordProtectionService::MAX_OUTCOME); } else { - PasswordProtectionService::LogPasswordEntryRequestOutcome( - outcome, matches_sync_password); - if (matches_sync_password) { + password_protection_service_->LogPasswordEntryRequestOutcome( + outcome, reused_password_type_); + if (reused_password_type_ == + LoginReputationClientRequest::PasswordReuseEvent::SIGN_IN_PASSWORD) { password_protection_service_->MaybeLogPasswordReuseLookupEvent( web_contents_, outcome, response.get()); } @@ -365,10 +367,25 @@ UMA_HISTOGRAM_ENUMERATION( kAnyPasswordEntryVerdictHistogram, response->verdict_type(), LoginReputationClientResponse_VerdictType_VerdictType_MAX + 1); - if (matches_sync_password) { + if (reused_password_type_ == LoginReputationClientRequest:: + PasswordReuseEvent::SIGN_IN_PASSWORD) { + if (password_protection_service_->GetSyncAccountType() == + LoginReputationClientRequest::PasswordReuseEvent::GSUITE) { + UMA_HISTOGRAM_ENUMERATION( + kGSuiteSyncPasswordEntryVerdictHistogram, + response->verdict_type(), + LoginReputationClientResponse_VerdictType_VerdictType_MAX + 1); + } UMA_HISTOGRAM_ENUMERATION( kSyncPasswordEntryVerdictHistogram, response->verdict_type(), LoginReputationClientResponse_VerdictType_VerdictType_MAX + 1); + } else if (reused_password_type_ == + LoginReputationClientRequest::PasswordReuseEvent:: + ENTERPRISE_PASSWORD) { + UMA_HISTOGRAM_ENUMERATION( + kEnterprisePasswordEntryVerdictHistogram, + response->verdict_type(), + LoginReputationClientResponse_VerdictType_VerdictType_MAX + 1); } else { UMA_HISTOGRAM_ENUMERATION( kProtectedPasswordEntryVerdictHistogram, response->verdict_type(),
diff --git a/components/safe_browsing/password_protection/password_protection_request.h b/components/safe_browsing/password_protection/password_protection_request.h index 00598b3b..ac27159 100644 --- a/components/safe_browsing/password_protection/password_protection_request.h +++ b/components/safe_browsing/password_protection/password_protection_request.h
@@ -28,6 +28,8 @@ extern const char kAnyPasswordEntryVerdictHistogram[]; extern const char kSyncPasswordEntryVerdictHistogram[]; extern const char kProtectedPasswordEntryVerdictHistogram[]; +extern const char kEnterprisePasswordEntryVerdictHistogram[]; +extern const char kGSuiteSyncPasswordEntryVerdictHistogram[]; // A request for checking if an unfamiliar login form or a password reuse event // is safe. PasswordProtectionRequest objects are owned by
diff --git a/components/safe_browsing/password_protection/password_protection_service.cc b/components/safe_browsing/password_protection/password_protection_service.cc index dce54bd..24c63cc 100644 --- a/components/safe_browsing/password_protection/password_protection_service.cc +++ b/components/safe_browsing/password_protection/password_protection_service.cc
@@ -15,6 +15,7 @@ #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_functions.h" +#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -82,6 +83,7 @@ } // namespace +// TODO(jialiul): Move all UMA consts and functions to a separate file. const char kPasswordOnFocusRequestOutcomeHistogram[] = "PasswordProtection.RequestOutcome.PasswordFieldOnFocus"; // Matches sync and/or saved password @@ -101,6 +103,23 @@ "PasswordProtection.ChromeSettingsAction.SyncPasswordEntry"; const char kSyncPasswordInterstitialHistogram[] = "PasswordProtection.InterstitialAction.SyncPasswordEntry"; +const char kEnterprisePasswordWarningDialogHistogram[] = + "PasswordProtection.ModalWarningDialogAction." + "NonGaiaEnterprisePasswordEntry"; +const char kEnterprisePasswordPageInfoHistogram[] = + "PasswordProtection.PageInfoAction.NonGaiaEnterprisePasswordEntry"; +const char kEnterprisePasswordInterstitialHistogram[] = + "PasswordProtection.InterstitialAction.NonGaiaEnterprisePasswordEntry"; +const char kEnterprisePasswordEntryRequestOutcomeHistogram[] = + "PasswordProtection.RequestOutcome.NonGaiaEnterprisePasswordEntry"; +const char kGSuiteSyncPasswordWarningDialogHistogram[] = + "PasswordProtection.ModalWarningDialogAction.GSuiteSyncPasswordEntry"; +const char kGSuiteSyncPasswordPageInfoHistogram[] = + "PasswordProtection.PageInfoAction.GSuiteSyncPasswordEntry"; +const char kGSuiteSyncPasswordInterstitialHistogram[] = + "PasswordProtection.InterstitialAction.GSuiteSyncPasswordEntry"; +const char kGSuiteSyncPasswordEntryRequestOutcomeHistogram[] = + "PasswordProtection.RequestOutcome.GSuiteSyncPasswordEntry"; PasswordProtectionService::PasswordProtectionService( const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager, @@ -135,24 +154,57 @@ hostname.find('.') != std::string::npos; } -void PasswordProtectionService::RecordWarningAction(WarningUIType ui_type, - WarningAction action) { +void PasswordProtectionService::RecordWarningAction( + WarningUIType ui_type, + WarningAction action, + ReusedPasswordType password_type) { + bool is_sign_in_password = + password_type == PasswordReuseEvent::SIGN_IN_PASSWORD; + bool is_gsuite_user = GetSyncAccountType() == PasswordReuseEvent::GSUITE; switch (ui_type) { case PAGE_INFO: - base::UmaHistogramEnumeration(kSyncPasswordPageInfoHistogram, action, - MAX_ACTION); + if (is_sign_in_password) { + base::UmaHistogramEnumeration(kSyncPasswordPageInfoHistogram, action, + MAX_ACTION); + if (is_gsuite_user) { + base::UmaHistogramEnumeration(kGSuiteSyncPasswordPageInfoHistogram, + action, MAX_ACTION); + } + } else { + base::UmaHistogramEnumeration(kEnterprisePasswordPageInfoHistogram, + action, MAX_ACTION); + } break; case MODAL_DIALOG: - base::UmaHistogramEnumeration(kSyncPasswordWarningDialogHistogram, action, - MAX_ACTION); + if (is_sign_in_password) { + base::UmaHistogramEnumeration(kSyncPasswordWarningDialogHistogram, + action, MAX_ACTION); + if (is_gsuite_user) { + base::UmaHistogramEnumeration( + kGSuiteSyncPasswordWarningDialogHistogram, action, MAX_ACTION); + } + } else { + base::UmaHistogramEnumeration(kEnterprisePasswordWarningDialogHistogram, + action, MAX_ACTION); + } break; case CHROME_SETTINGS: + DCHECK(is_sign_in_password); base::UmaHistogramEnumeration(kSyncPasswordChromeSettingsHistogram, action, MAX_ACTION); break; case INTERSTITIAL: - base::UmaHistogramEnumeration(kSyncPasswordInterstitialHistogram, action, - MAX_ACTION); + if (is_sign_in_password) { + base::UmaHistogramEnumeration(kSyncPasswordInterstitialHistogram, + action, MAX_ACTION); + if (is_gsuite_user) { + base::UmaHistogramEnumeration( + kGSuiteSyncPasswordInterstitialHistogram, action, MAX_ACTION); + } + } else { + base::UmaHistogramEnumeration(kEnterprisePasswordInterstitialHistogram, + action, MAX_ACTION); + } break; case NOT_USED: NOTREACHED(); @@ -398,7 +450,7 @@ RequestOutcome reason; if (CanSendPing(LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, main_frame_url, - /*matches_sync_password=*/false, &reason)) { + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, &reason)) { StartRequest(web_contents, main_frame_url, password_form_action, password_form_frame_url, PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, @@ -419,9 +471,7 @@ RequestOutcome reason; if (CanSendPing(LoginReputationClientRequest::PASSWORD_REUSE_EVENT, - main_frame_url, - reused_password_type == PasswordReuseEvent::SIGN_IN_PASSWORD, - &reason)) { + main_frame_url, reused_password_type, &reason)) { StartRequest(web_contents, main_frame_url, GURL(), GURL(), reused_password_type, matching_domains, LoginReputationClientRequest::PASSWORD_REUSE_EVENT, @@ -429,7 +479,7 @@ } else { MaybeLogPasswordReuseLookupEvent(web_contents, reason, nullptr); if (reason == PASSWORD_ALERT_MODE) { - ShowInterstitial(web_contents); + ShowInterstitial(web_contents, reused_password_type); } } } @@ -437,7 +487,7 @@ bool PasswordProtectionService::CanSendPing( LoginReputationClientRequest::TriggerType trigger_type, const GURL& main_frame_url, - bool matches_sync_password, + ReusedPasswordType password_type, RequestOutcome* reason) { *reason = URL_NOT_VALID_FOR_REPUTATION_COMPUTING; if (IsPingingEnabled(trigger_type, reason) && @@ -445,7 +495,7 @@ CanGetReputationOfURL(main_frame_url)) { return true; } - RecordNoPingingReason(trigger_type, *reason, matches_sync_password); + RecordNoPingingReason(trigger_type, *reason, password_type); return false; } @@ -733,8 +783,7 @@ bool PasswordProtectionService::PathVariantsMatchCacheExpression( const std::vector<std::string>& generated_paths, const std::string& cache_expression_path) { - return std::find(generated_paths.begin(), generated_paths.end(), - cache_expression_path) != generated_paths.end(); + return base::ContainsValue(generated_paths, cache_expression_path); } bool PasswordProtectionService::IsCacheExpired(int cache_creation_time, @@ -789,7 +838,7 @@ void PasswordProtectionService::RecordNoPingingReason( LoginReputationClientRequest::TriggerType trigger_type, RequestOutcome reason, - bool matches_sync_password) { + ReusedPasswordType password_type) { DCHECK(trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE || trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT); @@ -799,18 +848,24 @@ return; } - LogPasswordEntryRequestOutcome(reason, matches_sync_password); + LogPasswordEntryRequestOutcome(reason, password_type); } -// static void PasswordProtectionService::LogPasswordEntryRequestOutcome( RequestOutcome reason, - bool matches_sync_password) { + ReusedPasswordType password_type) { base::UmaHistogramEnumeration(kAnyPasswordEntryRequestOutcomeHistogram, reason, MAX_OUTCOME); - if (matches_sync_password) { + if (password_type == PasswordReuseEvent::SIGN_IN_PASSWORD) { + if (GetSyncAccountType() == PasswordReuseEvent::GSUITE) { + base::UmaHistogramEnumeration( + kGSuiteSyncPasswordEntryRequestOutcomeHistogram, reason, MAX_OUTCOME); + } base::UmaHistogramEnumeration(kSyncPasswordEntryRequestOutcomeHistogram, reason, MAX_OUTCOME); + } else if (password_type == PasswordReuseEvent::ENTERPRISE_PASSWORD) { + base::UmaHistogramEnumeration( + kEnterprisePasswordEntryRequestOutcomeHistogram, reason, MAX_OUTCOME); } else { base::UmaHistogramEnumeration( kProtectedPasswordEntryRequestOutcomeHistogram, reason, MAX_OUTCOME);
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h index 5bffbd9e..8282c99 100644 --- a/components/safe_browsing/password_protection/password_protection_service.h +++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -56,6 +56,15 @@ extern const char kSyncPasswordWarningDialogHistogram[]; extern const char kSyncPasswordPageInfoHistogram[]; extern const char kSyncPasswordChromeSettingsHistogram[]; +extern const char kSyncPasswordInterstitialHistogram[]; +extern const char kEnterprisePasswordEntryRequestOutcomeHistogram[]; +extern const char kEnterprisePasswordWarningDialogHistogram[]; +extern const char kEnterprisePasswordPageInfoHistogram[]; +extern const char kEnterprisePasswordInterstitialHistogram[]; +extern const char kGSuiteSyncPasswordEntryRequestOutcomeHistogram[]; +extern const char kGSuiteSyncPasswordWarningDialogHistogram[]; +extern const char kGSuiteSyncPasswordPageInfoHistogram[]; +extern const char kGSuiteSyncPasswordInterstitialHistogram[]; using ReusedPasswordType = LoginReputationClientRequest::PasswordReuseEvent::ReusedPasswordType; @@ -197,8 +206,10 @@ // (6) Its hostname is a dotless domain. static bool CanGetReputationOfURL(const GURL& url); - // Records user action to corresponding UMA histograms. - void RecordWarningAction(WarningUIType ui_type, WarningAction action); + // Records user action on warnings to corresponding UMA histograms. + void RecordWarningAction(WarningUIType ui_type, + WarningAction action, + ReusedPasswordType password_type); // If we want to show password reuse modal warning. bool ShouldShowModalWarning( @@ -213,20 +224,16 @@ ReusedPasswordType reused_password_type) = 0; // Shows chrome://reset-password interstitial. - virtual void ShowInterstitial(content::WebContents* web_contens) = 0; - - // Called when user interacts with warning UIs. - virtual void OnUserAction(content::WebContents* web_contents, - WarningUIType ui_type, - WarningAction action) = 0; + virtual void ShowInterstitial(content::WebContents* web_contens, + ReusedPasswordType password_type) = 0; virtual void UpdateSecurityState(safe_browsing::SBThreatType threat_type, content::WebContents* web_contents) = 0; // Log the |reason| to several UMA metrics, depending on the value - // of |matches_sync_password|. - static void LogPasswordEntryRequestOutcome(RequestOutcome reason, - bool matches_sync_password); + // of |password_type|. + void LogPasswordEntryRequestOutcome(RequestOutcome reason, + ReusedPasswordType password_type); // If user has clicked through any Safe Browsing interstitial on this given // |web_contents|. @@ -285,10 +292,10 @@ // and if Safe Browsing can compute reputation of |main_frame_url| (e.g. // Safe Browsing is not able to compute reputation of a private IP or // a local host). Update |reason| if sending ping is not allowed. - // |matches_sync_password| is used for UMA metric recording. + // |password_type| is used for UMA metric recording. bool CanSendPing(LoginReputationClientRequest::TriggerType trigger_type, const GURL& main_frame_url, - bool matches_sync_password, + ReusedPasswordType password_type, RequestOutcome* reason); // Called by a PasswordProtectionRequest instance when it finishes to remove @@ -427,10 +434,10 @@ const LoginReputationClientResponse* verdict, const base::Time& receive_time); - static void RecordNoPingingReason( + void RecordNoPingingReason( LoginReputationClientRequest::TriggerType trigger_type, RequestOutcome reason, - bool matches_sync_password); + ReusedPasswordType password_type); // Number of verdict stored for this profile for password on focus pings. int stored_verdict_count_password_on_focus_;
diff --git a/components/safe_browsing/proto/csd.proto b/components/safe_browsing/proto/csd.proto index 26745d8..e6cfcaa 100644 --- a/components/safe_browsing/proto/csd.proto +++ b/components/safe_browsing/proto/csd.proto
@@ -598,7 +598,16 @@ // https://opensource.apple.com/source/xnu/xnu-2782.1.97/bsd/sys/codesign.h optional bytes udif_code_signature = 40; - // next available tag number: 51; + // Mac-only. A detached code signature contains the DER-encoded PKCS7 data + // of a codesigned artifact. Detached signatures are used for signing files + // that are not Mach-O and thus cannot have a LC_CODE_SIGNATURE load command. + message DetachedCodeSignature { + required string file_name = 1; + required bytes contents = 2; + } + repeated DetachedCodeSignature detached_code_signature = 59; + + // next available tag number: 60; } message ReferrerChainOptions {
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc index bcb2736..1c945fe 100644 --- a/components/search_engines/template_url.cc +++ b/components/search_engines/template_url.cc
@@ -15,6 +15,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/metrics/field_trial.h" +#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" @@ -1441,7 +1442,7 @@ base::string16* encoded_original_query) const { std::vector<std::string> encodings(input_encodings()); - if (std::find(encodings.begin(), encodings.end(), "UTF-8") == encodings.end()) + if (!base::ContainsValue(encodings, "UTF-8")) encodings.push_back("UTF-8"); for (auto i = encodings.begin(); i != encodings.end(); ++i) { if (TryEncoding(search_terms_args.search_terms,
diff --git a/components/security_interstitials/content/unsafe_resource.cc b/components/security_interstitials/content/unsafe_resource.cc index 6a29eb1..f9693b5 100644 --- a/components/security_interstitials/content/unsafe_resource.cc +++ b/components/security_interstitials/content/unsafe_resource.cc
@@ -47,8 +47,12 @@ case safe_browsing::SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE: // Ad sampling happens in the background. case safe_browsing::SB_THREAT_TYPE_AD_SAMPLE: - // Password reuse warning happens after the page is finished loading. - case safe_browsing::SB_THREAT_TYPE_PASSWORD_REUSE: + // Sign-in password reuse warning happens after the page is finished + // loading. + case safe_browsing::SB_THREAT_TYPE_SIGN_IN_PASSWORD_REUSE: + // Enterprise password reuse warning happens after the page is finished + // loading. + case safe_browsing::SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE: // Suspicious site collection happens in the background case safe_browsing::SB_THREAT_TYPE_SUSPICIOUS_SITE: return false;
diff --git a/components/security_interstitials/content/unsafe_resource.h b/components/security_interstitials/content/unsafe_resource.h index 5f7a488..dfa70cb6 100644 --- a/components/security_interstitials/content/unsafe_resource.h +++ b/components/security_interstitials/content/unsafe_resource.h
@@ -68,7 +68,7 @@ base::Callback<content::WebContents*(void)> web_contents_getter; safe_browsing::ThreatSource threat_source; // |token| field is only set if |threat_type| is - // SB_THREAT_TYPE_PASSWORD_REUSE. + // SB_THREAT_TYPE_*_PASSWORD_REUSE. std::string token; };
diff --git a/components/security_state/core/security_state.h b/components/security_state/core/security_state.h index 4e6002a..d50c445a 100644 --- a/components/security_state/core/security_state.h +++ b/components/security_state/core/security_state.h
@@ -90,7 +90,8 @@ MALICIOUS_CONTENT_STATUS_MALWARE, MALICIOUS_CONTENT_STATUS_UNWANTED_SOFTWARE, MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING, - MALICIOUS_CONTENT_STATUS_PASSWORD_REUSE, + MALICIOUS_CONTENT_STATUS_SIGN_IN_PASSWORD_REUSE, + MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE, }; // Describes the security status of a page or request. This is the
diff --git a/components/services/pdf_compositor/pdf_compositor_service.cc b/components/services/pdf_compositor/pdf_compositor_service.cc index e75e34f..3cd761e3 100644 --- a/components/services/pdf_compositor/pdf_compositor_service.cc +++ b/components/services/pdf_compositor/pdf_compositor_service.cc
@@ -25,7 +25,7 @@ #include "content/public/child/dwrite_font_proxy_init_win.h" #elif defined(OS_MACOSX) #include "third_party/blink/public/platform/platform.h" -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #elif defined(OS_POSIX) && !defined(OS_ANDROID) #include "third_party/blink/public/platform/platform.h" #endif
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn index 5f31bc4..e14179b 100644 --- a/components/signin/core/browser/BUILD.gn +++ b/components/signin/core/browser/BUILD.gn
@@ -134,6 +134,7 @@ "//components/prefs", "//google_apis", "//net", + "//services/network/public/cpp", "//ui/gfx", "//url", ] @@ -214,6 +215,8 @@ "//components/webdata/common", "//google_apis:test_support", "//net:test_support", + "//services/network:test_support", + "//services/network/public/cpp", "//testing/gtest", ] }
diff --git a/components/signin/core/browser/DEPS b/components/signin/core/browser/DEPS index 360662e07..94b8327 100644 --- a/components/signin/core/browser/DEPS +++ b/components/signin/core/browser/DEPS
@@ -6,6 +6,8 @@ "+components/metrics", "+google/cacheinvalidation", "+jni", + "+services/network/public/cpp", + "+services/network/test", "+third_party/re2", "+ui/gfx", ]
diff --git a/components/signin/core/browser/account_fetcher_service.cc b/components/signin/core/browser/account_fetcher_service.cc index 255c520..00cef45 100644 --- a/components/signin/core/browser/account_fetcher_service.cc +++ b/components/signin/core/browser/account_fetcher_service.cc
@@ -21,14 +21,13 @@ #include "components/signin/core/browser/signin_client.h" #include "components/signin/core/browser/signin_switches.h" #include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace { const base::TimeDelta kRefreshFromTokenServiceDelay = base::TimeDelta::FromHours(24); -constexpr int kAccountImageDownloadSize = 64; - bool AccountSupportsUserInfo(const std::string& account_id) { // Supervised users use a specially scoped token which when used for general // purposes causes the token service to raise spurious auth errors. @@ -43,6 +42,8 @@ const char AccountFetcherService::kLastUpdatePref[] = "account_tracker_service_last_update"; +const int AccountFetcherService::kAccountImageDownloadSize = 64; + // AccountFetcherService implementation AccountFetcherService::AccountFetcherService() : account_tracker_service_(nullptr), @@ -266,7 +267,7 @@ // not be available yet when |Initialize| is called. if (!image_fetcher_) { image_fetcher_ = std::make_unique<image_fetcher::ImageFetcherImpl>( - std::move(image_decoder_), signin_client_->GetURLRequestContext()); + std::move(image_decoder_), signin_client_->GetURLLoaderFactory()); } return image_fetcher_.get(); }
diff --git a/components/signin/core/browser/account_fetcher_service.h b/components/signin/core/browser/account_fetcher_service.h index 993fa67..9958ff8 100644 --- a/components/signin/core/browser/account_fetcher_service.h +++ b/components/signin/core/browser/account_fetcher_service.h
@@ -51,6 +51,9 @@ // time the AccountTrackerService was updated. static const char kLastUpdatePref[]; + // Size used for downloading account pictures. Exposed for tests. + static const int kAccountImageDownloadSize; + AccountFetcherService(); ~AccountFetcherService() override;
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc index c51eb55d..8922e2b 100644 --- a/components/signin/core/browser/account_reconcilor.cc +++ b/components/signin/core/browser/account_reconcilor.cc
@@ -15,6 +15,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "components/signin/core/browser/account_reconcilor_delegate.h" @@ -471,8 +472,7 @@ chrome_accounts, gaia_accounts, primary_account, first_execution_); // |first_account| must be in |chrome_accounts|. DCHECK(first_account.empty() || - (std::find(chrome_accounts.begin(), chrome_accounts.end(), - first_account) != chrome_accounts.end())); + base::ContainsValue(chrome_accounts, first_account)); size_t number_gaia_accounts = gaia_accounts.size(); bool first_account_mismatch = (number_gaia_accounts > 0) && (first_account != gaia_accounts[0].id); @@ -483,9 +483,7 @@ int removed_from_cookie = 0; for (size_t i = 0; i < number_gaia_accounts; ++i) { if (gaia_accounts[i].valid && - chrome_accounts.end() == std::find(chrome_accounts.begin(), - chrome_accounts.end(), - gaia_accounts[i].id)) { + !base::ContainsValue(chrome_accounts, gaia_accounts[i].id)) { ++removed_from_cookie; } }
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc index bb6516c..980e2d55 100644 --- a/components/signin/core/browser/account_tracker_service_unittest.cc +++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -18,6 +18,7 @@ #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/avatar_icon_util.h" #include "components/signin/core/browser/child_account_info_fetcher.h" #include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/signin_pref_names.h" @@ -81,6 +82,14 @@ "/AAAAAAAAAAI/AAAAAAAAACQ/Efg/photo.jpg"; } +std::string AccountIdToPictureURLWithSize(const std::string& account_id) { + return signin::GetAvatarImageURLWithOptions( + GURL(AccountIdToPictureURL(account_id)), + AccountFetcherService::kAccountImageDownloadSize, + true /* no_silhouette */) + .spec(); +} + void CheckAccountDetails(const std::string& account_id, const AccountInfo& info) { EXPECT_EQ(account_id, info.account_id); @@ -267,9 +276,7 @@ class AccountTrackerServiceTest : public testing::Test { public: - AccountTrackerServiceTest() - : next_image_data_fetcher_id_( - image_fetcher::ImageDataFetcher::kFirstUrlFetcherId) {} + AccountTrackerServiceTest() {} ~AccountTrackerServiceTest() override {} @@ -353,6 +360,12 @@ } SigninClient* signin_client() { return signin_client_.get(); } + // Images go through test_url_loader_factory(); others use + // |test_fetcher_factory_| for now. + network::TestURLLoaderFactory* test_url_loader_factory() { + return signin_client_->test_url_loader_factory(); + } + protected: base::test::ScopedTaskEnvironment scoped_task_environment_; @@ -367,8 +380,6 @@ std::unique_ptr<AccountFetcherService> account_fetcher_; std::unique_ptr<AccountTrackerService> account_tracker_; std::unique_ptr<TestSigninClient> signin_client_; - - int next_image_data_fetcher_id_; }; void AccountTrackerServiceTest::ReturnFetchResults( @@ -406,12 +417,16 @@ void AccountTrackerServiceTest::ReturnAccountImageFetchSuccess( const std::string& account_id) { - ReturnFetchResults(next_image_data_fetcher_id_++, net::HTTP_OK, "image data"); + test_url_loader_factory()->AddResponse( + AccountIdToPictureURLWithSize(account_id), "image data"); + scoped_task_environment_.RunUntilIdle(); } void AccountTrackerServiceTest::ReturnAccountImageFetchFailure( const std::string& account_id) { - ReturnFetchResults(next_image_data_fetcher_id_++, net::HTTP_BAD_REQUEST, ""); + test_url_loader_factory()->AddResponse( + AccountIdToPictureURLWithSize(account_id), "", net::HTTP_BAD_REQUEST); + scoped_task_environment_.RunUntilIdle(); } TEST_F(AccountTrackerServiceTest, Basic) {
diff --git a/components/signin/core/browser/child_account_info_fetcher_impl.cc b/components/signin/core/browser/child_account_info_fetcher_impl.cc index faee2aec..64bdd2b 100644 --- a/components/signin/core/browser/child_account_info_fetcher_impl.cc +++ b/components/signin/core/browser/child_account_info_fetcher_impl.cc
@@ -4,6 +4,7 @@ #include "components/signin/core/browser/child_account_info_fetcher_impl.h" +#include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/trace_event/trace_event.h" #include "base/values.h" @@ -127,10 +128,8 @@ std::vector<std::string> service_flags = base::SplitString( services_iter->second, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - bool is_child_account = - std::find(service_flags.begin(), service_flags.end(), - AccountTrackerService::kChildAccountServiceFlag) != - service_flags.end(); + bool is_child_account = base::ContainsValue( + service_flags, AccountTrackerService::kChildAccountServiceFlag); if (!is_child_account && invalidation_service_) { // Don't bother listening for invalidations as a non-child account can't // become a child account.
diff --git a/components/signin/core/browser/signin_client.h b/components/signin/core/browser/signin_client.h index eba0efb..fbaf5c8 100644 --- a/components/signin/core/browser/signin_client.h +++ b/components/signin/core/browser/signin_client.h
@@ -30,6 +30,10 @@ class URLRequestContextGetter; } +namespace network { +class SharedURLLoaderFactory; +} + // An interface that needs to be supplied to the Signin component by its // embedder. class SigninClient : public KeyedService { @@ -70,11 +74,13 @@ virtual std::string GetSigninScopedDeviceId() = 0; // Returns the URL request context information associated with the client. + // DEPRECATED, new code should be using GetURLLoaderFactory instead. virtual net::URLRequestContextGetter* GetURLRequestContext() = 0; - // Returns whether the user's credentials should be merged into the cookie - // jar on signin completion. - virtual bool ShouldMergeSigninCredentialsIntoCookieJar() = 0; + // Returns the SharedURLLoaderFactory that should be used to fetch resources + // associated with the client. + virtual scoped_refptr<network::SharedURLLoaderFactory> + GetURLLoaderFactory() = 0; // Returns a string containing the version info of the product in which the // Signin component is being used.
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc index 2791801..afc3a99 100644 --- a/components/signin/core/browser/signin_manager.cc +++ b/components/signin/core/browser/signin_manager.cc
@@ -393,7 +393,8 @@ } void SigninManager::MergeSigninCredentialIntoCookieJar() { - if (!client_->ShouldMergeSigninCredentialsIntoCookieJar()) +#if !defined(OS_IOS) + if (account_consistency_ != signin::AccountConsistencyMethod::kMirror) return; if (!IsAuthenticated()) @@ -401,6 +402,7 @@ cookie_manager_service_->AddAccountToCookie(GetAuthenticatedAccountId(), "ChromiumSigninManager"); +#endif // !defined(OS_IOS) } void SigninManager::CompletePendingSignin() {
diff --git a/components/signin/core/browser/test_signin_client.cc b/components/signin/core/browser/test_signin_client.cc index 8eb66dd..e32875f 100644 --- a/components/signin/core/browser/test_signin_client.cc +++ b/components/signin/core/browser/test_signin_client.cc
@@ -11,10 +11,14 @@ #include "components/signin/core/browser/webdata/token_service_table.h" #include "components/webdata/common/web_data_service_base.h" #include "components/webdata/common/web_database_service.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" TestSigninClient::TestSigninClient(PrefService* pref_service) - : pref_service_(pref_service), + : shared_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)), + pref_service_(pref_service), are_signin_cookies_allowed_(true), network_calls_delayed_(false) {} @@ -48,6 +52,11 @@ return request_context_.get(); } +scoped_refptr<network::SharedURLLoaderFactory> +TestSigninClient::GetURLLoaderFactory() { + return shared_factory_; +} + void TestSigninClient::SetURLRequestContext( net::URLRequestContextGetter* request_context) { request_context_ = request_context; @@ -70,10 +79,6 @@ database_->Init(); } -bool TestSigninClient::ShouldMergeSigninCredentialsIntoCookieJar() { - return true; -} - std::unique_ptr<SigninClient::CookieChangeSubscription> TestSigninClient::AddCookieChangeCallback(const GURL& url, const std::string& name,
diff --git a/components/signin/core/browser/test_signin_client.h b/components/signin/core/browser/test_signin_client.h index 3aeb831..f10604eb 100644 --- a/components/signin/core/browser/test_signin_client.h +++ b/components/signin/core/browser/test_signin_client.h
@@ -17,6 +17,9 @@ #include "components/signin/core/browser/signin_client.h" #include "net/cookies/cookie_change_dispatcher.h" #include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" class PrefService; @@ -59,16 +62,21 @@ // Returns the empty string. std::string GetProductVersion() override; - // Returns a TestURLRequestContextGetter or an manually provided - // URLRequestContextGetter. + // Returns a manually provided URLRequestContextGetter. net::URLRequestContextGetter* GetURLRequestContext() override; - // For testing purposes, can override the TestURLRequestContextGetter created - // in the default constructor. + // Tells GetURLRequestContext() what to return. void SetURLRequestContext(net::URLRequestContextGetter* request_context); - // Returns true. - bool ShouldMergeSigninCredentialsIntoCookieJar() override; + // Wraps the test_url_loader_factory(). Note that this is totally independent + // of GetURLRequestContext(), so you may need to set some things differently + // based on what API the consumer is using, while transition away from + // URLRequestContextGetter is going on. + scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; + + network::TestURLLoaderFactory* test_url_loader_factory() { + return &test_url_loader_factory_; + } // Registers |callback| and returns the subscription. // Note that |callback| will never be called. @@ -108,6 +116,9 @@ private: base::ScopedTempDir temp_dir_; scoped_refptr<net::URLRequestContextGetter> request_context_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; + scoped_refptr<TokenWebData> database_; PrefService* pref_service_; bool are_signin_cookies_allowed_;
diff --git a/components/strings/components_strings_am.xtb b/components/strings/components_strings_am.xtb index 855a68c..df85d60 100644 --- a/components/strings/components_strings_am.xtb +++ b/components/strings/components_strings_am.xtb
@@ -809,6 +809,7 @@ <translation id="6891596781022320156">የመመሪያ ደረጃ አይደገፍም።</translation> <translation id="6895330447102777224">የእርስዎ ካርድ ተረጋግጧል</translation> <translation id="6897140037006041989">የተጠቀሚ ተወካይ</translation> +<translation id="6903319715792422884">አንዳንድ <ph name="BEGIN_WHITEPAPER_LINK" />የሥርዓት መረጃ እና የገጽ ይዘት<ph name="END_WHITEPAPER_LINK" />ን ወደ Google በመላክ የጥንቃቄ አሰሳን ለማሻሻል እንዲቻል ያግዙ።<ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">ተጠቃሚ፦</translation> <translation id="6945221475159498467">ይምረጡ</translation> <translation id="6948701128805548767">የመውሰጃ ዘዴዎችን እና መስፈርቶችን ለመመልከት አድራሻ ይምረጡ</translation> @@ -1013,6 +1014,7 @@ <translation id="8308427013383895095">በአውታረመረብ ግንኙነት ችግር ምክንያት የትርጉም ስራው ተሰናክሏል።</translation> <translation id="8311129316111205805">ክፍለ-ጊዜን ጫን</translation> <translation id="8332188693563227489">የ<ph name="HOST_NAME" /> መዳረሻ ተከልክሏል</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">በእርስዎ ደህንነት ላይ የሚያመጣቸውን ስጋቶች ከተረዱ አደገኛ ፕሮግራሞቹ ከመወገዳቸው በፊት <ph name="BEGIN_LINK" />ይህን ጣቢያ መጎብኘት<ph name="END_LINK" /> ይችላሉ።</translation> <translation id="8349305172487531364">የዕልባቶች አሞሌ</translation> <translation id="8363502534493474904">የአውሮፕላን ሁነታን ማጥፋት</translation>
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb index f7d4c0c..c2d8b26 100644 --- a/components/strings/components_strings_ar.xtb +++ b/components/strings/components_strings_ar.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">مستوى السياسة غير مدعوم.</translation> <translation id="6895330447102777224">تم التأكد من بطاقتك</translation> <translation id="6897140037006041989">وكيل المستخدم</translation> +<translation id="6903319715792422884">يمكنك المساعدة في تحسين التصفُّح الآمن عن طريق إرسال بعض <ph name="BEGIN_WHITEPAPER_LINK" />معلومات النظام ومحتوى الصفحة<ph name="END_WHITEPAPER_LINK" /> إلى Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">المستخدم:</translation> <translation id="6945221475159498467">تحديد</translation> <translation id="6948701128805548767">لعرض طرق الاستلام ومتطلباته، حدِّد عنوانًا</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">تعذّرت الترجمة بسبب حدوث مشكلة في الاتصال بالشبكة.</translation> <translation id="8311129316111205805">تحميل الجلسة</translation> <translation id="8332188693563227489">تم رفض الدخول إلى <ph name="HOST_NAME" />.</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">إذا كنت على دراية بالمخاطر التي تهدد أمانك، يمكنك <ph name="BEGIN_LINK" />زيارة هذا الموقع<ph name="END_LINK" /> قبل أن تتم إزالة البرامج الضارة.</translation> <translation id="8349305172487531364">شريط الإشارات</translation> <translation id="8363502534493474904">إيقاف تشغيل وضع الطائرة</translation>
diff --git a/components/strings/components_strings_bg.xtb b/components/strings/components_strings_bg.xtb index 685548a9..957b2f7 100644 --- a/components/strings/components_strings_bg.xtb +++ b/components/strings/components_strings_bg.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Нивото на правилото не се поддържа.</translation> <translation id="6895330447102777224">Картата ви е потвърдена</translation> <translation id="6897140037006041989">Потребителски агент</translation> +<translation id="6903319715792422884">Помогнете за подобряването на Безопасно сърфиране, като ни изпращате <ph name="BEGIN_WHITEPAPER_LINK" />системна информация и част от съдържанието на страниците<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Потребител:</translation> <translation id="6945221475159498467">Изберете</translation> <translation id="6948701128805548767">За да видите начините на вземане и изискванията, изберете адрес</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Преводът не бе успешен поради проблем с връзката към мрежата.</translation> <translation id="8311129316111205805">Зареждане на сесията</translation> <translation id="8332188693563227489">Достъпът до <ph name="HOST_NAME" /> бе отказан</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Ако разбирате рисковете за сигурността си, може <ph name="BEGIN_LINK" />да посетите този сайт<ph name="END_LINK" /> преди премахването на опасните програми.</translation> <translation id="8349305172487531364">Лента на отметките</translation> <translation id="8363502534493474904">Изключете самолетния режим.</translation>
diff --git a/components/strings/components_strings_bn.xtb b/components/strings/components_strings_bn.xtb index 5625127..74db9621 100644 --- a/components/strings/components_strings_bn.xtb +++ b/components/strings/components_strings_bn.xtb
@@ -1099,6 +1099,7 @@ <translation id="9148507642005240123">&সম্পাদনাকে পূর্বাবস্থায় ফেরান</translation> <translation id="9154194610265714752">আপডেট রয়েছে</translation> <translation id="9157595877708044936">সেট আপ হচ্ছে...</translation> +<translation id="9168814207360376865">আপনি কোনও পেমেন্ট পদ্ধতি সেভ করেছেন কিনা তা সাইটগুলিকে যাচাই করতে দিন</translation> <translation id="9169664750068251925">এই সাইটে সর্বদা অবরোধ করুন</translation> <translation id="9170848237812810038">&পূর্বাবস্থায় ফিরুন</translation> <translation id="917450738466192189">সার্ভারের শংসাপত্র অকার্যকর৷</translation>
diff --git a/components/strings/components_strings_ca.xtb b/components/strings/components_strings_ca.xtb index 9aa78adf..f621699 100644 --- a/components/strings/components_strings_ca.xtb +++ b/components/strings/components_strings_ca.xtb
@@ -1021,7 +1021,7 @@ <translation id="8363502534493474904">Desactiva el mode d'avió.</translation> <translation id="8364627913115013041">No s'ha definit.</translation> <translation id="8368476060205742148">Serveis de Google Play</translation> -<translation id="8380941800586852976">Perillosa</translation> +<translation id="8380941800586852976">Perillós</translation> <translation id="8382348898565613901">Les adreces d'interès que has visitat fa poc es mostren aquí</translation> <translation id="8398259832188219207">Informe d'error penjat el <ph name="UPLOAD_TIME" /></translation> <translation id="8412145213513410671">Bloqueigs (<ph name="CRASH_COUNT" />)</translation>
diff --git a/components/strings/components_strings_da.xtb b/components/strings/components_strings_da.xtb index 4f29c1b..466e1c00 100644 --- a/components/strings/components_strings_da.xtb +++ b/components/strings/components_strings_da.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Politikniveauet understøttes ikke.</translation> <translation id="6895330447102777224">Dit kort er bekræftet</translation> <translation id="6897140037006041989">Brugeragent</translation> +<translation id="6903319715792422884">Hjælp med at forbedre Beskyttet browsing ved at sende nogle <ph name="BEGIN_WHITEPAPER_LINK" />systemoplysninger og noget sideindhold<ph name="END_WHITEPAPER_LINK" /> til Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Bruger:</translation> <translation id="6945221475159498467">Vælg</translation> <translation id="6948701128805548767">Vælg en adresse for at se afhentningsmetoder og -krav</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Oversættelsen mislykkedes på grund af problemer med netværksforbindelsen.</translation> <translation id="8311129316111205805">Indlæs session</translation> <translation id="8332188693563227489">Adgangen til <ph name="HOST_NAME" /> blev nægtet</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Hvis du er indforstået med de forbundne sikkerhedsrisici, kan du <ph name="BEGIN_LINK" />besøge dette website<ph name="END_LINK" />, inden de skadelige programmer fjernes.</translation> <translation id="8349305172487531364">Bogmærkelinje</translation> <translation id="8363502534493474904">Deaktivere flytilstand</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">&Fortryd redigering</translation> <translation id="9154194610265714752">Opdateret</translation> <translation id="9157595877708044936">Konfigurerer...</translation> +<translation id="9168814207360376865">Tillad, at websites tjekker, om du har nogen gemte betalingsmetoder</translation> <translation id="9169664750068251925">Bloker altid på dette website</translation> <translation id="9170848237812810038">&Fortryd</translation> <translation id="9171296965991013597">Vil du lukke appen?</translation>
diff --git a/components/strings/components_strings_de.xtb b/components/strings/components_strings_de.xtb index f34c552..b9e0dbe 100644 --- a/components/strings/components_strings_de.xtb +++ b/components/strings/components_strings_de.xtb
@@ -809,6 +809,7 @@ <translation id="6891596781022320156">Richtlinienebene wird nicht unterstützt.</translation> <translation id="6895330447102777224">Ihre Karte wurde bestätigt</translation> <translation id="6897140037006041989">User-Agent</translation> +<translation id="6903319715792422884">Sie können uns dabei helfen, Safe Browsing weiter zu verbessern, <ph name="BEGIN_WHITEPAPER_LINK" />indem Sie einige Systeminformationen und Seiteninhalte an Google senden<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Nutzer:</translation> <translation id="6945221475159498467">Auswählen</translation> <translation id="6948701128805548767">Wählen Sie eine Adresse aus, um Abholoptionen und -anforderungen zu sehen</translation> @@ -1013,6 +1014,7 @@ <translation id="8308427013383895095">Die Übersetzung ist aufgrund eines Problems mit der Netzwerkverbindung fehlgeschlagen.</translation> <translation id="8311129316111205805">Sitzung laden</translation> <translation id="8332188693563227489">Der Zugriff auf <ph name="HOST_NAME" /> wurde verweigert</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Wenn Sie die Sicherheitsrisiken kennen, können Sie <ph name="BEGIN_LINK" />diese Website aufrufen<ph name="END_LINK" />, bevor die schädlichen Programme entfernt wurden.</translation> <translation id="8349305172487531364">Lesezeichenleiste</translation> <translation id="8363502534493474904">Flugmodus ausschalten</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">&Bearbeiten rückgängig machen</translation> <translation id="9154194610265714752">Aktualisiert</translation> <translation id="9157595877708044936">Einrichtung läuft...</translation> +<translation id="9168814207360376865">Ermöglicht Websites zu überprüfen, ob Sie eine Zahlungsmethode gespeichert haben</translation> <translation id="9169664750068251925">Auf dieser Website immer blockieren</translation> <translation id="9170848237812810038">&Rückgängig</translation> <translation id="9171296965991013597">App schließen?</translation>
diff --git a/components/strings/components_strings_el.xtb b/components/strings/components_strings_el.xtb index 32e4e86..d67bc51 100644 --- a/components/strings/components_strings_el.xtb +++ b/components/strings/components_strings_el.xtb
@@ -811,6 +811,7 @@ <translation id="6891596781022320156">Το επίπεδο πολιτικής δεν υποστηρίζεται.</translation> <translation id="6895330447102777224">Η κάρτα σας επιβεβαιώθηκε</translation> <translation id="6897140037006041989">Παράγοντας χρήστη</translation> +<translation id="6903319715792422884">Συμβάλετε στη βελτίωση της Ασφαλούς περιήγησης στέλνοντας ορισμένες <ph name="BEGIN_WHITEPAPER_LINK" />πληροφορίες συστήματος και περιεχόμενο σελίδων<ph name="END_WHITEPAPER_LINK" /> στην Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Χρήστης</translation> <translation id="6945221475159498467">Επιλογή</translation> <translation id="6948701128805548767">Για να δείτε τρόπους και απαιτήσεις παραλαβής, επιλέξτε μια διεύθυνση</translation> @@ -1015,6 +1016,7 @@ <translation id="8308427013383895095">Η μετάφραση απέτυχε λόγω προβλήματος με τη σύνδεση δικτύου.</translation> <translation id="8311129316111205805">Φόρτωση περιόδου λειτουργίας</translation> <translation id="8332188693563227489">Απορρίφθηκε η πρόσβαση στο κεντρικό υπολογιστή <ph name="HOST_NAME" /></translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Εάν κατανοείτε τους κινδύνους για την ασφάλειά σας, μπορείτε να <ph name="BEGIN_LINK" />επισκεφτείτε αυτόν τον ιστότοπο<ph name="END_LINK" /> πριν από την κατάργηση των επικίνδυνων προγραμμάτων.</translation> <translation id="8349305172487531364">Γραμμή σελιδοδεικτών</translation> <translation id="8363502534493474904">Απενεργοποιήστε τη λειτουργία πτήσης</translation>
diff --git a/components/strings/components_strings_es-419.xtb b/components/strings/components_strings_es-419.xtb index f9590f4..5823971 100644 --- a/components/strings/components_strings_es-419.xtb +++ b/components/strings/components_strings_es-419.xtb
@@ -811,6 +811,7 @@ <translation id="6891596781022320156">No se admite el nivel de políticas.</translation> <translation id="6895330447102777224">Tu tarjeta se confirmó</translation> <translation id="6897140037006041989">User agent</translation> +<translation id="6903319715792422884">Para mejorar la Navegación segura, envía <ph name="BEGIN_WHITEPAPER_LINK" />información del sistema y contenido de la página<ph name="END_WHITEPAPER_LINK" /> a Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Usuario:</translation> <translation id="6945221475159498467">Seleccionar</translation> <translation id="6948701128805548767">Para ver los requisitos y métodos de retiro, selecciona una dirección</translation> @@ -1015,6 +1016,7 @@ <translation id="8308427013383895095">Se produjo un error en la traducción a causa de un problema con la conexión de red.</translation> <translation id="8311129316111205805">Cargar sesión</translation> <translation id="8332188693563227489">Se denegó el acceso a <ph name="HOST_NAME" /></translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Si comprendes los riesgos de seguridad, puedes <ph name="BEGIN_LINK" />visitar este sitio<ph name="END_LINK" /> antes de que se hayan eliminado los programas peligrosos.</translation> <translation id="8349305172487531364">Barra de favoritos</translation> <translation id="8363502534493474904">Desactivar el modo de avión.</translation> @@ -1114,6 +1116,7 @@ <translation id="9148507642005240123">&Deshacer Editar</translation> <translation id="9154194610265714752">Actualizado</translation> <translation id="9157595877708044936">Configurando...</translation> +<translation id="9168814207360376865">Permitir que los sitios determinen si tienes formas de pago guardadas</translation> <translation id="9169664750068251925">Bloquear siempre en este sitio</translation> <translation id="9170848237812810038">&Deshacer</translation> <translation id="9171296965991013597">¿Deseas salir de la app?</translation>
diff --git a/components/strings/components_strings_et.xtb b/components/strings/components_strings_et.xtb index e039189..853a1e84 100644 --- a/components/strings/components_strings_et.xtb +++ b/components/strings/components_strings_et.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Reegli taset ei toetata.</translation> <translation id="6895330447102777224">Teie kaart on kinnitatud</translation> <translation id="6897140037006041989">Kasutajaagent</translation> +<translation id="6903319715792422884">Aidake ohutu sirvimise funktsiooni täiustada, saates Google'ile <ph name="BEGIN_WHITEPAPER_LINK" />süsteemiteavet ja lehesisu<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Kasutaja:</translation> <translation id="6945221475159498467">Vali</translation> <translation id="6948701128805548767">Kättesaamisviiside ja nõuete nägemiseks valige aadress</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Tõlkimine ebaõnnestus võrguühenduse probleemi tõttu.</translation> <translation id="8311129316111205805">Laadi seanss</translation> <translation id="8332188693563227489">Juurdepääs hostile <ph name="HOST_NAME" /> blokeeriti</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Kui mõistate, kuidas teie turvalisust ohustatakse, siis võite <ph name="BEGIN_LINK" />seda saiti külastada<ph name="END_LINK" /> enne, kui kahjulikud programmid on eemaldatud.</translation> <translation id="8349305172487531364">Järjehoidjariba</translation> <translation id="8363502534493474904">Lülitage lennurežiim välja</translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb index ee143947..a949521 100644 --- a/components/strings/components_strings_fa.xtb +++ b/components/strings/components_strings_fa.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">سطح خطمشی پشتیبانی نمیشود.</translation> <translation id="6895330447102777224">کارتتان تأیید شد</translation> <translation id="6897140037006041989">نماینده کاربر</translation> +<translation id="6903319715792422884">با ارسال برخی <ph name="BEGIN_WHITEPAPER_LINK" />اطلاعات سیستم و محتوای صفحه<ph name="END_WHITEPAPER_LINK" /> به Google، به بهبود «مرور ایمن» کمک کنید. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">کاربر:</translation> <translation id="6945221475159498467">انتخاب</translation> <translation id="6948701128805548767">برای دیدن روشهای تحویل گرفتن و شرایط موردنیاز، یک نشانی انتخاب کنید</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">ترجمه انجام نشد چون مشکلی در اتصال به شبکه رخ داد.</translation> <translation id="8311129316111205805">بار کردن جلسه</translation> <translation id="8332188693563227489">دسترسی به <ph name="HOST_NAME" /> رد شد</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">اگر خطرات امنیتیای که متوجه شما هستند را درک میکنید، میتوانید قبل از حذف شدن برنامههای خطرناک، <ph name="BEGIN_LINK" />از این سایت بازدید کنید<ph name="END_LINK" />.</translation> <translation id="8349305172487531364">نوار نشانکها</translation> <translation id="8363502534493474904">خاموش کردن حالت هواپیما</translation> @@ -1112,6 +1114,7 @@ <translation id="9148507642005240123">&واگرد ویرایش</translation> <translation id="9154194610265714752">بهروزرسانی شد</translation> <translation id="9157595877708044936">در حال راهاندازی...</translation> +<translation id="9168814207360376865">سایتها بتوانند بررسی کنند روش پرداخت ذخیرهشدهای دارید یا نه</translation> <translation id="9169664750068251925">همیشه مسدود در این سایت</translation> <translation id="9170848237812810038">&واگرد</translation> <translation id="9171296965991013597">از برنامه خارج میشوید؟</translation>
diff --git a/components/strings/components_strings_fi.xtb b/components/strings/components_strings_fi.xtb index 58cfe67..e030945 100644 --- a/components/strings/components_strings_fi.xtb +++ b/components/strings/components_strings_fi.xtb
@@ -1116,6 +1116,7 @@ <translation id="9148507642005240123">K&umoa muokkaus</translation> <translation id="9154194610265714752">Päivitetty</translation> <translation id="9157595877708044936">Valmistellaan...</translation> +<translation id="9168814207360376865">Salli sivustojen tarkastaa, oletko tallentanut maksutapoja</translation> <translation id="9169664750068251925">Estä aina tämä sivusto</translation> <translation id="9170848237812810038">K&umoa</translation> <translation id="9171296965991013597">Poistutaanko sovelluksesta?</translation>
diff --git a/components/strings/components_strings_fil.xtb b/components/strings/components_strings_fil.xtb index 9b11b4b..5a277eb 100644 --- a/components/strings/components_strings_fil.xtb +++ b/components/strings/components_strings_fil.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Hindi sinusuportahan ang antas ng patakaran.</translation> <translation id="6895330447102777224">Nakumpirma na ang iyong card</translation> <translation id="6897140037006041989">User Agent</translation> +<translation id="6903319715792422884">Tumulong sa pagpapahusay ng Ligtas na Pag-browse sa pamamagitan ng pagpapadala sa Google ng ilang <ph name="BEGIN_WHITEPAPER_LINK" />impormasyon ng system at content ng page<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">User:</translation> <translation id="6945221475159498467">Pumili</translation> <translation id="6948701128805548767">Upang makita ang mga pamamaraan at kinakailangan sa pag-pick up, pumili ng address</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Nabigo ang translation dahil sa problema sa koneksyon sa network.</translation> <translation id="8311129316111205805">I-load ang session</translation> <translation id="8332188693563227489">Tinanggihan ang access sa <ph name="HOST_NAME" /></translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Kung nauunawaan mo ang mga peligro sa iyong seguridad, maaari mong <ph name="BEGIN_LINK" />bisitahin ang site na ito<ph name="END_LINK" /> bago maalis ang mga mapanirang program.</translation> <translation id="8349305172487531364">Bookmarks bar</translation> <translation id="8363502534493474904">I-off ang airplane mode</translation> @@ -1112,6 +1114,7 @@ <translation id="9148507642005240123">&I-undo ang pag-e-edit</translation> <translation id="9154194610265714752">Na-update</translation> <translation id="9157595877708044936">Nagse-set up...</translation> +<translation id="9168814207360376865">Payagan ang mga site na tingnan kung may mga naka-save kang paraan ng pagbabayad</translation> <translation id="9169664750068251925">Palaging i-block sa site na ito</translation> <translation id="9170848237812810038">&I-undo</translation> <translation id="9171296965991013597">Umalis sa app?</translation>
diff --git a/components/strings/components_strings_fr.xtb b/components/strings/components_strings_fr.xtb index b55305d..38e25b2 100644 --- a/components/strings/components_strings_fr.xtb +++ b/components/strings/components_strings_fr.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Le niveau de la règle n'est pas accepté.</translation> <translation id="6895330447102777224">Carte validée</translation> <translation id="6897140037006041989">Agent utilisateur</translation> +<translation id="6903319715792422884">Aidez-nous à améliorer la navigation sécurisée en nous envoyant <ph name="BEGIN_WHITEPAPER_LINK" />des informations système et du contenu de page<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Utilisateur :</translation> <translation id="6945221475159498467">Sélectionner</translation> <translation id="6948701128805548767">Sélectionnez une adresse pour consulter les modes et conditions d'enlèvement disponibles</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Échec de la traduction en raison d'un problème de connexion réseau</translation> <translation id="8311129316111205805">Charger la session</translation> <translation id="8332188693563227489">L'accès à <ph name="HOST_NAME" /> a été refusé</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Si vous êtes conscient des risques auxquels vous vous exposez, vous pouvez <ph name="BEGIN_LINK" />consulter ce site<ph name="END_LINK" /> avant que les programmes dangereux aient été supprimés.</translation> <translation id="8349305172487531364">Barre de favoris</translation> <translation id="8363502534493474904">Désactiver le mode Avion</translation>
diff --git a/components/strings/components_strings_gu.xtb b/components/strings/components_strings_gu.xtb index 3145121..50c3364 100644 --- a/components/strings/components_strings_gu.xtb +++ b/components/strings/components_strings_gu.xtb
@@ -798,6 +798,7 @@ <translation id="6891596781022320156">નીતિ સ્તર સમર્થિત નથી.</translation> <translation id="6895330447102777224">તમારા કાર્ડની પુષ્ટિ કરવામાં આવી છે</translation> <translation id="6897140037006041989">વપરાશકર્તા એજન્ટ</translation> +<translation id="6903319715792422884">Googleને અમુક <ph name="BEGIN_WHITEPAPER_LINK" />સિસ્ટમ માહિતી અને પેજ કન્ટેન્ટ<ph name="END_WHITEPAPER_LINK" />મોકલીને સલામત બ્રાઉઝિંગ બહેતર બનાવવામાં સહાય કરો. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">વપરાશકર્તા: </translation> <translation id="6945221475159498467">પસંદ કરો</translation> <translation id="6948701128805548767">પિકઅપ પદ્ધતિ અને આવશ્યકતાઓ જોવા માટે, એક સરનામું પસંદ કરો</translation> @@ -1000,6 +1001,7 @@ <translation id="8308427013383895095">નેટવર્ક કનેક્શનમાં સમસ્યાને કારણે ભાષાંતર નિષ્ફળ રહ્યું.</translation> <translation id="8311129316111205805">સત્ર લોડ કરો</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> ની ઍક્સેસ નકારાઈ હતી</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">જો તમે તમારી સુરક્ષાના જોખમોને સમજો છો, તો તમે જોખમી પ્રોગ્રામ્સ દૂર કરી દેવામાં આવે તે પહેલાં <ph name="BEGIN_LINK" />આ સાઇટની મુલાકાત<ph name="END_LINK" /> લઈ શકો છો.</translation> <translation id="8349305172487531364">બુકમાર્ક્સ બાર</translation> <translation id="8363502534493474904">એરપ્લેન મોડ બંધ કરીને</translation>
diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb index 491a9c6e..73c5f05 100644 --- a/components/strings/components_strings_hi.xtb +++ b/components/strings/components_strings_hi.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">नीति स्तर समर्थित नहीं है.</translation> <translation id="6895330447102777224">आपके कार्ड की पुष्टि हो गई है</translation> <translation id="6897140037006041989">उपयोगकर्ता एजेंट</translation> +<translation id="6903319715792422884">Google को कुछ <ph name="BEGIN_WHITEPAPER_LINK" />सिस्टम जानकारी और पेज सामग्री<ph name="END_WHITEPAPER_LINK" /> भेजकर सुरक्षित ब्राउज़िंग को बेहतर बनाने में मदद करें. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">उपयोगकर्ता:</translation> <translation id="6945221475159498467">चुनें</translation> <translation id="6948701128805548767">पिकअप के तरीके और ज़रूरतें देखने के लिए, कोई पता चुनें</translation> @@ -854,7 +855,7 @@ <translation id="7271803869921933038">स्वीकार किए जाने वाले प्रीपेड कार्ड</translation> <translation id="7275334191706090484">प्रबंधित बुकमार्क</translation> <translation id="7298195798382681320">सुझाए गए</translation> -<translation id="7309308571273880165">क्रैैश रिपोर्ट <ph name="CRASH_TIME" /> बजे कैप्चर की गई (उपयोगकर्ता द्वारा अपलोड करने का अनुरोध किया गया, अभी तक अपलोड नहीं किया गया)</translation> +<translation id="7309308571273880165">खराबी की रिपोर्ट <ph name="CRASH_TIME" /> बजे दर्ज की गई (उपयोगकर्ता ने अपलोड करने का अनुरोध किया, अभी तक अपलोड नहीं किया गया)</translation> <translation id="7320336641823683070">कनेक्शन संबंधी सहायता</translation> <translation id="7334320624316649418">&पुन: क्रमित करना फिर से करें</translation> <translation id="733923710415886693">प्रमाणपत्र पारदर्शिता के माध्यम से सर्वर के प्रमाणपत्र को प्रकट नहीं किया गया.</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">नेटवर्क कनेक्शन में कोई समस्या होने के कारण अनुवाद विफल हुआ.</translation> <translation id="8311129316111205805">सत्र लोड करें</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> का एक्सेस अस्वीकृत किया गया</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">अगर आप अपनी सुरक्षा संबंधी जोखिमों को समझते हैं तो, खतरनाक प्रोग्राम हटाए जाने से पहले आप <ph name="BEGIN_LINK" />इस साइट पर विज़िट<ph name="END_LINK" /> कर सकते हैं.</translation> <translation id="8349305172487531364">बुकमार्क बार</translation> <translation id="8363502534493474904">हवाई जहाज़ मोड बंद करें</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">&संपादन वापस लाएं</translation> <translation id="9154194610265714752">अपडेट किया गया</translation> <translation id="9157595877708044936">सेट अप कर रहा है...</translation> +<translation id="9168814207360376865">साइट को यह देखने दें कि आपके भुगतान के तरीके सेव किए गए हैं या नहीं</translation> <translation id="9169664750068251925">इस साइट पर हमेशा अवरोधित करें</translation> <translation id="9170848237812810038">&पूर्ववत् करें</translation> <translation id="9171296965991013597">ऐप्लिकेशन छोड़ें?</translation>
diff --git a/components/strings/components_strings_hu.xtb b/components/strings/components_strings_hu.xtb index 7c3fac6..e12bb60 100644 --- a/components/strings/components_strings_hu.xtb +++ b/components/strings/components_strings_hu.xtb
@@ -808,6 +808,7 @@ <translation id="6891596781022320156">Ezt a házirendszintet a rendszer nem támogatja.</translation> <translation id="6895330447102777224">Kártyáját ellenőriztük</translation> <translation id="6897140037006041989">User agent</translation> +<translation id="6903319715792422884">A Biztonságos Böngészés fejlesztésének segítése bizonyos <ph name="BEGIN_WHITEPAPER_LINK" />rendszer-információknak és oldaltartalmaknak<ph name="END_WHITEPAPER_LINK" /> a Google-nak való elküldésével. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Felhasználó:</translation> <translation id="6945221475159498467">Kiválasztás</translation> <translation id="6948701128805548767">Az átvételi módok és követelmények megtekintéséhez válassza ki a címet</translation> @@ -1012,6 +1013,7 @@ <translation id="8308427013383895095">A fordítás a hálózati kapcsolat problémája miatt nem sikerült.</translation> <translation id="8311129316111205805">Munkamenet betöltése</translation> <translation id="8332188693563227489">A hozzáférés megtagadva a következőhöz: <ph name="HOST_NAME" /></translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Ha tisztában van a biztonságát fenyegető kockázatokkal, a veszélyes programok eltávolítása előtt is <ph name="BEGIN_LINK" />felkeresheti ezt a webhelyet<ph name="END_LINK" />.</translation> <translation id="8349305172487531364">Könyvjelzősáv</translation> <translation id="8363502534493474904">Repülős üzemmód kikapcsolása</translation> @@ -1111,6 +1113,7 @@ <translation id="9148507642005240123">&Szerkesztés visszavonása</translation> <translation id="9154194610265714752">Frissítve</translation> <translation id="9157595877708044936">Előkészítés...</translation> +<translation id="9168814207360376865">Engedélyezés a webhelyek számára, hogy ellenőrizzék, van-e elmentett fizetési módja</translation> <translation id="9169664750068251925">Mindig tiltsa ezen az oldalon</translation> <translation id="9170848237812810038">&Visszavonás</translation> <translation id="9171296965991013597">Bezárja az alkalmazást?</translation>
diff --git a/components/strings/components_strings_it.xtb b/components/strings/components_strings_it.xtb index 9a7ff0c..48fbe8d 100644 --- a/components/strings/components_strings_it.xtb +++ b/components/strings/components_strings_it.xtb
@@ -806,6 +806,7 @@ <translation id="6891596781022320156">Il livello della norma non è supportato.</translation> <translation id="6895330447102777224">La carta è stata confermata</translation> <translation id="6897140037006041989">User-agent</translation> +<translation id="6903319715792422884">Contribuisci a migliorare a Navigazione sicura, grazie all'invio a Google di qualche <ph name="BEGIN_WHITEPAPER_LINK" />informazione di sistema e contenuto delle pagine<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Utente:</translation> <translation id="6945221475159498467">Seleziona</translation> <translation id="6948701128805548767">Seleziona un indirizzo per conoscere i requisiti e i metodi di ritiro</translation> @@ -1010,6 +1011,7 @@ <translation id="8308427013383895095">La traduzione non è riuscita a causa di un problema con la connessione di rete.</translation> <translation id="8311129316111205805">Carica sessione</translation> <translation id="8332188693563227489">Accesso a <ph name="HOST_NAME" /> negato</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Se sei consapevole dei rischi per la tua sicurezza, potresti <ph name="BEGIN_LINK" />visitare questo sito<ph name="END_LINK" /> senza aspettare che vengano rimossi i programmi pericolosi.</translation> <translation id="8349305172487531364">Barra dei Preferiti</translation> <translation id="8363502534493474904">Disattivare la modalità aereo</translation> @@ -1108,6 +1110,7 @@ <translation id="9148507642005240123">&Annulla modifica</translation> <translation id="9154194610265714752">Aggiornato</translation> <translation id="9157595877708044936">Configurazione in corso...</translation> +<translation id="9168814207360376865">Consenti ai siti di controllare se hai metodi di pagamento salvati</translation> <translation id="9169664750068251925">Blocca sempre su questo sito</translation> <translation id="9170848237812810038">&Annulla</translation> <translation id="9171296965991013597">Uscire dall'app?</translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb index 56f45fd..ac035ef1 100644 --- a/components/strings/components_strings_iw.xtb +++ b/components/strings/components_strings_iw.xtb
@@ -815,6 +815,7 @@ <translation id="6891596781022320156">רמת המדיניות אינה נתמכת.</translation> <translation id="6895330447102777224">הכרטיס שלך מאושר</translation> <translation id="6897140037006041989">User agent</translation> +<translation id="6903319715792422884">על-ידי שליחה של חלק מ<ph name="BEGIN_WHITEPAPER_LINK" />פרטי המערכת ותוכן הדפים<ph name="END_WHITEPAPER_LINK" /> אל Google אפשר לעזור בשיפור של 'גלישה בטוחה'. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">משתמש:</translation> <translation id="6945221475159498467">בחר</translation> <translation id="6948701128805548767">עליך לבחור כתובת כדי לראות שיטות איסוף ודרישות</translation> @@ -1019,6 +1020,7 @@ <translation id="8308427013383895095">התרגום נכשל עקב בעיה בחיבור הרשת.</translation> <translation id="8311129316111205805">טעינת הפעלה</translation> <translation id="8332188693563227489">הגישה ל-<ph name="HOST_NAME" /> נדחתה</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">אם אתה מבין את סיכוני האבטחה, תוכל <ph name="BEGIN_LINK" />להיכנס לאתר לא בטוח זה<ph name="END_LINK" /> לפני הסרת התכניות המסוכנות.</translation> <translation id="8349305172487531364">סרגל סימניות</translation> <translation id="8363502534493474904">לכבות את מצב הטיסה</translation>
diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb index daab1bb..ffee3dc 100644 --- a/components/strings/components_strings_ja.xtb +++ b/components/strings/components_strings_ja.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">ポリシーレベルがサポートされていません。</translation> <translation id="6895330447102777224">カードを確認しました</translation> <translation id="6897140037006041989">ユーザー エージェント</translation> +<translation id="6903319715792422884"><ph name="BEGIN_WHITEPAPER_LINK" />一部のシステム情報とページのコンテンツ<ph name="END_WHITEPAPER_LINK" />を Google に送信して、セーフ ブラウジングの改善にご協力ください。<ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">ユーザー:</translation> <translation id="6945221475159498467">選択</translation> <translation id="6948701128805548767">受け取り方法と要件を確認するには、住所を選択してください</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">ネットワーク接続に問題があったため翻訳できませんでした。</translation> <translation id="8311129316111205805">セッションを読み込む</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> へのアクセスが拒否されました</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">有害なプログラムが削除されるより前に<ph name="BEGIN_LINK" />このサイトにアクセスする<ph name="END_LINK" />場合は、セキュリティ上のリスクについてご承知おきください。</translation> <translation id="8349305172487531364">ブックマーク バー</translation> <translation id="8363502534493474904">機内モードをオフにする</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">編集の取り消し(&U)</translation> <translation id="9154194610265714752">更新完了</translation> <translation id="9157595877708044936">セットアップ中...</translation> +<translation id="9168814207360376865">お支払い方法を保存しているかどうかの確認をサイトに許可する</translation> <translation id="9169664750068251925">このサイトでは常にブロック</translation> <translation id="9170848237812810038">取消(&U)</translation> <translation id="9171296965991013597">アプリを終了しますか?</translation>
diff --git a/components/strings/components_strings_kn.xtb b/components/strings/components_strings_kn.xtb index 3e15bd73..c7e974c 100644 --- a/components/strings/components_strings_kn.xtb +++ b/components/strings/components_strings_kn.xtb
@@ -804,6 +804,7 @@ <translation id="6891596781022320156">ನೀತಿಯ ಮಟ್ಟವು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ.</translation> <translation id="6895330447102777224">ನಿಮ್ಮ ಕಾರ್ಡ್ ಅನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ</translation> <translation id="6897140037006041989">ಬಳಕೆದಾರ ಏಜೆಂಟ್</translation> +<translation id="6903319715792422884"><ph name="BEGIN_WHITEPAPER_LINK" />ಸಿಸ್ಟಂ ಕುರಿತು ಕೆಲವೊಂದು ಮಾಹಿತಿಯನ್ನು ಮತ್ತು ಪುಟದ ವಿಷಯವನ್ನು<ph name="END_WHITEPAPER_LINK" /> Google ಗೆ ಕಳುಹಿಸುವ ಮೂಲಕ, ಸುರಕ್ಷಿತ ಬ್ರೌಸಿಂಗ್ ಅನ್ನು ಸುಧಾರಿಸಲು ಸಹಾಯ ಮಾಡಿ. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">ಬಳಕೆದಾರ:</translation> <translation id="6945221475159498467">ಆಯ್ಕೆಮಾಡಿ</translation> <translation id="6948701128805548767">ಪಿಕಪ್ ವಿಧಾನಗಳು ಹಾಗೂ ಆವಶ್ಯಕತೆಗಳನ್ನು ನೋಡಲು, ಒಂದು ವಿಳಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</translation> @@ -1007,6 +1008,7 @@ <translation id="8308427013383895095">ನೆಟ್ವರ್ಕ್ ಸಂಪರ್ಕದಲ್ಲಿನ ಸಮಸ್ಯೆಯಿಂದಾಗಿ ಭಾಷಾಂತರವು ವಿಫಲವಾಗಿದೆ.</translation> <translation id="8311129316111205805">ಸೆಶನ್ ಲೋಡ್ ಮಾಡಿ</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> ಗೆ ಪ್ರವೇಶವನ್ನು ನಿರಾಕರಿಸಲಾಗಿದೆ</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">ನಿಮ್ಮ ಸುರಕ್ಷತೆ ಅಪಾಯಗಳು ನಿಮಗೆ ಅರ್ಥವಾಗಿದ್ದರೆ, ಅಪಾಯಕಾರಿ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ತೆಗೆದುಹಾಕುವುದಕ್ಕೂ ಮೊದಲು ನೀವು <ph name="BEGIN_LINK" />ಈ ಸೈಟ್ಗೆ ಭೇಟಿ<ph name="END_LINK" /> ನೀಡಬಹುದು.</translation> <translation id="8349305172487531364">ಬುಕ್ಮಾರ್ಕ್ಗಳ ಬಾರ್</translation> <translation id="8363502534493474904">ಏರ್ಪ್ಲೇನ್ ಮೋಡ್ ಆಫ್ ಮಾಡಲಾಗುತ್ತಿದೆ</translation> @@ -1106,6 +1108,7 @@ <translation id="9148507642005240123">&ಸಂಪಾದಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation> <translation id="9154194610265714752">ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="9157595877708044936">ಹೊಂದಿಸಲಾಗುತ್ತಿದೆ...</translation> +<translation id="9168814207360376865">ನೀವು ಪಾವತಿ ವಿಧಾನಗಳನ್ನು ಉಳಿಸಿದಲ್ಲಿ ಪರಿಶೀಲಿಸಲು ಸೈಟ್ಗಳನ್ನು ಅನುಮತಿಸಿ</translation> <translation id="9169664750068251925">ಈ ಸೈಟ್ ಅನ್ನು ಯಾವಾಗಲೂ ನಿರ್ಬಂಧಿಸು</translation> <translation id="9170848237812810038">&ರದ್ದುಮಾಡು</translation> <translation id="9171296965991013597">ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ತ್ಯಜಿಸಬೇಕೆ?</translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb index b6ced25..22a414e6 100644 --- a/components/strings/components_strings_ko.xtb +++ b/components/strings/components_strings_ko.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">정책 수준이 지원되지 않습니다.</translation> <translation id="6895330447102777224">카드가 확인되었습니다.</translation> <translation id="6897140037006041989">사용자 에이전트</translation> +<translation id="6903319715792422884">일부 <ph name="BEGIN_WHITEPAPER_LINK" />시스템 정보와 페이지 콘텐츠를<ph name="END_WHITEPAPER_LINK" /> Google로 전송하여 세이프 브라우징을 개선하도록 도와주세요. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">사용자:</translation> <translation id="6945221475159498467">선택</translation> <translation id="6948701128805548767">수령 방법과 요구사항을 확인하려면 주소를 선택하세요.</translation> @@ -1013,6 +1014,7 @@ <translation id="8308427013383895095">네트워크 연결 문제로 인해 번역에 실패했습니다.</translation> <translation id="8311129316111205805">세션 로드</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" />에 대한 액세스가 거부됨</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_YEAR" />/<ph name="EXPIRATION_MONTH" /></translation> <translation id="834457929814110454">보안 관련 위험을 이해한다면 악성 프로그램이 삭제되기 전에 <ph name="BEGIN_LINK" />이 사이트를 방문<ph name="END_LINK" />해도 됩니다.</translation> <translation id="8349305172487531364">북마크바</translation> <translation id="8363502534493474904">비행기 모드 사용 중지</translation>
diff --git a/components/strings/components_strings_lt.xtb b/components/strings/components_strings_lt.xtb index d0fd19b1..a1b24c2c 100644 --- a/components/strings/components_strings_lt.xtb +++ b/components/strings/components_strings_lt.xtb
@@ -1116,6 +1116,7 @@ <translation id="9148507642005240123">&Anuliuoti redagavimą</translation> <translation id="9154194610265714752">Atnaujinta</translation> <translation id="9157595877708044936">Nustatoma...</translation> +<translation id="9168814207360376865">Leisti svetainėms tikrinti, ar esate išsaugoję mokėjimo metodus</translation> <translation id="9169664750068251925">Visada blokuoti šioje svetainėje</translation> <translation id="9170848237812810038">&Atšaukti</translation> <translation id="9171296965991013597">Išeiti iš programos?</translation>
diff --git a/components/strings/components_strings_lv.xtb b/components/strings/components_strings_lv.xtb index d31058b1..ed72e61 100644 --- a/components/strings/components_strings_lv.xtb +++ b/components/strings/components_strings_lv.xtb
@@ -809,6 +809,7 @@ <translation id="6891596781022320156">Politikas līmenis netiek atbalstīts.</translation> <translation id="6895330447102777224">Karte ir apstiprināta</translation> <translation id="6897140037006041989">Lietotāja aģents</translation> +<translation id="6903319715792422884">Palīdziet uzlabot Drošo pārlūkošanu, nosūtot noteiktu <ph name="BEGIN_WHITEPAPER_LINK" />sistēmas informāciju un lapas saturu<ph name="END_WHITEPAPER_LINK" /> Google serveriem. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Lietotājs:</translation> <translation id="6945221475159498467">Atlasīt</translation> <translation id="6948701128805548767">Lai skatītu saņemšanas veidus un prasības, atlasiet adresi.</translation> @@ -1013,6 +1014,7 @@ <translation id="8308427013383895095">Tulkošana neizdevās, jo radās problēma ar tīkla savienojumu.</translation> <translation id="8311129316111205805">Ielādēt sesiju</translation> <translation id="8332188693563227489">Piekļuve vietnei <ph name="HOST_NAME" /> tika noraidīta</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Ja apzināties drošības risku, varat arī <ph name="BEGIN_LINK" />apmeklēt šo vietni<ph name="END_LINK" />, pirms ir noņemtas kaitīgās programmas.</translation> <translation id="8349305172487531364">Grāmatzīmju josla</translation> <translation id="8363502534493474904">Izslēdziet lidojuma režīmu.</translation> @@ -1112,6 +1114,7 @@ <translation id="9148507642005240123">&Atsaukt labojumu</translation> <translation id="9154194610265714752">Atjaunināts</translation> <translation id="9157595877708044936">Notiek uzstādīšana...</translation> +<translation id="9168814207360376865">Atļaut vietnēm pārbaudīt, vai jums ir saglabāti maksājumu veidi</translation> <translation id="9169664750068251925">Vienmēr bloķēt šajā vietnē</translation> <translation id="9170848237812810038">&Atsaukt</translation> <translation id="9171296965991013597">Vai aizvērt lietotni?</translation>
diff --git a/components/strings/components_strings_ml.xtb b/components/strings/components_strings_ml.xtb index 3c37465..23722441e 100644 --- a/components/strings/components_strings_ml.xtb +++ b/components/strings/components_strings_ml.xtb
@@ -809,6 +809,7 @@ <translation id="6891596781022320156">നയ നില പിന്തുണയ്ക്കുന്നില്ല.</translation> <translation id="6895330447102777224">നിങ്ങളുടെ കാർഡ് സ്ഥിരീകരിച്ചു</translation> <translation id="6897140037006041989">ഉപയോക്തൃ ഏജന്റ്</translation> +<translation id="6903319715792422884">ചില <ph name="BEGIN_WHITEPAPER_LINK" />സിസ്റ്റം വിവരങ്ങളും പേജ് ഉള്ളടക്കവും<ph name="END_WHITEPAPER_LINK" /> Google-ലേക്ക് അയച്ച്, സുരക്ഷിത ബ്രൗസിംഗ് മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">ഉപയോക്താവ്:</translation> <translation id="6945221475159498467">തിരഞ്ഞെടുക്കുക</translation> <translation id="6948701128805548767">പിക്ക്അപ്പ് രീതികളും ആവശ്യകതകളും കാണാൻ ഒരു വിലാസം തിരഞ്ഞെടുക്കുക</translation> @@ -1011,6 +1012,7 @@ <translation id="8308427013383895095">നെറ്റ്വര്ക്ക് കണക്ഷനിലെ ഒരു പിശക് കാരണം വിവര്ത്തനം പരാജയപ്പെട്ടു.</translation> <translation id="8311129316111205805">സെഷൻ ലോഡ് ചെയ്യുക</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> ഹോസ്റ്റിലേക്കുള്ള ആക്സസ്സ് നിരസിച്ചു</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">നിങ്ങളുടെ സുരക്ഷയെ ബാധിക്കാനിടയുണ്ടെന്ന് മനസ്സിലാക്കുകയാണെങ്കിൽ, ദോഷകരമായ പ്രോഗ്രാമുകൾ നീക്കംചെയ്യുന്നതിനു മുമ്പ് <ph name="BEGIN_LINK" />ഈ സൈറ്റ് നിങ്ങൾക്ക് സന്ദർശിക്കാം<ph name="END_LINK" />.</translation> <translation id="8349305172487531364">ബുക്മാര്ക്ക് ബാര്</translation> <translation id="8363502534493474904">ഫ്ലൈറ്റ് മോഡ് ഓഫാക്കുന്നു</translation> @@ -1110,6 +1112,7 @@ <translation id="9148507642005240123">&എഡിറ്റുചെയ്യുന്നത് പഴയപടിയാക്കുക</translation> <translation id="9154194610265714752">അപ്ഡേറ്റുചെയ്തു</translation> <translation id="9157595877708044936">സജ്ജീകരിക്കുന്നു...</translation> +<translation id="9168814207360376865">നിങ്ങൾ പേയ്മെന്റ് രീതികൾ സംരക്ഷിച്ചിട്ടുണ്ടോ എന്ന് പരിശോധിക്കാൻ സൈറ്റുകളെ അനുവദിക്കുക</translation> <translation id="9169664750068251925">ഈ സൈറ്റിൽ എല്ലായ്പ്പോഴും തടയുക</translation> <translation id="9170848237812810038">&പൂര്വാവസ്ഥയിലാക്കുക</translation> <translation id="9171296965991013597">ആപ്പ് വിടണോ?</translation>
diff --git a/components/strings/components_strings_mr.xtb b/components/strings/components_strings_mr.xtb index 3cc56e9..94f589d 100644 --- a/components/strings/components_strings_mr.xtb +++ b/components/strings/components_strings_mr.xtb
@@ -811,6 +811,7 @@ <translation id="6891596781022320156">धोरण स्तर समर्थित नाही.</translation> <translation id="6895330447102777224">आपल्या कार्डची पुष्टी केली</translation> <translation id="6897140037006041989">वापरकर्ता एजंट</translation> +<translation id="6903319715792422884">सुरक्षित ब्राउझिंगमध्ये सुधारणा करण्यासाठी Google ला काही <ph name="BEGIN_WHITEPAPER_LINK" />सिस्टम माहिती आणि पेज आशय<ph name="END_WHITEPAPER_LINK" /> पाठवून मदत करा. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">वापरकर्ता:</translation> <translation id="6945221475159498467">निवडा</translation> <translation id="6948701128805548767">पिकअप पद्धती आणि आवश्यकता पाहण्यासाठी, एक पत्ता निवडा</translation> @@ -1015,6 +1016,7 @@ <translation id="8308427013383895095">नेटवर्क कनेक्शनसह समस्या असल्यामुळे भाषांतर अयशस्वी झाला.</translation> <translation id="8311129316111205805">सेशन लोड करा</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> मधील प्रवेश नाकारला</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">आपल्याला आपल्या सुरक्षिततेच्या जोखमी समजत असल्यास, धोकादायक प्रोग्राम काढले जाण्यापूर्वी आपण <ph name="BEGIN_LINK" />या असुरक्षित साइटला भेट देऊ शकता<ph name="END_LINK" />.</translation> <translation id="8349305172487531364">बुकमार्क बार</translation> <translation id="8363502534493474904">विमान मोड बंद करा</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">&संपादित करा पूर्ववत करा</translation> <translation id="9154194610265714752">अपडेट केलेले</translation> <translation id="9157595877708044936">सेट अप करीत आहे...</translation> +<translation id="9168814207360376865">तुम्ही पेमेंट पद्धती सेव्ह केल्या आहेत का हे तपासण्याची साइटला परवानगी द्या</translation> <translation id="9169664750068251925">या साइटवर नेहमी अवरोधित करा</translation> <translation id="9170848237812810038">&पूर्ववत करा</translation> <translation id="9171296965991013597">अॅप सोडायचे?</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb index d132971..b3c368a 100644 --- a/components/strings/components_strings_ms.xtb +++ b/components/strings/components_strings_ms.xtb
@@ -811,6 +811,7 @@ <translation id="6891596781022320156">Tahap dasar tidak disokong.</translation> <translation id="6895330447102777224">Kad anda telah disahkan</translation> <translation id="6897140037006041989">Ejen Pengguna</translation> +<translation id="6903319715792422884">Bantu dalam meningkatkan Penyemakan Imbas Selamat dengan menghantar beberapa <ph name="BEGIN_WHITEPAPER_LINK" />maklumat sistem dan kandungan halaman<ph name="END_WHITEPAPER_LINK" /> kepada Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Pengguna:</translation> <translation id="6945221475159498467">Pilih</translation> <translation id="6948701128805548767">Pilih alamat untuk melihat kaedah dan syarat pengambilan</translation> @@ -1015,6 +1016,7 @@ <translation id="8308427013383895095">Gagal terjemahan kerana masalah dengan sambungan rangkaian.</translation> <translation id="8311129316111205805">Muatkan sesi</translation> <translation id="8332188693563227489">Akses ke <ph name="HOST_NAME" /> dinafikan</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Jika anda memahami risiko terhadap keselamatan anda, anda boleh <ph name="BEGIN_LINK" />lawati tapak ini<ph name="END_LINK" /> sebelum atur cara berbahaya dialih keluar.</translation> <translation id="8349305172487531364">Bar penanda halaman</translation> <translation id="8363502534493474904">Matikan mod pesawat</translation>
diff --git a/components/strings/components_strings_nl.xtb b/components/strings/components_strings_nl.xtb index 6fd8ff5..ba90ca4 100644 --- a/components/strings/components_strings_nl.xtb +++ b/components/strings/components_strings_nl.xtb
@@ -805,6 +805,7 @@ <translation id="6891596781022320156">Beleidsniveau wordt niet ondersteund.</translation> <translation id="6895330447102777224">Je creditcard is bevestigd</translation> <translation id="6897140037006041989">User-agent</translation> +<translation id="6903319715792422884">Help Safe Browsing te verbeteren door bepaalde <ph name="BEGIN_WHITEPAPER_LINK" />systeeminformatie en paginacontent<ph name="END_WHITEPAPER_LINK" /> naar Google te verzenden. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Gebruiker:</translation> <translation id="6945221475159498467">Selecteren</translation> <translation id="6948701128805548767">Selecteer een adres om ophaalmethoden en vereisten te bekijken</translation> @@ -1009,6 +1010,7 @@ <translation id="8308427013383895095">De vertaling is mislukt omdat er een probleem is opgetreden met de netwerkverbinding.</translation> <translation id="8311129316111205805">Sessie laden</translation> <translation id="8332188693563227489">Toegang tot <ph name="HOST_NAME" /> is geweigerd</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Als je de beveiligingsrisico's begrijpt, kun je <ph name="BEGIN_LINK" />deze site bezoeken<ph name="END_LINK" /> voordat de schadelijke programma's zijn verwijderd.</translation> <translation id="8349305172487531364">Bladwijzerbalk</translation> <translation id="8363502534493474904">Schakel de vliegtuigmodus uit</translation>
diff --git a/components/strings/components_strings_no.xtb b/components/strings/components_strings_no.xtb index 5f29c14..4141ce2 100644 --- a/components/strings/components_strings_no.xtb +++ b/components/strings/components_strings_no.xtb
@@ -1112,6 +1112,7 @@ <translation id="9148507642005240123">&Angre endringen</translation> <translation id="9154194610265714752">Oppdatert</translation> <translation id="9157595877708044936">Konfigurerer ...</translation> +<translation id="9168814207360376865">Tillatt nettsteder å sjekke om du har noen lagrede betalingsmåter</translation> <translation id="9169664750068251925">Blokkér alltid på dette nettstedet</translation> <translation id="9170848237812810038">&Angre</translation> <translation id="9171296965991013597">Vil du gå ut av appen?</translation>
diff --git a/components/strings/components_strings_pl.xtb b/components/strings/components_strings_pl.xtb index e98ca377..2e92680 100644 --- a/components/strings/components_strings_pl.xtb +++ b/components/strings/components_strings_pl.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Ten poziom zasad nie jest obsługiwany.</translation> <translation id="6895330447102777224">Karta została potwierdzona</translation> <translation id="6897140037006041989">Klient</translation> +<translation id="6903319715792422884">Pomóż w ulepszaniu Bezpiecznego przeglądania, wysyłając do Google pewne <ph name="BEGIN_WHITEPAPER_LINK" />informacje o systemie i część zawartości stron<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Użytkownik:</translation> <translation id="6945221475159498467">Wybierz</translation> <translation id="6948701128805548767">Aby zobaczyć metody odbioru oraz wymagania, wybierz adres</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Tłumaczenie nie powiodło się z powodu problemu z połączeniem sieciowym.</translation> <translation id="8311129316111205805">Wczytaj sesję</translation> <translation id="8332188693563227489">Odmowa dostępu do <ph name="HOST_NAME" /></translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Jeśli rozumiesz zagrożenie, możesz <ph name="BEGIN_LINK" />wejść na tę stronę<ph name="END_LINK" />, zanim szkodliwe programy zostaną usunięte.</translation> <translation id="8349305172487531364">Pasek zakładek</translation> <translation id="8363502534493474904">Wyłącz tryb samolotowy</translation>
diff --git a/components/strings/components_strings_pt-PT.xtb b/components/strings/components_strings_pt-PT.xtb index 8148066..88fd509 100644 --- a/components/strings/components_strings_pt-PT.xtb +++ b/components/strings/components_strings_pt-PT.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">O nível da política não é suportado.</translation> <translation id="6895330447102777224">O seu cartão foi confirmado</translation> <translation id="6897140037006041989">Agente do utilizador</translation> +<translation id="6903319715792422884">Ajude a melhorar a Navegação segura ao enviar algumas <ph name="BEGIN_WHITEPAPER_LINK" />informações do sistema e conteúdo de páginas<ph name="END_WHITEPAPER_LINK" /> para a Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Utilizador:</translation> <translation id="6945221475159498467">Selecionar</translation> <translation id="6948701128805548767">Para ver os métodos de recolha e os requisitos, selecione um endereço</translation> @@ -1013,6 +1014,7 @@ <translation id="8308427013383895095">A tradução falhou devido a um problema com a ligação de rede.</translation> <translation id="8311129316111205805">Carregar sessão</translation> <translation id="8332188693563227489">O acesso a <ph name="HOST_NAME" /> foi recusado</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Se compreende os riscos para a sua segurança, pode <ph name="BEGIN_LINK" />visitar este site<ph name="END_LINK" /> antes de os programas prejudiciais terem sido removidos.</translation> <translation id="8349305172487531364">Barra de marcadores</translation> <translation id="8363502534493474904">Desativar o modo de avião</translation>
diff --git a/components/strings/components_strings_ro.xtb b/components/strings/components_strings_ro.xtb index 7c2f1b0..ba7cccd 100644 --- a/components/strings/components_strings_ro.xtb +++ b/components/strings/components_strings_ro.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Nivelul politicii nu este acceptat.</translation> <translation id="6895330447102777224">Cardul tău este confirmat</translation> <translation id="6897140037006041989">User Agent</translation> +<translation id="6903319715792422884">Ne poți ajuta să îmbunătățim Navigarea sigură dacă trimiți la Google anumite <ph name="BEGIN_WHITEPAPER_LINK" />informații despre sistem și conținutul paginii<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Utilizator:</translation> <translation id="6945221475159498467">Selectează</translation> <translation id="6948701128805548767">Pentru a vedea metodele de preluare și cerințele, selectează o adresă</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Traducerea nu a reușit din cauza unei probleme cu conexiunea la rețea.</translation> <translation id="8311129316111205805">Încarcă sesiunea</translation> <translation id="8332188693563227489">Accesul la <ph name="HOST_NAME" /> nu este permis</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Dacă îți asumi riscurile de securitate, poți să <ph name="BEGIN_LINK" />accesezi acest site<ph name="END_LINK" /> înainte ca programele periculoase să fie eliminate.</translation> <translation id="8349305172487531364">Bara de marcaje</translation> <translation id="8363502534493474904">să dezactivezi modul Avion.</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">&Anulați editarea</translation> <translation id="9154194610265714752">Actualizat</translation> <translation id="9157595877708044936">Se configurează...</translation> +<translation id="9168814207360376865">Permite site-urilor să verifice dacă ai salvat metode de plată</translation> <translation id="9169664750068251925">Blocați întotdeauna pe acest site</translation> <translation id="9170848237812810038">&Anulează</translation> <translation id="9171296965991013597">Ieși din aplicație?</translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb index ca7b283..63977d3 100644 --- a/components/strings/components_strings_ru.xtb +++ b/components/strings/components_strings_ru.xtb
@@ -1113,6 +1113,7 @@ <translation id="9148507642005240123">&Отменить изменения</translation> <translation id="9154194610265714752">Обновлено</translation> <translation id="9157595877708044936">Настройка...</translation> +<translation id="9168814207360376865">Разрешить сайтам проверять наличие сохраненных способов оплаты</translation> <translation id="9169664750068251925">Всегда блокировать на этом сайте</translation> <translation id="9170848237812810038">&Отменить</translation> <translation id="9171296965991013597">Закрыть приложение?</translation>
diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb index 84f4349..a338a42 100644 --- a/components/strings/components_strings_sk.xtb +++ b/components/strings/components_strings_sk.xtb
@@ -1110,6 +1110,7 @@ <translation id="9148507642005240123">&Vrátiť späť úpravu</translation> <translation id="9154194610265714752">Aktualizované</translation> <translation id="9157595877708044936">Prebieha nastavenie...</translation> +<translation id="9168814207360376865">Povoliť webom zisťovať, či máte uložené spôsoby platby</translation> <translation id="9169664750068251925">Vždy blokovať na tomto webe</translation> <translation id="9170848237812810038">&Naspäť</translation> <translation id="9171296965991013597">Opustiť aplikáciu?</translation>
diff --git a/components/strings/components_strings_sl.xtb b/components/strings/components_strings_sl.xtb index 61d9398..51f8462 100644 --- a/components/strings/components_strings_sl.xtb +++ b/components/strings/components_strings_sl.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Raven pravilnika ni podprta.</translation> <translation id="6895330447102777224">Kartica je potrjena.</translation> <translation id="6897140037006041989">Uporabnikov posrednik</translation> +<translation id="6903319715792422884">S pošiljanjem nekaterih <ph name="BEGIN_WHITEPAPER_LINK" />informacij o sistemu in vsebine strani<ph name="END_WHITEPAPER_LINK" /> Googlu lahko pomagate izboljšati Varno brskanje. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Uporabnik:</translation> <translation id="6945221475159498467">Izberi</translation> <translation id="6948701128805548767">Če si želite ogledati načine prevzema in zahteve, izberite naslov</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Prevod ni uspel zaradi težave s povezavo omrežja.</translation> <translation id="8311129316111205805">Naloži sejo</translation> <translation id="8332188693563227489">Dostop do spletnega mesta <ph name="HOST_NAME" /> je bil zavrnjen</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Če se zavedate varnostnega tveganja, lahko <ph name="BEGIN_LINK" />obiščete to spletno mesto<ph name="END_LINK" />, preden bodo škodljivi programi odstranjeni.</translation> <translation id="8349305172487531364">Vrstica z zaznamki</translation> <translation id="8363502534493474904">izklopiti način za letalo</translation>
diff --git a/components/strings/components_strings_sr.xtb b/components/strings/components_strings_sr.xtb index a3c0ec0..99427a3 100644 --- a/components/strings/components_strings_sr.xtb +++ b/components/strings/components_strings_sr.xtb
@@ -809,6 +809,7 @@ <translation id="6891596781022320156">Ниво смерница није подржан.</translation> <translation id="6895330447102777224">Картица је потврђена</translation> <translation id="6897140037006041989">Кориснички агент</translation> +<translation id="6903319715792422884">Побољшајте Безбедно прегледање слањем <ph name="BEGIN_WHITEPAPER_LINK" />системских информација и садржаја страница<ph name="END_WHITEPAPER_LINK" /> Google-у. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Корисник:</translation> <translation id="6945221475159498467">Изабери</translation> <translation id="6948701128805548767">Да бисте видели начине и захтеве за преузимање, изаберите адресу</translation> @@ -1013,6 +1014,7 @@ <translation id="8308427013383895095">Превођење није успело због проблема са мрежном везом.</translation> <translation id="8311129316111205805">Учитај сесију</translation> <translation id="8332188693563227489">Приступ хосту <ph name="HOST_NAME" /> је одбијен</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Ако разумете безбедносне ризике, можете да <ph name="BEGIN_LINK" />посетите овај сајт<ph name="END_LINK" /> пре него што уклонимо штетне програме.</translation> <translation id="8349305172487531364">Трака са обележивачима</translation> <translation id="8363502534493474904">да искључите режим рада у авиону</translation> @@ -1112,6 +1114,7 @@ <translation id="9148507642005240123">&Опозови измену</translation> <translation id="9154194610265714752">Ажурирано</translation> <translation id="9157595877708044936">Подешавање...</translation> +<translation id="9168814207360376865">Дозволите сајтовима да проверавају да ли имате сачуване начине плаћања</translation> <translation id="9169664750068251925">Увек блокирај на овом сајту</translation> <translation id="9170848237812810038">&Опозови</translation> <translation id="9171296965991013597">Желите ли да изађете из апликације?</translation>
diff --git a/components/strings/components_strings_sv.xtb b/components/strings/components_strings_sv.xtb index 917f088..6d798b2 100644 --- a/components/strings/components_strings_sv.xtb +++ b/components/strings/components_strings_sv.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Policynivån stöds inte.</translation> <translation id="6895330447102777224">Kortet har bekräftats</translation> <translation id="6897140037006041989">Användaragent</translation> +<translation id="6903319715792422884">Hjälp oss att förbättra Säker webbsökning genom att låta <ph name="BEGIN_WHITEPAPER_LINK" />viss systeminformation och visst sidinnehåll<ph name="END_WHITEPAPER_LINK" /> skickas automatiskt till Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Användare:</translation> <translation id="6945221475159498467">Välj</translation> <translation id="6948701128805548767">Välj en adress för att visa alternativ för utlämning och krav</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Det gick inte att översätta på grund av ett nätverksfel.</translation> <translation id="8311129316111205805">Läs in session</translation> <translation id="8332188693563227489">Åtkomst nekades till <ph name="HOST_NAME" />.</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Om du är medveten om säkerhetsriskerna kan du <ph name="BEGIN_LINK" />besöka den här osäkra webbplatsen<ph name="END_LINK" /> innan de skadliga programmen har tagits bort.</translation> <translation id="8349305172487531364">Bokmärkesfältet</translation> <translation id="8363502534493474904">inaktivera flygplansläget</translation>
diff --git a/components/strings/components_strings_sw.xtb b/components/strings/components_strings_sw.xtb index a80e484..9fbdd83 100644 --- a/components/strings/components_strings_sw.xtb +++ b/components/strings/components_strings_sw.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Kiwango cha sera hakitumiki.</translation> <translation id="6895330447102777224">Kadi yako imethibitishwa</translation> <translation id="6897140037006041989">Programu ya Mtumiaji</translation> +<translation id="6903319715792422884">Tusaidie tuboreshe huduma ya Kuvinjari Salama kwa kutuma baadhi ya <ph name="BEGIN_WHITEPAPER_LINK" />maudhui ya ukurasa na maelezo ya mfumo<ph name="END_WHITEPAPER_LINK" /> kwa Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Mtumiaji:</translation> <translation id="6945221475159498467">Chagua</translation> <translation id="6948701128805548767">Chagua anwani ili uone mbinu za kuchukua na mahitaji</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Utafsiri haukufanikiwa kwa sababu ya hitilafu ya seva.</translation> <translation id="8311129316111205805">Pakia kipindi</translation> <translation id="8332188693563227489">Ufikiaji wa <ph name="HOST_NAME" /> umekataliwa</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Ikiwa unaelewa hatari kwa usalama wako, unaweza <ph name="BEGIN_LINK" />kutembelea tovuti hii<ph name="END_LINK" /> kabla programu hatari hazijaondolewa.</translation> <translation id="8349305172487531364">Sehemu ya Alamisho</translation> <translation id="8363502534493474904">Kuzima hali ya ndegeni</translation>
diff --git a/components/strings/components_strings_ta.xtb b/components/strings/components_strings_ta.xtb index 1729b613..23ee14b4 100644 --- a/components/strings/components_strings_ta.xtb +++ b/components/strings/components_strings_ta.xtb
@@ -806,6 +806,7 @@ <translation id="6891596781022320156">கொள்கையின் நிலை ஆதரிக்கப்படவில்லை.</translation> <translation id="6895330447102777224">கார்டு உறுதிசெய்யப்பட்டது</translation> <translation id="6897140037006041989">பயனர் முகவர்</translation> +<translation id="6903319715792422884">Googleக்கு சில <ph name="BEGIN_WHITEPAPER_LINK" />சாதனத் தகவல்களையும் பக்க உள்ளடக்கத்தையும்<ph name="END_WHITEPAPER_LINK" /> அனுப்புவதன் மூலம் பாதுகாப்பான உலாவலை மேம்படுத்த உதவுங்கள். <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">பயனர்:</translation> <translation id="6945221475159498467">தேர்ந்தெடு</translation> <translation id="6948701128805548767">பிக்அப் முறைகளையும் தேவைகளையும் பார்க்க, முகவரியைத் தேர்ந்தெடுக்கவும்</translation> @@ -1010,6 +1011,7 @@ <translation id="8308427013383895095">பிணைய இணைப்பில் ஒரு சிக்கல் இருப்பதால் மொழிப்பெயர்ப்பு தோல்வியடைந்தது.</translation> <translation id="8311129316111205805">அமர்வை ஏற்று</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> க்கான அணுகல் மறுக்கப்பட்டது</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">உங்கள் பாதுகாப்பிற்கான ஆபத்தைப் புரிந்துகொண்டால், தீங்கான நிரல்களை அகற்றும் முன் <ph name="BEGIN_LINK" />இந்தத் தளத்தைப் பார்வையிடலாம்<ph name="END_LINK" />.</translation> <translation id="8349305172487531364">புக்மார்க் பட்டி</translation> <translation id="8363502534493474904">விமானப் பயன்முறையை முடக்குதல்</translation>
diff --git a/components/strings/components_strings_te.xtb b/components/strings/components_strings_te.xtb index ab4d729d..c4d284e 100644 --- a/components/strings/components_strings_te.xtb +++ b/components/strings/components_strings_te.xtb
@@ -808,6 +808,7 @@ <translation id="6891596781022320156">విధానం స్థాయికి మద్దతు లేదు.</translation> <translation id="6895330447102777224">మీ కార్డ్ నిర్ధారించబడింది</translation> <translation id="6897140037006041989">వినియోగదారు ప్రతినిధి</translation> +<translation id="6903319715792422884"><ph name="BEGIN_WHITEPAPER_LINK" />కొంత సిస్టమ్ సమాచారం మరియు పేజీ కంటెంట్<ph name="END_WHITEPAPER_LINK" />ను Googleకి పంపడం ద్వారా సురక్షిత బ్రౌజింగ్ని మెరుగుపరచడంలో మీరు సహాయపడవచ్చు. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">వినియోగదారు:</translation> <translation id="6945221475159498467">ఎంచుకోండి</translation> <translation id="6948701128805548767">పికప్ పద్ధతులు మరియు అవసరాలను చూడాలంటే, చిరునామాని ఎంచుకోండి</translation> @@ -1012,6 +1013,7 @@ <translation id="8308427013383895095">నెట్వర్క్ కనెక్షన్తో సమస్య ఉన్నందున అనువాదం విఫలమైంది.</translation> <translation id="8311129316111205805">సెషన్ని లోడ్ చేయి</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" />కి ప్రాప్యత నిరాకరించబడింది</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">మీ భద్రతకు వాటిల్లే ఆపదల గురించి మీకు అర్థం అయ్యి ఉంటే, హానికర ప్రోగ్రామ్లు తీసివేయబడటానికి ముందే మీరు <ph name="BEGIN_LINK" />ఈ సైట్ను సందర్శించవచ్చు<ph name="END_LINK" />.</translation> <translation id="8349305172487531364">బుక్మార్క్ల పట్టీ</translation> <translation id="8363502534493474904">ఎయిర్ప్లైన్ మోడ్ను ఆఫ్ చేయడం</translation> @@ -1111,6 +1113,7 @@ <translation id="9148507642005240123">&సవరించడాన్ని రద్దు చేయి</translation> <translation id="9154194610265714752">నవీకరించబడింది</translation> <translation id="9157595877708044936">అమర్చుతోంది...</translation> +<translation id="9168814207360376865">మీ వద్ద సేవ్ చేయబడిన చెల్లింపు పద్ధతులు ఉన్నాయో లేదో తనిఖీ చేయడానికి సైట్లను అనుమతించండి</translation> <translation id="9169664750068251925">ఈ సైట్లో ఎల్లప్పుడూ బ్లాక్ చేయి</translation> <translation id="9170848237812810038">&అన్డు</translation> <translation id="917450738466192189">సర్వర్ యొక్క ప్రమాణపత్రం చెల్లుబాటు కాదు.</translation>
diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb index b425d41..956868e 100644 --- a/components/strings/components_strings_th.xtb +++ b/components/strings/components_strings_th.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">ระดับนโยบายไม่ได้รับการสนับสนุน</translation> <translation id="6895330447102777224">บัตรของคุณได้รับการยืนยันแล้ว</translation> <translation id="6897140037006041989">User agent</translation> +<translation id="6903319715792422884">ช่วยปรับปรุง Safe Browsing โดยส่ง<ph name="BEGIN_WHITEPAPER_LINK" />ข้อมูลบางอย่างของระบบและเนื้อหาของหน้า<ph name="END_WHITEPAPER_LINK" />ให้ Google <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">ผู้ใช้:</translation> <translation id="6945221475159498467">เลือก</translation> <translation id="6948701128805548767">หากต้องการดูวิธีการรับสินค้าและข้อกำหนด โปรดเลือกที่อยู่</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">การแปลล้มเหลวเนื่องจากเกิดปัญหาการเชื่อมต่อกับเครือข่าย </translation> <translation id="8311129316111205805">โหลดเซสชัน</translation> <translation id="8332188693563227489">การเข้าถึง <ph name="HOST_NAME" /> ถูกปฏิเสธ</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">หากคุณเข้าใจความเสี่ยงต่อความปลอดภัย คุณสามารถ<ph name="BEGIN_LINK" />ไปยังไซต์นี้<ph name="END_LINK" />ก่อนที่จะมีการนำโปรแกรมอันตรายออก</translation> <translation id="8349305172487531364">แถบบุ๊กมาร์ก</translation> <translation id="8363502534493474904">ปิดโหมดบนเครื่องบิน</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">&เลิกทำการแก้ไข</translation> <translation id="9154194610265714752">อัปเดตแล้ว</translation> <translation id="9157595877708044936">กำลังตั้งค่า...</translation> +<translation id="9168814207360376865">อนุญาตให้เว็บไซต์ตรวจสอบว่าคุณได้บันทึกวิธีการชำระเงินไว้ไหม</translation> <translation id="9169664750068251925">บล็อกบนไซต์นี้เสมอ</translation> <translation id="9170848237812810038">เ&ลิกทำ</translation> <translation id="9171296965991013597">ออกจากแอปไหม</translation>
diff --git a/components/strings/components_strings_tr.xtb b/components/strings/components_strings_tr.xtb index 6d1f19b..faf470c 100644 --- a/components/strings/components_strings_tr.xtb +++ b/components/strings/components_strings_tr.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Politika düzeyi desteklenmiyor.</translation> <translation id="6895330447102777224">Kartınız onaylandı</translation> <translation id="6897140037006041989">Kullanıcı Aracısı</translation> +<translation id="6903319715792422884">Google'a bazı <ph name="BEGIN_WHITEPAPER_LINK" />sistem bilgilerini ve sayfa içeriklerini<ph name="END_WHITEPAPER_LINK" /> göndererek Güvenli Tarama'nın iyileştirilmesine yardımcı olabilirsiniz. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Kullanıcı:</translation> <translation id="6945221475159498467">Seç</translation> <translation id="6948701128805548767">Alım yöntemlerini ve gereksinimlerini görmek için bir adres seçin</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Ağ bağlantısıyla ilgili bir sorun nedeniyle çeviri başarısız oldu.</translation> <translation id="8311129316111205805">Oturum yükle</translation> <translation id="8332188693563227489"><ph name="HOST_NAME" /> ana makinesine erişim reddedildi</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Güvenliğinize ilişkin riskleri anladıysanız <ph name="BEGIN_LINK" />bu siteyi<ph name="END_LINK" /> zararlı programlar kaldırılmadan önce ziyaret edebilirsiniz.</translation> <translation id="8349305172487531364">Yer işaretleri çubuğu</translation> <translation id="8363502534493474904">Uçak modunu kapatma</translation> @@ -1113,6 +1115,7 @@ <translation id="9148507642005240123">Düzenlemeyi &geri al</translation> <translation id="9154194610265714752">Güncellendi</translation> <translation id="9157595877708044936">Ayarlanıyor...</translation> +<translation id="9168814207360376865">Sitelerin, kayıtlı ödeme yöntemleriniz olup olmadığını kontrol etmesine izin verin</translation> <translation id="9169664750068251925">Bu sitede her zaman engelle</translation> <translation id="9170848237812810038">&Geri al</translation> <translation id="9171296965991013597">Uygulamadan çıkılsın mı?</translation>
diff --git a/components/strings/components_strings_uk.xtb b/components/strings/components_strings_uk.xtb index 8e359d8..852ed80 100644 --- a/components/strings/components_strings_uk.xtb +++ b/components/strings/components_strings_uk.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Правило не підтримується.</translation> <translation id="6895330447102777224">Дані картки підтверджено</translation> <translation id="6897140037006041989">Агент користувача</translation> +<translation id="6903319715792422884">Допоможіть покращити Безпечний перегляд, надсилаючи в Google деяку <ph name="BEGIN_WHITEPAPER_LINK" />інформацію про систему та вміст сторінок<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Користувач:</translation> <translation id="6945221475159498467">Вибрати</translation> <translation id="6948701128805548767">Укажіть адресу, щоб переглянути способи отримання та вимоги.</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Переклад не виконано через проблему підключення до мережі.</translation> <translation id="8311129316111205805">Завантажити сеанс</translation> <translation id="8332188693563227489">Відмовлено в доступі до хосту <ph name="HOST_NAME" /></translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Якщо ви розумієте ризики, пов’язані з безпекою, можете <ph name="BEGIN_LINK" />перейти на цей сайт<ph name="END_LINK" /> до того, як небезпечні програми буде видалено.</translation> <translation id="8349305172487531364">Панель закладок</translation> <translation id="8363502534493474904">вимкнути режим польоту</translation>
diff --git a/components/strings/components_strings_vi.xtb b/components/strings/components_strings_vi.xtb index df3c3d4..1096cc0 100644 --- a/components/strings/components_strings_vi.xtb +++ b/components/strings/components_strings_vi.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">Cấp chính sách không được hỗ trợ.</translation> <translation id="6895330447102777224">Thẻ của bạn đã được xác nhận</translation> <translation id="6897140037006041989">Tác nhân Người dùng</translation> +<translation id="6903319715792422884">Giúp cải thiện Duyệt web an toàn bằng cách gửi một số <ph name="BEGIN_WHITEPAPER_LINK" />thông tin hệ thống và nội dung trang<ph name="END_WHITEPAPER_LINK" /> tới Google. <ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">Người dùng:</translation> <translation id="6945221475159498467">Chọn</translation> <translation id="6948701128805548767">Để xem các yêu cầu và phương thức nhận hàng, hãy chọn một địa chỉ</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">Không thể dịch do kết nối mạng có sự cố.</translation> <translation id="8311129316111205805">Tải phiên</translation> <translation id="8332188693563227489">Quyền truy cập <ph name="HOST_NAME" /> bị từ chối</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">Nếu bạn hiểu các rủi ro về bảo mật, bạn có thể <ph name="BEGIN_LINK" />truy cập trang này<ph name="END_LINK" /> trước khi các chương trình độc hại bị xóa.</translation> <translation id="8349305172487531364">Thanh dấu trang</translation> <translation id="8363502534493474904">Tắt chế độ trên máy bay</translation>
diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb index c0ad719..9e4eccb 100644 --- a/components/strings/components_strings_zh-CN.xtb +++ b/components/strings/components_strings_zh-CN.xtb
@@ -806,6 +806,7 @@ <translation id="6891596781022320156">政策级别不受支持。</translation> <translation id="6895330447102777224">已确认您的信用卡</translation> <translation id="6897140037006041989">用户代理</translation> +<translation id="6903319715792422884">您可以选择向 Google 发送一些<ph name="BEGIN_WHITEPAPER_LINK" />系统信息和网页内容<ph name="END_WHITEPAPER_LINK" />,以帮助我们改进安全浏览功能。<ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">用户:</translation> <translation id="6945221475159498467">选择</translation> <translation id="6948701128805548767">要查看取货方式和要求,请选择相应地址</translation> @@ -1010,6 +1011,7 @@ <translation id="8308427013383895095">由于网络连接问题,翻译失败。</translation> <translation id="8311129316111205805">加载会话</translation> <translation id="8332188693563227489">访问 <ph name="HOST_NAME" /> 的请求遭到拒绝</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">如果您了解自己将面临的安全风险,则可以在有害程序被清除之前<ph name="BEGIN_LINK" />访问此网站<ph name="END_LINK" />。</translation> <translation id="8349305172487531364">书签栏</translation> <translation id="8363502534493474904">关闭飞行模式</translation> @@ -1109,6 +1111,7 @@ <translation id="9148507642005240123">撤消修改(&U)</translation> <translation id="9154194610265714752">已更新</translation> <translation id="9157595877708044936">正在设置...</translation> +<translation id="9168814207360376865">允许网站检查您是否已保存付款方式</translation> <translation id="9169664750068251925">在此网站上始终阻止</translation> <translation id="9170848237812810038">撤消(&U)</translation> <translation id="9171296965991013597">要退出应用吗?</translation>
diff --git a/components/strings/components_strings_zh-TW.xtb b/components/strings/components_strings_zh-TW.xtb index 614c7e1..532a12b 100644 --- a/components/strings/components_strings_zh-TW.xtb +++ b/components/strings/components_strings_zh-TW.xtb
@@ -810,6 +810,7 @@ <translation id="6891596781022320156">系統不支援這項政策的層級。</translation> <translation id="6895330447102777224">您的信用卡已通過驗證</translation> <translation id="6897140037006041989">使用者代理程式</translation> +<translation id="6903319715792422884">將部分<ph name="BEGIN_WHITEPAPER_LINK" />系統資訊和網頁內容<ph name="END_WHITEPAPER_LINK" />傳送給 Google,協助我們改善安全瀏覽功能。<ph name="PRIVACY_PAGE_LINK" /></translation> <translation id="6915804003454593391">使用者:</translation> <translation id="6945221475159498467">選取</translation> <translation id="6948701128805548767">如要查看取件方式和相關規定,請選取一個地址</translation> @@ -1014,6 +1015,7 @@ <translation id="8308427013383895095">網路連線發生問題,翻譯作業失敗。</translation> <translation id="8311129316111205805">載入工作階段</translation> <translation id="8332188693563227489">存取 <ph name="HOST_NAME" /> 的要求遭到拒絕</translation> +<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation> <translation id="834457929814110454">如果你瞭解安全性風險,也可以選擇在有害程式尚未遭到移除的狀態下<ph name="BEGIN_LINK" />造訪這個網站<ph name="END_LINK" />。</translation> <translation id="8349305172487531364">書籤列</translation> <translation id="8363502534493474904">關閉飛航模式</translation> @@ -1112,6 +1114,7 @@ <translation id="9148507642005240123">復原編輯(&U)</translation> <translation id="9154194610265714752">已更新</translation> <translation id="9157595877708044936">設定中...</translation> +<translation id="9168814207360376865">允許網站檢查付款方式是否已成功儲存</translation> <translation id="9169664750068251925">永遠禁止在這個網站執行</translation> <translation id="9170848237812810038">取消(&U)</translation> <translation id="9171296965991013597">要離開應用程式嗎?</translation>
diff --git a/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc b/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc index 8930aab..b6cae29 100644 --- a/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc +++ b/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc
@@ -113,6 +113,13 @@ NOTIMPLEMENTED(); return nullptr; } + bool IsNetworkBlockedByPolicy(const std::string& type, + const std::string& guid, + const std::string& profile_path, + const std::string& hex_ssid) const override { + NOTIMPLEMENTED(); + return false; + } bool create_configuration_called() const { return create_configuration_called_;
diff --git a/components/tracing/common/trace_startup_config.cc b/components/tracing/common/trace_startup_config.cc index 50748e2d..8cf535a 100644 --- a/components/tracing/common/trace_startup_config.cc +++ b/components/tracing/common/trace_startup_config.cc
@@ -161,11 +161,9 @@ return startup_duration_; } -#if !defined(OS_ANDROID) base::FilePath TraceStartupConfig::GetResultFile() const { DCHECK(IsEnabled()); return result_file_; } -#endif } // namespace tracing
diff --git a/components/tracing/common/trace_startup_config.h b/components/tracing/common/trace_startup_config.h index a5acfdc3..d68503c 100644 --- a/components/tracing/common/trace_startup_config.h +++ b/components/tracing/common/trace_startup_config.h
@@ -43,15 +43,14 @@ // the result file after shutting the browser down. // // result_file: The file that contains the trace log. The default result -// file path is chrometrace.log. Chrome will dump the trace -// log to this file +// file path is chrometrace.log, except on Android, where the +// default path is generated by tracing controller. Chrome +// will dump the trace log to this file // 1) after startup_duration if it is specified; // 2) or after browser shutdown if startup duration is 0. // One can also stop tracing and get the result by other ways, // e.g., by DevTools. In that case, the trace log will not be // saved to this file. -// Notice: This is not supported on Android. The result file -// path will be generated by tracing controller. // // The trace config file can be specified by the --trace-config-file flag on // most platforms except on Android, e.g., --trace-config-file=path/to/file/. @@ -93,9 +92,7 @@ base::trace_event::TraceConfig GetTraceConfig() const; int GetStartupDuration() const; -#if !defined(OS_ANDROID) base::FilePath GetResultFile() const; -#endif private: // This allows constructor and destructor to be private and usable only
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index c272a95..8938a18 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -122,7 +122,8 @@ if (!language_state_.page_needs_translation() || language_state_.translation_pending() || language_state_.translation_declined() || - language_state_.IsPageTranslated()) { + language_state_.IsPageTranslated() || + !base::FeatureList::IsEnabled(translate::kTranslateUI)) { return; } @@ -131,7 +132,8 @@ if (net::NetworkChangeNotifier::IsOffline()) return; - if (!ignore_missing_key_for_testing_ && !::google_apis::HasKeysConfigured()) { + if (!ignore_missing_key_for_testing_ && + !::google_apis::HasAPIKeyConfigured()) { // Without an API key, translate won't work, so don't offer to translate in // the first place. Leave prefs::kOfferTranslateEnabled on, though, because // that settings syncs and we don't want to turn off translate everywhere
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc index 76dc414..2a2e82a 100644 --- a/components/translate/core/browser/translate_prefs.cc +++ b/components/translate/core/browser/translate_prefs.cc
@@ -111,6 +111,9 @@ const base::Feature kTranslateRecentTarget{"TranslateRecentTarget", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kTranslateUI{"TranslateUI", + base::FEATURE_ENABLED_BY_DEFAULT}; + DenialTimeUpdate::DenialTimeUpdate(PrefService* prefs, const std::string& language, size_t max_denial_count)
diff --git a/components/translate/core/browser/translate_prefs.h b/components/translate/core/browser/translate_prefs.h index e16a9316..cf4b1ed 100644 --- a/components/translate/core/browser/translate_prefs.h +++ b/components/translate/core/browser/translate_prefs.h
@@ -43,6 +43,9 @@ // target language option. extern const base::Feature kTranslateRecentTarget; +// Enable or disable the Translate popup altogether. +extern const base::Feature kTranslateUI; + // Minimum number of times the user must accept a translation before we show // a shortcut to the "Always Translate" functionality. #if defined(OS_ANDROID) || defined(OS_IOS)
diff --git a/components/unified_consent/BUILD.gn b/components/unified_consent/BUILD.gn index b7b2c59..2197f204 100644 --- a/components/unified_consent/BUILD.gn +++ b/components/unified_consent/BUILD.gn
@@ -8,10 +8,14 @@ "pref_names.h", "unified_consent_service.cc", "unified_consent_service.h", + "unified_consent_service_client.h", ] deps = [ "//base", + "//components/autofill/core/common", + "//components/browser_sync", "//components/pref_registry", + "//components/safe_browsing", "//components/signin/core/browser", "//components/sync", "//services/identity/public/cpp",
diff --git a/components/unified_consent/DEPS b/components/unified_consent/DEPS index 7f3ccd4a..4d2acc4 100644 --- a/components/unified_consent/DEPS +++ b/components/unified_consent/DEPS
@@ -1,6 +1,10 @@ include_rules = [ + "+components/autofill/core/common", + "+components/browser_sync", "+components/keyed_service/core", "+components/pref_registry", "+components/prefs", + "+components/safe_browsing/common", + "+components/sync/base", "+services/identity/public/cpp", ]
diff --git a/components/unified_consent/pref_names.cc b/components/unified_consent/pref_names.cc index 09025ea..7d4a2c9 100644 --- a/components/unified_consent/pref_names.cc +++ b/components/unified_consent/pref_names.cc
@@ -6,6 +6,8 @@ namespace prefs { +const char kUnifiedConsentGiven[] = "unified_consent_given"; + const char kUrlKeyedAnonymizedDataCollectionEnabled[] = "url_keyed_anonymized_data_collection.enabled";
diff --git a/components/unified_consent/pref_names.h b/components/unified_consent/pref_names.h index 122bf01f..ac20a73 100644 --- a/components/unified_consent/pref_names.h +++ b/components/unified_consent/pref_names.h
@@ -7,6 +7,7 @@ namespace prefs { +extern const char kUnifiedConsentGiven[]; extern const char kUrlKeyedAnonymizedDataCollectionEnabled[]; } // namespace prefs
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index 3a636e8..6f56377 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -4,17 +4,37 @@ #include "components/unified_consent/unified_consent_service.h" +#include "components/autofill/core/common/autofill_pref_names.h" +#include "components/browser_sync/profile_sync_service.h" #include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/common/safe_browsing_prefs.h" +#include "components/sync/base/model_type.h" #include "components/unified_consent/pref_names.h" +#include "components/unified_consent/unified_consent_service_client.h" UnifiedConsentService::UnifiedConsentService( + UnifiedConsentServiceClient* service_client, PrefService* pref_service, - identity::IdentityManager* identity_manager) - : pref_service_(pref_service), identity_manager_(identity_manager) { + identity::IdentityManager* identity_manager, + browser_sync::ProfileSyncService* profile_sync_service) + : service_client_(service_client), + pref_service_(pref_service), + identity_manager_(identity_manager), + profile_sync_service_(profile_sync_service) { DCHECK(pref_service_); DCHECK(identity_manager_); + DCHECK(profile_sync_service_); identity_manager_->AddObserver(this); + + pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); + pref_change_registrar_->Init(pref_service); + pref_change_registrar_->Add( + prefs::kUnifiedConsentGiven, + base::BindRepeating( + &UnifiedConsentService::OnUnifiedConsentGivenPrefChanged, + base::Unretained(this))); } UnifiedConsentService::~UnifiedConsentService() {} @@ -23,6 +43,7 @@ user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref(prefs::kUrlKeyedAnonymizedDataCollectionEnabled, false); + registry->RegisterBooleanPref(prefs::kUnifiedConsentGiven, false); } void UnifiedConsentService::Shutdown() { @@ -35,4 +56,38 @@ // for making search and browsing better. pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled, false); + // When signing out, the unfied consent is revoked. + pref_service_->SetBoolean(prefs::kUnifiedConsentGiven, false); +} + +void UnifiedConsentService::OnUnifiedConsentGivenPrefChanged() { + bool enabled = pref_service_->GetBoolean(prefs::kUnifiedConsentGiven); + + if (!enabled) { + if (identity_manager_->HasPrimaryAccount()) { + // KeepEverythingSynced is set to false, so the user can select individual + // sync data types. + profile_sync_service_->OnUserChoseDatatypes( + false, syncer::UserSelectableTypes()); + } + return; + } + + DCHECK(profile_sync_service_->IsSyncAllowed()); + DCHECK(identity_manager_->HasPrimaryAccount()); + + // Enable all sync data types. + pref_service_->SetBoolean(autofill::prefs::kAutofillWalletImportEnabled, + true); + profile_sync_service_->OnUserChoseDatatypes(true, + syncer::UserSelectableTypes()); + + // Enable all non-personalized services. + pref_service_->SetBoolean(prefs::kSafeBrowsingEnabled, true); + service_client_->SetAlternateErrorPagesEnabled(true); + service_client_->SetMetricsReportingEnabled(true); + service_client_->SetSafeBrowsingExtendedReportingEnabled(true); + service_client_->SetSearchSuggestEnabled(true); + service_client_->SetSafeBrowsingExtendedReportingEnabled(true); + service_client_->SetNetworkPredictionEnabled(true); }
diff --git a/components/unified_consent/unified_consent_service.h b/components/unified_consent/unified_consent_service.h index 519f6b33..50740c1 100644 --- a/components/unified_consent/unified_consent_service.h +++ b/components/unified_consent/unified_consent_service.h
@@ -6,6 +6,7 @@ #define COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_H_ #include <memory> +#include <vector> #include "base/macros.h" #include "base/observer_list.h" @@ -15,15 +16,26 @@ namespace user_prefs { class PrefRegistrySyncable; } + +class PrefChangeRegistrar; class PrefService; +namespace browser_sync { +class ProfileSyncService; +} + +class UnifiedConsentServiceClient; + // A browser-context keyed service that is used to manage the user consent // when UnifiedConsent feature is enabled. class UnifiedConsentService : public KeyedService, public identity::IdentityManager::Observer { public: - UnifiedConsentService(PrefService* pref_service, - identity::IdentityManager* identity_manager); + // + UnifiedConsentService(UnifiedConsentServiceClient* service_client, + PrefService* pref_service, + identity::IdentityManager* identity_manager, + browser_sync::ProfileSyncService* profile_sync_service); ~UnifiedConsentService() override; // Register the prefs used by this UnifiedConsentService. @@ -37,8 +49,17 @@ const AccountInfo& previous_primary_account_info) override; private: + // Called when |prefs::kUnifiedConsentGiven| pref value changes. + // When set to true, it enables syncing of all data types and it enables all + // non-personalized services. Otherwise it does nothing. + void OnUnifiedConsentGivenPrefChanged(); + + UnifiedConsentServiceClient* service_client_; PrefService* pref_service_; identity::IdentityManager* identity_manager_; + browser_sync::ProfileSyncService* profile_sync_service_; + + std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; DISALLOW_COPY_AND_ASSIGN(UnifiedConsentService); };
diff --git a/components/unified_consent/unified_consent_service_client.h b/components/unified_consent/unified_consent_service_client.h new file mode 100644 index 0000000..f250c76 --- /dev/null +++ b/components/unified_consent/unified_consent_service_client.h
@@ -0,0 +1,24 @@ +// 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 COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_ +#define COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_ + +class UnifiedConsentServiceClient { + public: + virtual ~UnifiedConsentServiceClient() {} + + // Enables/disables Link Doctor error pages. + virtual void SetAlternateErrorPagesEnabled(bool enabled) = 0; + // Enables/disables metrics reporting. + virtual void SetMetricsReportingEnabled(bool enabled) = 0; + // Enables/disables search suggestions. + virtual void SetSearchSuggestEnabled(bool enabled) = 0; + // Enables/disables extended safe browsing. + virtual void SetSafeBrowsingExtendedReportingEnabled(bool enabled) = 0; + // Enables/disables prediction of network actions. + virtual void SetNetworkPredictionEnabled(bool enabled) = 0; +}; + +#endif // COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_
diff --git a/components/update_client/update_client.cc b/components/update_client/update_client.cc index 4d3c9b4..561bbcf9 100644 --- a/components/update_client/update_client.cc +++ b/components/update_client/update_client.cc
@@ -16,6 +16,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/observer_list.h" +#include "base/stl_util.h" #include "base/threading/thread_checker.h" #include "base/threading/thread_task_runner_handle.h" #include "components/prefs/pref_registry_simple.h" @@ -183,14 +184,14 @@ for (const auto task : tasks_) { const auto ids = task->GetIds(); - if (std::find(ids.begin(), ids.end(), id) != ids.end()) { + if (base::ContainsValue(ids, id)) { return true; } } for (const auto task : task_queue_) { const auto ids = task->GetIds(); - if (std::find(ids.begin(), ids.end(), id) != ids.end()) { + if (base::ContainsValue(ids, id)) { return true; } }
diff --git a/components/url_matcher/url_matcher.cc b/components/url_matcher/url_matcher.cc index 012d2f01..12c6cc5 100644 --- a/components/url_matcher/url_matcher.cc +++ b/components/url_matcher/url_matcher.cc
@@ -682,8 +682,7 @@ URLMatcherSchemeFilter::~URLMatcherSchemeFilter() {} bool URLMatcherSchemeFilter::IsMatch(const GURL& url) const { - return std::find(filters_.begin(), filters_.end(), url.scheme()) != - filters_.end(); + return base::ContainsValue(filters_, url.scheme()); } //
diff --git a/components/viz/host/BUILD.gn b/components/viz/host/BUILD.gn index f59610d..d46d577 100644 --- a/components/viz/host/BUILD.gn +++ b/components/viz/host/BUILD.gn
@@ -14,6 +14,8 @@ "hit_test/hit_test_query.cc", "hit_test/hit_test_query.h", "hit_test/hit_test_region_observer.h", + "host_display_client.cc", + "host_display_client.h", "host_frame_sink_client.h", "host_frame_sink_manager.cc", "host_frame_sink_manager.h", @@ -52,6 +54,10 @@ "//services/viz/public/interfaces", "//ui/gfx/geometry", ] + + if (is_mac) { + deps += [ "//ui/accelerated_widget_mac" ] + } } viz_source_set("unit_tests") {
diff --git a/components/viz/host/DEPS b/components/viz/host/DEPS index b9d508f1..c24c606 100644 --- a/components/viz/host/DEPS +++ b/components/viz/host/DEPS
@@ -15,6 +15,7 @@ "+services/viz/public/interfaces/hit_test", "+skia", "+third_party/skia", + "+ui/accelerated_widget_mac", ] specific_include_rules = {
diff --git a/components/viz/host/host_display_client.cc b/components/viz/host/host_display_client.cc new file mode 100644 index 0000000..bdd1e8b --- /dev/null +++ b/components/viz/host/host_display_client.cc
@@ -0,0 +1,65 @@ +// 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 "components/viz/host/host_display_client.h" + +#if defined(OS_MACOSX) +#include "ui/accelerated_widget_mac/ca_layer_frame_sink.h" +#endif + +#if defined(OS_WIN) +#include <windows.h> + +#include "components/viz/common/display/use_layered_window.h" +#include "components/viz/host/layered_window_updater_impl.h" +#include "ui/base/win/internal_constants.h" +#endif + +namespace viz { + +HostDisplayClient::HostDisplayClient(gfx::AcceleratedWidget widget) + : binding_(this) { +#if defined(OS_MACOSX) || defined(OS_WIN) + widget_ = widget; +#endif +} + +HostDisplayClient::~HostDisplayClient() = default; + +mojom::DisplayClientPtr HostDisplayClient::GetBoundPtr( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + mojom::DisplayClientPtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr), task_runner); + return ptr; +} + +void HostDisplayClient::DidSwapAfterSnapshotRequestReceived( + const std::vector<ui::LatencyInfo>& latency_info) {} + +#if defined(OS_MACOSX) +void HostDisplayClient::OnDisplayReceivedCALayerParams( + const gfx::CALayerParams& ca_layer_params) { + ui::CALayerFrameSink* ca_layer_frame_sink = + ui::CALayerFrameSink::FromAcceleratedWidget(widget_); + if (ca_layer_frame_sink) + ca_layer_frame_sink->UpdateCALayerTree(ca_layer_params); + else + DLOG(WARNING) << "Received frame for non-existent widget."; +} +#endif + +#if defined(OS_WIN) +void HostDisplayClient::CreateLayeredWindowUpdater( + mojom::LayeredWindowUpdaterRequest request) { + if (!NeedsToUseLayerWindow(widget_)) { + DLOG(ERROR) << "HWND shouldn't be using a layered window"; + return; + } + + layered_window_updater_ = + std::make_unique<LayeredWindowUpdaterImpl>(widget_, std::move(request)); +} +#endif + +} // namespace viz
diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h new file mode 100644 index 0000000..7fd5a4a9 --- /dev/null +++ b/components/viz/host/host_display_client.h
@@ -0,0 +1,62 @@ +// 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 COMPONENTS_VIZ_HOST_HOST_DISPLAY_CLIENT_H_ +#define COMPONENTS_VIZ_HOST_HOST_DISPLAY_CLIENT_H_ + +#include <memory> +#include <vector> + +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "build/build_config.h" +#include "components/viz/host/viz_host_export.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/viz/privileged/interfaces/compositing/display_private.mojom.h" +#include "ui/gfx/native_widget_types.h" + +namespace viz { + +class LayeredWindowUpdaterImpl; + +// mojom::DisplayClient implementation that relays calls to platform specific +// functions. +class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient { + public: + explicit HostDisplayClient(gfx::AcceleratedWidget widget); + ~HostDisplayClient() override; + + mojom::DisplayClientPtr GetBoundPtr( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + private: + // mojom::DisplayClient implementation: + void DidSwapAfterSnapshotRequestReceived( + const std::vector<ui::LatencyInfo>& latency_info) override; + +#if defined(OS_MACOSX) + void OnDisplayReceivedCALayerParams( + const gfx::CALayerParams& ca_layer_params) override; +#endif + +#if defined(OS_WIN) + void CreateLayeredWindowUpdater( + mojom::LayeredWindowUpdaterRequest request) override; +#endif + + mojo::Binding<mojom::DisplayClient> binding_; +#if defined(OS_MACOSX) || defined(OS_WIN) + gfx::AcceleratedWidget widget_; +#endif + +#if defined(OS_WIN) + std::unique_ptr<LayeredWindowUpdaterImpl> layered_window_updater_; +#endif + + DISALLOW_COPY_AND_ASSIGN(HostDisplayClient); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_HOST_HOST_DISPLAY_CLIENT_H_
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 3399978..a001356 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -225,7 +225,8 @@ #if BUILDFLAG(ENABLE_VULKAN) } else if (output_surface_->vulkan_context_provider()) { renderer_ = std::make_unique<SkiaRenderer>( - &settings_, output_surface_.get(), resource_provider_.get()); + &settings_, output_surface_.get(), resource_provider_.get(), + nullptr /* skia_output_surface */); #endif } else { auto renderer = std::make_unique<SoftwareRenderer>(
diff --git a/components/viz/service/display/display_resource_provider.cc b/components/viz/service/display/display_resource_provider.cc index d4acb35c..33d9ca8 100644 --- a/components/viz/service/display/display_resource_provider.cc +++ b/components/viz/service/display/display_resource_provider.cc
@@ -6,6 +6,7 @@ #include "base/atomic_sequence_num.h" #include "base/numerics/safe_math.h" +#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_dump_manager.h" @@ -68,7 +69,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // If no ContextProvider, then we are doing software compositing and a // SharedBitmapManager must be given. - DCHECK(compositor_context_provider || shared_bitmap_manager); + DCHECK(mode_ == kGpu || shared_bitmap_manager); // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). // Don't register a dump provider in these cases. @@ -870,8 +871,7 @@ ResourceMetadata DisplayResourceProvider::LockSetForExternalUse::LockResource( ResourceId id) { - DCHECK(std::find(resources_.begin(), resources_.end(), id) == - resources_.end()); + DCHECK(!base::ContainsValue(resources_, id)); resources_.push_back(id); return resource_provider_->LockForExternalUse(id); }
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 8a78fb2c..1b4a3a5 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -142,7 +142,7 @@ void TearDown() override { cc::GLRendererPixelTest::TearDown(); - ASSERT_FALSE(renderer()->IsContextLost()); + ASSERT_FALSE(renderer()); } void TestShaderWithDrawingFrame(
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 507daa40..53c5a90 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -842,6 +842,7 @@ ::testing::Types<GLRenderer, SoftwareRenderer, SkiaRenderer, + cc::SkiaRendererDDL, cc::GLRendererWithExpandedViewport, cc::SoftwareRendererWithExpandedViewport>; TYPED_TEST_CASE(RendererPixelTest, RendererTypes); @@ -895,6 +896,13 @@ } template <> +bool FuzzyForSoftwareOnlyPixelComparator<cc::SkiaRendererDDL>::Compare( + const SkBitmap& actual_bmp, + const SkBitmap& expected_bmp) const { + return fuzzy_.Compare(actual_bmp, expected_bmp); +} + +template <> bool FuzzyForSoftwareOnlyPixelComparator< cc::SoftwareRendererWithExpandedViewport>:: Compare(const SkBitmap& actual_bmp, const SkBitmap& expected_bmp) const { @@ -1301,6 +1309,11 @@ } template <> +uint32_t GetColor<cc::SkiaRendererDDL>(const SkColor& color) { + return GetSkiaOrGLColor(color); +} + +template <> uint32_t GetColor<cc::GLRendererWithExpandedViewport>(const SkColor& color) { return GetSkiaOrGLColor(color); } @@ -1596,6 +1609,11 @@ kMaxResourceSize); } + void TearDown() override { + video_resource_updater_ = nullptr; + GLRendererPixelTest::TearDown(); + } + std::unique_ptr<media::VideoResourceUpdater> video_resource_updater_; }; @@ -2573,7 +2591,7 @@ // The software renderer does not support background filters yet. using BackgroundFilterRendererTypes = - ::testing::Types<GLRenderer, SkiaRenderer>; + ::testing::Types<GLRenderer, SkiaRenderer, cc::SkiaRendererDDL>; TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter, BackgroundFilterRendererTypes);
diff --git a/components/viz/service/display/skia_output_surface.h b/components/viz/service/display/skia_output_surface.h index b85838b..bdc29aa 100644 --- a/components/viz/service/display/skia_output_surface.h +++ b/components/viz/service/display/skia_output_surface.h
@@ -14,6 +14,7 @@ namespace viz { +class CopyOutputRequest; struct ResourceMetadata; // This class extends the OutputSurface for SkiaRenderer needs. In future, the @@ -25,10 +26,22 @@ SkiaOutputSurface(); ~SkiaOutputSurface() override; - // Get a SkCanvas for the current frame. The SkiaRenderer will use this - // SkCanvas to draw quads. This class retains the ownership of the SkCanvas, - // And this SkCanvas may become invalid, when the frame is swapped out. - virtual SkCanvas* GetSkCanvasForCurrentFrame() = 0; + // Begin painting the current frame. This method will create a + // SkDeferredDisplayListRecorder and return a SkCanvas of it. + // The SkiaRenderer will use this SkCanvas to paint the current + // frame. + // And this SkCanvas may become invalid, when FinishPaintCurrentFrame is + // called. + virtual SkCanvas* BeginPaintCurrentFrame() = 0; + + // Finish painting the current frame. It should be paired with + // BeginPaintCurrentFrame. This method will schedule a GPU task to play the + // DDL back on GPU thread on the SkSurface for the framebuffer. This method + // returns a sync token which can be waited on in a command buffer to ensure + // the paint operation is completed. This token is released when the GPU ops + // from painting the current frame have been seen and processed by the GPU + // main. + virtual gpu::SyncToken FinishPaintCurrentFrame() = 0; // Make a promise SkImage from the given |metadata|. The SkiaRenderer can use // the image with SkCanvas returned by |GetSkCanvasForCurrentFrame|, but Skia @@ -49,13 +62,8 @@ std::vector<ResourceMetadata> metadatas, SkYUVColorSpace yuv_color_space) = 0; - // Swaps the current backbuffer to the screen and return a sync token which - // can be waited on in a command buffer to ensure the frame is completed. This - // token is released when the GPU ops from drawing the frame have been seen - // and processed by the GPU main. - // TODO(penghuang): replace OutputSurface::SwapBuffers with this method when - // SkiaRenderer and DDL are used everywhere. - virtual gpu::SyncToken SkiaSwapBuffers(OutputSurfaceFrame frame) = 0; + // Swaps the current backbuffer to the screen. + virtual void SkiaSwapBuffers(OutputSurfaceFrame frame) = 0; // Begin painting a render pass. This method will create a // SkDeferredDisplayListRecorder and return a SkCanvas of it. The SkiaRenderer @@ -89,6 +97,12 @@ // FinishPaintRenderPass. virtual void RemoveRenderPassResource(std::vector<RenderPassId> ids) = 0; + // Copy the output of the current frame if the |id| is zero, otherwise copy + // the output of a cached SkSurface for the given |id|. + virtual void CopyOutput(RenderPassId id, + const gfx::Rect& copy_rect, + std::unique_ptr<CopyOutputRequest> request) = 0; + private: DISALLOW_COPY_AND_ASSIGN(SkiaOutputSurface); };
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 8fb3745..0544d031 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -29,6 +29,7 @@ #include "components/viz/service/display/resource_metadata.h" #include "components/viz/service/display/skia_output_surface.h" #include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/vulkan/buildflags.h" #include "skia/ext/opacity_filter_canvas.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" @@ -195,6 +196,8 @@ SkiaRenderer::~SkiaRenderer() = default; bool SkiaRenderer::CanPartialSwap() { + if (IsUsingVulkan()) + return false; if (use_swap_with_bounds_) return false; auto* context_provider = output_surface_->context_provider(); @@ -205,7 +208,7 @@ void SkiaRenderer::BeginDrawingFrame() { TRACE_EVENT0("viz", "SkiaRenderer::BeginDrawingFrame"); - if (is_using_ddl()) + if (IsUsingVulkan() || is_using_ddl()) return; // Copied from GLRenderer. scoped_refptr<ResourceFence> read_lock_fence; @@ -226,7 +229,7 @@ for (ResourceId resource_id : quad->resources) resource_provider_->WaitSyncToken(resource_id); } - } + } } void SkiaRenderer::FinishDrawingFrame() { @@ -274,11 +277,7 @@ } if (is_using_ddl()) { - auto sync_token = - skia_output_surface_->SkiaSwapBuffers(std::move(output_frame)); - promise_images_.clear(); - yuv_promise_images_.clear(); - lock_set_for_external_use_.UnlockResources(sync_token); + skia_output_surface_->SkiaSwapBuffers(std::move(output_frame)); } else { // TODO(penghuang): remove it when SkiaRenderer and SkDDL are always used. output_surface_->SwapBuffers(std::move(output_frame)); @@ -312,13 +311,37 @@ // TODO(weiliangc): Set up correct can_use_lcd_text for SkSurfaceProps flags. // How to setup is in ResourceProvider. (http://crbug.com/644851) if (is_using_ddl()) { - root_canvas_ = skia_output_surface_->GetSkCanvasForCurrentFrame(); + root_canvas_ = skia_output_surface_->BeginPaintCurrentFrame(); + is_drawing_render_pass_ = false; DCHECK(root_canvas_); } else { - auto* gr_context = output_surface_->context_provider()->GrContext(); - if (!root_canvas_ || root_canvas_->getGrContext() != gr_context || - gfx::SkISizeToSize(root_canvas_->getBaseLayerSize()) != - current_frame()->device_viewport_size) { + auto* gr_context = GetGrContext(); + if (IsUsingVulkan()) { +#if BUILDFLAG(ENABLE_VULKAN) + auto* vulkan_surface = output_surface_->GetVulkanSurface(); + auto* swap_chain = vulkan_surface->GetSwapChain(); + VkImage image = swap_chain->GetCurrentImage(swap_chain->current_image()); + GrVkImageInfo vk_image_info; + vk_image_info.fImage = image; + vk_image_info.fAlloc = {VK_NULL_HANDLE, 0, 0, 0}; + vk_image_info.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + vk_image_info.fImageTiling = VK_IMAGE_TILING_OPTIMAL; + vk_image_info.fFormat = VK_FORMAT_B8G8R8A8_UNORM; + vk_image_info.fLevelCount = 1; + GrBackendRenderTarget render_target( + current_frame()->device_viewport_size.width(), + current_frame()->device_viewport_size.height(), 0, 0, vk_image_info); + root_surface_ = SkSurface::MakeFromBackendRenderTarget( + gr_context, render_target, kTopLeft_GrSurfaceOrigin, + kBGRA_8888_SkColorType, nullptr, &surface_props); + DCHECK(root_surface_); + root_canvas_ = root_surface_->getCanvas(); +#else + NOTREACHED(); +#endif + } else if (!root_canvas_ || root_canvas_->getGrContext() != gr_context || + gfx::SkISizeToSize(root_canvas_->getBaseLayerSize()) != + current_frame()->device_viewport_size) { // Either no SkSurface setup yet, or new GrContext, need to create new // surface. GrGLFramebufferInfo framebuffer_info; @@ -332,6 +355,7 @@ root_surface_ = SkSurface::MakeFromBackendRenderTarget( gr_context, render_target, kBottomLeft_GrSurfaceOrigin, kRGB_888x_SkColorType, nullptr, &surface_props); + DCHECK(root_surface_); root_canvas_ = root_surface_->getCanvas(); } } @@ -877,12 +901,6 @@ // TODO(weiliangc): Make copy request work. (crbug.com/644851) TRACE_EVENT0("viz", "SkiaRenderer::CopyDrawnRenderPass"); - if (is_using_ddl()) { - // TODO(penghuang): Support it with SkDDL. - NOTIMPLEMENTED(); - return; - } - gfx::Rect copy_rect = current_frame()->current_render_pass->output_rect; if (request->has_area()) copy_rect.Intersect(request->area()); @@ -892,20 +910,32 @@ gfx::Rect window_copy_rect = MoveFromDrawToWindowSpace(copy_rect); - sk_sp<SkImage> copy_image = current_surface_->makeImageSnapshot()->makeSubset( - RectToSkIRect(window_copy_rect)); - - if (request->result_format() == CopyOutputResult::Format::RGBA_BITMAP) { - // Send copy request by copying into a bitmap. - SkBitmap bitmap; - copy_image->asLegacyBitmap(&bitmap); - - request->SendResult( - std::make_unique<CopyOutputSkBitmapResult>(copy_rect, bitmap)); + if (request->result_format() != CopyOutputResult::Format::RGBA_BITMAP || + request->is_scaled() || + (request->has_result_selection() && + request->result_selection() == gfx::Rect(copy_rect.size()))) { + // TODO(crbug.com/644851): Complete the implementation for all request + // types, scaling, etc. + NOTIMPLEMENTED(); return; } - NOTREACHED(); + if (is_using_ddl()) { + auto render_pass_id = + is_drawing_render_pass_ ? current_frame()->current_render_pass->id : 0; + skia_output_surface_->CopyOutput(render_pass_id, window_copy_rect, + std::move(request)); + return; + } + + sk_sp<SkImage> copy_image = current_surface_->makeImageSnapshot()->makeSubset( + RectToSkIRect(window_copy_rect)); + + // Send copy request by copying into a bitmap. + SkBitmap bitmap; + copy_image->asLegacyBitmap(&bitmap); + request->SendResult( + std::make_unique<CopyOutputSkBitmapResult>(copy_rect, bitmap)); } void SkiaRenderer::SetEnableDCLayers(bool enable) { @@ -922,13 +952,13 @@ void SkiaRenderer::FinishDrawingQuadList() { if (is_using_ddl()) { - if (is_drawing_render_pass_) { - gpu::SyncToken sync_token = skia_output_surface_->FinishPaintRenderPass(); - promise_images_.clear(); - yuv_promise_images_.clear(); - lock_set_for_external_use_.UnlockResources(sync_token); - is_drawing_render_pass_ = false; - } + gpu::SyncToken sync_token = + is_drawing_render_pass_ + ? skia_output_surface_->FinishPaintRenderPass() + : skia_output_surface_->FinishPaintCurrentFrame(); + promise_images_.clear(); + yuv_promise_images_.clear(); + lock_set_for_external_use_.UnlockResources(sync_token); } else { current_canvas_->flush(); } @@ -952,6 +982,23 @@ return true; } +bool SkiaRenderer::IsUsingVulkan() const { +#if BUILDFLAG(ENABLE_VULKAN) + if (output_surface_->vulkan_context_provider()) + return output_surface_->vulkan_context_provider()->GetGrContext(); +#endif + return false; +} + +GrContext* SkiaRenderer::GetGrContext() { + DCHECK(!is_using_ddl()); +#if BUILDFLAG(ENABLE_VULKAN) + if (output_surface_->vulkan_context_provider()) + return output_surface_->vulkan_context_provider()->GetGrContext(); +#endif + return output_surface_->context_provider()->GrContext(); +} + void SkiaRenderer::UpdateRenderPassTextures( const RenderPassList& render_passes_in_draw_order, const base::flat_map<RenderPassId, RenderPassRequirements>& @@ -997,10 +1044,17 @@ caps.texture_format_bgra8888 = true; GrContext* gr_context = nullptr; if (!is_using_ddl()) { - ContextProvider* context_provider = output_surface_->context_provider(); - caps.texture_format_bgra8888 = - context_provider->ContextCapabilities().texture_format_bgra8888; - gr_context = context_provider->GrContext(); + if (IsUsingVulkan()) { + // TODO(penghuang): check supported format correctly. + caps.texture_format_bgra8888 = true; + } else { + ContextProvider* context_provider = output_surface_->context_provider(); + if (context_provider) { + caps.texture_format_bgra8888 = + context_provider->ContextCapabilities().texture_format_bgra8888; + } + } + gr_context = GetGrContext(); } render_pass_backings_.insert(std::pair<RenderPassId, RenderPassBacking>( render_pass_id,
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index 92cb4f81..4f38c99 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -35,7 +35,7 @@ SkiaRenderer(const RendererSettings* settings, OutputSurface* output_surface, DisplayResourceProvider* resource_provider, - SkiaOutputSurface* skia_output_surface = nullptr); + SkiaOutputSurface* skia_output_surface); ~SkiaRenderer() override; void SwapBuffers(std::vector<ui::LatencyInfo> latency_info, @@ -97,6 +97,8 @@ bool ShouldApplyBackgroundFilters( const RenderPassDrawQuad* quad, const cc::FilterOperations* background_filters) const; + bool IsUsingVulkan() const; + GrContext* GetGrContext(); bool is_using_ddl() const { return !!skia_output_surface_; } // A map from RenderPass id to the texture used to draw the RenderPass from.
diff --git a/components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h b/components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h index a68a45205..e14751d6 100644 --- a/components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h +++ b/components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h
@@ -6,6 +6,7 @@ #define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_IN_PROCESS_GPU_MEMORY_BUFFER_MANAGER_H_ #include "base/memory/weak_ptr.h" +#include "components/viz/service/viz_service_export.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" namespace gpu { @@ -15,7 +16,8 @@ namespace viz { -class InProcessGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager { +class VIZ_SERVICE_EXPORT InProcessGpuMemoryBufferManager + : public gpu::GpuMemoryBufferManager { public: explicit InProcessGpuMemoryBufferManager( gpu::GpuChannelManager* channel_manager);
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 1cf080a4..a08898b 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -8,6 +8,7 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" +#include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/service/display/output_surface_client.h" #include "components/viz/service/display/output_surface_frame.h" @@ -277,7 +278,7 @@ return 0; } -SkCanvas* SkiaOutputSurfaceImpl::GetSkCanvasForCurrentFrame() { +SkCanvas* SkiaOutputSurfaceImpl::BeginPaintCurrentFrame() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(recorder_); DCHECK_EQ(current_render_pass_id_, 0u); @@ -285,6 +286,30 @@ return recorder_->getCanvas(); } +gpu::SyncToken SkiaOutputSurfaceImpl::FinishPaintCurrentFrame() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(recorder_); + + gpu::SyncToken sync_token(gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE, + impl_on_gpu_->command_buffer_id(), + ++sync_fence_release_); + sync_token.SetVerifyFlush(); + + auto ddl = recorder_->detach(); + DCHECK(ddl); + recorder_.reset(); + auto sequence_id = gpu_service_->skia_output_surface_sequence_id(); + // impl_on_gpu_ is released on the GPU thread by a posted task from + // SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained. + auto callback = + base::BindOnce(&SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame, + base::Unretained(impl_on_gpu_.get()), std::move(ddl), + std::move(yuv_resource_metadatas_), sync_fence_release_); + gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task( + sequence_id, std::move(callback), std::move(resource_sync_tokens_))); + return sync_token; +} + sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImage( ResourceMetadata metadata) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -329,29 +354,18 @@ kPremul_SkAlphaType, nullptr /* color_space */, std::move(yuv_metadata)); } -gpu::SyncToken SkiaOutputSurfaceImpl::SkiaSwapBuffers( - OutputSurfaceFrame frame) { +void SkiaOutputSurfaceImpl::SkiaSwapBuffers(OutputSurfaceFrame frame) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(recorder_); - - gpu::SyncToken sync_token(gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE, - impl_on_gpu_->command_buffer_id(), - ++sync_fence_release_); - sync_token.SetVerifyFlush(); - - auto ddl = recorder_->detach(); - DCHECK(ddl); + DCHECK(!recorder_); RecreateRecorder(); auto sequence_id = gpu_service_->skia_output_surface_sequence_id(); // impl_on_gpu_ is released on the GPU thread by a posted task from // SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained. - auto callback = base::BindOnce( - &SkiaOutputSurfaceImplOnGpu::SwapBuffers, - base::Unretained(impl_on_gpu_.get()), std::move(frame), std::move(ddl), - std::move(yuv_resource_metadatas_), sync_fence_release_); + auto callback = + base::BindOnce(&SkiaOutputSurfaceImplOnGpu::SwapBuffers, + base::Unretained(impl_on_gpu_.get()), std::move(frame)); gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task( - sequence_id, std::move(callback), std::move(resource_sync_tokens_))); - return sync_token; + sequence_id, std::move(callback), std::vector<gpu::SyncToken>())); } SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass( @@ -445,6 +459,7 @@ void SkiaOutputSurfaceImpl::RemoveRenderPassResource( std::vector<RenderPassId> ids) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!ids.empty()); auto sequence_id = gpu_service_->skia_output_surface_sequence_id(); // impl_on_gpu_ is released on the GPU thread by a posted task from @@ -456,6 +471,19 @@ sequence_id, std::move(callback), std::vector<gpu::SyncToken>())); } +void SkiaOutputSurfaceImpl::CopyOutput( + RenderPassId id, + const gfx::Rect& copy_rect, + std::unique_ptr<CopyOutputRequest> request) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + auto sequence_id = gpu_service_->skia_output_surface_sequence_id(); + auto callback = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::CopyOutput, + base::Unretained(impl_on_gpu_.get()), id, + copy_rect, std::move(request)); + gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task( + sequence_id, std::move(callback), std::vector<gpu::SyncToken>())); +} + void SkiaOutputSurfaceImpl::InitializeOnGpuThread(base::WaitableEvent* event) { base::ScopedClosureRunner scoped_runner( base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(event)));
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index a116346d..9fdcf5e 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -9,6 +9,7 @@ #include "base/optional.h" #include "base/threading/thread_checker.h" #include "components/viz/service/display/skia_output_surface.h" +#include "components/viz/service/viz_service_export.h" #include "gpu/command_buffer/common/sync_token.h" #include "gpu/ipc/common/surface_handle.h" #include "gpu/ipc/in_process_command_buffer.h" @@ -37,7 +38,7 @@ // render into. In SwapBuffers, it detaches a SkDeferredDisplayList from the // recorder and plays it back on the framebuffer SkSurface on the GPU thread // through SkiaOutputSurfaceImpleOnGpu. -class SkiaOutputSurfaceImpl : public SkiaOutputSurface { +class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { public: SkiaOutputSurfaceImpl( GpuServiceImpl* gpu_service, @@ -72,12 +73,13 @@ bool needs_swap_size_notifications) override; // SkiaOutputSurface implementation: - SkCanvas* GetSkCanvasForCurrentFrame() override; + SkCanvas* BeginPaintCurrentFrame() override; + gpu::SyncToken FinishPaintCurrentFrame() override; sk_sp<SkImage> MakePromiseSkImage(ResourceMetadata metadata) override; sk_sp<SkImage> MakePromiseSkImageFromYUV( std::vector<ResourceMetadata> metadatas, SkYUVColorSpace yuv_color_space) override; - gpu::SyncToken SkiaSwapBuffers(OutputSurfaceFrame frame) override; + void SkiaSwapBuffers(OutputSurfaceFrame frame) override; SkCanvas* BeginPaintRenderPass(const RenderPassId& id, const gfx::Size& surface_size, ResourceFormat format, @@ -88,6 +90,9 @@ ResourceFormat format, bool mipmap) override; void RemoveRenderPassResource(std::vector<RenderPassId> ids) override; + void CopyOutput(RenderPassId id, + const gfx::Rect& copy_rect, + std::unique_ptr<CopyOutputRequest> request) override; private: template <class T>
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 7b2b5bed..cc247a0 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
@@ -7,6 +7,7 @@ #include "base/atomic_sequence_num.h" #include "base/callback_helpers.h" #include "base/synchronization/waitable_event.h" +#include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/service/display/output_surface_frame.h" #include "components/viz/service/gl/gpu_service_impl.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" @@ -18,10 +19,12 @@ #include "gpu/config/gpu_preferences.h" #include "gpu/ipc/service/image_transport_surface.h" #include "third_party/skia/include/private/SkDeferredDisplayList.h" +#include "ui/gfx/skia_util.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gl_version_info.h" +#include "ui/gl/init/gl_factory.h" namespace viz { namespace { @@ -64,8 +67,13 @@ gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE, command_buffer_id_, gpu_service_->skia_output_surface_sequence_id()); - surface_ = gpu::ImageTransportSurface::CreateNativeSurface( - weak_ptr_factory_.GetWeakPtr(), surface_handle_, gl::GLSurfaceFormat()); + if (surface_handle_) { + surface_ = gpu::ImageTransportSurface::CreateNativeSurface( + weak_ptr_factory_.GetWeakPtr(), surface_handle_, gl::GLSurfaceFormat()); + } else { + // surface_ could be null for pixel tests. + surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size(1, 1)); + } DCHECK(surface_); if (!gpu_service_->CreateGrContextIfNecessary(surface_.get())) { @@ -101,6 +109,7 @@ SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + sync_point_client_state_->Destroy(); } void SkiaOutputSurfaceImplOnGpu::Reshape( @@ -157,8 +166,7 @@ } } -void SkiaOutputSurfaceImplOnGpu::SwapBuffers( - OutputSurfaceFrame frame, +void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame( std::unique_ptr<SkDeferredDisplayList> ddl, std::vector<YUVResourceMetadata*> yuv_resource_metadatas, uint64_t sync_fence_release) { @@ -175,11 +183,20 @@ sk_surface_->draw(ddl.get()); gpu_service_->gr_context()->flush(); + sync_point_client_state_->ReleaseFenceSync(sync_fence_release); +} + +void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(sk_surface_); + if (!gpu_service_->context_for_skia()->MakeCurrent(surface_.get())) { + LOG(FATAL) << "Failed to make current."; + // TODO(penghuang): Handle the failure. + } OnSwapBuffers(); surface_->SwapBuffers(frame.need_presentation_feedback ? buffer_presented_callback_ : base::DoNothing()); - sync_point_client_state_->ReleaseFenceSync(sync_fence_release); } void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass( @@ -214,6 +231,7 @@ void SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource( std::vector<RenderPassId> ids) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!ids.empty()); for (const auto& id : ids) { auto it = offscreen_surfaces_.find(id); @@ -222,6 +240,31 @@ } } +void SkiaOutputSurfaceImplOnGpu::CopyOutput( + RenderPassId id, + const gfx::Rect& copy_rect, + std::unique_ptr<CopyOutputRequest> request) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // TODO(crbug.com/644851): Complete the implementation for all request types, + // scaling, etc. + DCHECK_EQ(request->result_format(), CopyOutputResult::Format::RGBA_BITMAP); + DCHECK(!request->is_scaled()); + DCHECK(!request->has_result_selection() || + request->result_selection() == gfx::Rect(copy_rect.size())); + + DCHECK(!id || offscreen_surfaces_.find(id) != offscreen_surfaces_.end()); + auto* surface = id ? offscreen_surfaces_[id].get() : sk_surface_.get(); + + sk_sp<SkImage> copy_image = + surface->makeImageSnapshot()->makeSubset(RectToSkIRect(copy_rect)); + // Send copy request by copying into a bitmap. + SkBitmap bitmap; + copy_image->asLegacyBitmap(&bitmap); + request->SendResult( + std::make_unique<CopyOutputSkBitmapResult>(copy_rect, bitmap)); +} + void SkiaOutputSurfaceImplOnGpu::FullfillPromiseTexture( const ResourceMetadata& metadata, GrBackendTexture* backend_texture) {
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 a0f475c..6342160 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
@@ -98,16 +98,20 @@ bool use_stencil, SkSurfaceCharacterization* characterization, base::WaitableEvent* event); - void SwapBuffers(OutputSurfaceFrame frame, - std::unique_ptr<SkDeferredDisplayList> ddl, - std::vector<YUVResourceMetadata*> yuv_resource_metadatas, - uint64_t sync_fence_release); + void FinishPaintCurrentFrame( + std::unique_ptr<SkDeferredDisplayList> ddl, + std::vector<YUVResourceMetadata*> yuv_resource_metadatas, + uint64_t sync_fence_release); + void SwapBuffers(OutputSurfaceFrame frame); void FinishPaintRenderPass( RenderPassId id, std::unique_ptr<SkDeferredDisplayList> ddl, std::vector<YUVResourceMetadata*> yuv_resource_metadatas, uint64_t sync_fence_release); void RemoveRenderPassResource(std::vector<RenderPassId> ids); + void CopyOutput(RenderPassId id, + const gfx::Rect& copy_rect, + std::unique_ptr<CopyOutputRequest> request); // Fullfill callback for promise SkImage created from a resource. void FullfillPromiseTexture(const ResourceMetadata& metadata,
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index b76da9d..334b2b06 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <utility> +#include "base/stl_util.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/surfaces/surface_info.h" @@ -542,8 +543,7 @@ void CompositorFrameSinkSupport::AttachCaptureClient( CapturableFrameSink::Client* client) { - DCHECK(std::find(capture_clients_.begin(), capture_clients_.end(), client) == - capture_clients_.end()); + DCHECK(!base::ContainsValue(capture_clients_, client)); capture_clients_.push_back(client); }
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index e2fee32..6bfa995 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -165,8 +165,14 @@ scheduler_->DestroySequence(skia_output_surface_sequence_id_); } - gr_context_ = nullptr; - context_for_skia_ = nullptr; + if (context_for_skia_) { + // Initialize an offscreen surface, so MakeCurrent can work. + auto surface = gl::init::CreateOffscreenGLSurface(gfx::Size(1, 1)); + context_for_skia_->MakeCurrent(surface.get()); + gr_context_ = nullptr; + context_for_skia_ = nullptr; + } + DCHECK(!gr_context_); media_gpu_channel_manager_.reset(); gpu_channel_manager_.reset(); owned_sync_point_manager_.reset(); @@ -284,10 +290,9 @@ LOG(FATAL) << "Failed to make current."; // TODO(penghuang): handle the failure. } - auto native_interface = - GrGLMakeAssembledInterface(nullptr, [](void* ctx, const char name[]) { - return gl::GetGLProcAddress(name); - }); + + const auto* gl_version_info = context_for_skia_->GetVersionInfo(); + auto native_interface = gl::init::CreateGrGLInterface(*gl_version_info); DCHECK(native_interface); GrContextOptions options;
diff --git a/components/web_contents_delegate_android/web_contents_delegate_android.cc b/components/web_contents_delegate_android/web_contents_delegate_android.cc index e6f3b040..70edaf6 100644 --- a/components/web_contents_delegate_android/web_contents_delegate_android.cc +++ b/components/web_contents_delegate_android/web_contents_delegate_android.cc
@@ -169,7 +169,8 @@ void WebContentsDelegateAndroid::RendererUnresponsive( WebContents* source, - content::RenderWidgetHost* render_widget_host) { + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); if (obj.is_null())
diff --git a/components/web_contents_delegate_android/web_contents_delegate_android.h b/components/web_contents_delegate_android/web_contents_delegate_android.h index 14d0033..db514ed 100644 --- a/components/web_contents_delegate_android/web_contents_delegate_android.h +++ b/components/web_contents_delegate_android/web_contents_delegate_android.h
@@ -65,7 +65,8 @@ double load_progress) override; void RendererUnresponsive( content::WebContents* source, - content::RenderWidgetHost* render_widget_host) override; + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override; void RendererResponsive( content::WebContents* source, content::RenderWidgetHost* render_widget_host) override;
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 59fc90f07..4787f14 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -102,8 +102,8 @@ #include "third_party/blink/public/platform/web_font_render_style.h" #include "third_party/boringssl/src/include/openssl/crypto.h" #include "third_party/boringssl/src/include/openssl/rand.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontConfigInterface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontMgr_android.h" #include "third_party/webrtc_overrides/init_webrtc.h" // nogncheck
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 9ca97f3..6552c76 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2103,6 +2103,8 @@ "accessibility/web_contents_accessibility_android.h", "android/content_ui_event_handler.cc", "android/content_ui_event_handler.h", + "android/content_view_core.cc", + "android/content_view_core.h", "android/content_view_statics.cc", "android/date_time_chooser_android.cc", "android/date_time_chooser_android.h", @@ -2157,10 +2159,6 @@ "android/tracing_controller_android.h", "android/web_contents_observer_proxy.cc", "android/web_contents_observer_proxy.h", - "compositor/external_begin_frame_controller_client_impl.cc", - "compositor/external_begin_frame_controller_client_impl.h", - "compositor/in_process_display_client.cc", - "compositor/in_process_display_client.h", "frame_host/render_frame_host_android.cc", "frame_host/render_frame_host_android.h", "media/capture/screen_capture_device_android.cc", @@ -2216,6 +2214,7 @@ "//ui/accessibility/mojom", "//ui/android", "//ui/compositor", + "//ui/compositor/host", ] defines += [ "APPCACHE_USE_SIMPLE_CACHE", @@ -2342,8 +2341,6 @@ sources += [ "compositor/browser_compositor_output_surface.cc", "compositor/browser_compositor_output_surface.h", - "compositor/external_begin_frame_controller_client_impl.cc", - "compositor/external_begin_frame_controller_client_impl.h", "compositor/gpu_browser_compositor_output_surface.cc", "compositor/gpu_browser_compositor_output_surface.h", "compositor/gpu_output_surface_mac.cc", @@ -2354,8 +2351,6 @@ "compositor/gpu_surfaceless_browser_compositor_output_surface.h", "compositor/image_transport_factory.cc", "compositor/image_transport_factory.h", - "compositor/in_process_display_client.cc", - "compositor/in_process_display_client.h", "compositor/offscreen_browser_compositor_output_surface.cc", "compositor/offscreen_browser_compositor_output_surface.h", "compositor/owned_mailbox.cc", @@ -2394,6 +2389,7 @@ deps += [ "//components/viz/service", "//ui/compositor", + "//ui/compositor/host", ] }
diff --git a/content/browser/accessibility/accessibility_ui.cc b/content/browser/accessibility/accessibility_ui.cc index 17fa4863..4dada73 100644 --- a/content/browser/accessibility/accessibility_ui.cc +++ b/content/browser/accessibility/accessibility_ui.cc
@@ -39,6 +39,7 @@ #include "content/public/common/url_constants.h" #include "net/base/escape.h" #include "ui/accessibility/platform/ax_platform_node.h" +#include "ui/base/webui/web_ui_util.h" static const char kTargetsDataFile[] = "targets-data.json"; @@ -105,8 +106,13 @@ title = base::UTF16ToUTF8(web_contents->GetTitle()); NavigationController& controller = web_contents->GetController(); NavigationEntry* entry = controller.GetVisibleEntry(); - if (entry != nullptr && entry->GetURL().is_valid()) - favicon_url = entry->GetFavicon().url; + if (entry != nullptr && entry->GetURL().is_valid()) { + gfx::Image favicon_image = entry->GetFavicon().image; + if (!favicon_image.IsEmpty()) { + const SkBitmap* favicon_bitmap = favicon_image.ToSkBitmap(); + favicon_url = GURL(webui::GetBitmapDataUrl(*favicon_bitmap)); + } + } accessibility_mode = web_contents->GetAccessibilityMode(); }
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index f59ee70..dfbf208 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -484,10 +484,7 @@ } NSView* BrowserAccessibilityManagerMac::GetParentView() { - gfx::AcceleratedWidget accelerated_widget = - delegate() ? delegate()->AccessibilityGetAcceleratedWidget() - : gfx::kNullAcceleratedWidget; - return ui::AcceleratedWidgetMac::GetNSView(accelerated_widget); + return delegate()->AccessibilityGetNativeViewAccessible(); } } // namespace content
diff --git a/content/browser/android/content_view_core.cc b/content/browser/android/content_view_core.cc new file mode 100644 index 0000000..25123a21 --- /dev/null +++ b/content/browser/android/content_view_core.cc
@@ -0,0 +1,147 @@ +// 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 "content/browser/android/content_view_core.h" + +#include "content/browser/frame_host/interstitial_page_impl.h" +#include "content/browser/renderer_host/render_widget_host_view_android.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/web_contents/web_contents_view_android.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/common/content_client.h" +#include "content/public/common/user_agent.h" +#include "jni/ContentViewCoreImpl_jni.h" +#include "ui/android/window_android.h" + +using base::android::AttachCurrentThread; +using base::android::JavaParamRef; +using base::android::JavaRef; +using base::android::ScopedJavaLocalRef; + +namespace content { + +namespace { + +RenderWidgetHostViewAndroid* GetRenderWidgetHostViewFromHost( + RenderViewHost* host) { + return static_cast<RenderWidgetHostViewAndroid*>( + host->GetWidget()->GetView()); +} + +} // namespace + +ContentViewCore::ContentViewCore(JNIEnv* env, + const JavaRef<jobject>& obj, + WebContents* web_contents) + : WebContentsObserver(web_contents), + java_ref_(env, obj), + web_contents_(static_cast<WebContentsImpl*>(web_contents)) { + // Currently, the only use case we have for overriding a user agent involves + // spoofing a desktop Linux user agent for "Request desktop site". + // Automatically set it for all WebContents so that it is available when a + // NavigationEntry requires the user agent to be overridden. + const char kLinuxInfoStr[] = "X11; Linux x86_64"; + std::string product = content::GetContentClient()->GetProduct(); + std::string spoofed_ua = + BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product); + web_contents->SetUserAgentOverride(spoofed_ua, false); +} + +ContentViewCore::~ContentViewCore() { + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); + java_ref_.reset(); + if (!j_obj.is_null()) { + Java_ContentViewCoreImpl_onNativeContentViewCoreDestroyed( + env, j_obj, reinterpret_cast<intptr_t>(this)); + } +} + +void ContentViewCore::OnJavaContentViewCoreDestroyed( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { + DCHECK(env->IsSameObject(java_ref_.get(env).obj(), obj)); + java_ref_.reset(); + // Java peer has gone, ContentViewCore is not functional and waits to + // be destroyed with WebContents. + DCHECK(web_contents_); +} + +void ContentViewCore::RenderViewReady() { + WebContentsViewAndroid* view = + static_cast<WebContentsViewAndroid*>(web_contents_->GetView()); + if (view->device_orientation() == 0) + return; + RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid(); + if (rwhva) + rwhva->UpdateScreenInfo(GetViewAndroid()); + + web_contents_->OnScreenOrientationChange(); +} + +void ContentViewCore::WebContentsDestroyed() { + delete this; +} + +void ContentViewCore::RenderViewHostChanged(RenderViewHost* old_host, + RenderViewHost* new_host) { + if (old_host) { + auto* view = GetRenderWidgetHostViewFromHost(old_host); + if (view) + view->UpdateNativeViewTree(nullptr); + + view = GetRenderWidgetHostViewFromHost(new_host); + if (view) + view->UpdateNativeViewTree(GetViewAndroid()); + } + SetFocusInternal(GetViewAndroid()->HasFocus()); +} + +RenderWidgetHostViewAndroid* ContentViewCore::GetRenderWidgetHostViewAndroid() + const { + RenderWidgetHostView* rwhv = NULL; + if (web_contents_) { + rwhv = web_contents_->GetRenderWidgetHostView(); + if (web_contents_->ShowingInterstitialPage()) { + rwhv = web_contents_->GetInterstitialPage() + ->GetMainFrame() + ->GetRenderViewHost() + ->GetWidget() + ->GetView(); + } + } + return static_cast<RenderWidgetHostViewAndroid*>(rwhv); +} + +ui::ViewAndroid* ContentViewCore::GetViewAndroid() const { + return web_contents_->GetView()->GetNativeView(); +} + +// ---------------------------------------------------------------------------- +// Methods called from Java via JNI +// ---------------------------------------------------------------------------- + +void ContentViewCore::SetFocusInternal(bool focused) { + if (!GetRenderWidgetHostViewAndroid()) + return; + + if (focused) + GetRenderWidgetHostViewAndroid()->GotFocus(); + else + GetRenderWidgetHostViewAndroid()->LostFocus(); +} + +// This is called for each ContentView. +jlong JNI_ContentViewCoreImpl_Init(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& jweb_contents) { + WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( + WebContents::FromJavaWebContents(jweb_contents)); + CHECK(web_contents) + << "A ContentViewCore should be created with a valid WebContents."; + return reinterpret_cast<intptr_t>( + new ContentViewCore(env, obj, web_contents)); +} + +} // namespace content
diff --git a/content/browser/android/content_view_core.h b/content/browser/android/content_view_core.h new file mode 100644 index 0000000..a846c53 --- /dev/null +++ b/content/browser/android/content_view_core.h
@@ -0,0 +1,70 @@ +// 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 CONTENT_BROWSER_ANDROID_CONTENT_VIEW_CORE_H_ +#define CONTENT_BROWSER_ANDROID_CONTENT_VIEW_CORE_H_ + +#include "base/android/jni_android.h" +#include "base/android/jni_weak_ref.h" +#include "base/android/scoped_java_ref.h" +#include "base/macros.h" +#include "content/public/browser/web_contents_observer.h" + +namespace ui { +class ViewAndroid; +} + +namespace content { + +class RenderWidgetHostViewAndroid; +class WebContentsImpl; + +class ContentViewCore : public WebContentsObserver { + public: + ContentViewCore(JNIEnv* env, + const base::android::JavaRef<jobject>& obj, + WebContents* web_contents); + + ~ContentViewCore() override; + + // -------------------------------------------------------------------------- + // Methods called from Java via JNI + // -------------------------------------------------------------------------- + + void OnJavaContentViewCoreDestroyed( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + + private: + + // WebContentsObserver implementation. + void RenderViewReady() override; + void RenderViewHostChanged(RenderViewHost* old_host, + RenderViewHost* new_host) override; + void WebContentsDestroyed() override; + + // -------------------------------------------------------------------------- + // Other private methods and data + // -------------------------------------------------------------------------- + + ui::ViewAndroid* GetViewAndroid() const; + + RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid() const; + + // Update focus state of the RenderWidgetHostView. + void SetFocusInternal(bool focused); + + // A weak reference to the Java ContentViewCore object. + JavaObjectWeakGlobalRef java_ref_; + + // Reference to the current WebContents used to determine how and what to + // display in the ContentViewCore. + WebContentsImpl* web_contents_; + + DISALLOW_COPY_AND_ASSIGN(ContentViewCore); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_ANDROID_CONTENT_VIEW_CORE_H_
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index e541f3a8..19f74fcad 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1593,15 +1593,15 @@ base::FilePath BrowserMainLoop::GetStartupTraceFileName() const { base::FilePath trace_file; -#if defined(OS_ANDROID) - TracingControllerAndroid::GenerateTracingFilePath(&trace_file); -#else trace_file = tracing::TraceStartupConfig::GetInstance()->GetResultFile(); if (trace_file.empty()) { +#if defined(OS_ANDROID) + TracingControllerAndroid::GenerateTracingFilePath(&trace_file); +#else // Default to saving the startup trace into the current dir. trace_file = base::FilePath().AppendASCII("chrometrace.log"); - } #endif + } return trace_file; }
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index ef78520..d3dc6c9 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -28,6 +28,7 @@ #include "components/viz/common/frame_sinks/delay_based_time_source.h" #include "components/viz/common/gl_helper.h" #include "components/viz/common/switches.h" +#include "components/viz/host/host_display_client.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/host/renderer_settings_creation.h" #include "components/viz/service/display/display.h" @@ -40,10 +41,8 @@ #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "content/browser/browser_main_loop.h" #include "content/browser/compositor/browser_compositor_output_surface.h" -#include "content/browser/compositor/external_begin_frame_controller_client_impl.h" #include "content/browser/compositor/gpu_browser_compositor_output_surface.h" #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h" -#include "content/browser/compositor/in_process_display_client.h" #include "content/browser/compositor/offscreen_browser_compositor_output_surface.h" #include "content/browser/compositor/reflector_impl.h" #include "content/browser/compositor/software_browser_compositor_output_surface.h" @@ -70,6 +69,7 @@ #include "ui/base/ui_base_switches_util.h" #include "ui/compositor/compositor.h" #include "ui/compositor/compositor_switches.h" +#include "ui/compositor/host/external_begin_frame_controller_client_impl.h" #include "ui/compositor/layer.h" #include "ui/display/display_switches.h" #include "ui/display/types/display_snapshot.h" @@ -116,7 +116,7 @@ #if BUILDFLAG(ENABLE_VULKAN) #include "components/viz/common/gpu/vulkan_in_process_context_provider.h" #include "content/browser/compositor/vulkan_browser_compositor_output_surface.h" -#include "gpu/vulkan/init/vulkan_factory.cc" +#include "gpu/vulkan/init/vulkan_factory.h" #endif using viz::ContextProvider; @@ -155,7 +155,7 @@ std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source; std::unique_ptr<viz::ExternalBeginFrameControllerImpl> external_begin_frame_controller; - std::unique_ptr<ExternalBeginFrameControllerClientImpl> + std::unique_ptr<ui::ExternalBeginFrameControllerClientImpl> external_begin_frame_controller_client; ReflectorImpl* reflector = nullptr; std::unique_ptr<viz::Display> display; @@ -554,13 +554,13 @@ std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source; std::unique_ptr<viz::ExternalBeginFrameControllerImpl> external_begin_frame_controller; - std::unique_ptr<ExternalBeginFrameControllerClientImpl> + std::unique_ptr<ui::ExternalBeginFrameControllerClientImpl> external_begin_frame_controller_client; viz::BeginFrameSource* begin_frame_source = nullptr; if (compositor->external_begin_frames_enabled()) { external_begin_frame_controller_client = - std::make_unique<ExternalBeginFrameControllerClientImpl>( + std::make_unique<ui::ExternalBeginFrameControllerClientImpl>( compositor.get()); // We don't bind the controller mojo interface, since we only use the // ExternalBeginFrameControllerImpl directly and not via mojo (plus, as it @@ -610,7 +610,7 @@ compositor->frame_sink_id(), std::move(display_output_surface), std::move(scheduler), compositor->task_runner()); data->display_client = - std::make_unique<InProcessDisplayClient>(compositor->widget()); + std::make_unique<viz::HostDisplayClient>(compositor->widget()); GetFrameSinkManager()->RegisterBeginFrameSource(begin_frame_source, compositor->frame_sink_id()); // Note that we are careful not to destroy prior BeginFrameSource objects
diff --git a/content/browser/compositor/in_process_display_client.cc b/content/browser/compositor/in_process_display_client.cc deleted file mode 100644 index 8f5e7a1b..0000000 --- a/content/browser/compositor/in_process_display_client.cc +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/compositor/in_process_display_client.h" - -#include "content/browser/renderer_host/render_widget_host_impl.h" - -#if defined(OS_MACOSX) -#include "ui/accelerated_widget_mac/ca_layer_frame_sink.h" -#endif - -#if defined(OS_WIN) -#include <windows.h> - -#include "components/viz/common/display/use_layered_window.h" -#include "components/viz/host/layered_window_updater_impl.h" -#include "ui/base/win/internal_constants.h" -#endif - -namespace content { - -InProcessDisplayClient::InProcessDisplayClient(gfx::AcceleratedWidget widget) - : binding_(this) { -#if defined(OS_MACOSX) || defined(OS_WIN) - widget_ = widget; -#endif -} - -InProcessDisplayClient::~InProcessDisplayClient() = default; - -viz::mojom::DisplayClientPtr InProcessDisplayClient::GetBoundPtr( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - viz::mojom::DisplayClientPtr ptr; - binding_.Bind(mojo::MakeRequest(&ptr), task_runner); - return ptr; -} - -void InProcessDisplayClient::DidSwapAfterSnapshotRequestReceived( - const std::vector<ui::LatencyInfo>& latency_info) {} - -#if defined(OS_MACOSX) -void InProcessDisplayClient::OnDisplayReceivedCALayerParams( - const gfx::CALayerParams& ca_layer_params) { - ui::CALayerFrameSink* ca_layer_frame_sink = - ui::CALayerFrameSink::FromAcceleratedWidget(widget_); - if (ca_layer_frame_sink) - ca_layer_frame_sink->UpdateCALayerTree(ca_layer_params); - else - DLOG(WARNING) << "Received frame for non-existent widget."; -} -#endif - -#if defined(OS_WIN) -void InProcessDisplayClient::CreateLayeredWindowUpdater( - viz::mojom::LayeredWindowUpdaterRequest request) { - if (!viz::NeedsToUseLayerWindow(widget_)) { - DLOG(ERROR) << "HWND shouldn't be using a layered window"; - return; - } - - layered_window_updater_ = std::make_unique<viz::LayeredWindowUpdaterImpl>( - widget_, std::move(request)); -} -#endif - -} // namespace content
diff --git a/content/browser/compositor/in_process_display_client.h b/content/browser/compositor/in_process_display_client.h deleted file mode 100644 index f273104..0000000 --- a/content/browser/compositor/in_process_display_client.h +++ /dev/null
@@ -1,60 +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 CONTENT_BROWSER_COMPOSITOR_IN_PROCESS_DISPLAY_CLIENT_H_ -#define CONTENT_BROWSER_COMPOSITOR_IN_PROCESS_DISPLAY_CLIENT_H_ - -#include <memory> -#include <vector> - -#include "base/single_thread_task_runner.h" -#include "build/build_config.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/viz/privileged/interfaces/compositing/display_private.mojom.h" -#include "ui/gfx/native_widget_types.h" - -namespace viz { -class LayeredWindowUpdaterImpl; -} - -namespace content { - -// A DisplayClient that can be used to display received -// gfx::CALayerParams in a CALayer tree in this process. -class InProcessDisplayClient : public viz::mojom::DisplayClient { - public: - explicit InProcessDisplayClient(gfx::AcceleratedWidget widget); - ~InProcessDisplayClient() override; - - viz::mojom::DisplayClientPtr GetBoundPtr( - scoped_refptr<base::SingleThreadTaskRunner> task_runner); - - private: - // viz::mojom::DisplayClient implementation: - void DidSwapAfterSnapshotRequestReceived( - const std::vector<ui::LatencyInfo>& latency_info) override; - -#if defined(OS_MACOSX) - void OnDisplayReceivedCALayerParams( - const gfx::CALayerParams& ca_layer_params) override; -#endif - -#if defined(OS_WIN) - void CreateLayeredWindowUpdater( - viz::mojom::LayeredWindowUpdaterRequest request) override; -#endif - - mojo::Binding<viz::mojom::DisplayClient> binding_; -#if defined(OS_MACOSX) || defined(OS_WIN) - gfx::AcceleratedWidget widget_; -#endif - -#if defined(OS_WIN) - std::unique_ptr<viz::LayeredWindowUpdaterImpl> layered_window_updater_; -#endif -}; - -} // namespace content - -#endif // CONTENT_BROWSER_COMPOSITOR_IN_PROCESS_DISPLAY_CLIENT_H_
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index 7707e903..93a459f 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -17,11 +17,9 @@ #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/gpu/raster_context_provider.h" #include "components/viz/host/host_frame_sink_manager.h" -#include "components/viz/host/renderer_settings_creation.h" #include "components/viz/service/display_embedder/compositing_mode_reporter_impl.h" #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h" #include "content/browser/browser_main_loop.h" -#include "content/browser/compositor/external_begin_frame_controller_client_impl.h" #include "content/browser/gpu/compositor_util.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_process_host.h" @@ -110,12 +108,13 @@ gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory, scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner, viz::CompositingModeReporterImpl* compositing_mode_reporter) - : gpu_channel_establish_factory_(gpu_channel_establish_factory), - resize_task_runner_(std::move(resize_task_runner)), + : ui::HostContextFactoryPrivate( + kBrowserClientId, + BrowserMainLoop::GetInstance()->host_frame_sink_manager(), + resize_task_runner), + gpu_channel_establish_factory_(gpu_channel_establish_factory), compositing_mode_reporter_(compositing_mode_reporter), - frame_sink_id_allocator_(kBrowserClientId), task_graph_runner_(std::make_unique<cc::SingleThreadTaskGraphRunner>()), - renderer_settings_(viz::CreateRendererSettings()), weak_ptr_factory_(this) { DCHECK(gpu_channel_establish_factory_); task_graph_runner_->Start("CompositorTileWorker1", @@ -150,7 +149,7 @@ // Setup HostFrameSinkManager with interface endpoints. GetHostFrameSinkManager()->BindAndSetManager( - std::move(frame_sink_manager_client_request), resize_task_runner_, + std::move(frame_sink_manager_client_request), resize_task_runner(), std::move(frame_sink_manager)); // Hop to the IO thread, then send the other side of interface to viz process. @@ -181,7 +180,8 @@ compositor->widget()); #endif - if (is_gpu_compositing_disabled_ || compositor->force_software_compositor()) { + if (is_gpu_compositing_disabled() || + compositor->force_software_compositor()) { OnEstablishedGpuChannel(compositor, nullptr); return; } @@ -192,7 +192,7 @@ scoped_refptr<viz::ContextProvider> VizProcessTransportFactory::SharedMainThreadContextProvider() { - if (is_gpu_compositing_disabled_) + if (is_gpu_compositing_disabled()) return nullptr; if (!main_context_provider_) { @@ -211,14 +211,7 @@ } void VizProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) { -#if defined(OS_WIN) - // TODO(crbug.com/791660): Make sure that GpuProcessHost::SetChildSurface() - // doesn't crash the GPU process after parent is unregistered. - gfx::RenderingWindowManager::GetInstance()->UnregisterParent( - compositor->widget()); -#endif - - compositor_data_map_.erase(compositor); + UnconfigureCompositor(compositor); } double VizProcessTransportFactory::GetRefreshRate() const { @@ -251,137 +244,13 @@ return true; } -std::unique_ptr<ui::Reflector> VizProcessTransportFactory::CreateReflector( - ui::Compositor* source, - ui::Layer* target) { - // TODO(crbug.com/601869): Reflector needs to be rewritten for viz. - NOTIMPLEMENTED(); - return nullptr; -} - -void VizProcessTransportFactory::RemoveReflector(ui::Reflector* reflector) { - // TODO(crbug.com/601869): Reflector needs to be rewritten for viz. - NOTIMPLEMENTED(); -} - -viz::FrameSinkId VizProcessTransportFactory::AllocateFrameSinkId() { - return frame_sink_id_allocator_.NextFrameSinkId(); -} - -viz::HostFrameSinkManager* -VizProcessTransportFactory::GetHostFrameSinkManager() { - return BrowserMainLoop::GetInstance()->host_frame_sink_manager(); -} - -void VizProcessTransportFactory::SetDisplayVisible(ui::Compositor* compositor, - bool visible) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - iter->second.display_private->SetDisplayVisible(visible); -} - -void VizProcessTransportFactory::ResizeDisplay(ui::Compositor* compositor, - const gfx::Size& size) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - iter->second.display_private->Resize(size); -} - -void VizProcessTransportFactory::DisableSwapUntilResize( - ui::Compositor* compositor) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - { - // Browser needs to block for Viz to receive and process this message. - // Otherwise when we return from WM_WINDOWPOSCHANGING message handler and - // receive a WM_WINDOWPOSCHANGED the resize is finalized and any swaps of - // wrong size by Viz can cause the swapped content to get scaled. - // TODO(samans): Investigate nonblocking ways for solving - // https://crbug.com/811945. - mojo::SyncCallRestrictions::ScopedAllowSyncCall scoped_allow_sync_call; - iter->second.display_private->DisableSwapUntilResize(); - } -} - -void VizProcessTransportFactory::SetDisplayColorMatrix( - ui::Compositor* compositor, - const SkMatrix44& matrix) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - iter->second.display_private->SetDisplayColorMatrix(gfx::Transform(matrix)); -} - -void VizProcessTransportFactory::SetDisplayColorSpace( - ui::Compositor* compositor, - const gfx::ColorSpace& blending_color_space, - const gfx::ColorSpace& output_color_space) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - iter->second.display_private->SetDisplayColorSpace(blending_color_space, - output_color_space); -} - -void VizProcessTransportFactory::SetAuthoritativeVSyncInterval( - ui::Compositor* compositor, - base::TimeDelta interval) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - iter->second.display_private->SetAuthoritativeVSyncInterval(interval); -} - -void VizProcessTransportFactory::SetDisplayVSyncParameters( - ui::Compositor* compositor, - base::TimeTicks timebase, - base::TimeDelta interval) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - iter->second.display_private->SetDisplayVSyncParameters(timebase, interval); -} - -void VizProcessTransportFactory::IssueExternalBeginFrame( - ui::Compositor* compositor, - const viz::BeginFrameArgs& args) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - - DCHECK(iter->second.external_begin_frame_controller_client); - iter->second.external_begin_frame_controller_client->GetController() - ->IssueExternalBeginFrame(args); -} - -void VizProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor, - bool secure) { - auto iter = compositor_data_map_.find(compositor); - if (iter == compositor_data_map_.end() || !iter->second.display_private) - return; - iter->second.display_private->SetOutputIsSecure(secure); -} - -viz::FrameSinkManagerImpl* VizProcessTransportFactory::GetFrameSinkManager() { - // When running with viz there is no FrameSinkManagerImpl in the browser - // process. FrameSinkManagerImpl runs in the GPU process instead. Anything in - // the browser process that relies FrameSinkManagerImpl or SurfaceManager - // internal state needs to change. See https://crbug.com/787097 and - // https://crbug.com/760181 for more context. - NOTREACHED(); - return nullptr; -} - void VizProcessTransportFactory::DisableGpuCompositing() { - if (!is_gpu_compositing_disabled_) + if (!is_gpu_compositing_disabled()) DisableGpuCompositing(nullptr); } bool VizProcessTransportFactory::IsGpuCompositingDisabled() { - return is_gpu_compositing_disabled_; + return is_gpu_compositing_disabled(); } ui::ContextFactory* VizProcessTransportFactory::GetContextFactory() { @@ -410,7 +279,7 @@ DLOG(ERROR) << "Switching to software compositing."; // Change the result of IsGpuCompositingDisabled() before notifying anything. - is_gpu_compositing_disabled_ = true; + set_is_gpu_compositing_disabled(true); compositing_mode_reporter_->SetUsingSoftwareCompositing(); @@ -427,27 +296,18 @@ main_context_provider_ = nullptr; } - // Here we remove the FrameSink from every compositor that needs to fall back - // to software compositing. - // - // Releasing the FrameSink from the compositor will remove it from - // |compositor_data_map_|, so we can't do that while iterating though the - // collection. - std::vector<ui::Compositor*> to_release; - to_release.reserve(compositor_data_map_.size()); - for (auto& pair : compositor_data_map_) { - ui::Compositor* compositor = pair.first; + // Reemove the FrameSink from every compositor that needs to fall back to + // software compositing. + for (ui::Compositor* compositor : GetAllCompositors()) { // The |guilty_compositor| is in the process of setting up its FrameSink // so removing it from |compositor_data_map_| would be both pointless and // the cause of a crash. // Compositors with force_software_compositor() do not follow the global // compositing mode, so they do not need to changed. - if (compositor != guilty_compositor && - !compositor->force_software_compositor()) { - to_release.push_back(compositor); - } - } - for (ui::Compositor* compositor : to_release) { + if (compositor == guilty_compositor || + compositor->force_software_compositor()) + continue; + // Compositor expects to be not visible when releasing its FrameSink. bool visible = compositor->IsVisible(); compositor->SetVisible(false); @@ -472,8 +332,8 @@ if (!compositor) return; - bool gpu_compositing = - !is_gpu_compositing_disabled_ && !compositor->force_software_compositor(); + bool gpu_compositing = !is_gpu_compositing_disabled() && + !compositor->force_software_compositor(); if (gpu_compositing) { auto context_result = @@ -490,73 +350,6 @@ } } -#if defined(OS_WIN) - gfx::RenderingWindowManager::GetInstance()->RegisterParent( - compositor->widget()); -#endif - - auto& compositor_data = compositor_data_map_[compositor]; - - auto root_params = viz::mojom::RootCompositorFrameSinkParams::New(); - - // Create interfaces for a root CompositorFrameSink. - viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info; - root_params->compositor_frame_sink = mojo::MakeRequest(&sink_info); - viz::mojom::CompositorFrameSinkClientRequest client_request = - mojo::MakeRequest(&root_params->compositor_frame_sink_client); - root_params->display_private = - mojo::MakeRequest(&compositor_data.display_private); - compositor_data.display_client = - std::make_unique<InProcessDisplayClient>(compositor->widget()); - root_params->display_client = - compositor_data.display_client->GetBoundPtr(resize_task_runner_) - .PassInterface(); - -#if defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW) - gpu::SurfaceHandle surface_handle = compositor->widget(); -#else - // TODO(kylechar): Fix this when we support macOS. - gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle; -#endif - - // Initialize ExternalBeginFrameController client if enabled. - compositor_data.external_begin_frame_controller_client.reset(); - if (compositor->external_begin_frames_enabled()) { - compositor_data.external_begin_frame_controller_client = - std::make_unique<ExternalBeginFrameControllerClientImpl>(compositor); - root_params->external_begin_frame_controller = - compositor_data.external_begin_frame_controller_client - ->GetControllerRequest(); - root_params->external_begin_frame_controller_client = - compositor_data.external_begin_frame_controller_client->GetBoundPtr() - .PassInterface(); - } - - root_params->frame_sink_id = compositor->frame_sink_id(); - root_params->widget = surface_handle; - root_params->gpu_compositing = gpu_compositing; - root_params->renderer_settings = renderer_settings_; - - // Connects the viz process end of CompositorFrameSink message pipes. The - // browser compositor may request a new CompositorFrameSink on context loss, - // which will destroy the existing CompositorFrameSink. - GetHostFrameSinkManager()->CreateRootCompositorFrameSink( - std::move(root_params)); - compositor_data.display_private->Resize(compositor->size()); - - // Create LayerTreeFrameSink with the browser end of CompositorFrameSink. - cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params; - params.compositor_task_runner = compositor->task_runner(); - params.gpu_memory_buffer_manager = GetGpuMemoryBufferManager(); - params.pipes.compositor_frame_sink_associated_info = std::move(sink_info); - params.pipes.client_request = std::move(client_request); - params.local_surface_id_provider = - std::make_unique<viz::DefaultLocalSurfaceIdProvider>(); - params.enable_surface_synchronization = true; - params.hit_test_data_provider = - std::make_unique<viz::HitTestDataProviderDrawQuad>( - /*should_ask_for_child_region=*/false); - scoped_refptr<viz::ContextProvider> compositor_context; scoped_refptr<viz::RasterContextProvider> worker_context; if (gpu_compositing) { @@ -564,20 +357,14 @@ compositor_context = main_context_provider_; worker_context = worker_context_provider_; } - compositor->SetLayerTreeFrameSink( - std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>( - std::move(compositor_context), std::move(worker_context), ¶ms)); - -#if defined(OS_WIN) - gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild( - compositor->widget()); -#endif + ConfigureCompositor(compositor_weak_ptr, std::move(compositor_context), + std::move(worker_context)); } gpu::ContextResult VizProcessTransportFactory::TryCreateContextsForGpuCompositing( scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) { - DCHECK(!is_gpu_compositing_disabled_); + DCHECK(!is_gpu_compositing_disabled()); // Fallback to software compositing if there is no IPC channel. if (!gpu_channel_host) @@ -635,7 +422,7 @@ kCompositorContextSupportsLocking, kCompositorContextSupportsGLES2, kCompositorContextSupportsRaster, kCompositorContextSupportsGrContext, ui::command_buffer_metrics::UI_COMPOSITOR_CONTEXT); - main_context_provider_->SetDefaultTaskRunner(resize_task_runner_); + main_context_provider_->SetDefaultTaskRunner(resize_task_runner()); auto context_result = main_context_provider_->BindToCurrentThread(); if (context_result != gpu::ContextResult::kSuccess) { @@ -662,12 +449,4 @@ observer.OnLostResources(); } -VizProcessTransportFactory::CompositorData::CompositorData() = default; -VizProcessTransportFactory::CompositorData::CompositorData( - CompositorData&& other) = default; -VizProcessTransportFactory::CompositorData::~CompositorData() = default; -VizProcessTransportFactory::CompositorData& -VizProcessTransportFactory::CompositorData::operator=(CompositorData&& other) = - default; - } // namespace content
diff --git a/content/browser/compositor/viz_process_transport_factory.h b/content/browser/compositor/viz_process_transport_factory.h index 0ce445ed..42f91b1 100644 --- a/content/browser/compositor/viz_process_transport_factory.h +++ b/content/browser/compositor/viz_process_transport_factory.h
@@ -7,19 +7,16 @@ #include <memory> -#include "base/containers/flat_map.h" #include "base/macros.h" #include "build/build_config.h" -#include "components/viz/common/display/renderer_settings.h" #include "components/viz/common/gpu/context_lost_observer.h" -#include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "content/browser/compositor/image_transport_factory.h" -#include "content/browser/compositor/in_process_display_client.h" #include "gpu/command_buffer/common/context_result.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h" #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h" #include "ui/compositor/compositor.h" +#include "ui/compositor/host/host_context_factory_private.h" namespace base { class SingleThreadTaskRunner; @@ -44,14 +41,12 @@ namespace content { -class ExternalBeginFrameControllerClientImpl; - // A replacement for GpuProcessTransportFactory to be used when running viz. In // this configuration the display compositor is located in the viz process // instead of in the browser process. Any interaction with the display // compositor must happen over IPC. class VizProcessTransportFactory : public ui::ContextFactory, - public ui::ContextFactoryPrivate, + public ui::HostContextFactoryPrivate, public ImageTransportFactory, public viz::ContextLostObserver { public: @@ -77,31 +72,6 @@ void RemoveObserver(ui::ContextFactoryObserver* observer) override; bool SyncTokensRequiredForDisplayCompositor() override; - // ui::ContextFactoryPrivate implementation. - std::unique_ptr<ui::Reflector> CreateReflector(ui::Compositor* source, - ui::Layer* target) override; - void RemoveReflector(ui::Reflector* reflector) override; - viz::FrameSinkId AllocateFrameSinkId() override; - viz::HostFrameSinkManager* GetHostFrameSinkManager() override; - void SetDisplayVisible(ui::Compositor* compositor, bool visible) override; - void ResizeDisplay(ui::Compositor* compositor, - const gfx::Size& size) override; - void DisableSwapUntilResize(ui::Compositor* compositor) override; - void SetDisplayColorMatrix(ui::Compositor* compositor, - const SkMatrix44& matrix) override; - void SetDisplayColorSpace(ui::Compositor* compositor, - const gfx::ColorSpace& blending_color_space, - const gfx::ColorSpace& output_color_space) override; - void SetAuthoritativeVSyncInterval(ui::Compositor* compositor, - base::TimeDelta interval) override; - void SetDisplayVSyncParameters(ui::Compositor* compositor, - base::TimeTicks timebase, - base::TimeDelta interval) override; - void IssueExternalBeginFrame(ui::Compositor* compositor, - const viz::BeginFrameArgs& args) override; - void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override; - viz::FrameSinkManagerImpl* GetFrameSinkManager() override; - // ImageTransportFactory implementation. void DisableGpuCompositing() override; bool IsGpuCompositingDisabled() override; @@ -113,26 +83,6 @@ void OnContextLost() override; private: - struct CompositorData { - CompositorData(); - CompositorData(CompositorData&& other); - ~CompositorData(); - CompositorData& operator=(CompositorData&& other); - - // Privileged interface that controls the display for a root - // CompositorFrameSink. - viz::mojom::DisplayPrivateAssociatedPtr display_private; - std::unique_ptr<InProcessDisplayClient> display_client; - - // Controls external BeginFrames for the display. Only set if external - // BeginFrames are enabled for the compositor. - std::unique_ptr<ExternalBeginFrameControllerClientImpl> - external_begin_frame_controller_client; - - private: - DISALLOW_COPY_AND_ASSIGN(CompositorData); - }; - // Disables GPU compositing. This notifies UI and renderer compositors to drop // LayerTreeFrameSinks and request new ones. If fallback happens while // creating a new LayerTreeFrameSink for UI compositor it should be passed in @@ -162,15 +112,11 @@ void OnLostMainThreadSharedContext(); gpu::GpuChannelEstablishFactory* const gpu_channel_establish_factory_; - scoped_refptr<base::SingleThreadTaskRunner> const resize_task_runner_; // Controls the compositing mode based on what mode the display compositors // are using. viz::CompositingModeReporterImpl* const compositing_mode_reporter_; - base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_; - bool is_gpu_compositing_disabled_ = false; - base::ObserverList<ui::ContextFactoryObserver> observer_list_; // ContextProvider used on worker threads for rasterization. @@ -180,9 +126,7 @@ // returned from GetSharedMainThreadContextProvider(). scoped_refptr<ui::ContextProviderCommandBuffer> main_context_provider_; - viz::FrameSinkIdAllocator frame_sink_id_allocator_; std::unique_ptr<cc::SingleThreadTaskGraphRunner> task_graph_runner_; - const viz::RendererSettings renderer_settings_; base::WeakPtrFactory<VizProcessTransportFactory> weak_ptr_factory_;
diff --git a/content/browser/devtools/devtools_manager_unittest.cc b/content/browser/devtools/devtools_manager_unittest.cc index b945b03..ef8e846 100644 --- a/content/browser/devtools/devtools_manager_unittest.cc +++ b/content/browser/devtools/devtools_manager_unittest.cc
@@ -4,7 +4,10 @@ #include "content/browser/devtools/devtools_manager.h" +#include <map> #include <memory> +#include <string> +#include <utility> #include "base/guid.h" #include "base/location.h" @@ -84,8 +87,10 @@ TestWebContentsDelegate() : renderer_unresponsive_received_(false) {} // Notification that the contents is hung. - void RendererUnresponsive(WebContents* source, - RenderWidgetHost* render_widget_host) override { + void RendererUnresponsive( + WebContents* source, + RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override { renderer_unresponsive_received_ = true; } @@ -141,7 +146,7 @@ client_host.InspectAgentHost(agent_host.get()); // Start with a short timeout. - inspected_rvh->GetWidget()->StartHangMonitorTimeout( + inspected_rvh->GetWidget()->StartInputEventAckTimeout( TimeDelta::FromMilliseconds(10)); // Wait long enough for first timeout and see if it fired. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -153,7 +158,7 @@ // Now close devtools and check that the notification is delivered. client_host.Close(); // Start with a short timeout. - inspected_rvh->GetWidget()->StartHangMonitorTimeout( + inspected_rvh->GetWidget()->StartInputEventAckTimeout( TimeDelta::FromMilliseconds(10)); // Wait long enough for first timeout and see if it fired. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -178,7 +183,7 @@ } private: - std::map<std::string,int> event_counter_; + std::map<std::string, int> event_counter_; void recordEvent(const std::string& name) { if (event_counter_.find(name) == event_counter_.end()) @@ -213,7 +218,6 @@ const std::string& message) override { recordEvent(std::string("SendMessageToBackend.") + message); }; - }; TEST_F(DevToolsManagerTest, TestExternalProxy) {
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 5397fc1..ddffc8d 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -43,6 +43,7 @@ #include "content/public/browser/download_request_utils.h" #include "content/public/browser/resource_throttle.h" #include "content/public/common/content_paths.h" +#include "content/public/common/content_switches.h" #include "content/public/common/webplugininfo.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -3031,6 +3032,27 @@ download->GetTargetFilePath().BaseName().value().c_str()); } +class DownloadContentTestWithMojoBlobURLs : public DownloadContentTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + DownloadContentTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures, + "MojoBlobURLs"); + } +}; + +IN_PROC_BROWSER_TEST_F(DownloadContentTestWithMojoBlobURLs, + DownloadAttributeBlobURL) { + GURL document_url = + embedded_test_server()->GetURL("/download/download-attribute-blob.html"); + download::DownloadItem* download = + StartDownloadAndReturnItem(shell(), document_url); + WaitForCompletion(download); + + EXPECT_STREQ(FILE_PATH_LITERAL("suggested-filename.txt"), + download->GetTargetFilePath().BaseName().value().c_str()); +} + IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeSameSiteCookie) { base::ThreadRestrictions::ScopedAllowIO allow_io_during_test; net::EmbeddedTestServer test_server;
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index c0506910..b2744fe 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -564,6 +564,16 @@ // Actually log the UMA. UMA_HISTOGRAM_ENUMERATION("Stability.ChildFrameCrash.Visibility", visibility); + + if (visibility == CrashVisibility::kShownAfterCrashing) { + auto* rfh = frame_proxy_in_parent_renderer_->frame_tree_node() + ->current_frame_host(); + if (rfh->GetParent() && rfh->is_local_root()) { + UMA_HISTOGRAM_BOOLEAN( + "RenderFrameHostImpl.ReceivedPostMessageFromNonDescendant", + rfh->received_post_message_from_non_descendant()); + } + } } bool CrossProcessFrameConnector::IsVisible() {
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index b2b60a1..f62877a 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -391,6 +391,15 @@ static_cast<int32_t>(base::HashMetricName(name) & 0x7fffffffull)); } +// Set crash keys that will help understand the circumstances of a renderer +// kill. Note that the commit URL is already reported in a crash key, and +// additional keys are logged in RenderProcessHostImpl::ShutdownForBadMessage. +void LogRendererKillCrashKeys(const GURL& site_url) { + static auto* site_url_key = base::debug::AllocateCrashKeyString( + "current_site_url", base::debug::CrashKeySize::Size64); + base::debug::SetCrashKeyString(site_url_key, site_url.spec()); +} + } // namespace class RenderFrameHostImpl::DroppedInterfaceRequestLogger @@ -3333,12 +3342,7 @@ registry_->AddInterface(base::BindRepeating( &media::MediaMetricsProvider::Create, - // Only save decode stats when on-the-record. - GetSiteInstance()->GetBrowserContext()->IsOffTheRecord() - ? nullptr - : GetSiteInstance() - ->GetBrowserContext() - ->GetVideoDecodePerfHistory())); + GetSiteInstance()->GetBrowserContext()->GetVideoDecodePerfHistory())); if (base::CommandLine::ForCurrentProcess()->HasSwitch( cc::switches::kEnableGpuBenchmarking)) { @@ -5001,6 +5005,8 @@ // should be killed. if (!is_permitted_error_page && !CanCommitURL(validated_params->url)) { VLOG(1) << "Blocked URL " << validated_params->url.spec(); + LogRendererKillCrashKeys(GetSiteInstance()->GetSiteURL()); + // Kills the process. bad_message::ReceivedBadMessage(process, bad_message::RFH_CAN_COMMIT_URL_BLOCKED); @@ -5011,6 +5017,9 @@ // be allowed to commit in this RenderFrameHost. if (!CanCommitOrigin(validated_params->origin, validated_params->url)) { DEBUG_ALIAS_FOR_ORIGIN(origin_debug_alias, validated_params->origin); + LogRendererKillCrashKeys(GetSiteInstance()->GetSiteURL()); + + // Kills the process. bad_message::ReceivedBadMessage(process, bad_message::RFH_INVALID_ORIGIN_ON_COMMIT); return false;
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 7201433..df20e7c 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -737,6 +737,14 @@ // for unload handler processing. void SetSubframeUnloadTimeoutForTesting(const base::TimeDelta& timeout); + bool received_post_message_from_non_descendant() const { + return received_post_message_from_non_descendant_; + } + + void did_receive_post_message_from_non_descendant() { + received_post_message_from_non_descendant_ = true; + } + protected: friend class RenderFrameHostFactory; @@ -1283,6 +1291,12 @@ // relevant NavigationEntry. int nav_entry_id_; + // Tracks if a frame has been influenced by post message from + // non-descendant frames. Useful for determining if silently reloading a + // crashed frame is safe. Post messages from descendants to not matter for + // this decision since they will be reloaded as well. + bool received_post_message_from_non_descendant_ = false; + // Used to swap out or shut down this RFH when the unload event is taking too // long to execute, depending on the number of active frames in the // SiteInstance. May be null in tests.
diff --git a/content/browser/frame_host/render_frame_message_filter.cc b/content/browser/frame_host/render_frame_message_filter.cc index dc7b2c6..e397845 100644 --- a/content/browser/frame_host/render_frame_message_filter.cc +++ b/content/browser/frame_host/render_frame_message_filter.cc
@@ -35,6 +35,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/common/content_constants.h" #include "gpu/GLES2/gl2extchromium.h" +#include "mojo/public/cpp/bindings/callback_helpers.h" #include "mojo/public/cpp/system/message_pipe.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/cookies/canonical_cookie.h" @@ -125,6 +126,29 @@ std::move(blob_url_loader_factory)); } +// With network service disabled the downloads code wouldn't know what to do +// with a BlobURLToken, so this method is used to convert from a token to a +// BlobDataHandle to be passed on to the rest of the downloads system. +void DownloadBlobURLFromToken( + std::unique_ptr<download::DownloadUrlParameters> params, + blink::mojom::BlobURLTokenPtr, + const base::WeakPtr<storage::BlobStorageContext>& context, + const base::UnguessableToken& token) { + std::unique_ptr<storage::BlobDataHandle> blob_handle; + GURL blob_url; + if (context) { + std::string uuid; + if (context->registry().GetTokenMapping(token, &blob_url, &uuid) && + blob_url == params->url()) { + blob_handle = context->GetBlobDataFromUUID(uuid); + } + } + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&DownloadUrlOnUIThread, std::move(params), + std::move(blob_handle), nullptr)); +} + // Common functionality for converting a sync renderer message to a callback // function in the browser. Derive from this, create it on the heap when // issuing your callback. When done, write your reply parameters into @@ -363,6 +387,24 @@ if (url.SchemeIsBlob()) { ChromeBlobStorageContext* blob_context = GetChromeBlobStorageContextForResourceContext(resource_context_); + + // With network service disabled the downloads code wouldn't know what to do + // with the BlobURLToken (or the resulting URLLoaderFactory). So for that + // case convert the token to a BlobDataHandle before passing it of to the + // rest of the downloads system. + if (blob_url_token && + !base::FeatureList::IsEnabled(network::features::kNetworkService)) { + blink::mojom::BlobURLTokenPtr blob_url_token_ptr( + std::move(blob_url_token)); + auto* raw_token = blob_url_token_ptr.get(); + raw_token->GetToken(mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce(&DownloadBlobURLFromToken, std::move(parameters), + std::move(blob_url_token_ptr), + blob_context->context()->AsWeakPtr()), + base::UnguessableToken())); + return; + } + blob_data_handle = blob_context->context()->GetBlobDataFromPublicURL(url); // Don't care if the above fails. We are going to let the download go // through and allow it to be interrupted so that the embedder can deal.
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc index b7de8bc9..50d11ecb0 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -375,6 +375,11 @@ ->SynchronizeVisualPropertiesIgnoringPendingAck(); } + if (!source_rfh->frame_tree_node()->IsDescendantOf( + target_rfh->frame_tree_node())) { + target_rfh->did_receive_post_message_from_non_descendant(); + } + // Ensure that we have a swapped-out RVH and proxy for the source frame // in the target SiteInstance. If it doesn't exist, create it on demand // and also create its opener chain, since that will also be accessible
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index faeae257..cf9cf4a 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -186,6 +186,7 @@ net::URLRequest* request, ResourceContext* resource_context, bool is_main_frame) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); // If previews have already been turned off, or we are inheriting values on a // sub-frame, don't check any further. if (previews_to_allow & PREVIEWS_OFF ||
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index e4f966c..d916fcb 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -30,6 +30,7 @@ #include "media/base/media_content_type.h" #if !defined(USE_AURA) +#include "content/browser/android/content_view_core.h" #include "content/browser/renderer_host/render_widget_host_view_android.h" #endif
diff --git a/content/browser/media/capture/content_capture_device_browsertest_base.cc b/content/browser/media/capture/content_capture_device_browsertest_base.cc index 73ba0a4..a33ddda 100644 --- a/content/browser/media/capture/content_capture_device_browsertest_base.cc +++ b/content/browser/media/capture/content_capture_device_browsertest_base.cc
@@ -143,8 +143,8 @@ void ContentCaptureDeviceBrowserTestBase::StopAndDeAllocate() { device_->StopAndDeAllocate(); - RunUntilIdle(); device_.reset(); + RunUntilIdle(); } void ContentCaptureDeviceBrowserTestBase::RunUntilIdle() {
diff --git a/content/browser/media/capture/cursor_renderer.cc b/content/browser/media/capture/cursor_renderer.cc index 66352cc..6434a15 100644 --- a/content/browser/media/capture/cursor_renderer.cc +++ b/content/browser/media/capture/cursor_renderer.cc
@@ -283,11 +283,11 @@ CursorRendererUndoer::~CursorRendererUndoer() = default; -CursorRendererUndoer::CursorRendererUndoer(CursorRendererUndoer&& other) = - default; +CursorRendererUndoer::CursorRendererUndoer( + CursorRendererUndoer&& other) noexcept = default; CursorRendererUndoer& CursorRendererUndoer::operator=( - CursorRendererUndoer&& other) = default; + CursorRendererUndoer&& other) noexcept = default; namespace {
diff --git a/content/browser/media/capture/cursor_renderer.h b/content/browser/media/capture/cursor_renderer.h index b9d1acc..64409bd 100644 --- a/content/browser/media/capture/cursor_renderer.h +++ b/content/browser/media/capture/cursor_renderer.h
@@ -185,8 +185,8 @@ CursorRendererUndoer(); ~CursorRendererUndoer(); - CursorRendererUndoer(CursorRendererUndoer&& other); - CursorRendererUndoer& operator=(CursorRendererUndoer&& other); + CursorRendererUndoer(CursorRendererUndoer&& other) noexcept; + CursorRendererUndoer& operator=(CursorRendererUndoer&& other) noexcept; void TakeSnapshot(const media::VideoFrame& frame, const gfx::Rect& rect);
diff --git a/content/browser/media/capture/web_contents_audio_input_stream.cc b/content/browser/media/capture/web_contents_audio_input_stream.cc index 15115a2..e1593cc 100644 --- a/content/browser/media/capture/web_contents_audio_input_stream.cc +++ b/content/browser/media/capture/web_contents_audio_input_stream.cc
@@ -177,15 +177,20 @@ tracker_->Start( initial_render_process_id_, initial_main_render_frame_id_, base::Bind(&Impl::OnTargetChanged, this)); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(&Impl::IncrementCapturerCount, this)); + IncrementCapturerCount(); return true; } void WebContentsAudioInputStream::Impl::IncrementCapturerCount() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&Impl::IncrementCapturerCount, this)); + return; + } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (WebContents* contents = tracker_->web_contents()) contents->IncrementCapturerCount(gfx::Size()); } @@ -237,9 +242,7 @@ if (state_ == OPENED) { state_ = CONSTRUCTED; - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&Impl::DecrementCapturerCount, this)); + DecrementCapturerCount(); tracker_->Stop(); mixer_stream_->Close(); } @@ -249,8 +252,14 @@ } void WebContentsAudioInputStream::Impl::DecrementCapturerCount() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindOnce(&Impl::DecrementCapturerCount, this)); + return; + } + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (WebContents* contents = tracker_->web_contents()) contents->DecrementCapturerCount(); }
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc index c440442..e4122a24 100644 --- a/content/browser/media/capture/web_contents_video_capture_device.cc +++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -53,10 +53,15 @@ AsWeakPtr(), render_process_id, main_render_frame_id)); } - ~FrameTracker() final { DCHECK_CURRENTLY_ON(BrowserThread::UI); } + ~FrameTracker() final { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (is_capturing_) + DidStopCapturingWebContents(); + } void WillStartCapturingWebContents(const gfx::Size& capture_size) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!is_capturing_); auto* contents = web_contents(); if (!contents) { @@ -85,14 +90,18 @@ << preferred_size.ToString() << " from a capture size of " << capture_size.ToString(); contents->IncrementCapturerCount(preferred_size); + is_capturing_ = true; } void DidStopCapturingWebContents() { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (auto* contents = web_contents()) { + DCHECK(is_capturing_); contents->DecrementCapturerCount(); + is_capturing_ = false; } + DCHECK(!is_capturing_); } private: @@ -134,6 +143,7 @@ void DidDestroyFullscreenWidget() final { OnPossibleTargetChange(); } void WebContentsDestroyed() final { Observe(nullptr); + is_capturing_ = false; OnPossibleTargetChange(); } @@ -192,6 +202,9 @@ viz::FrameSinkId target_frame_sink_id_; gfx::NativeView target_native_view_ = gfx::NativeView(); + // Indicates whether the WebContents's capturer count needs to be decremented. + bool is_capturing_ = false; + DISALLOW_COPY_AND_ASSIGN(FrameTracker); };
diff --git a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc index 643c570..ec35ff5a 100644 --- a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc +++ b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
@@ -195,6 +195,7 @@ capture_stack()->ExpectHasLogMessages(); device->StopAndDeAllocate(); + device.reset(); RunUntilIdle(); } @@ -204,6 +205,7 @@ ErrorsOutWhenWebContentsIsDestroyed) { NavigateToInitialDocument(); AllocateAndStartAndWaitForFirstFrame(); + EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured()); // Initially, the device captures any content changes normally. ChangePageContentColor(SK_ColorRED); @@ -226,6 +228,7 @@ SuspendsAndResumes) { NavigateToInitialDocument(); AllocateAndStartAndWaitForFirstFrame(); + EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured()); // Initially, the device captures any content changes normally. ChangePageContentColor(SK_ColorRED); @@ -252,6 +255,7 @@ WaitForFrameWithColor(SK_ColorGREEN); StopAndDeAllocate(); + EXPECT_FALSE(shell()->web_contents()->IsBeingCaptured()); } // Tests that the device delivers refresh frames when asked, while the source @@ -260,6 +264,7 @@ DeliversRefreshFramesUponRequest) { NavigateToInitialDocument(); AllocateAndStartAndWaitForFirstFrame(); + EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured()); // Set the page content to a known color. ChangePageContentColor(SK_ColorRED); @@ -274,6 +279,7 @@ } StopAndDeAllocate(); + EXPECT_FALSE(shell()->web_contents()->IsBeingCaptured()); } class WebContentsVideoCaptureDeviceBrowserTestP @@ -331,6 +337,7 @@ NavigateToInitialDocument(); AllocateAndStartAndWaitForFirstFrame(); + EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured()); for (int visilibilty_case = 0; visilibilty_case < 3; ++visilibilty_case) { switch (visilibilty_case) { @@ -378,6 +385,7 @@ } StopAndDeAllocate(); + EXPECT_FALSE(shell()->web_contents()->IsBeingCaptured()); } } // namespace
diff --git a/content/browser/media/key_system_support_impl.cc b/content/browser/media/key_system_support_impl.cc index c173e263..b0e70d2 100644 --- a/content/browser/media/key_system_support_impl.cc +++ b/content/browser/media/key_system_support_impl.cc
@@ -6,10 +6,12 @@ #include <vector> +#include "base/command_line.h" #include "base/containers/flat_set.h" #include "base/feature_list.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" +#include "base/strings/string_split.h" #include "content/public/browser/cdm_registry.h" #include "content/public/common/cdm_info.h" #include "media/base/key_system_names.h" @@ -28,6 +30,32 @@ available); } +std::vector<media::VideoCodec> GetEnabledHardwareSecureCodecsFromCommandLine() { + std::vector<media::VideoCodec> result; + + auto* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line) + return result; + + auto codecs_string = command_line->GetSwitchValueASCII( + switches::kEnableHardwareSecureCodecsForTesting); + const auto supported_codecs = base::SplitStringPiece( + codecs_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + + for (const auto& codec : supported_codecs) { + if (codec == "vp8") + result.push_back(media::VideoCodec::kCodecVP8); + else if (codec == "vp9") + result.push_back(media::VideoCodec::kCodecVP9); + else if (codec == "avc1") + result.push_back(media::VideoCodec::kCodecH264); + else + DVLOG(1) << "Unsupported codec specified on command line: " << codec; + } + + return result; +} + } // namespace // static @@ -80,6 +108,9 @@ std::vector<media::EncryptionMode>(schemes.begin(), schemes.end()); if (base::FeatureList::IsEnabled(media::kHardwareSecureDecryption)) { + capability->hw_secure_video_codecs = + GetEnabledHardwareSecureCodecsFromCommandLine(); + // TODO(xhwang): Call into GetContentClient()->browser() to get key system // specific hardware secure decryption capability on Windows. NOTIMPLEMENTED();
diff --git a/content/browser/payments/payment_app_browsertest.cc b/content/browser/payments/payment_app_browsertest.cc index bd35aa9b..27c7f2b 100644 --- a/content/browser/payments/payment_app_browsertest.cc +++ b/content/browser/payments/payment_app_browsertest.cc
@@ -275,10 +275,10 @@ EXPECT_EQ("https://example.com/", PopConsoleString() /* topOrigin */); EXPECT_EQ("https://example.com/", PopConsoleString() /* paymentRequestOrigin */); - EXPECT_EQ("[{\"supportedMethods\":[\"basic-card\"]}]", + EXPECT_EQ("[{\"supportedMethods\":\"basic-card\"}]", PopConsoleString() /* methodData */); EXPECT_EQ( - "[{\"additionalDisplayItems\":[],\"supportedMethods\":[\"basic-card\"]," + "[{\"additionalDisplayItems\":[],\"supportedMethods\":\"basic-card\"," "\"total\":{\"amount\":{\"currency\":\"USD\"," "\"value\":\"55\"},\"label\":\"\",\"pending\":false}}" "]", @@ -320,14 +320,14 @@ EXPECT_EQ("https://example.com/", PopConsoleString() /* paymentRequestOrigin */); EXPECT_EQ("payment-request-id", PopConsoleString() /* paymentRequestId */); - EXPECT_EQ("[{\"supportedMethods\":[\"basic-card\"]}]", + EXPECT_EQ("[{\"supportedMethods\":\"basic-card\"}]", PopConsoleString() /* methodData */); EXPECT_EQ( "{\"currency\":\"USD\"," "\"value\":\"55\"}", PopConsoleString() /* total */); EXPECT_EQ( - "[{\"additionalDisplayItems\":[],\"supportedMethods\":[\"basic-card\"]," + "[{\"additionalDisplayItems\":[],\"supportedMethods\":\"basic-card\"," "\"total\":{\"amount\":{\"currency\":\"USD\"," "\"value\":\"55\"},\"label\":\"\",\"pending\":false}}" "]", @@ -357,13 +357,13 @@ EXPECT_EQ("https://example.com/", PopConsoleString() /* paymentRequestOrigin */); EXPECT_EQ("payment-request-id", PopConsoleString() /* paymentRequestId */); - EXPECT_EQ("[{\"supportedMethods\":[\"https://bobpay.com\"]}]", + EXPECT_EQ("[{\"supportedMethods\":\"https://bobpay.com\"}]", PopConsoleString() /* methodData */); EXPECT_EQ("{\"currency\":\"USD\",\"value\":\"55\"}", PopConsoleString() /* total */); EXPECT_EQ( - "[{\"additionalDisplayItems\":[],\"supportedMethods\":[\"https://" - "bobpay.com\"]," + "[{\"additionalDisplayItems\":[],\"supportedMethods\":\"https://" + "bobpay.com\"," "\"total\":{\"amount\":{\"currency\":\"USD\"," "\"value\":\"55\"},\"label\":\"\",\"pending\":false}}" "]",
diff --git a/content/browser/payments/payment_app_provider_impl.cc b/content/browser/payments/payment_app_provider_impl.cc index 1c36dd8..5dd48fc 100644 --- a/content/browser/payments/payment_app_provider_impl.cc +++ b/content/browser/payments/payment_app_provider_impl.cc
@@ -13,6 +13,7 @@ #include "content/browser/service_worker/service_worker_version.h" #include "content/browser/storage_partition_impl.h" #include "content/common/service_worker/service_worker_status_code.h" +#include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/permission_manager.h" #include "content/public/browser/permission_type.h" @@ -569,6 +570,35 @@ base::BindOnce(&AbortInvokePaymentApp, browser_context)); } +bool PaymentAppProviderImpl::IsValidInstallablePaymentApp( + const GURL& manifest_url, + const GURL& sw_js_url, + const GURL& sw_scope, + std::string* error_message) { + DCHECK(manifest_url.is_valid() && sw_js_url.is_valid() && + sw_scope.is_valid()); + + // TODO(crbug.com/853924): Unify duplicated code between here and + // ServiceWorkerProviderHost::IsValidRegisterMessage. + if (ServiceWorkerUtils::ContainsDisallowedCharacter(sw_js_url, sw_scope, + error_message)) { + return false; + } + + std::vector<GURL> urls = {manifest_url, sw_js_url, sw_scope}; + if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { + *error_message = + "Origins are not matching, or some origins cannot access service " + "worker " + "(manifest:" + + manifest_url.spec() + " scope:" + sw_scope.spec() + + " sw:" + sw_js_url.spec() + ")"; + return false; + } + + return true; +} + PaymentAppProviderImpl::PaymentAppProviderImpl() = default; PaymentAppProviderImpl::~PaymentAppProviderImpl() = default;
diff --git a/content/browser/payments/payment_app_provider_impl.h b/content/browser/payments/payment_app_provider_impl.h index f1f4fa09..cd7d6956 100644 --- a/content/browser/payments/payment_app_provider_impl.h +++ b/content/browser/payments/payment_app_provider_impl.h
@@ -45,6 +45,10 @@ void SetOpenedWindow(WebContents* web_contents) override; void CloseOpenedWindow(BrowserContext* browser_context) override; void OnClosingOpenedWindow(BrowserContext* browser_context) override; + bool IsValidInstallablePaymentApp(const GURL& manifest_url, + const GURL& sw_js_url, + const GURL& sw_scope, + std::string* error_message) override; private: PaymentAppProviderImpl();
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.h b/content/browser/renderer_host/browser_compositor_view_mac.h index ac6a5a5..921df41 100644 --- a/content/browser/renderer_host/browser_compositor_view_mac.h +++ b/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -69,7 +69,6 @@ // no valid frame is available. const gfx::CALayerParams* GetLastCALayerParams() const; - gfx::AcceleratedWidget GetAcceleratedWidget(); void DidCreateNewRendererCompositorFrameSink( viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink); void OnDidNotProduceFrame(const viz::BeginFrameAck& ack);
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm index e23d2f9..fce1e64 100644 --- a/content/browser/renderer_host/browser_compositor_view_mac.mm +++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -240,14 +240,6 @@ g_spare_recyclable_compositors.Get().clear(); } -gfx::AcceleratedWidget BrowserCompositorMac::GetAcceleratedWidget() { - if (recyclable_compositor_) { - return recyclable_compositor_->accelerated_widget_mac() - ->accelerated_widget(); - } - return gfx::kNullAcceleratedWidget; -} - DelegatedFrameHost* BrowserCompositorMac::GetDelegatedFrameHost() { DCHECK(delegated_frame_host_); return delegated_frame_host_.get();
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 04f08250..029ea05 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -48,6 +48,7 @@ #include "components/viz/common/gpu/vulkan_in_process_context_provider.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" +#include "components/viz/host/host_display_client.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/display/display.h" #include "components/viz/service/display/display_scheduler.h" @@ -59,8 +60,6 @@ #include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "content/browser/browser_main_loop.h" -#include "content/browser/compositor/external_begin_frame_controller_client_impl.h" -#include "content/browser/compositor/in_process_display_client.h" #include "content/browser/compositor/surface_utils.h" #include "content/browser/gpu/compositor_util.h" #include "content/browser/gpu/gpu_data_manager_impl.h" @@ -86,6 +85,7 @@ #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/skia/include/core/SkMallocPixelRef.h" #include "ui/android/window_android.h" +#include "ui/compositor/host/external_begin_frame_controller_client_impl.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/gfx/ca_layer_params.h" @@ -114,12 +114,12 @@ ~SingleThreadTaskGraphRunner() override { Shutdown(); } }; -// An implementation of InProcessDisplayClient which handles swap callbacks. -class AndroidInProcessDisplayClient : public InProcessDisplayClient { +// An implementation of HostDisplayClient which handles swap callbacks. +class AndroidHostDisplayClient : public viz::HostDisplayClient { public: - AndroidInProcessDisplayClient( + explicit AndroidHostDisplayClient( base::RepeatingCallback<void(const gfx::Size&)> on_swap) - : InProcessDisplayClient(gfx::kNullAcceleratedWidget), + : HostDisplayClient(gfx::kNullAcceleratedWidget), on_swap_(std::move(on_swap)) {} // viz::mojom::DisplayClient implementation: @@ -1223,14 +1223,14 @@ mojo::MakeRequest(&root_params->compositor_frame_sink_client); root_params->display_private = mojo::MakeRequest(&display_private_); display_client_ = - std::make_unique<AndroidInProcessDisplayClient>(base::BindRepeating( + std::make_unique<AndroidHostDisplayClient>(base::BindRepeating( &CompositorImpl::DidSwapBuffers, weak_factory_.GetWeakPtr())); root_params->display_client = display_client_->GetBoundPtr(task_runner).PassInterface(); // Initialize ExternalBeginFrameControllerClient. external_begin_frame_controller_client_ = - std::make_unique<ExternalBeginFrameControllerClientImpl>(this); + std::make_unique<ui::ExternalBeginFrameControllerClientImpl>(this); root_params->external_begin_frame_controller = external_begin_frame_controller_client_->GetControllerRequest(); root_params->external_begin_frame_controller_client =
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 6165219..fa619b3 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -43,18 +43,21 @@ class LayerTreeHost; } +namespace ui { +class ExternalBeginFrameControllerClientImpl; +} + namespace viz { class Display; class FrameSinkId; class FrameSinkManagerImpl; +class HostDisplayClient; class HostFrameSinkManager; class OutputSurface; } namespace content { class CompositorClient; -class InProcessDisplayClient; -class ExternalBeginFrameControllerClientImpl; // ----------------------------------------------------------------------------- // Browser-side compositor that manages a tree of content and UI layers. @@ -263,10 +266,10 @@ // Viz-specific members for communicating with the display. viz::mojom::DisplayPrivateAssociatedPtr display_private_; - std::unique_ptr<InProcessDisplayClient> display_client_; + std::unique_ptr<viz::HostDisplayClient> display_client_; // Viz-specific member which manages sending begin frames to the Viz process. - std::unique_ptr<ExternalBeginFrameControllerClientImpl> + std::unique_ptr<ui::ExternalBeginFrameControllerClientImpl> external_begin_frame_controller_client_; // Test-only. Called when we are notified of a swap.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 4230365..528fe17 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2383,8 +2383,9 @@ if (crash_report_mode == CrashReportMode::GENERATE_CRASH_DUMP) { // Set crash keys to understand renderer kills related to site isolation. auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + std::string lock_url = policy->GetOriginLock(GetID()).spec(); base::debug::SetCrashKeyString(bad_message::GetKilledProcessOriginLockKey(), - policy->GetOriginLock(GetID()).spec()); + lock_url.empty() ? "(none)" : lock_url); std::string site_isolation_mode; if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) @@ -2393,6 +2394,8 @@ site_isolation_mode += "tdi "; if (SiteIsolationPolicy::AreIsolatedOriginsEnabled()) site_isolation_mode += "io "; + if (site_isolation_mode.empty()) + site_isolation_mode = "(none)"; static auto* isolation_mode_key = base::debug::AllocateCrashKeyString( "site_isolation_mode", base::debug::CrashKeySize::Size32);
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index f8a97cb4..f9bffda 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -10,6 +10,7 @@ #include <string> #include <vector> +#include "base/callback.h" #include "build/build_config.h" #include "content/common/content_export.h" #include "content/common/drag_event_source_info.h" @@ -155,7 +156,10 @@ // Notification that the renderer has become unresponsive. The // delegate can use this notification to show a warning to the user. - virtual void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) {} + // See also WebContentsDelegate::RendererUnresponsive. + virtual void RendererUnresponsive( + RenderWidgetHostImpl* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) {} // Notification that a previously unresponsive renderer has become // responsive again. The delegate can use this notification to end the
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 5cff3f5..ac367a6 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -406,7 +406,7 @@ const auto* command_line = base::CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(switches::kDisableHangMonitor)) { - hang_monitor_timeout_.reset(new TimeoutMonitor( + input_event_ack_timeout_.reset(new TimeoutMonitor( base::Bind(&RenderWidgetHostImpl::RendererIsUnresponsive, weak_factory_.GetWeakPtr()))); } @@ -690,7 +690,7 @@ visual_properties_ack_pending_ = false; // Don't bother reporting hung state when we aren't active. - StopHangMonitorTimeout(); + StopInputEventAckTimeout(); // If we have a renderer, then inform it that we are being hidden so it can // reduce its resource utilization. @@ -720,7 +720,7 @@ ForceFirstFrameAfterNavigationTimeout(); SendScreenRects(); - RestartHangMonitorTimeoutIfNecessary(); + RestartInputEventAckTimeoutIfNecessary(); // Always repaint on restore. bool needs_repainting = true; @@ -1105,39 +1105,39 @@ void RenderWidgetHostImpl::ProcessIgnoreInputEventsChanged( bool ignore_input_events) { if (ignore_input_events) - StopHangMonitorTimeout(); + StopInputEventAckTimeout(); else - RestartHangMonitorTimeoutIfNecessary(); + RestartInputEventAckTimeoutIfNecessary(); } -void RenderWidgetHostImpl::StartHangMonitorTimeout(TimeDelta delay) { - if (!hang_monitor_timeout_) +void RenderWidgetHostImpl::StartInputEventAckTimeout(TimeDelta delay) { + if (!input_event_ack_timeout_) return; - hang_monitor_timeout_->Start(delay); - hang_monitor_start_time_ = clock_->NowTicks(); + input_event_ack_timeout_->Start(delay); + input_event_ack_start_time_ = clock_->NowTicks(); } -void RenderWidgetHostImpl::RestartHangMonitorTimeoutIfNecessary() { - if (hang_monitor_timeout_ && in_flight_event_count_ > 0 && !is_hidden_) - hang_monitor_timeout_->Restart(hung_renderer_delay_); +void RenderWidgetHostImpl::RestartInputEventAckTimeoutIfNecessary() { + if (input_event_ack_timeout_ && in_flight_event_count_ > 0 && !is_hidden_) + input_event_ack_timeout_->Restart(hung_renderer_delay_); } bool RenderWidgetHostImpl::IsCurrentlyUnresponsive() const { return is_unresponsive_; } -void RenderWidgetHostImpl::StopHangMonitorTimeout() { - if (hang_monitor_timeout_) - hang_monitor_timeout_->Stop(); +void RenderWidgetHostImpl::StopInputEventAckTimeout() { + if (input_event_ack_timeout_) + input_event_ack_timeout_->Stop(); - if (!hang_monitor_start_time_.is_null()) { - base::TimeDelta elapsed = clock_->NowTicks() - hang_monitor_start_time_; + if (!input_event_ack_start_time_.is_null()) { + base::TimeDelta elapsed = clock_->NowTicks() - input_event_ack_start_time_; const base::TimeDelta kMinimumHangTimeToReport = base::TimeDelta::FromSeconds(5); if (elapsed >= kMinimumHangTimeToReport) UMA_HISTOGRAM_LONG_TIMES("Renderer.Hung.Duration", elapsed); - hang_monitor_start_time_ = TimeTicks(); + input_event_ack_start_time_ = TimeTicks(); } RendererIsResponsive(); } @@ -1466,9 +1466,6 @@ switch (delegate_->PreHandleKeyboardEvent(key_event)) { case KeyboardEventProcessingResult::HANDLED: return; - case KeyboardEventProcessingResult::HANDLED_WANTS_KEY_UP: - suppress_events_until_keydown_ = false; - return; #if defined(USE_AURA) case KeyboardEventProcessingResult::HANDLED_DONT_UPDATE_EVENT: if (update_event) @@ -1890,7 +1887,7 @@ // Reset this to ensure the hung renderer mechanism is working properly. in_flight_event_count_ = 0; - StopHangMonitorTimeout(); + StopInputEventAckTimeout(); if (view_) { view_->RenderProcessGone(status, exit_code); @@ -2046,7 +2043,10 @@ is_unresponsive_ = true; if (delegate_) - delegate_->RendererUnresponsive(this); + delegate_->RendererUnresponsive( + this, base::BindRepeating( + &RenderWidgetHostImpl::RestartInputEventAckTimeoutIfNecessary, + weak_factory_.GetWeakPtr())); // Do not add code after this since the Delegate may delete this // RenderWidgetHostImpl in RendererUnresponsive. @@ -2451,7 +2451,7 @@ void RenderWidgetHostImpl::IncrementInFlightEventCount() { ++in_flight_event_count_; if (!is_hidden_) - StartHangMonitorTimeout(hung_renderer_delay_); + StartInputEventAckTimeout(hung_renderer_delay_); } void RenderWidgetHostImpl::DecrementInFlightEventCount( @@ -2459,12 +2459,12 @@ --in_flight_event_count_; if (in_flight_event_count_ <= 0) { // Cancel pending hung renderer checks since the renderer is responsive. - StopHangMonitorTimeout(); + StopInputEventAckTimeout(); } else { // Only restart the hang monitor timer if we got a response from the // main thread. if (ack_source == InputEventAckSource::MAIN_THREAD) - RestartHangMonitorTimeoutIfNecessary(); + RestartInputEventAckTimeoutIfNecessary(); } } @@ -2981,7 +2981,7 @@ void RenderWidgetHostImpl::SetupInputRouter() { in_flight_event_count_ = 0; - StopHangMonitorTimeout(); + StopInputEventAckTimeout(); associated_widget_input_handler_ = nullptr; widget_input_handler_ = nullptr;
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 47e2ccf0..dddbe4f2 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -11,6 +11,7 @@ #include <list> #include <map> #include <memory> +#include <set> #include <string> #include <utility> #include <vector> @@ -197,7 +198,6 @@ int GetRoutingID() const override; RenderWidgetHostViewBase* GetView() const override; bool IsLoading() const override; - void RestartHangMonitorTimeoutIfNecessary() override; bool IsCurrentlyUnresponsive() const override; void SetIgnoreInputEvents(bool ignore_input_events) override; bool SynchronizeVisualProperties() override; @@ -755,13 +755,13 @@ private: FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, - DontPostponeHangMonitorTimeout); + DontPostponeInputEventAckTimeout); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, HiddenPaint); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, RendererExitedNoDrag); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, - StopAndStartHangMonitorTimeout); + StopAndStartInputEventAckTimeout); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, - ShorterDelayHangMonitorTimeout); + ShorterDelayInputEventAckTimeout); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, SynchronizeVisualProperties); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, AutoResizeWithScale); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, @@ -792,7 +792,7 @@ // destructor is called as well. void Destroy(bool also_delete); - // Called by |hang_monitor_timeout_| on delayed response from the renderer. + // Called by |input_event_ack_timeout_| on delayed response from the renderer. void RendererIsUnresponsive(); // Called by |new_content_rendering_timeout_| if a renderer has loaded new @@ -878,11 +878,16 @@ // Starts a hang monitor timeout. If there's already a hang monitor timeout // the new one will only fire if it has a shorter delay than the time // left on the existing timeouts. - void StartHangMonitorTimeout(base::TimeDelta delay); + void StartInputEventAckTimeout(base::TimeDelta delay); // Stops all existing hang monitor timeouts and assumes the renderer is // responsive. - void StopHangMonitorTimeout(); + void StopInputEventAckTimeout(); + + // Implementation of |hang_monitor_restarter| callback passed to + // RenderWidgetHostDelegate::RendererUnresponsive if the unresponsiveness + // was noticed because of input event ack timeout. + void RestartInputEventAckTimeoutIfNecessary(); void SetupInputRouter(); @@ -1055,8 +1060,8 @@ // Receives and handles all input events. std::unique_ptr<InputRouter> input_router_; - std::unique_ptr<TimeoutMonitor> hang_monitor_timeout_; - base::TimeTicks hang_monitor_start_time_; + std::unique_ptr<TimeoutMonitor> input_event_ack_timeout_; + base::TimeTicks input_event_ack_start_time_; std::unique_ptr<TimeoutMonitor> new_content_rendering_timeout_;
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index f4ecec5f..b3d3d52 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -161,7 +161,7 @@ class TestFrameTokenMessageQueue : public FrameTokenMessageQueue { public: - TestFrameTokenMessageQueue(FrameTokenMessageQueue::Client* client) + explicit TestFrameTokenMessageQueue(FrameTokenMessageQueue::Client* client) : FrameTokenMessageQueue(client) {} ~TestFrameTokenMessageQueue() override {} @@ -184,7 +184,6 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl { public: - // Allow poking at a few private members. using RenderWidgetHostImpl::GetVisualProperties; using RenderWidgetHostImpl::RendererExited; @@ -592,7 +591,9 @@ return handle_wheel_event_; } - void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) override { + void RendererUnresponsive( + RenderWidgetHostImpl* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override { unresponsive_timer_fired_ = true; } @@ -1461,13 +1462,13 @@ // Test that the hang monitor timer expires properly if a new timer is started // while one is in progress (see crbug.com/11007). -TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) { +TEST_F(RenderWidgetHostTest, DontPostponeInputEventAckTimeout) { // Start with a short timeout. - host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10)); + host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(10)); // Immediately try to add a long 30 second timeout. EXPECT_FALSE(delegate_->unresponsive_timer_fired()); - host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30)); + host_->StartInputEventAckTimeout(TimeDelta::FromSeconds(30)); // Wait long enough for first timeout and see if it fired. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -1479,14 +1480,14 @@ // Test that the hang monitor timer expires properly if it is started, stopped, // and then started again. -TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) { +TEST_F(RenderWidgetHostTest, StopAndStartInputEventAckTimeout) { // Start with a short timeout, then stop it. - host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10)); - host_->StopHangMonitorTimeout(); + host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(10)); + host_->StopInputEventAckTimeout(); // Start it again to ensure it still works. EXPECT_FALSE(delegate_->unresponsive_timer_fired()); - host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10)); + host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(10)); // Wait long enough for first timeout and see if it fired. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -1498,13 +1499,13 @@ // Test that the hang monitor timer expires properly if it is started, then // updated to a shorter duration. -TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) { +TEST_F(RenderWidgetHostTest, ShorterDelayInputEventAckTimeout) { // Start with a timeout. - host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100)); + host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(100)); // Start it again with shorter delay. EXPECT_FALSE(delegate_->unresponsive_timer_fired()); - host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20)); + host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(20)); // Wait long enough for the second timeout and see if it fired. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -1516,7 +1517,7 @@ // Test that the hang monitor timer is effectively disabled when the widget is // hidden. -TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) { +TEST_F(RenderWidgetHostTest, InputEventAckTimeoutDisabledForInputWhenHidden) { host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1)); SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 10, 0, false);
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index e691d42..d805b96 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -152,7 +152,7 @@ BrowserAccessibilityManager* CreateBrowserAccessibilityManager( BrowserAccessibilityDelegate* delegate, bool for_root_frame) override; gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds) override; - gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override; + gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override; base::Optional<SkColor> GetBackgroundColor() const override; void SetParentUiLayer(ui::Layer* parent_ui_layer) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 6ed537f..2fe63e9 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1280,9 +1280,9 @@ return gfx::Point(originInScreen.x, originInScreen.y); } -gfx::AcceleratedWidget -RenderWidgetHostViewMac::AccessibilityGetAcceleratedWidget() { - return browser_compositor_->GetAcceleratedWidget(); +gfx::NativeViewAccessible +RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessible() { + return cocoa_view(); } void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
diff --git a/content/browser/screen_orientation/screen_orientation_delegate_android.cc b/content/browser/screen_orientation/screen_orientation_delegate_android.cc index 7f88ed3..f328210 100644 --- a/content/browser/screen_orientation/screen_orientation_delegate_android.cc +++ b/content/browser/screen_orientation/screen_orientation_delegate_android.cc
@@ -4,6 +4,7 @@ #include "content/browser/screen_orientation/screen_orientation_delegate_android.h" +#include "content/browser/android/content_view_core.h" #include "content/browser/screen_orientation/screen_orientation_provider.h" #include "jni/ScreenOrientationProviderImpl_jni.h" #include "ui/android/window_android.h"
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index f5fc5073..47747e85 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -12,6 +12,7 @@ #include "base/strings/string_util.h" #include "base/time/time.h" #include "content/browser/service_worker/embedded_worker_status.h" +#include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" @@ -562,6 +563,11 @@ static_cast<int>(WorkerPreparationType::NUM_TYPES)); } + // Don't record .Time if S13nServiceWorker is enabled. + // https://crbug.com/852664 + if (ServiceWorkerUtils::IsServicificationEnabled()) + return; + // Record the preparation time. UMA_HISTOGRAM_MEDIUM_TIMES( "ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time", time);
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc index 94fa743..31932be 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.cc +++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -167,7 +167,8 @@ net::NetLogWithSource() /* TODO(scottmg): net log? */, base::BindOnce(&ServiceWorkerNavigationLoader::DidPrepareFetchEvent, weak_factory_.GetWeakPtr(), - base::WrapRefCounted(active_worker)), + base::WrapRefCounted(active_worker), + active_worker->running_status()), base::BindOnce(&ServiceWorkerNavigationLoader::DidDispatchFetchEvent, weak_factory_.GetWeakPtr())); did_navigation_preload_ = @@ -208,8 +209,19 @@ } void ServiceWorkerNavigationLoader::DidPrepareFetchEvent( - scoped_refptr<ServiceWorkerVersion> version) { + scoped_refptr<ServiceWorkerVersion> version, + EmbeddedWorkerStatus initial_worker_status) { response_head_.service_worker_ready_time = base::TimeTicks::Now(); + + // Note that we don't record worker preparation time in S13nServiceWorker + // path for now. If we want to measure worker preparation time we can + // calculate it from response_head_.service_worker_ready_time and + // response_head_.load_timing.request_start. + // https://crbug.com/852664 + ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame( + base::TimeDelta(), initial_worker_status, + version->embedded_worker()->start_situation(), did_navigation_preload_, + resource_request_.url); } void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
diff --git a/content/browser/service_worker/service_worker_navigation_loader.h b/content/browser/service_worker/service_worker_navigation_loader.h index ab6643f..4af50d8 100644 --- a/content/browser/service_worker/service_worker_navigation_loader.h +++ b/content/browser/service_worker/service_worker_navigation_loader.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/browser/loader/navigation_loader_interceptor.h" +#include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" #include "content/browser/service_worker/service_worker_metrics.h" #include "content/browser/service_worker/service_worker_response_type.h" @@ -101,7 +102,8 @@ // For FORWARD_TO_SERVICE_WORKER case. void StartRequest(); - void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version); + void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version, + EmbeddedWorkerStatus initial_worker_status); void DidDispatchFetchEvent( ServiceWorkerStatusCode status, ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc index b5cfd60..4e363e98 100644 --- a/content/browser/service_worker/service_worker_new_script_loader.cc +++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -396,6 +396,8 @@ DCHECK_EQ(WriterState::kWriting, header_writer_state_); DCHECK_NE(net::ERR_IO_PENDING, error); if (error != net::OK) { + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_HEADERS_ERROR); CommitCompleted(network::URLLoaderCompletionStatus(error), kServiceWorkerFetchScriptError); return; @@ -480,6 +482,8 @@ case MOJO_RESULT_OK: break; case MOJO_RESULT_FAILED_PRECONDITION: + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_DATA_ERROR); CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED), kServiceWorkerFetchScriptError); return; @@ -518,11 +522,15 @@ net::Error error) { DCHECK_NE(net::ERR_IO_PENDING, error); if (error != net::OK) { + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_DATA_ERROR); CommitCompleted(network::URLLoaderCompletionStatus(error), kServiceWorkerFetchScriptError); return; } DCHECK(pending_buffer); + ServiceWorkerMetrics::CountWriteResponseResult( + ServiceWorkerMetrics::WRITE_OK); pending_buffer->CompleteRead(bytes_written); // Get the consumer handle from a previous read operation if we have one. network_consumer_ = pending_buffer->ReleaseHandle(); @@ -557,8 +565,6 @@ version_->script_cache_map()->NotifyFinishedCaching( request_url_, bytes_written, error_code, status_message); - // TODO(nhiroki): Record ServiceWorkerMetrics::CountWriteResponseResult(). - // (https://crbug.com/762357) client_->OnComplete(status); client_producer_.reset();
diff --git a/content/browser/service_worker/service_worker_new_script_loader_unittest.cc b/content/browser/service_worker/service_worker_new_script_loader_unittest.cc index 709edf45..3921ee0 100644 --- a/content/browser/service_worker/service_worker_new_script_loader_unittest.cc +++ b/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
@@ -10,6 +10,7 @@ #include <utility> #include "base/run_loop.h" #include "base/strings/string_util.h" +#include "base/test/metrics/histogram_tester.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_disk_cache.h" @@ -35,6 +36,8 @@ const char kNormalScriptURL[] = "https://example.com/normal.js"; const char kNormalImportedScriptURL[] = "https://my-awesome-cdn.com/import_script.js"; +const char kHistogramWriteResponseResult[] = + "ServiceWorker.DiskCache.WriteResponseResult"; // MockHTTPServer is a utility to provide mocked responses for // ServiceWorkerNewScriptLoader. @@ -315,6 +318,8 @@ }; TEST_F(ServiceWorkerNewScriptLoaderTest, Success) { + base::HistogramTester histogram_tester; + const GURL kScriptURL(kNormalScriptURL); std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -334,9 +339,13 @@ // The response should also be stored in the storage. EXPECT_TRUE(VerifyStoredResponse(kScriptURL)); + histogram_tester.ExpectUniqueSample(kHistogramWriteResponseResult, + ServiceWorkerMetrics::WRITE_OK, 1); } TEST_F(ServiceWorkerNewScriptLoaderTest, Success_EmptyBody) { + base::HistogramTester histogram_tester; + const GURL kScriptURL("https://example.com/empty.js"); std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -356,9 +365,13 @@ // The response should also be stored in the storage. EXPECT_TRUE(VerifyStoredResponse(kScriptURL)); + // We don't record write response result if body is empty. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Success_LargeBody) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -389,9 +402,14 @@ // The response should also be stored in the storage. EXPECT_TRUE(VerifyStoredResponse(kScriptURL)); + // WRITE_OK should be recorded twice as we record every single write success. + histogram_tester.ExpectUniqueSample(kHistogramWriteResponseResult, + ServiceWorkerMetrics::WRITE_OK, 2); } TEST_F(ServiceWorkerNewScriptLoaderTest, Error_404) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -409,9 +427,13 @@ // The response shouldn't be stored in the storage. EXPECT_FALSE(VerifyStoredResponse(kScriptURL)); + // No sample should be recorded since a write didn't occur. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Error_Redirect) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -430,9 +452,13 @@ // The response shouldn't be stored in the storage. EXPECT_FALSE(VerifyStoredResponse(kScriptURL)); + // No sample should be recorded since a write didn't occur. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Error_CertificateError) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -453,9 +479,13 @@ // The response shouldn't be stored in the storage. EXPECT_FALSE(VerifyStoredResponse(kScriptURL)); + // No sample should be recorded since a write didn't occur. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Error_NoMimeType) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -473,9 +503,13 @@ // The response shouldn't be stored in the storage. EXPECT_FALSE(VerifyStoredResponse(kScriptURL)); + // No sample should be recorded since a write didn't occur. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Error_BadMimeType) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -495,9 +529,13 @@ // The response shouldn't be stored in the storage. EXPECT_FALSE(VerifyStoredResponse(kScriptURL)); + // No sample should be recorded since a write didn't occur. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Success_PathRestriction) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -528,9 +566,13 @@ // The response should also be stored in the storage. EXPECT_TRUE(VerifyStoredResponse(kScriptURL)); + histogram_tester.ExpectUniqueSample(kHistogramWriteResponseResult, + ServiceWorkerMetrics::WRITE_OK, 1); } TEST_F(ServiceWorkerNewScriptLoaderTest, Error_PathRestriction) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -555,9 +597,13 @@ // The response shouldn't be stored in the storage. EXPECT_FALSE(VerifyStoredResponse(kScriptURL)); + // No sample should be recorded since a write didn't occur. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Error_RedundantWorker) { + base::HistogramTester histogram_tester; + std::unique_ptr<network::TestURLLoaderClient> client; std::unique_ptr<ServiceWorkerNewScriptLoader> loader; @@ -577,6 +623,8 @@ // The response shouldn't be stored in the storage. EXPECT_FALSE(VerifyStoredResponse(kScriptURL)); + // No sample should be recorded since a write didn't occur. + histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0); } TEST_F(ServiceWorkerNewScriptLoaderTest, Update) {
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc index 7dc950d..17dd4d4 100644 --- a/content/browser/web_contents/web_contents_android.cc +++ b/content/browser/web_contents/web_contents_android.cc
@@ -22,6 +22,7 @@ #include "base/task_scheduler/post_task.h" #include "content/browser/accessibility/browser_accessibility_android.h" #include "content/browser/accessibility/browser_accessibility_manager_android.h" +#include "content/browser/android/content_view_core.h" #include "content/browser/android/java/gin_java_bridge_dispatcher_host.h" #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/media/android/browser_media_player_manager.h" @@ -850,9 +851,13 @@ void WebContentsAndroid::SetFocus(JNIEnv* env, const JavaParamRef<jobject>& obj, jboolean focused) { - WebContentsViewAndroid* view = - static_cast<WebContentsViewAndroid*>(web_contents_->GetView()); - view->SetFocus(focused); + RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid(); + if (!rwhva) + return; + if (focused) + rwhva->GotFocus(); + else + rwhva->LostFocus(); } int WebContentsAndroid::GetTopControlsShrinkBlinkHeightPixForTesting(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 1f30c885..ca9117be 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5299,8 +5299,6 @@ view_->Focus(); } - view_->RenderViewReady(); - for (auto& observer : observers_) observer.RenderViewReady(); } @@ -5843,7 +5841,8 @@ } void WebContentsImpl::RendererUnresponsive( - RenderWidgetHostImpl* render_widget_host) { + RenderWidgetHostImpl* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { for (auto& observer : observers_) observer.OnRendererUnresponsive(render_widget_host->GetProcess()); @@ -5854,7 +5853,8 @@ return; if (delegate_) - delegate_->RendererUnresponsive(this, render_widget_host); + delegate_->RendererUnresponsive(this, render_widget_host, + std::move(hang_monitor_restarter)); } void WebContentsImpl::RendererResponsive(
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 06aa9549..f4e07714 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -723,7 +723,9 @@ RenderWidgetHostImpl* GetRenderWidgetHostWithPageFocus() override; void FocusOwningWebContents( RenderWidgetHostImpl* render_widget_host) override; - void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) override; + void RendererUnresponsive( + RenderWidgetHostImpl* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override; void RendererResponsive(RenderWidgetHostImpl* render_widget_host) override; void RequestToLockMouse(RenderWidgetHostImpl* render_widget_host, bool user_gesture,
diff --git a/content/browser/web_contents/web_contents_view.h b/content/browser/web_contents/web_contents_view.h index b9cc9d60..cf8c74f 100644 --- a/content/browser/web_contents/web_contents_view.h +++ b/content/browser/web_contents/web_contents_view.h
@@ -110,9 +110,6 @@ // fully created. virtual void RenderViewCreated(RenderViewHost* host) = 0; - // Invoked when the WebContents is notified that the RenderView is ready. - virtual void RenderViewReady() = 0; - // Invoked when the WebContents is notified that the RenderView has been // swapped in. virtual void RenderViewSwappedIn(RenderViewHost* host) = 0;
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc index 16ce6c0..3a67038d 100644 --- a/content/browser/web_contents/web_contents_view_android.cc +++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -57,6 +57,22 @@ !content::GetContentClient()->UsingSynchronousCompositing(); return should_request_unbuffered_dispatch; } + +RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid( + WebContents* web_contents) { + RenderWidgetHostView* rwhv = NULL; + if (web_contents) { + rwhv = web_contents->GetRenderWidgetHostView(); + if (web_contents->ShowingInterstitialPage()) { + rwhv = web_contents->GetInterstitialPage() + ->GetMainFrame() + ->GetRenderViewHost() + ->GetWidget() + ->GetView(); + } + } + return static_cast<RenderWidgetHostViewAndroid*>(rwhv); +} } // static @@ -115,22 +131,19 @@ void WebContentsViewAndroid::SetOverscrollRefreshHandler( std::unique_ptr<ui::OverscrollRefreshHandler> overscroll_refresh_handler) { overscroll_refresh_handler_ = std::move(overscroll_refresh_handler); - auto* rwhv = web_contents_->GetRenderWidgetHostView(); - if (rwhv) { - static_cast<RenderWidgetHostViewAndroid*>(rwhv) - ->OnOverscrollRefreshHandlerAvailable(); - } + RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); + if (rwhv) + rwhv->OnOverscrollRefreshHandlerAvailable(); if (web_contents_->ShowingInterstitialPage()) { - rwhv = web_contents_->GetInterstitialPage() - ->GetMainFrame() - ->GetRenderViewHost() - ->GetWidget() - ->GetView(); - if (rwhv) { - static_cast<RenderWidgetHostViewAndroid*>(rwhv) - ->OnOverscrollRefreshHandlerAvailable(); - } + rwhv = static_cast<RenderWidgetHostViewAndroid*>( + web_contents_->GetInterstitialPage() + ->GetMainFrame() + ->GetRenderViewHost() + ->GetWidget() + ->GetView()); + if (rwhv) + rwhv->OnOverscrollRefreshHandlerAvailable(); } } @@ -154,16 +167,8 @@ RenderWidgetHostViewAndroid* WebContentsViewAndroid::GetRenderWidgetHostViewAndroid() { - RenderWidgetHostView* rwhv = nullptr; - rwhv = web_contents_->GetRenderWidgetHostView(); - if (web_contents_->ShowingInterstitialPage()) { - rwhv = web_contents_->GetInterstitialPage() - ->GetMainFrame() - ->GetRenderViewHost() - ->GetWidget() - ->GetView(); - } - return static_cast<RenderWidgetHostViewAndroid*>(rwhv); + return static_cast<RenderWidgetHostViewAndroid*>( + web_contents_->GetRenderWidgetHostView()); } gfx::NativeWindow WebContentsViewAndroid::GetTopLevelNativeWindow() const { @@ -186,13 +191,11 @@ } void WebContentsViewAndroid::Focus() { + RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); if (web_contents_->ShowingInterstitialPage()) { web_contents_->GetInterstitialPage()->Focus(); - } else { - auto* rwhv = web_contents_->GetRenderWidgetHostView(); - if (rwhv) { - static_cast<RenderWidgetHostViewAndroid*>(rwhv)->Focus(); - } + } else if (rwhv) { + rwhv->Focus(); } } @@ -270,45 +273,7 @@ void WebContentsViewAndroid::RenderViewCreated(RenderViewHost* host) { } -void WebContentsViewAndroid::RenderViewReady() { - render_view_host_ = web_contents_->GetRenderViewHost(); - if (device_orientation_ == 0) - return; - auto* rwhva = GetRenderWidgetHostViewAndroid(); - if (rwhva) - rwhva->UpdateScreenInfo(web_contents_->GetView()->GetNativeView()); - - web_contents_->OnScreenOrientationChange(); -} - void WebContentsViewAndroid::RenderViewSwappedIn(RenderViewHost* host) { - if (render_view_host_) { - auto* rwhv = render_view_host_->GetWidget()->GetView(); - if (rwhv && rwhv->GetNativeView()) { - static_cast<RenderWidgetHostViewAndroid*>(rwhv)->UpdateNativeViewTree( - nullptr); - } - } - auto* rwhv = host->GetWidget()->GetView(); - if (rwhv && rwhv->GetNativeView()) { - static_cast<RenderWidgetHostViewAndroid*>(rwhv)->UpdateNativeViewTree( - GetNativeView()); - } - - SetFocus(view_.HasFocus()); - render_view_host_ = host; -} - -void WebContentsViewAndroid::SetFocus(bool focused) { - auto* rwhv = GetRenderWidgetHostViewAndroid(); - if (!rwhv || !rwhv->GetNativeView()) - return; - - auto* rwhva = static_cast<RenderWidgetHostViewAndroid*>(rwhv); - if (focused) - rwhva->GotFocus(); - else - rwhva->LostFocus(); } void WebContentsViewAndroid::SetOverscrollControllerEnabled(bool enabled) { @@ -316,13 +281,11 @@ void WebContentsViewAndroid::ShowContextMenu( RenderFrameHost* render_frame_host, const ContextMenuParams& params) { - auto* rwhv = static_cast<RenderWidgetHostViewAndroid*>( - web_contents_->GetRenderWidgetHostView()); + RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid(); // See if context menu is handled by SelectionController as a selection menu. // If not, use the delegate to show it. - if (rwhv && rwhv->ShowSelectionMenu(params)) { + if (view && view->ShowSelectionMenu(params)) return; - } if (delegate_) delegate_->ShowContextMenu(render_frame_host, params); @@ -587,7 +550,7 @@ } void WebContentsViewAndroid::OnSizeChanged() { - auto* rwhv = GetRenderWidgetHostViewAndroid(); + auto* rwhv = ::content::GetRenderWidgetHostViewAndroid(web_contents_); if (rwhv) { web_contents_->SendScreenRects(); rwhv->SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h index 28c7e5b..3b6ab05 100644 --- a/content/browser/web_contents/web_contents_view_android.h +++ b/content/browser/web_contents/web_contents_view_android.h
@@ -80,7 +80,6 @@ RenderWidgetHost* render_widget_host) override; void SetPageTitle(const base::string16& title) override; void RenderViewCreated(RenderViewHost* host) override; - void RenderViewReady() override; void RenderViewSwappedIn(RenderViewHost* host) override; void SetOverscrollControllerEnabled(bool enabled) override; @@ -123,7 +122,6 @@ void OnSizeChanged() override; void OnPhysicalBackingSizeChanged() override; - void SetFocus(bool focused); void set_device_orientation(int orientation) { device_orientation_ = orientation; } @@ -170,8 +168,6 @@ gfx::PointF drag_location_; gfx::PointF drag_screen_location_; - RenderViewHost* render_view_host_ = nullptr; - DISALLOW_COPY_AND_ASSIGN(WebContentsViewAndroid); };
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 47423474..617bfe3 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -843,8 +843,6 @@ void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) { } -void WebContentsViewAura::RenderViewReady() {} - void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) { }
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h index 047c902..82807c7f 100644 --- a/content/browser/web_contents/web_contents_view_aura.h +++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -119,7 +119,6 @@ RenderWidgetHost* render_widget_host) override; void SetPageTitle(const base::string16& title) override; void RenderViewCreated(RenderViewHost* host) override; - void RenderViewReady() override; void RenderViewSwappedIn(RenderViewHost* host) override; void SetOverscrollControllerEnabled(bool enabled) override;
diff --git a/content/browser/web_contents/web_contents_view_child_frame.cc b/content/browser/web_contents/web_contents_view_child_frame.cc index 94874ac..e95c31d6 100644 --- a/content/browser/web_contents/web_contents_view_child_frame.cc +++ b/content/browser/web_contents/web_contents_view_child_frame.cc
@@ -99,8 +99,6 @@ void WebContentsViewChildFrame::RenderViewCreated(RenderViewHost* host) {} -void WebContentsViewChildFrame::RenderViewReady() {} - void WebContentsViewChildFrame::RenderViewSwappedIn(RenderViewHost* host) {} void WebContentsViewChildFrame::SetOverscrollControllerEnabled(bool enabled) {
diff --git a/content/browser/web_contents/web_contents_view_child_frame.h b/content/browser/web_contents/web_contents_view_child_frame.h index 973e0ae9..17275be 100644 --- a/content/browser/web_contents/web_contents_view_child_frame.h +++ b/content/browser/web_contents/web_contents_view_child_frame.h
@@ -45,7 +45,6 @@ RenderWidgetHost* render_widget_host) override; void SetPageTitle(const base::string16& title) override; void RenderViewCreated(RenderViewHost* host) override; - void RenderViewReady() override; void RenderViewSwappedIn(RenderViewHost* host) override; void SetOverscrollControllerEnabled(bool enabled) override; #if defined(OS_MACOSX)
diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc index 84e2810f..f6a43ca6 100644 --- a/content/browser/web_contents/web_contents_view_guest.cc +++ b/content/browser/web_contents/web_contents_view_guest.cc
@@ -163,10 +163,6 @@ platform_view_->RenderViewCreated(host); } -void WebContentsViewGuest::RenderViewReady() { - platform_view_->RenderViewReady(); -} - void WebContentsViewGuest::RenderViewSwappedIn(RenderViewHost* host) { platform_view_->RenderViewSwappedIn(host); }
diff --git a/content/browser/web_contents/web_contents_view_guest.h b/content/browser/web_contents/web_contents_view_guest.h index 3ccd66e..4a06fe5 100644 --- a/content/browser/web_contents/web_contents_view_guest.h +++ b/content/browser/web_contents/web_contents_view_guest.h
@@ -63,7 +63,6 @@ RenderWidgetHost* render_widget_host) override; void SetPageTitle(const base::string16& title) override; void RenderViewCreated(RenderViewHost* host) override; - void RenderViewReady() override; void RenderViewSwappedIn(RenderViewHost* host) override; void SetOverscrollControllerEnabled(bool enabled) override; #if defined(OS_MACOSX)
diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h index 8d62193b..4640550 100644 --- a/content/browser/web_contents/web_contents_view_mac.h +++ b/content/browser/web_contents/web_contents_view_mac.h
@@ -98,7 +98,6 @@ RenderWidgetHost* render_widget_host) override; void SetPageTitle(const base::string16& title) override; void RenderViewCreated(RenderViewHost* host) override; - void RenderViewReady() override; void RenderViewSwappedIn(RenderViewHost* host) override; void SetOverscrollControllerEnabled(bool enabled) override; bool IsEventTracking() const override;
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index 64405196..00b2d2a 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -423,8 +423,6 @@ host->EnablePreferredSizeMode(); } -void WebContentsViewMac::RenderViewReady() {} - void WebContentsViewMac::RenderViewSwappedIn(RenderViewHost* host) { }
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index ed5e362..7c31dd0 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -36,6 +36,7 @@ #include "content/app/resources/grit/content_resources.h" #include "content/app/strings/grit/content_strings.h" #include "content/child/child_thread_impl.h" +#include "content/common/service_worker/service_worker_utils.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" @@ -680,6 +681,10 @@ return GetContentClient()->AllowScriptExtensionForServiceWorker(scriptUrl); } +bool BlinkPlatformImpl::IsServiceWorkerNetServicificationEnabled() { + return ServiceWorkerUtils::IsServicificationEnabled(); +} + blink::WebCrypto* BlinkPlatformImpl::Crypto() { return &web_crypto_; }
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index 59ef224..ba8f61b 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -97,6 +97,7 @@ const blink::WebSize& cumulative_scroll) override; bool AllowScriptExtensionForServiceWorker( const blink::WebURL& script_url) override; + bool IsServiceWorkerNetServicificationEnabled() override; blink::WebCrypto* Crypto() override; const char* GetBrowserServiceName() const override; blink::WebMediaCapabilitiesClient* MediaCapabilitiesClient() override;
diff --git a/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc b/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc index 6f8be2d2..a6cd064c 100644 --- a/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc +++ b/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
@@ -17,7 +17,7 @@ #include "content/public/common/service_names.mojom.h" #include "skia/ext/fontmgr_default_win.h" #include "third_party/blink/public/web/win/web_font_rendering.h" -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkTypeface_win.h" namespace mswr = Microsoft::WRL;
diff --git a/content/child/font_warmup_win.cc b/content/child/font_warmup_win.cc index d9e98c1..be505c8 100644 --- a/content/child/font_warmup_win.cc +++ b/content/child/font_warmup_win.cc
@@ -25,8 +25,8 @@ #include "build/build_config.h" #include "ppapi/buildflags/buildflags.h" #include "skia/ext/fontmgr_default_win.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkRefCnt.h" -#include "third_party/skia/include/ports/SkFontMgr.h" #include "third_party/skia/include/ports/SkTypeface_win.h" #if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/content/child/font_warmup_win_unittest.cc b/content/child/font_warmup_win_unittest.cc index 9065ae0..0dea002 100644 --- a/content/child/font_warmup_win_unittest.cc +++ b/content/child/font_warmup_win_unittest.cc
@@ -16,11 +16,11 @@ #include "base/sys_byteorder.h" #include "base/win/windows_version.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkString.h" #include "third_party/skia/include/core/SkTypeface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" namespace content {
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 1220284..7ca2e1c 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -363,6 +363,7 @@ "java/src/org/chromium/content/browser/ContentNfcDelegate.java", "java/src/org/chromium/content/browser/ContentUiEventHandler.java", "java/src/org/chromium/content/browser/ContentVideoViewImpl.java", + "java/src/org/chromium/content/browser/ContentViewCoreImpl.java", "java/src/org/chromium/content/browser/ContentViewStaticsImpl.java", "java/src/org/chromium/content/browser/GestureListenerManagerImpl.java", "java/src/org/chromium/content/browser/GpuProcessCallback.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java index 407f89ca..a6d7aae2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
@@ -7,6 +7,8 @@ import android.content.Context; import android.view.ViewGroup; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; import org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl; import org.chromium.content.browser.input.ImeAdapterImpl; import org.chromium.content.browser.input.SelectPopup; @@ -23,11 +25,15 @@ /** * Implementation of the interface {@ContentViewCore}. */ +@JNINamespace("content") public class ContentViewCoreImpl implements ContentViewCore { private static final String TAG = "cr_ContentViewCore"; private WebContentsImpl mWebContents; + // Native pointer to C++ ContentViewCore object which will be set by nativeInit(). + private long mNativeContentViewCore; + private boolean mInitialized; private static final class UserDataFactoryLazyHolder { @@ -73,6 +79,7 @@ mWebContents.setViewAndroidDelegate(viewDelegate); mWebContents.setTopLevelNativeWindow(windowAndroid); + mNativeContentViewCore = nativeInit(mWebContents); ViewGroup containerView = viewDelegate.getContainerView(); ImeAdapterImpl.create( @@ -91,16 +98,31 @@ mInitialized = true; } - private boolean initialized() { + public boolean initialized() { return mInitialized; } + @CalledByNative + private void onNativeContentViewCoreDestroyed(long nativeContentViewCore) { + assert nativeContentViewCore == mNativeContentViewCore; + mNativeContentViewCore = 0; + } + @Override public void destroy() { + if (mNativeContentViewCore != 0) { + nativeOnJavaContentViewCoreDestroyed(mNativeContentViewCore); + } // This is called to fix crash. See https://crbug.com/803244 // TODO(jinsukkim): Use an observer to let the manager handle it on its own. GestureListenerManagerImpl.fromWebContents(mWebContents).reset(); mWebContents.destroyContentsInternal(); mWebContents = null; + mNativeContentViewCore = 0; + + // See warning in javadoc before adding more clean up code here. } + + private native long nativeInit(WebContents webContents); + private native void nativeOnJavaContentViewCoreDestroyed(long nativeContentViewCore); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/OWNERS b/content/public/android/javatests/src/org/chromium/content/browser/OWNERS index 39f1109..7abd8e3 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/OWNERS +++ b/content/public/android/javatests/src/org/chromium/content/browser/OWNERS
@@ -7,10 +7,6 @@ # Media Session API related per-file MediaSession*.java=mlamouri@chromium.org -# Process management related -per-file BindingManagerTest.java=mariakhomenko@chromium.org -per-file ChildProcessLauncherTest.java=mariakhomenko@chromium.org - # Java Bridge per-file JavaBridge*=michaelbai@chromium.org per-file JavaBridge*=torne@chromium.org
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 2581636..bbd8d325 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -23,7 +23,6 @@ #include "content/public/common/url_loader_throttle.h" #include "device/geolocation/public/cpp/location_provider.h" #include "media/audio/audio_manager.h" -#include "media/base/cdm_factory.h" #include "media/media_buildflags.h" #include "mojo/public/cpp/bindings/associated_interface_ptr.h" #include "net/ssl/client_cert_identity.h" @@ -186,10 +185,6 @@ return false; } -std::unique_ptr<media::CdmFactory> ContentBrowserClient::CreateCdmFactory() { - return nullptr; -} - bool ContentBrowserClient::ShouldAssignSiteForURL(const GURL& url) { return true; }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 6319f7004..84c1197 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -76,7 +76,6 @@ namespace media { class AudioLogFactory; class AudioManager; -class CdmFactory; } namespace mojo { @@ -966,10 +965,6 @@ // returns a non-null value. virtual bool OverridesAudioManager(); - // Creates and returns a factory used for creating CDM instances for playing - // protected content. - virtual std::unique_ptr<media::CdmFactory> CreateCdmFactory(); - // Populates |mappings| with all files that need to be mapped before launching // a child process. #if (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA)
diff --git a/content/public/browser/keyboard_event_processing_result.h b/content/public/browser/keyboard_event_processing_result.h index ba43542c..4030a52 100644 --- a/content/public/browser/keyboard_event_processing_result.h +++ b/content/public/browser/keyboard_event_processing_result.h
@@ -11,9 +11,6 @@ // The event was handled. HANDLED, - // The event was handled, and we want to be notified of the keyup event too. - HANDLED_WANTS_KEY_UP, - #if defined(USE_AURA) // The event was handled, but don't update the underlying event. A value // HANDLED results in calling ui::Event::SetHandled(), where as this does not.
diff --git a/content/public/browser/payment_app_provider.h b/content/public/browser/payment_app_provider.h index 8c1c0bb..bde1386 100644 --- a/content/public/browser/payment_app_provider.h +++ b/content/public/browser/payment_app_provider.h
@@ -79,6 +79,13 @@ // to abort payment request. virtual void OnClosingOpenedWindow(BrowserContext* browser_context) = 0; + // Check whether given |sw_js_url| from |manifest_url| is allowed to register + // with |sw_scope|. + virtual bool IsValidInstallablePaymentApp(const GURL& manifest_url, + const GURL& sw_js_url, + const GURL& sw_scope, + std::string* error_message) = 0; + protected: virtual ~PaymentAppProvider() {} };
diff --git a/content/public/browser/render_widget_host.h b/content/public/browser/render_widget_host.h index f547b65..29e577f 100644 --- a/content/public/browser/render_widget_host.h +++ b/content/public/browser/render_widget_host.h
@@ -7,6 +7,9 @@ #include <stdint.h> +#include <memory> +#include <vector> + #include "base/callback.h" #include "content/common/content_export.h" #include "content/public/browser/native_web_keyboard_event.h" @@ -195,14 +198,6 @@ // Returns true if the renderer is loading, false if not. virtual bool IsLoading() const = 0; - // Restart the active hang monitor timeout if the renderer is actively - // waiting on a response. Clears all existing timeouts and starts with - // a new one. This can be because the renderer has become - // active, the tab is being hidden, or the user has chosen to wait some more - // to give the tab a chance to become active and we don't want to display a - // warning too soon. - virtual void RestartHangMonitorTimeoutIfNecessary() = 0; - // Returns true if the renderer is considered unresponsive. virtual bool IsCurrentlyUnresponsive() const = 0; @@ -264,7 +259,7 @@ const gfx::PointF& client_pt, const gfx::PointF& screen_pt, blink::WebDragOperationsMask operations_allowed, - int key_modifiers){}; + int key_modifiers) {} virtual void DragTargetDragOver( const gfx::PointF& client_pt, const gfx::PointF& screen_pt, @@ -281,11 +276,11 @@ // either in a drop or by being cancelled. virtual void DragSourceEndedAt(const gfx::PointF& client_pt, const gfx::PointF& screen_pt, - blink::WebDragOperation operation){}; + blink::WebDragOperation operation) {} // Notifies the renderer that we're done with the drag and drop operation. // This allows the renderer to reset some state. - virtual void DragSourceSystemDragEnded() {}; + virtual void DragSourceSystemDragEnded() {} // Filters drop data before it is passed to RenderWidgetHost. virtual void FilterDropData(DropData* drop_data) {}
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 414e3423..fd74527 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -323,13 +323,18 @@ // the WebContents that is hung, and |render_widget_host| is the // RenderWidgetHost that, while routing events to it, discovered the hang. // + // |hang_monitor_restarter| can be used to restart the timer used to + // detect the hang. The timer is typically restarted when the renderer has + // become active, the tab got hidden, or the user has chosen to wait some + // more. + // // Useful member functions on |render_widget_host|: // - Getting the hung render process: GetProcess() // - Querying whether the process is still hung: IsCurrentlyUnresponsive() - // - Waiting for the process to recover on its own: - // RestartHangMonitorTimeoutIfNecessary() - virtual void RendererUnresponsive(WebContents* source, - RenderWidgetHost* render_widget_host) {} + virtual void RendererUnresponsive( + WebContents* source, + RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) {} // Notification that a process in the WebContents is no longer hung. |source| // is the WebContents that was hung, and |render_widget_host| is the
diff --git a/content/public/common/previews_state.h b/content/public/common/previews_state.h index 8fce0d1..fcf4941 100644 --- a/content/public/common/previews_state.h +++ b/content/public/common/previews_state.h
@@ -38,7 +38,7 @@ // the resource. Server transformations may // still happen if the page is heavy. NOSCRIPT_ON = 1 << 6, // Request that script be disabled for page load. - PREVIEWS_STATE_LAST = PREVIEWS_OFF + PREVIEWS_STATE_LAST = NOSCRIPT_ON }; // Combination of all previews that are guaranteed not to provide partial
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index df419c1..d0d196e 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -697,7 +697,8 @@ void SimulateUnresponsiveRenderer(WebContents* web_contents, RenderWidgetHost* widget) { static_cast<WebContentsImpl*>(web_contents) - ->RendererUnresponsive(RenderWidgetHostImpl::From(widget)); + ->RendererUnresponsive(RenderWidgetHostImpl::From(widget), + base::DoNothing::Repeatedly()); } #if defined(USE_AURA) @@ -1638,62 +1639,6 @@ namespace { -class SurfaceHitTestReadyNotifier { - public: - explicit SurfaceHitTestReadyNotifier(RenderWidgetHostViewBase* target_view); - ~SurfaceHitTestReadyNotifier() {} - - void WaitForSurfaceReady(RenderWidgetHostViewBase* root_container); - - private: - bool ContainsSurfaceId(const viz::SurfaceId& container_surface_id); - - viz::SurfaceManager* surface_manager_; - RenderWidgetHostViewBase* target_view_; - - DISALLOW_COPY_AND_ASSIGN(SurfaceHitTestReadyNotifier); -}; - -SurfaceHitTestReadyNotifier::SurfaceHitTestReadyNotifier( - RenderWidgetHostViewBase* target_view) - : target_view_(target_view) { - surface_manager_ = GetFrameSinkManager()->surface_manager(); -} - -void SurfaceHitTestReadyNotifier::WaitForSurfaceReady( - RenderWidgetHostViewBase* root_view) { - viz::SurfaceId root_surface_id = root_view->GetCurrentSurfaceId(); - while (!ContainsSurfaceId(root_surface_id)) { - // TODO(kenrb): Need a better way to do this. Needs investigation on - // whether we can add a callback through RenderWidgetHostViewBaseObserver - // from OnSwapCompositorFrame and avoid this busy waiting. A callback on - // every compositor frame might be generally undesirable for performance, - // however. - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); - run_loop.Run(); - } -} - -bool SurfaceHitTestReadyNotifier::ContainsSurfaceId( - const viz::SurfaceId& container_surface_id) { - if (!container_surface_id.is_valid()) - return false; - - viz::Surface* container_surface = - surface_manager_->GetSurfaceForId(container_surface_id); - if (!container_surface || !container_surface->active_referenced_surfaces()) - return false; - - for (const viz::SurfaceId& id : - *container_surface->active_referenced_surfaces()) { - if (id == target_view_->GetCurrentSurfaceId() || ContainsSurfaceId(id)) - return true; - } - return false; -} - RenderFrameMetadataProvider* RenderFrameMetadataProviderFromFrameTreeNode( FrameTreeNode* node) { DCHECK(node); @@ -1718,38 +1663,6 @@ } // namespace -void WaitForGuestSurfaceReady(content::WebContents* guest_web_contents) { - RenderWidgetHostViewChildFrame* child_view = - static_cast<RenderWidgetHostViewChildFrame*>( - guest_web_contents->GetRenderWidgetHostView()); - - RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( - static_cast<content::WebContentsImpl*>(guest_web_contents) - ->GetOuterWebContents() - ->GetRenderWidgetHostView()); - - SurfaceHitTestReadyNotifier notifier(child_view); - notifier.WaitForSurfaceReady(root_view); -} - -void WaitForChildFrameSurfaceReady(content::RenderFrameHost* child_frame) { - RenderWidgetHostViewBase* child_view = - static_cast<RenderFrameHostImpl*>(child_frame) - ->GetRenderWidgetHost() - ->GetView(); - if (!child_view || !child_view->IsRenderWidgetHostViewChildFrame()) - return; - - RenderWidgetHostViewBase* root_view = - static_cast<CrossProcessFrameConnector*>( - static_cast<RenderWidgetHostViewChildFrame*>(child_view) - ->FrameConnectorForTesting()) - ->GetRootRenderWidgetHostViewForTesting(); - - SurfaceHitTestReadyNotifier notifier(child_view); - notifier.WaitForSurfaceReady(root_view); -} - TitleWatcher::TitleWatcher(WebContents* web_contents, const base::string16& expected_title) : WebContentsObserver(web_contents) {
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 72713ab..4027853 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -544,35 +544,6 @@ gfx::Point point); #endif // defined(USE_AURA) -// Deprecated: With upcoming changes to display compositing the signal of a -// surface being activated is no longer matched to the submission of hit test -// data. -// -// To wait for hit test data to be submitted see -// HitTestRegionObserver::WaitForHitTestDataOrGuestSurfaceReady. -// -// To wait for frame submission see RenderFrameSubmissionObserver. -// -// Waits until the cc::Surface associated with a guest/cross-process-iframe -// has been drawn for the first time. Once this method returns it should be -// safe to assume that events sent to the top-level RenderWidgetHostView can -// be expected to properly hit-test to this surface, if appropriate. -void WaitForGuestSurfaceReady(content::WebContents* web_contents); - -// Deprecated: With upcoming changes to display compositing the signal of a -// surface being activated is no longer matched to the submission of hit test -// data. -// -// To wait for hit test data to be submitted see -// HitTestRegionObserver::WaitForHitTestDataOrChildSurfaceReady. -// -// To wait for frame submission see RenderFrameSubmissionObserver. -// Waits until the cc::Surface associated with a cross-process child frame -// has been drawn for the first time. Once this method returns it should be -// safe to assume that events sent to the top-level RenderWidgetHostView can -// be expected to properly hit-test to this surface, if appropriate. -void WaitForChildFrameSurfaceReady(content::RenderFrameHost* child_frame); - // Watches title changes on a WebContents, blocking until an expected title is // set. class TitleWatcher : public WebContentsObserver {
diff --git a/content/public/test/hit_test_region_observer.cc b/content/public/test/hit_test_region_observer.cc index 8d24f9b..3a6960f 100644 --- a/content/public/test/hit_test_region_observer.cc +++ b/content/public/test/hit_test_region_observer.cc
@@ -6,21 +6,126 @@ #include <algorithm> +#include "base/test/test_timeouts.h" #include "components/viz/common/features.h" #include "components/viz/host/host_frame_sink_manager.h" +#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" +#include "components/viz/service/surfaces/surface_manager.h" #include "content/browser/compositor/surface_utils.h" +#include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/renderer_host/frame_connector_delegate.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/render_widget_host_view_child_frame.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" namespace content { -void WaitForHitTestDataOrChildSurfaceReady( - content::RenderFrameHost* child_frame) { +namespace { +class SurfaceHitTestReadyNotifier { + public: + explicit SurfaceHitTestReadyNotifier(RenderWidgetHostViewBase* target_view); + ~SurfaceHitTestReadyNotifier() {} + + void WaitForSurfaceReady(RenderWidgetHostViewBase* root_container); + + private: + bool ContainsSurfaceId(const viz::SurfaceId& container_surface_id); + + viz::SurfaceManager* surface_manager_; + RenderWidgetHostViewBase* target_view_; + + DISALLOW_COPY_AND_ASSIGN(SurfaceHitTestReadyNotifier); +}; + +SurfaceHitTestReadyNotifier::SurfaceHitTestReadyNotifier( + RenderWidgetHostViewBase* target_view) + : target_view_(target_view) { + surface_manager_ = GetFrameSinkManager()->surface_manager(); +} + +void SurfaceHitTestReadyNotifier::WaitForSurfaceReady( + RenderWidgetHostViewBase* root_view) { + viz::SurfaceId root_surface_id = root_view->GetCurrentSurfaceId(); + while (!ContainsSurfaceId(root_surface_id)) { + // TODO(kenrb): Need a better way to do this. Needs investigation on + // whether we can add a callback through RenderWidgetHostViewBaseObserver + // from OnSwapCompositorFrame and avoid this busy waiting. A callback on + // every compositor frame might be generally undesirable for performance, + // however. + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); + run_loop.Run(); + } +} + +bool SurfaceHitTestReadyNotifier::ContainsSurfaceId( + const viz::SurfaceId& container_surface_id) { + if (!container_surface_id.is_valid()) + return false; + + viz::Surface* container_surface = + surface_manager_->GetSurfaceForId(container_surface_id); + if (!container_surface || !container_surface->active_referenced_surfaces()) + return false; + + for (const viz::SurfaceId& id : + *container_surface->active_referenced_surfaces()) { + if (id == target_view_->GetCurrentSurfaceId() || ContainsSurfaceId(id)) + return true; + } + return false; +} + +// Waits until the cc::Surface associated with a guest/cross-process-iframe +// has been drawn for the first time. Once this method returns it should be +// safe to assume that events sent to the top-level RenderWidgetHostView can +// be expected to properly hit-test to this surface, if appropriate. +void WaitForGuestSurfaceReady(content::WebContents* guest_web_contents) { + RenderWidgetHostViewChildFrame* child_view = + static_cast<RenderWidgetHostViewChildFrame*>( + guest_web_contents->GetRenderWidgetHostView()); + + RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( + static_cast<content::WebContentsImpl*>(guest_web_contents) + ->GetOuterWebContents() + ->GetRenderWidgetHostView()); + + SurfaceHitTestReadyNotifier notifier(child_view); + notifier.WaitForSurfaceReady(root_view); +} + +// To wait for frame submission see RenderFrameSubmissionObserver. +// Waits until the cc::Surface associated with a cross-process child frame +// has been drawn for the first time. Once this method returns it should be +// safe to assume that events sent to the top-level RenderWidgetHostView can +// be expected to properly hit-test to this surface, if appropriate. +void WaitForChildFrameSurfaceReady(content::RenderFrameHost* child_frame) { + RenderWidgetHostViewBase* child_view = + static_cast<RenderFrameHostImpl*>(child_frame) + ->GetRenderWidgetHost() + ->GetView(); + if (!child_view || !child_view->IsRenderWidgetHostViewChildFrame()) + return; + + RenderWidgetHostViewBase* root_view = + static_cast<CrossProcessFrameConnector*>( + static_cast<RenderWidgetHostViewChildFrame*>(child_view) + ->FrameConnectorForTesting()) + ->GetRootRenderWidgetHostViewForTesting(); + + SurfaceHitTestReadyNotifier notifier(child_view); + notifier.WaitForSurfaceReady(root_view); +} + +} // namespace + +void WaitForHitTestDataOrChildSurfaceReady(RenderFrameHost* child_frame) { RenderWidgetHostViewBase* child_view = static_cast<RenderFrameHostImpl*>(child_frame) ->GetRenderWidgetHost() @@ -35,8 +140,7 @@ WaitForChildFrameSurfaceReady(child_frame); } -void WaitForHitTestDataOrGuestSurfaceReady( - content::WebContents* guest_web_contents) { +void WaitForHitTestDataOrGuestSurfaceReady(WebContents* guest_web_contents) { DCHECK(static_cast<RenderWidgetHostViewBase*>( guest_web_contents->GetRenderWidgetHostView()) ->IsRenderWidgetHostViewChildFrame());
diff --git a/content/public/test/hit_test_region_observer.h b/content/public/test/hit_test_region_observer.h index f1a147f..e403c57 100644 --- a/content/public/test/hit_test_region_observer.h +++ b/content/public/test/hit_test_region_observer.h
@@ -22,10 +22,8 @@ // When Viz Hit Testing is available, waits until hit test data for // |child_frame| has been submitted, see WaitForHitTestData. Otherwise waits // until the cc::Surface associated with |child_frame| has been activated. -void WaitForHitTestDataOrChildSurfaceReady( - content::RenderFrameHost* child_frame); -void WaitForHitTestDataOrGuestSurfaceReady( - content::WebContents* guest_web_contents); +void WaitForHitTestDataOrChildSurfaceReady(RenderFrameHost* child_frame); +void WaitForHitTestDataOrGuestSurfaceReady(WebContents* guest_web_contents); // TODO(jonross): Move this to components/viz/host/hit_test/ as a standalone // HitTestDataWaiter (is-a HitTestRegionObserver) once Viz HitTesting is on by
diff --git a/content/renderer/media/webrtc/mock_peer_connection_impl.cc b/content/renderer/media/webrtc/mock_peer_connection_impl.cc index d2ff26e..28b9294 100644 --- a/content/renderer/media/webrtc/mock_peer_connection_impl.cc +++ b/content/renderer/media/webrtc/mock_peer_connection_impl.cc
@@ -95,8 +95,6 @@ class MockDtmfSender : public DtmfSenderInterface { public: - explicit MockDtmfSender(AudioTrackInterface* track) - : track_(track), observer_(nullptr), duration_(0), inter_tone_gap_(0) {} void RegisterObserver(DtmfSenderObserverInterface* observer) override { observer_ = observer; } @@ -110,20 +108,15 @@ inter_tone_gap_ = inter_tone_gap; return true; } - const AudioTrackInterface* track() const override { return track_.get(); } std::string tones() const override { return tones_; } int duration() const override { return duration_; } int inter_tone_gap() const override { return inter_tone_gap_; } - protected: - ~MockDtmfSender() override {} - private: - rtc::scoped_refptr<AudioTrackInterface> track_; - DtmfSenderObserverInterface* observer_; + DtmfSenderObserverInterface* observer_ = nullptr; std::string tones_; - int duration_; - int inter_tone_gap_; + int duration_ = 0; + int inter_tone_gap_ = 0; }; FakeRtpSender::FakeRtpSender( @@ -175,8 +168,7 @@ rtc::scoped_refptr<webrtc::DtmfSenderInterface> FakeRtpSender::GetDtmfSender() const { - NOTIMPLEMENTED(); - return nullptr; + return new rtc::RefCountedObject<MockDtmfSender>(); } FakeRtpReceiver::FakeRtpReceiver( @@ -318,14 +310,6 @@ return true; } -rtc::scoped_refptr<DtmfSenderInterface> -MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) { - if (!track) { - return nullptr; - } - return new rtc::RefCountedObject<MockDtmfSender>(track); -} - std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> MockPeerConnectionImpl::GetSenders() const { std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> senders;
diff --git a/content/renderer/media/webrtc/mock_peer_connection_impl.h b/content/renderer/media/webrtc/mock_peer_connection_impl.h index 87d3b22..6905b97 100644 --- a/content/renderer/media/webrtc/mock_peer_connection_impl.h +++ b/content/renderer/media/webrtc/mock_peer_connection_impl.h
@@ -90,8 +90,6 @@ webrtc::MediaStreamTrackInterface* track, std::vector<webrtc::MediaStreamInterface*> streams) override; bool RemoveTrack(webrtc::RtpSenderInterface* sender) override; - rtc::scoped_refptr<webrtc::DtmfSenderInterface> - CreateDtmfSender(webrtc::AudioTrackInterface* track) override; std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> GetSenders() const override; std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> GetReceivers()
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 26d82738..e299127 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -1750,13 +1750,21 @@ "ServiceWorkerContextClient::DispatchCookieChangeEvent", "request_id", request_id); - // TODO(pwnall): Map |cause| to a blink enum. Currently, a cookie overwrite - // shows up as delete + insert. - bool is_cookie_delete = - cause != ::network::mojom::CookieChangeCause::INSERTED; - proxy_->DispatchCookieChangeEvent( - request_id, blink::WebString::FromUTF8(cookie.Name()), - blink::WebString::FromUTF8(cookie.Value()), is_cookie_delete); + // After onion-souping, the conversion below will be done by mojo directly. + DCHECK(!cookie.IsHttpOnly()); + base::Optional<blink::WebCanonicalCookie> web_cookie_opt = + blink::WebCanonicalCookie::Create( + blink::WebString::FromUTF8(cookie.Name()), + blink::WebString::FromUTF8(cookie.Value()), + blink::WebString::FromUTF8(cookie.Domain()), + blink::WebString::FromUTF8(cookie.Path()), cookie.CreationDate(), + cookie.ExpiryDate(), cookie.LastAccessDate(), cookie.IsSecure(), + false /* cookie.IsHttpOnly() */, + static_cast<network::mojom::CookieSameSite>(cookie.SameSite()), + static_cast<network::mojom::CookiePriority>(cookie.Priority())); + DCHECK(web_cookie_opt.has_value()); + + proxy_->DispatchCookieChangeEvent(request_id, web_cookie_opt.value(), cause); } void ServiceWorkerContextClient::Ping(PingCallback callback) {
diff --git a/content/renderer/service_worker/service_worker_context_client_unittest.cc b/content/renderer/service_worker/service_worker_context_client_unittest.cc index d9fbfee..029a3247 100644 --- a/content/renderer/service_worker/service_worker_context_client_unittest.cc +++ b/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -105,10 +105,10 @@ override { NOTREACHED(); } - void DispatchCookieChangeEvent(int event_id, - const blink::WebString& name, - const blink::WebString& value, - bool is_deleted) override { + void DispatchCookieChangeEvent( + int event_id, + const blink::WebCanonicalCookie& cookie, + ::network::mojom::CookieChangeCause change_cause) override { NOTREACHED(); } void DispatchExtendableMessageEvent(
diff --git a/content/renderer/service_worker/service_worker_type_converters.cc b/content/renderer/service_worker/service_worker_type_converters.cc index 3065d0e5..08c6f00 100644 --- a/content/renderer/service_worker/service_worker_type_converters.cc +++ b/content/renderer/service_worker/service_worker_type_converters.cc
@@ -72,15 +72,11 @@ TypeConverter<blink::WebPaymentMethodData, payments::mojom::PaymentMethodDataPtr>:: Convert(const payments::mojom::PaymentMethodDataPtr& input) { + DCHECK(input->supported_methods.size() == 1); + blink::WebPaymentMethodData output; - - output.supported_methods = - blink::WebVector<blink::WebString>(input->supported_methods.size()); - for (size_t i = 0; i < input->supported_methods.size(); i++) { - output.supported_methods[i] = - blink::WebString::FromUTF8(input->supported_methods[i]); - } - + output.supported_method = + blink::WebString::FromUTF8(input->supported_methods[0]); output.stringified_data = blink::WebString::FromUTF8(input->stringified_data); return output; @@ -111,14 +107,12 @@ TypeConverter<blink::WebPaymentDetailsModifier, payments::mojom::PaymentDetailsModifierPtr>:: Convert(const payments::mojom::PaymentDetailsModifierPtr& input) { + DCHECK(input->method_data->supported_methods.size() == 1); + blink::WebPaymentDetailsModifier output; - output.supported_methods = blink::WebVector<blink::WebString>( - input->method_data->supported_methods.size()); - for (size_t i = 0; i < input->method_data->supported_methods.size(); i++) { - output.supported_methods[i] = - blink::WebString::FromUTF8(input->method_data->supported_methods[i]); - } + output.supported_method = + blink::WebString::FromUTF8(input->method_data->supported_methods[0]); output.total = mojo::ConvertTo<blink::WebPaymentItem>(input->total);
diff --git a/content/renderer/service_worker/worker_fetch_context_impl.cc b/content/renderer/service_worker/worker_fetch_context_impl.cc index da6ba12..bc1ebd9 100644 --- a/content/renderer/service_worker/worker_fetch_context_impl.cc +++ b/content/renderer/service_worker/worker_fetch_context_impl.cc
@@ -83,6 +83,10 @@ void SetServiceWorkerURLLoaderFactory( network::mojom::URLLoaderFactoryPtr service_worker_loader_factory) { + if (!service_worker_loader_factory) { + service_worker_loader_factory_ = nullptr; + return; + } service_worker_loader_factory_ = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>( std::move(service_worker_loader_factory)); @@ -368,8 +372,8 @@ DCHECK(ServiceWorkerUtils::IsServicificationEnabled()); if (!web_loader_factory_) return; - if (IsControlledByServiceWorker() == - blink::mojom::ControllerServiceWorkerMode::kNoController) { + if (IsControlledByServiceWorker() != + blink::mojom::ControllerServiceWorkerMode::kControlled) { web_loader_factory_->SetServiceWorkerURLLoaderFactory(nullptr); return; }
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 4c8ea31..7db63e0 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -306,6 +306,7 @@ "//ui/gfx/ipc/geometry", "//ui/gfx/ipc/skia", "//ui/gl", + "//ui/platform_window", "//url", "//v8", ]
diff --git a/content/shell/DEPS b/content/shell/DEPS index 1018b37..bb03394e1 100644 --- a/content/shell/DEPS +++ b/content/shell/DEPS
@@ -26,6 +26,7 @@ # The content_shell for aura must work with the views and aura "+ui/aura", + "+ui/platform_window", "+ui/views", # Content Shell can depend on more components than content/, since:
diff --git a/content/shell/app/blink_test_platform_support_android.cc b/content/shell/app/blink_test_platform_support_android.cc index fb6dadc..2b37988 100644 --- a/content/shell/app/blink_test_platform_support_android.cc +++ b/content/shell/app/blink_test_platform_support_android.cc
@@ -5,7 +5,7 @@ #include "content/shell/app/blink_test_platform_support.h" #include "skia/ext/fontmgr_default_android.h" -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontMgr_android.h" namespace {
diff --git a/content/shell/app/blink_test_platform_support_fuchsia.cc b/content/shell/app/blink_test_platform_support_fuchsia.cc index 1852401..650d504a 100644 --- a/content/shell/app/blink_test_platform_support_fuchsia.cc +++ b/content/shell/app/blink_test_platform_support_fuchsia.cc
@@ -5,7 +5,7 @@ #include "content/shell/app/blink_test_platform_support.h" #include "skia/ext/fontmgr_default_android.h" -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontMgr_android.h" namespace content {
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 94d143f..2c9aae28 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -824,9 +824,8 @@ devtools_protocol_test_bindings_.reset(); WebContentsObserver::Observe(nullptr); if (test_phase_ != BETWEEN_TESTS) { + // CloseAllWindows will also signal the main message loop to exit. Shell::CloseAllWindows(); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated()); test_phase_ = CLEAN_UP; } else if (main_window_) { main_window_->Close(); @@ -1192,14 +1191,14 @@ } base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated()); + FROM_HERE, base::BindOnce(&Shell::QuitMainMessageLoopForTesting)); } void BlinkTestController::OnLeakDetectionDone( const LeakDetector::LeakDetectionReport& report) { if (!report.leaked) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated()); + FROM_HERE, base::BindOnce(&Shell::QuitMainMessageLoopForTesting)); return; }
diff --git a/content/shell/browser/layout_test/layout_test_browser_main.cc b/content/shell/browser/layout_test/layout_test_browser_main.cc index eba1790..675696f2 100644 --- a/content/shell/browser/layout_test/layout_test_browser_main.cc +++ b/content/shell/browser/layout_test/layout_test_browser_main.cc
@@ -98,8 +98,9 @@ } } if (!ran_at_least_once) { + // CloseAllWindows will cause the |main_runner| loop to quit. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated()); + FROM_HERE, base::BindOnce(&content::Shell::CloseAllWindows)); main_runner->Run(); } @@ -149,9 +150,8 @@ if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kCheckLayoutTestSysDeps)) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated()); + FROM_HERE, base::BindOnce(&content::Shell::CloseAllWindows)); main_runner->Run(); - content::Shell::CloseAllWindows(); main_runner->Shutdown(); return 0; }
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc index 8abb0ee..4964305 100644 --- a/content/shell/browser/shell.cc +++ b/content/shell/browser/shell.cc
@@ -6,6 +6,10 @@ #include <stddef.h> +#include <map> +#include <string> +#include <utility> + #include "base/command_line.h" #include "base/location.h" #include "base/macros.h" @@ -170,6 +174,11 @@ // Pump the message loop to allow window teardown tasks to run. base::RunLoop().RunUntilIdle(); + // If there were no windows open then the message loop quit closure will + // not have been run. + if (*g_quit_main_message_loop) + std::move(*g_quit_main_message_loop).Run(); + PlatformExit(); } @@ -177,6 +186,10 @@ *g_quit_main_message_loop = std::move(quit_closure); } +void Shell::QuitMainMessageLoopForTesting() { + std::move(*g_quit_main_message_loop).Run(); +} + void Shell::SetShellCreatedCallback( base::Callback<void(Shell*)> shell_created_callback) { DCHECK(shell_created_callback_.is_null()); @@ -489,12 +502,12 @@ blink::WebDisplayMode Shell::GetDisplayMode( const WebContents* web_contents) const { - // TODO : should return blink::WebDisplayModeFullscreen wherever user puts - // a browser window into fullscreen (not only in case of renderer-initiated - // fullscreen mode): crbug.com/476874. - return IsFullscreenForTabOrPending(web_contents) - ? blink::kWebDisplayModeFullscreen - : blink::kWebDisplayModeBrowser; + // TODO: should return blink::WebDisplayModeFullscreen wherever user puts + // a browser window into fullscreen (not only in case of renderer-initiated + // fullscreen mode): crbug.com/476874. + return IsFullscreenForTabOrPending(web_contents) + ? blink::kWebDisplayModeFullscreen + : blink::kWebDisplayModeBrowser; } void Shell::RequestToLockMouse(WebContents* web_contents, @@ -546,8 +559,10 @@ return switches::IsRunWebTestsSwitchPresent(); } -void Shell::RendererUnresponsive(WebContents* source, - RenderWidgetHost* render_widget_host) { +void Shell::RendererUnresponsive( + WebContents* source, + RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { BlinkTestController* blink_test_controller = BlinkTestController::Get(); if (blink_test_controller && switches::IsRunWebTestsSwitchPresent()) blink_test_controller->RendererUnresponsive();
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h index 76d8e90..3c20aa8 100644 --- a/content/shell/browser/shell.h +++ b/content/shell/browser/shell.h
@@ -7,6 +7,7 @@ #include <stdint.h> #include <memory> +#include <string> #include <vector> #include "base/callback_forward.h" @@ -112,13 +113,19 @@ // Returns the currently open windows. static std::vector<Shell*>& windows() { return windows_; } - // Closes all windows and returns. + // Closes all windows, pumps teardown tasks, then returns. The main message + // loop will be signalled to quit, before the call returns. static void CloseAllWindows(); // Stores the supplied |quit_closure|, to be run when the last Shell instance // is destroyed. static void SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure); + // Used by the BlinkTestController to stop the message loop before closing all + // windows, for specific tests. Fails if called after the message loop has + // already been signalled to quit. + static void QuitMainMessageLoopForTesting(); + // Used for content_browsertests. Called once. static void SetShellCreatedCallback( base::Callback<void(Shell*)> shell_created_callback); @@ -178,8 +185,10 @@ const base::string16& message, int32_t line_no, const base::string16& source_id) override; - void RendererUnresponsive(WebContents* source, - RenderWidgetHost* render_widget_host) override; + void RendererUnresponsive( + WebContents* source, + RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) override; void ActivateContents(WebContents* contents) override; bool ShouldAllowRunningInsecureContent(content::WebContents* web_contents, bool allowed_per_prefs,
diff --git a/content/shell/browser/shell_platform_data_aura.cc b/content/shell/browser/shell_platform_data_aura.cc index be1d936..eb7c13c 100644 --- a/content/shell/browser/shell_platform_data_aura.cc +++ b/content/shell/browser/shell_platform_data_aura.cc
@@ -16,6 +16,7 @@ #include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/input_method_factory.h" +#include "ui/platform_window/platform_window_init_properties.h" #include "ui/wm/core/default_activation_client.h" namespace content { @@ -61,7 +62,8 @@ ShellPlatformDataAura::ShellPlatformDataAura(const gfx::Size& initial_size) { CHECK(aura::Env::GetInstance()); - host_.reset(aura::WindowTreeHost::Create(gfx::Rect(initial_size))); + host_ = aura::WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(initial_size)}); host_->InitHost(); host_->window()->Show(); host_->window()->SetLayoutManager(new FillLayout(host_->window()));
diff --git a/content/test/data/payments/payment_app.js b/content/test/data/payments/payment_app.js index 3bb1e56..a382d34a 100644 --- a/content/test/data/payments/payment_app.js +++ b/content/test/data/payments/payment_app.js
@@ -24,12 +24,10 @@ e.respondWith(new Promise(resolve => { e.methodData.forEach(methodData => { - methodData.supportedMethods.forEach(method => { - if (method == 'basic-card') { - resolve(true); - return; - } - }); + if (methodData.supportedMethods == 'basic-card') { + resolve(true); + return; + } }); })); });
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index cbe1a792..0c1001c9 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -208,7 +208,7 @@ ['win', ('nvidia', 0x1cb3), 'opengl'], bug=715001) self.Fail('conformance/textures/misc/texture-size.html', ['win', ('nvidia', 0x1cb3), 'opengl'], bug=703779) - self.Flaky('conformance2/rendering/attrib-type-match.html', + self.Fail('conformance2/rendering/attrib-type-match.html', ['win', 'nvidia', 'opengl'], bug=782254) self.Fail('deqp/functional/gles3/shaderpackingfunction.html', ['win', 'nvidia', 'opengl'], bug=795030)
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index 59c271d..b6816fd 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -68,8 +68,8 @@ #elif defined(OS_WIN) #include "content/child/font_warmup_win.h" #include "third_party/blink/public/web/win/web_font_rendering.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkRefCnt.h" -#include "third_party/skia/include/ports/SkFontMgr.h" #include "third_party/skia/include/ports/SkTypeface_win.h" #include "ui/gfx/win/direct_write.h" #endif
diff --git a/device/bluetooth/cast/bluetooth_device_cast.cc b/device/bluetooth/cast/bluetooth_device_cast.cc index 32ccb2a..4fd0dd0 100644 --- a/device/bluetooth/cast/bluetooth_device_cast.cc +++ b/device/bluetooth/cast/bluetooth_device_cast.cc
@@ -352,12 +352,7 @@ } void BluetoothDeviceCast::DisconnectGatt() { - DVLOG(2) << __func__ << " pending:" << pending_disconnect_; - if (pending_disconnect_) - return; - pending_disconnect_ = true; - remote_device_->Disconnect(base::BindOnce(&BluetoothDeviceCast::OnDisconnect, - weak_factory_.GetWeakPtr())); + // The device is intentionally not disconnected. } void BluetoothDeviceCast::OnConnect(bool success) { @@ -367,11 +362,4 @@ DidFailToConnectGatt(ERROR_FAILED); } -void BluetoothDeviceCast::OnDisconnect(bool success) { - DVLOG(2) << __func__ << " success:" << success; - pending_disconnect_ = false; - if (!success) - LOG(ERROR) << "Request to DisconnectGatt() failed!"; -} - } // namespace device
diff --git a/device/bluetooth/cast/bluetooth_device_cast.h b/device/bluetooth/cast/bluetooth_device_cast.h index 0f212b1..5adb9144 100644 --- a/device/bluetooth/cast/bluetooth_device_cast.h +++ b/device/bluetooth/cast/bluetooth_device_cast.h
@@ -122,9 +122,6 @@ // Called back from connect requests generated from CreateGattConnectionImpl. void OnConnect(bool success); - // Called back from disconnect requests. - void OnDisconnect(bool success); - // Called in response to GetServices void OnGetServices( std::vector<scoped_refptr<chromecast::bluetooth::RemoteService>> @@ -132,7 +129,6 @@ bool connected_; bool pending_connect_ = false; - bool pending_disconnect_ = false; const scoped_refptr<chromecast::bluetooth::RemoteDevice> remote_device_; const std::string address_;
diff --git a/docs/fuchsia_build_instructions.md b/docs/fuchsia_build_instructions.md index 3310320..aa5af39 100644 --- a/docs/fuchsia_build_instructions.md +++ b/docs/fuchsia_build_instructions.md
@@ -125,6 +125,6 @@ A useful alias (for "Build And Run Filtered") is: ```shell -alias barf='ninja -C out/fuchsia base_unittests -j1000 && out/fuchsia/bin/run_base_unittests --test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter' +alias barf='ninja -C out/fuchsia net_unittests -j1000 && out/fuchsia/bin/run_net_unittests --test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter' ``` to build and run only the tests that are not excluded/known-failing on the bot.
diff --git a/docs/speed/apk_size_regressions.md b/docs/speed/apk_size_regressions.md index aae78d8..f66429ab 100644 --- a/docs/speed/apk_size_regressions.md +++ b/docs/speed/apk_size_regressions.md
@@ -168,7 +168,7 @@ ## Step 1: Check work queue daily - * Bugs requiring sheriffs to take a look at are labeled `Performance-Sheriff` and `Performance-Size`. + * Bugs requiring sheriffs to take a look at are labeled `Performance-Sheriff` and `Performance-Size` [here](https://bugs.chromium.org/p/chromium/issues/list?q=label:Performance-Sheriff%20label:Performance-Size&sort=-modified). * After resolving the bug by finding an owner or debugging or commenting, remove the `Performance-Sheriff` label. ## Step 2: Check alerts regularly
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 0f93841..716f3f07 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -671,7 +671,8 @@ void WebViewGuest::RendererUnresponsive( WebContents* source, - content::RenderWidgetHost* render_widget_host) { + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { auto args = std::make_unique<base::DictionaryValue>(); args->SetInteger(webview::kProcessId, render_widget_host->GetProcess()->GetID());
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index 08d3a047..27f819d 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -7,6 +7,9 @@ #include <stdint.h> +#include <map> +#include <memory> +#include <string> #include <vector> #include "base/macros.h" @@ -214,7 +217,8 @@ content::RenderWidgetHost* render_widget_host) final; void RendererUnresponsive( content::WebContents* source, - content::RenderWidgetHost* render_widget_host) final; + content::RenderWidgetHost* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) final; void RequestMediaAccessPermission( content::WebContents* source, const content::MediaStreamRequest& request,
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index 31cc189..00b549d 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -437,11 +437,11 @@ const base::Optional<std::string>& error) { DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence()); if (error) { - ReportUnpackingError(*error); + ReportUnpackExtensionFailed(*error); return; } if (!manifest || !manifest->is_dict()) { - ReportUnpackingError(manifest_errors::kInvalidManifest); + ReportUnpackExtensionFailed(manifest_errors::kInvalidManifest); return; } @@ -454,13 +454,13 @@ Extension::Create(extension_root_, location_, *manifest_dict, creation_flags_, extension_id_, &error_msg)); if (!extension) { - ReportUnpackingError(error_msg); + ReportUnpackExtensionFailed(error_msg); return; } std::vector<InstallWarning> warnings; if (!file_util::ValidateExtension(extension.get(), &error_msg, &warnings)) { - ReportUnpackingError(error_msg); + ReportUnpackExtensionFailed(error_msg); return; } extension->AddInstallWarnings(warnings); @@ -702,12 +702,13 @@ DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence()); if (error) { - ReportUnpackingError(*error); + ReportUnpackExtensionFailed(*error); return; } if (json_ruleset && !json_ruleset->is_list()) { - ReportUnpackingError(manifest_errors::kDeclarativeNetRequestListNotPassed); + ReportUnpackExtensionFailed( + manifest_errors::kDeclarativeNetRequestListNotPassed); return; } @@ -776,17 +777,11 @@ return json_parser_ptr_.get(); } -void SandboxedUnpacker::ReportUnpackingError(base::StringPiece error) { - unpacker_io_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&SandboxedUnpacker::UnpackExtensionFailed, this, - base::UTF8ToUTF16(error))); -} - -void SandboxedUnpacker::UnpackExtensionFailed(const base::string16& error) { +void SandboxedUnpacker::ReportUnpackExtensionFailed(base::StringPiece error) { DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence()); - ReportFailure( - SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED, - l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error)); + ReportFailure(SandboxedUnpackerFailureReason::UNPACKER_CLIENT_FAILED, + l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, + base::UTF8ToUTF16(error))); } base::string16 SandboxedUnpacker::FailureReasonToString16(
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h index 132ff75..1744f76 100644 --- a/extensions/browser/sandboxed_unpacker.h +++ b/extensions/browser/sandboxed_unpacker.h
@@ -62,6 +62,9 @@ // dnr_ruleset_checksum - Checksum for the indexed ruleset corresponding to // the Declarative Net Request API. Optional since it's only valid for // extensions which provide a declarative ruleset. + // + // Note: OnUnpackSuccess/Failure may be called either synchronously or + // asynchronously from SandboxedUnpacker::StartWithCrx/Directory. virtual void OnUnpackSuccess( const base::FilePath& temp_dir, const base::FilePath& extension_root, @@ -163,9 +166,9 @@ const base::Optional<std::string>& error); void UnpackExtensionSucceeded( std::unique_ptr<base::DictionaryValue> manifest); - void UnpackExtensionFailed(const base::string16& error); - void ReportUnpackingError(base::StringPiece error); + // Helper which calls ReportFailure. + void ReportUnpackExtensionFailed(base::StringPiece error); void ImageSanitizationDone(std::unique_ptr<base::DictionaryValue> manifest, ImageSanitizer::Status status,
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn index d5eb72f..b46aaa83 100644 --- a/extensions/shell/BUILD.gn +++ b/extensions/shell/BUILD.gn
@@ -198,6 +198,7 @@ "browser/shell_native_app_window_aura.h", ] deps += [ + "//ui/platform_window", "//ui/wm", "//ui/wm/public", ] @@ -341,6 +342,7 @@ "//google_apis", "//testing/gtest", "//ui/gl:test_support", + "//ui/platform_window", ] data_deps = [
diff --git a/extensions/shell/browser/DEPS b/extensions/shell/browser/DEPS index 1d151d0..ac34117 100644 --- a/extensions/shell/browser/DEPS +++ b/extensions/shell/browser/DEPS
@@ -41,6 +41,7 @@ "+ui/chromeos", "+ui/display", "+ui/ozone/public", + "+ui/platform_window", "+ui/views", "+ui/wm",
diff --git a/extensions/shell/browser/root_window_controller.cc b/extensions/shell/browser/root_window_controller.cc index 9eee4a9..3da1e72b 100644 --- a/extensions/shell/browser/root_window_controller.cc +++ b/extensions/shell/browser/root_window_controller.cc
@@ -15,6 +15,7 @@ #include "ui/display/display.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +#include "ui/platform_window/platform_window_init_properties.h" #include "ui/wm/core/default_screen_position_client.h" namespace extensions { @@ -102,8 +103,9 @@ screen_position_client_(std::make_unique<ScreenPositionClient>()) { DCHECK(desktop_delegate_); DCHECK(browser_context_); - host_.reset(aura::WindowTreeHost::Create(bounds)); + host_ = + aura::WindowTreeHost::Create(ui::PlatformWindowInitProperties{bounds}); host_->InitHost(); host_->window()->Show();
diff --git a/extensions/shell/browser/shell_screen_unittest.cc b/extensions/shell/browser/shell_screen_unittest.cc index b3f31bd..678271f 100644 --- a/extensions/shell/browser/shell_screen_unittest.cc +++ b/extensions/shell/browser/shell_screen_unittest.cc
@@ -13,6 +13,7 @@ #include "ui/display/display.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace extensions { @@ -30,8 +31,9 @@ EXPECT_EQ("640x480", screen.GetPrimaryDisplay().size().ToString()); // Tests that reshaping the host window reshapes the display. - std::unique_ptr<aura::WindowTreeHost> host(aura::WindowTreeHost::Create( - gfx::Rect(screen.GetPrimaryDisplay().GetSizeInPixel()))); + std::unique_ptr<aura::WindowTreeHost> host = + aura::WindowTreeHost::Create(ui::PlatformWindowInitProperties{ + gfx::Rect(screen.GetPrimaryDisplay().GetSizeInPixel())}); host->AddObserver(&screen); host->InitHost(); EXPECT_TRUE(host->window());
diff --git a/google_apis/google_api_keys.cc b/google_apis/google_api_keys.cc index 2e8437e..d05b9ef 100644 --- a/google_apis/google_api_keys.cc +++ b/google_apis/google_api_keys.cc
@@ -300,19 +300,8 @@ static base::LazyInstance<APIKeyCache>::DestructorAtExit g_api_key_cache = LAZY_INSTANCE_INITIALIZER; -bool HasKeysConfigured() { - if (GetAPIKey() == DUMMY_API_TOKEN) - return false; - - for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) { - OAuth2Client client = static_cast<OAuth2Client>(client_id); - if (GetOAuth2ClientID(client) == DUMMY_API_TOKEN || - GetOAuth2ClientSecret(client) == DUMMY_API_TOKEN) { - return false; - } - } - - return true; +bool HasAPIKeyConfigured() { + return GetAPIKey() != DUMMY_API_TOKEN; } std::string GetAPIKey() { @@ -329,6 +318,18 @@ } #endif +bool HasOAuthClientConfigured() { + for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) { + OAuth2Client client = static_cast<OAuth2Client>(client_id); + if (GetOAuth2ClientID(client) == DUMMY_API_TOKEN || + GetOAuth2ClientSecret(client) == DUMMY_API_TOKEN) { + return false; + } + } + + return true; +} + std::string GetOAuth2ClientID(OAuth2Client client) { return g_api_key_cache.Get().GetClientID(client); }
diff --git a/google_apis/google_api_keys.h b/google_apis/google_api_keys.h index 20d896e..d4979fe9 100644 --- a/google_apis/google_api_keys.h +++ b/google_apis/google_api_keys.h
@@ -60,8 +60,8 @@ extern const char kAPIKeysDevelopersHowToURL[]; -// Returns true if no dummy API keys or OAuth2 tokens are set. -bool HasKeysConfigured(); +// Returns true if no dummy API key is set. +bool HasAPIKeyConfigured(); // Retrieves the API key, a.k.a. developer key, or a dummy string // if not set. @@ -89,6 +89,9 @@ CLIENT_NUM_ITEMS // Must be last item. }; +// Returns true if no dummy OAuth2 client ID and secret are set. +bool HasOAuthClientConfigured(); + // Retrieves the OAuth2 client ID for the specified client, or the // empty string if not set. //
diff --git a/google_apis/google_api_keys_mac_unittest.mm b/google_apis/google_api_keys_mac_unittest.mm index 90115c8..ae0d4c1 100644 --- a/google_apis/google_api_keys_mac_unittest.mm +++ b/google_apis/google_api_keys_mac_unittest.mm
@@ -87,7 +87,8 @@ [[[mock_bundle stub] andReturn:nil] objectForInfoDictionaryKey:[OCMArg any]]; base::mac::SetOverrideFrameworkBundle(mock_bundle); - EXPECT_TRUE(testcase::HasKeysConfigured()); + EXPECT_TRUE(testcase::HasAPIKeyConfigured()); + EXPECT_TRUE(testcase::HasOAuthClientConfigured()); // Once the keys have been configured, the bundle isn't used anymore. base::mac::SetOverrideFrameworkBundle(nil);
diff --git a/google_apis/google_api_keys_unittest.cc b/google_apis/google_api_keys_unittest.cc index 1b0515f..d334db5 100644 --- a/google_apis/google_api_keys_unittest.cc +++ b/google_apis/google_api_keys_unittest.cc
@@ -123,7 +123,8 @@ TEST_F(GoogleAPIKeysTest, OfficialKeys) { namespace testcase = official_build::google_apis; - EXPECT_TRUE(testcase::HasKeysConfigured()); + EXPECT_TRUE(testcase::HasAPIKeyConfigured()); + EXPECT_TRUE(testcase::HasOAuthClientConfigured()); std::string api_key = testcase::g_api_key_cache.Get().api_key(); std::string id_main = testcase::g_api_key_cache.Get().GetClientID( @@ -220,7 +221,8 @@ TEST_F(GoogleAPIKeysTest, DefaultKeys) { namespace testcase = default_keys::google_apis; - EXPECT_FALSE(testcase::HasKeysConfigured()); + EXPECT_FALSE(testcase::HasAPIKeyConfigured()); + EXPECT_FALSE(testcase::HasOAuthClientConfigured()); std::string api_key = testcase::g_api_key_cache.Get().api_key(); std::string id_main = testcase::g_api_key_cache.Get().GetClientID( @@ -286,7 +288,8 @@ TEST_F(GoogleAPIKeysTest, OverrideSomeKeys) { namespace testcase = override_some_keys::google_apis; - EXPECT_FALSE(testcase::HasKeysConfigured()); + EXPECT_TRUE(testcase::HasAPIKeyConfigured()); + EXPECT_FALSE(testcase::HasOAuthClientConfigured()); std::string api_key = testcase::g_api_key_cache.Get().api_key(); std::string id_main = testcase::g_api_key_cache.Get().GetClientID( @@ -359,7 +362,8 @@ TEST_F(GoogleAPIKeysTest, OverrideAllKeys) { namespace testcase = override_all_keys::google_apis; - EXPECT_TRUE(testcase::HasKeysConfigured()); + EXPECT_TRUE(testcase::HasAPIKeyConfigured()); + EXPECT_TRUE(testcase::HasOAuthClientConfigured()); std::string api_key = testcase::g_api_key_cache.Get().api_key(); std::string id_main = testcase::g_api_key_cache.Get().GetClientID( @@ -446,7 +450,8 @@ env->SetVar("GOOGLE_CLIENT_SECRET_REMOTING", "env-SECRET_REMOTING"); env->SetVar("GOOGLE_CLIENT_SECRET_REMOTING_HOST", "env-SECRET_REMOTING_HOST"); - EXPECT_TRUE(testcase::HasKeysConfigured()); + EXPECT_TRUE(testcase::HasAPIKeyConfigured()); + EXPECT_TRUE(testcase::HasOAuthClientConfigured()); // It's important that the first call to Get() only happen after the // environment variables have been set. @@ -550,7 +555,8 @@ testcase::SetOAuth2ClientSecret(testcase::CLIENT_REMOTING_HOST, secret_remoting_host); - EXPECT_TRUE(testcase::HasKeysConfigured()); + EXPECT_TRUE(testcase::HasAPIKeyConfigured()); + EXPECT_TRUE(testcase::HasOAuthClientConfigured()); EXPECT_EQ(api_key, testcase::GetAPIKey());
diff --git a/gpu/vulkan/BUILD.gn b/gpu/vulkan/BUILD.gn index 383aedb..699522e 100644 --- a/gpu/vulkan/BUILD.gn +++ b/gpu/vulkan/BUILD.gn
@@ -55,10 +55,6 @@ defines = [ "VULKAN_IMPLEMENTATION" ] - if (use_x11) { - defines += [ "VK_USE_PLATFORM_XLIB_KHR" ] - } - all_dependent_configs = [ "//third_party/vulkan:vulkan_config" ] deps = [
diff --git a/gpu/vulkan/generate_bindings.py b/gpu/vulkan/generate_bindings.py index a3b228c..41337de 100755 --- a/gpu/vulkan/generate_bindings.py +++ b/gpu/vulkan/generate_bindings.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env_python +#!/usr/bin/env python # 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. @@ -123,12 +123,6 @@ PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = nullptr; PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = nullptr; PFN_vkDestroyInstance vkDestroyInstance = nullptr; -#if defined(VK_USE_PLATFORM_XLIB_KHR) - PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = nullptr; -#endif // defined(VK_USE_PLATFORM_XLIB_KHR) -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = nullptr; -#endif // defined(VK_USE_PLATFORM_ANDROID_KHR) // Physical Device functions PFN_vkGetPhysicalDeviceQueueFamilyProperties @@ -142,10 +136,6 @@ vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr; PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr; -#if defined(VK_USE_PLATFORM_XLIB_KHR) - PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR - vkGetPhysicalDeviceXlibPresentationSupportKHR = nullptr; -#endif // defined(VK_USE_PLATFORM_XLIB_KHR) // Device functions """)
diff --git a/gpu/vulkan/init/BUILD.gn b/gpu/vulkan/init/BUILD.gn index 0c1b9ed..568f57b 100644 --- a/gpu/vulkan/init/BUILD.gn +++ b/gpu/vulkan/init/BUILD.gn
@@ -22,10 +22,11 @@ "//gpu/vulkan", ] + deps = [] if (use_x11) { - public_deps += [ "//gpu/vulkan/x" ] + deps += [ "//gpu/vulkan/x" ] } if (use_ozone) { - public_deps += [ "//ui/ozone" ] + deps += [ "//ui/ozone" ] } }
diff --git a/gpu/vulkan/init/vulkan_factory.h b/gpu/vulkan/init/vulkan_factory.h index 4fc7d92..6aaa4b0 100644 --- a/gpu/vulkan/init/vulkan_factory.h +++ b/gpu/vulkan/init/vulkan_factory.h
@@ -8,11 +8,10 @@ #include <memory> #include "base/component_export.h" +#include "gpu/vulkan/vulkan_implementation.h" namespace gpu { -class VulkanImplementation; - COMPONENT_EXPORT(VULKAN_INIT) std::unique_ptr<VulkanImplementation> CreateVulkanImplementation();
diff --git a/gpu/vulkan/vulkan_function_pointers.h b/gpu/vulkan/vulkan_function_pointers.h index 649a274..c028b670 100644 --- a/gpu/vulkan/vulkan_function_pointers.h +++ b/gpu/vulkan/vulkan_function_pointers.h
@@ -44,12 +44,6 @@ PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = nullptr; PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = nullptr; PFN_vkDestroyInstance vkDestroyInstance = nullptr; -#if defined(VK_USE_PLATFORM_XLIB_KHR) - PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = nullptr; -#endif // defined(VK_USE_PLATFORM_XLIB_KHR) -#if defined(VK_USE_PLATFORM_ANDROID_KHR) - PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = nullptr; -#endif // defined(VK_USE_PLATFORM_ANDROID_KHR) // Physical Device functions PFN_vkGetPhysicalDeviceQueueFamilyProperties @@ -63,10 +57,6 @@ vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr; PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr; -#if defined(VK_USE_PLATFORM_XLIB_KHR) - PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR - vkGetPhysicalDeviceXlibPresentationSupportKHR = nullptr; -#endif // defined(VK_USE_PLATFORM_XLIB_KHR) // Device functions PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR = nullptr;
diff --git a/gpu/vulkan/vulkan_implementation_android.cc b/gpu/vulkan/vulkan_implementation_android.cc index a2514c94..885a051 100644 --- a/gpu/vulkan/vulkan_implementation_android.cc +++ b/gpu/vulkan/vulkan_implementation_android.cc
@@ -30,20 +30,15 @@ if (!vulkan_instance_.Initialize(required_extensions)) { vulkan_instance_.Destroy(); - base::UnloadNativeLibrary(vulkan_function_pointers->vulkan_loader_library_); - vulkan_function_pointers->vulkan_loader_library_ = nullptr; return false; } // Initialize platform function pointers - vulkan_function_pointers->vkCreateAndroidSurfaceKHR = - reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>( - vulkan_function_pointers->vkGetInstanceProcAddr( - vulkan_instance_.vk_instance(), "vkCreateAndroidSurfaceKHR")); - if (!vulkan_function_pointers->vkCreateAndroidSurfaceKHR) { + vkCreateAndroidSurfaceKHR_ = reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>( + vulkan_function_pointers->vkGetInstanceProcAddr( + vulkan_instance_.vk_instance(), "vkCreateAndroidSurfaceKHR")); + if (!vkCreateAndroidSurfaceKHR_) { vulkan_instance_.Destroy(); - base::UnloadNativeLibrary(vulkan_function_pointers->vulkan_loader_library_); - vulkan_function_pointers->vulkan_loader_library_ = nullptr; return false; }
diff --git a/gpu/vulkan/vulkan_implementation_android.h b/gpu/vulkan/vulkan_implementation_android.h index 14f6a0e..541431c 100644 --- a/gpu/vulkan/vulkan_implementation_android.h +++ b/gpu/vulkan/vulkan_implementation_android.h
@@ -32,6 +32,8 @@ private: VulkanInstance vulkan_instance_; + PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(VulkanImplementationAndroid); };
diff --git a/gpu/vulkan/vulkan_instance.cc b/gpu/vulkan/vulkan_instance.cc index c52c682..16f6421 100644 --- a/gpu/vulkan/vulkan_instance.cc +++ b/gpu/vulkan/vulkan_instance.cc
@@ -289,8 +289,11 @@ vkDestroyDebugReportCallbackEXT(vk_instance_, warning_callback_, nullptr); } #endif - vulkan_function_pointers->vkDestroyInstance(vk_instance_, nullptr); - base::UnloadNativeLibrary(vulkan_function_pointers->vulkan_loader_library_); + if (vk_instance_ != VK_NULL_HANDLE) { + vulkan_function_pointers->vkDestroyInstance(vk_instance_, nullptr); + } + if (vulkan_function_pointers->vulkan_loader_library_) + base::UnloadNativeLibrary(vulkan_function_pointers->vulkan_loader_library_); vulkan_function_pointers->vulkan_loader_library_ = nullptr; vk_instance_ = VK_NULL_HANDLE; }
diff --git a/gpu/vulkan/x/BUILD.gn b/gpu/vulkan/x/BUILD.gn index c5347d4e..119e84c 100644 --- a/gpu/vulkan/x/BUILD.gn +++ b/gpu/vulkan/x/BUILD.gn
@@ -8,6 +8,10 @@ assert(enable_vulkan) assert(use_x11 || use_ozone) +config("vulkan_x11") { + defines = [ "VK_USE_PLATFORM_XLIB_KHR" ] +} + component("x") { output_name = "vulkan_x11" @@ -16,11 +20,9 @@ "vulkan_implementation_x11.h", ] - defines = [ - "IS_VULKAN_X11_IMPL", - "VK_USE_PLATFORM_XLIB_KHR", - ] + defines = [ "IS_VULKAN_X11_IMPL" ] + public_configs = [ ":vulkan_x11" ] configs += [ "//build/config/linux:x11" ] deps = [
diff --git a/gpu/vulkan/x/vulkan_implementation_x11.cc b/gpu/vulkan/x/vulkan_implementation_x11.cc index 7d8f1378..8ab7297 100644 --- a/gpu/vulkan/x/vulkan_implementation_x11.cc +++ b/gpu/vulkan/x/vulkan_implementation_x11.cc
@@ -35,33 +35,25 @@ if (!vulkan_instance_.Initialize(required_extensions)) { vulkan_instance_.Destroy(); - base::UnloadNativeLibrary(vulkan_function_pointers->vulkan_loader_library_); - vulkan_function_pointers->vulkan_loader_library_ = nullptr; return false; } // Initialize platform function pointers - vulkan_function_pointers->vkGetPhysicalDeviceXlibPresentationSupportKHR = + vkGetPhysicalDeviceXlibPresentationSupportKHR_ = reinterpret_cast<PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR>( vulkan_function_pointers->vkGetInstanceProcAddr( vulkan_instance_.vk_instance(), "vkGetPhysicalDeviceXlibPresentationSupportKHR")); - if (!vulkan_function_pointers - ->vkGetPhysicalDeviceXlibPresentationSupportKHR) { + if (!vkGetPhysicalDeviceXlibPresentationSupportKHR_) { vulkan_instance_.Destroy(); - base::UnloadNativeLibrary(vulkan_function_pointers->vulkan_loader_library_); - vulkan_function_pointers->vulkan_loader_library_ = nullptr; return false; } - vulkan_function_pointers->vkCreateXlibSurfaceKHR = - reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>( - vulkan_function_pointers->vkGetInstanceProcAddr( - vulkan_instance_.vk_instance(), "vkCreateXlibSurfaceKHR")); - if (!vulkan_function_pointers->vkCreateXlibSurfaceKHR) { + vkCreateXlibSurfaceKHR_ = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>( + vulkan_function_pointers->vkGetInstanceProcAddr( + vulkan_instance_.vk_instance(), "vkCreateXlibSurfaceKHR")); + if (!vkCreateXlibSurfaceKHR_) { vulkan_instance_.Destroy(); - base::UnloadNativeLibrary(vulkan_function_pointers->vulkan_loader_library_); - vulkan_function_pointers->vulkan_loader_library_ = nullptr; return false; } @@ -74,15 +66,12 @@ std::unique_ptr<VulkanSurface> VulkanImplementationX11::CreateViewSurface( gfx::AcceleratedWidget window) { - VulkanFunctionPointers* vulkan_function_pointers = - gpu::GetVulkanFunctionPointers(); - VkSurfaceKHR surface; VkXlibSurfaceCreateInfoKHR surface_create_info = {}; surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; surface_create_info.dpy = x_display_; surface_create_info.window = window; - VkResult result = vulkan_function_pointers->vkCreateXlibSurfaceKHR( + VkResult result = vkCreateXlibSurfaceKHR_( GetVulkanInstance(), &surface_create_info, nullptr, &surface); if (VK_SUCCESS != result) { DLOG(ERROR) << "vkCreateXlibSurfaceKHR() failed: " << result; @@ -96,14 +85,10 @@ VkPhysicalDevice device, const std::vector<VkQueueFamilyProperties>& queue_family_properties, uint32_t queue_family_index) { - VulkanFunctionPointers* vulkan_function_pointers = - gpu::GetVulkanFunctionPointers(); - - return vulkan_function_pointers - ->vkGetPhysicalDeviceXlibPresentationSupportKHR( - device, queue_family_index, x_display_, - XVisualIDFromVisual( - DefaultVisual(x_display_, DefaultScreen(x_display_)))); + return vkGetPhysicalDeviceXlibPresentationSupportKHR_( + device, queue_family_index, x_display_, + XVisualIDFromVisual( + DefaultVisual(x_display_, DefaultScreen(x_display_)))); } } // namespace gpu
diff --git a/gpu/vulkan/x/vulkan_implementation_x11.h b/gpu/vulkan/x/vulkan_implementation_x11.h index e51145d..4d7798d 100644 --- a/gpu/vulkan/x/vulkan_implementation_x11.h +++ b/gpu/vulkan/x/vulkan_implementation_x11.h
@@ -35,6 +35,10 @@ XDisplay* const x_display_; VulkanInstance vulkan_instance_; + PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR + vkGetPhysicalDeviceXlibPresentationSupportKHR_ = nullptr; + PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(VulkanImplementationX11); };
diff --git a/headless/lib/headless_devtools_client_browsertest.cc b/headless/lib/headless_devtools_client_browsertest.cc index a564ab1..eb79d95 100644 --- a/headless/lib/headless_devtools_client_browsertest.cc +++ b/headless/lib/headless_devtools_client_browsertest.cc
@@ -952,11 +952,16 @@ // Make sure we don't fail because the renderer crashed! void RenderProcessExited(base::TerminationStatus status, int exit_code) override { -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) && defined(ADDRESS_SANITIZER) + // TODO(crbug.com/845011): Make ASan not interfere and expect a crash. + // ASan's normal error exit code is 1, which base categorizes as the process + // being killed. + EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); +#elif defined(OS_WIN) || defined(OS_MACOSX) EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status); #else EXPECT_EQ(base::TERMINATION_STATUS_ABNORMAL_TERMINATION, status); -#endif // defined(OS_WIN) || defined(OS_MACOSX) +#endif } };
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index b19629b..1d2303c3 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -222,6 +222,7 @@ recipe { properties: "mastername:chromium.fyi" } + execution_timeout_secs: 36000 # 10h } builder_mixins { @@ -351,6 +352,8 @@ builder_mixins { name: "mac-try" mixins: "mac" + # mac bots may run both on Mac Minis with cores:4 and VMs with cores:8. + dimensions: "cores:" recipe { properties: "mastername:tryserver.chromium.mac" properties_j: "$depot_tools/bot_update:{\"apply_patch_on_gclient\":true}" @@ -398,8 +401,6 @@ name: "ios-try" mixins: "mac-try" mixins: "xcode-caches" - # ios bots may run both on Mac Minis with cores:4 and VMs with cores:8. - dimensions: "cores:" recipe { name: "ios/try" } @@ -1463,6 +1464,7 @@ builders { name: "Linux CFI" dimensions: "os:Ubuntu-14.04" + dimensions: "cores:32" mixins: "memory-ci" } builders { @@ -1550,7 +1552,7 @@ } builders { name: "Mac ASan 64 Builder" - dimensions: "os:Mac-10.12.2" + dimensions: "os:Mac-10.13" mixins: "memory-ci" } builders { @@ -1710,7 +1712,7 @@ } builders { name: "Mac ASan 64 Tests (1)" - dimensions: "os:Mac-10.9.5" + dimensions: "os:Mac-10.13" mixins: "memory-ci" } builders { @@ -1886,6 +1888,7 @@ builders { name: "Android CFI" dimensions: "os:Ubuntu-14.04" + dimensions: "cores:32" mixins: "memory-ci" } builders { @@ -2070,6 +2073,9 @@ dimensions: "os:Mac-10.13" dimensions: "cores:4" mixins: "fyi-ci" + recipe { + name: "ios/unified_builder_tester" + } } builders { name: "ASan Release (32-bit x86 with V8-ARM)"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index c3b8d94b..bee39621 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -1954,58 +1954,59 @@ ref: "refs/heads/master" manifest_name: "REVISION" builders { - name: "buildbot/chromium.fyi/Win Builder Goma Canary" + name: "buildbucket/luci.chromium.ci/Win Builder Goma Canary" } builders { - name: "buildbot/chromium.fyi/Win Builder (dbg) Goma Canary" + name: "buildbucket/luci.chromium.ci/Win Builder (dbg) Goma Canary" } builders { - name: "buildbot/chromium.fyi/Win Goma Canary LocalOutputCache" + name: "buildbucket/luci.chromium.ci/Win Goma Canary LocalOutputCache" } builders { - name: "buildbot/chromium.fyi/Win cl.exe Goma Canary LocalOutputCache" + name: "buildbucket/luci.chromium.ci/Win cl.exe Goma Canary LocalOutputCache" } builders { - name: "buildbot/chromium.fyi/Win7 Builder Goma Canary" + name: "buildbucket/luci.chromium.ci/Win7 Builder Goma Canary" } builders { - name: "buildbot/chromium.fyi/Win7 Builder (dbg) Goma Canary" + name: "buildbucket/luci.chromium.ci/Win7 Builder (dbg) Goma Canary" } builders { - name: "buildbot/chromium.fyi/WinMSVC64 Goma Canary" + name: "buildbucket/luci.chromium.ci/WinMSVC64 Goma Canary" } builders { - name: "buildbot/chromium.fyi/Mac Builder Goma Canary" + name: "buildbucket/luci.chromium.ci/Mac Builder Goma Canary" } builders { - name: "buildbot/chromium.fyi/Mac Builder (dbg) Goma Canary" + name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Canary" } builders { - name: "buildbot/chromium.fyi/Mac Goma Canary (clobber)" + name: "buildbucket/luci.chromium.ci/Mac Goma Canary (clobber)" } builders { - name: "buildbot/chromium.fyi/Mac Builder (dbg) Goma Canary (clobber)" + name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Canary (clobber)" } builders { - name: "buildbot/chromium.fyi/Mac Goma Canary LocalOutputCache" + name: "buildbucket/luci.chromium.ci/Mac Goma Canary LocalOutputCache" } builders { - name: "buildbot/chromium.fyi/chromeos-amd64-generic-rel-goma-canary" + name: "buildbucket/luci.chromium.ci/chromeos-amd64-generic-rel-goma-canary" } builders { - name: "buildbot/chromium.fyi/Linux Builder Goma Canary" + name: "buildbucket/luci.chromium.ci/Linux Builder Goma Canary" } builders { - name: "buildbot/chromium.fyi/Linux x64 Goma Canary (clobber)" + name: "buildbucket/luci.chromium.ci/Linux x64 Goma Canary (clobber)" } builders { - name: "buildbot/chromium.fyi/Linux x64 Goma Canary LocalOutputCache" + name: "buildbucket/luci.chromium.ci/Linux x64 Goma Canary LocalOutputCache" } builders { - name: "buildbot/chromium.fyi/Android Builder (dbg) Goma Canary" + name: "buildbucket/luci.chromium.ci/Android Builder (dbg) Goma Canary" } builders { name: "buildbot/chromium.fyi/ios-device-goma-canary-clobber" + name: "buildbucket/luci.chromium.ci/ios-device-goma-canary-clobber" } }
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index f47e0137..25cfddf8 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -61,6 +61,7 @@ triggers: "Android ASAN (dbg)" triggers: "Android Builder (dbg) Goma Canary" triggers: "Android Builder (dbg)" + triggers: "Android CFI" triggers: "Android Cronet Builder" triggers: "Android FYI 32 Vk Release (Nexus 5X)" triggers: "Android FYI 32 dEQP Vk Release (Nexus 5X)" @@ -143,9 +144,13 @@ triggers: "Linux Builder (dbg)(32)" triggers: "Linux Builder Goma Canary" triggers: "Linux Builder" + triggers: "Linux CFI" + triggers: "Linux Chromium OS ASan LSan Builder" triggers: "Linux ChromiumOS Full" + triggers: "Linux ChromiumOS MSan Builder" triggers: "Linux Clang Analyzer" triggers: "Linux FYI GPU TSAN Release" + triggers: "Linux MSan Builder" triggers: "Linux TSan Builder" triggers: "Linux Viz" triggers: "Linux remote_run Builder" @@ -157,6 +162,7 @@ triggers: "Mac ASAN Debug" triggers: "Mac ASAN Release Media" triggers: "Mac ASAN Release" + triggers: "Mac ASan 64 Builder" triggers: "Mac Builder (dbg) Goma Canary (clobber)" triggers: "Mac Builder (dbg) Goma Canary" triggers: "Mac Builder (dbg)" @@ -216,6 +222,7 @@ triggers: "ios-simulator-cronet" triggers: "ios-simulator-full-configs" triggers: "ios-simulator-xcode-clang" + triggers: "ios11-beta-simulator" triggers: "ios12-sdk-device" triggers: "ios12-sdk-simulator" triggers: "ios12-sdk-xcode-clang" @@ -3637,6 +3644,16 @@ } } +job { + id: "ios11-beta-simulator" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "ios11-beta-simulator" + } +} + ################################################################################ # Cron Jobs.
diff --git a/ios/build/bots/chromium.mac/ios12-sdk-simulator.json b/ios/build/bots/chromium.mac/ios12-sdk-simulator.json index 5830d7d..8672ce3 100644 --- a/ios/build/bots/chromium.mac/ios12-sdk-simulator.json +++ b/ios/build/bots/chromium.mac/ios12-sdk-simulator.json
@@ -22,108 +22,108 @@ "sdk": "iphonesimulator12.0", "tests": [ { - "include": "eg_cq_tests.json", - "device type": "iPhone X", - "os": "12.0", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPhone X", - "os": "12.0", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPad Air 2", - "os": "12.0", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPhone 7", - "os": "12.0", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPhone 6s Plus", - "os": "10.3", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPhone 7", - "os": "11.2", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPad Air 2", - "os": "11.2", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPad Air 2", - "os": "10.3", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_tests.json", - "device type": "iPhone X", - "os": "11.2", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_cq_tests.json", - "device type": "iPad Air 2", - "os": "10.3", - "host os": "Mac-10.13.5" - }, - { - "include": "eg_cq_tests.json", - "device type": "iPhone X", - "os": "11.2", - "host os": "Mac-10.13.5" - }, - { - "include": "screen_size_dependent_tests.json", - "device type": "iPhone 6s Plus", - "os": "12.0", - "host os": "Mac-10.13.5" - }, - { - "include": "screen_size_dependent_tests.json", - "device type": "iPhone 6s", - "os": "12.0", - "host os": "Mac-10.13.5" - }, - { - "include": "screen_size_dependent_tests.json", - "device type": "iPad Air 2", - "os": "12.0", - "host os": "Mac-10.13.5" - }, - { - "include": "screen_size_dependent_tests.json", - "device type": "iPad Air 2", - "os": "11.2", - "host os": "Mac-10.13.5" - }, - { - "include": "screen_size_dependent_tests.json", - "device type": "iPad Air 2", - "os": "10.3", - "host os": "Mac-10.13.5" - }, - { "include": "common_tests.json", "device type": "iPhone 6s", "os": "11.2", "host os": "Mac-10.13.5" }, { + "include": "screen_size_dependent_tests.json", + "device type": "iPhone 6s Plus", + "os": "12.0", + "host os": "Mac-10.13.5" + }, + { + "include": "screen_size_dependent_tests.json", + "device type": "iPhone 6s", + "os": "12.0", + "host os": "Mac-10.13.5" + }, + { + "include": "screen_size_dependent_tests.json", + "device type": "iPad Air 2", + "os": "12.0", + "host os": "Mac-10.13.5" + }, + { + "include": "screen_size_dependent_tests.json", + "device type": "iPad Air 2", + "os": "11.2", + "host os": "Mac-10.13.5" + }, + { + "include": "screen_size_dependent_tests.json", + "device type": "iPad Air 2", + "os": "10.3", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_cq_tests.json", + "device type": "iPhone X", + "os": "12.0", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPhone X", + "os": "12.0", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPad Air 2", + "os": "12.0", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPhone 7", + "os": "12.0", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPhone 6s Plus", + "os": "10.3", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPhone 7", + "os": "11.2", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPad Air 2", + "os": "11.2", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPad Air 2", + "os": "10.3", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_tests.json", + "device type": "iPhone X", + "os": "11.2", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_cq_tests.json", + "device type": "iPad Air 2", + "os": "10.3", + "host os": "Mac-10.13.5" + }, + { + "include": "eg_cq_tests.json", + "device type": "iPhone X", + "os": "11.2", + "host os": "Mac-10.13.5" + }, + { "include": "eg_cq_tests.json", "device type": "iPhone 6s", "os": "12.0",
diff --git a/ios/chrome/app/startup/setup_debugging.mm b/ios/chrome/app/startup/setup_debugging.mm index bebb2b1..179706b 100644 --- a/ios/chrome/app/startup/setup_debugging.mm +++ b/ios/chrome/app/startup/setup_debugging.mm
@@ -6,7 +6,6 @@ #include <objc/runtime.h> -#include "base/ios/ios_util.h" #include "base/logging.h" #include "base/strings/sys_string_conversions.h" #include "components/crash/core/common/objc_zombie.h" @@ -37,13 +36,6 @@ [whiteList addObject:@"voice_icon_keyboard_accessory"]; [whiteList addObject:@"voice_icon"]; -#if defined(__IPHONE_12_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0) - // TODO(crbug.com/852431): radar://41088480 Asset catalogs fail for jpg - // imagesets with the iOS 12 SDK running with iOS 11. whiteList these for now. - if (!base::ios::IsRunningOnIOS12OrLater()) - [whiteList addObject:@"stack_view_background_noise"]; -#endif - // The original implementation of [UIImage imageNamed:]. // Called by the new implementation. static IMP originalImp;
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ca.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ca.xtb index 228a226..024b946 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ca.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ca.xtb
@@ -1,7 +1,7 @@ <?xml version="1.0" ?> <!DOCTYPE translationbundle> <translationbundle lang="ca"> -<translation id="114721135501989771">Gaudeix de les eines intel·ligents de Google a Chrome</translation> +<translation id="114721135501989771">Eines intel·ligents a Chrome</translation> <translation id="1326317727527857210">Inicieu la sessió a Chrome per accedir a les vostres pestanyes des dels altres dispositius que tingueu.</translation> <translation id="1759842336958782510">Chrome</translation> <translation id="1816764564654397850">Avís de privadesa de Google Chrome</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ca.xtb b/ios/chrome/app/strings/resources/ios_strings_ca.xtb index 768d584..0015e1c 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ca.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ca.xtb
@@ -113,7 +113,7 @@ <translation id="2909437209446960244">Pestanyes recents</translation> <translation id="291754862089661335">Situa el codi QR o el codi de barres dins d'aquest marc</translation> <translation id="2921219216347069551">No es pot compartir la pàgina</translation> -<translation id="2923448633003185837">Enganxa i ves</translation> +<translation id="2923448633003185837">Enganxa i ves-hi</translation> <translation id="292639812446257861">Marca com a no llegit</translation> <translation id="2933759065870693102">Llanterna</translation> <translation id="2969979262385602596">No s'ha pogut iniciar la sessió. Torneu-ho a provar més tard.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_kn.xtb b/ios/chrome/app/strings/resources/ios_strings_kn.xtb index d69c939..b1389b0 100644 --- a/ios/chrome/app/strings/resources/ios_strings_kn.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_kn.xtb
@@ -445,7 +445,7 @@ <translation id="9188680907066685419">ನಿರ್ವಹಿಸಲಾದ ಖಾತೆಯಿಂದ ಸೈನ್ ಔಟ್ ಮಾಡಿ</translation> <translation id="9203116392574189331">ಹ್ಯಾಂಡ್ಆಫ್</translation> <translation id="9223358826628549784">ಕ್ರ್ಯಾಶ್ ವರದಿಯನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ.</translation> -<translation id="932327136139879170">ಮುಖಪುಟ</translation> +<translation id="932327136139879170">Home</translation> <translation id="935490618240037774">ನಿಮ್ಮ ಬುಕ್ಮಾರ್ಕ್ಗಳು, ಇತಿಹಾಸ, ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಇತರ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ನಿಮ್ಮ Google ಖಾತೆಗೆ ಸಿಂಕ್ ಮಾಡಲಾಗುತ್ತದೆ ಈ ಮೂಲಕ ಅವುಗಳನ್ನು ನಿಮ್ಮ ಎಲ್ಲಾ ಸಾಧನಗಳಲ್ಲಿ ನೀವು ಬಳಸಬಹುದು.</translation> <translation id="939598580284253335">ಪಾಸ್ಫ್ರೇಸ್ ಅನ್ನು ನಮೂದಿಸಿ</translation> <translation id="976982866697960176">ಸಿಂಕ್ ಮಾಡಲಾದ ಡೇಟಾವನ್ನು ನಿರ್ವಹಿಸಿ...</translation>
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 6cbc6a5..656da7c2 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -22,6 +22,7 @@ #include "base/sys_info.h" #include "components/autofill/core/browser/autofill_experiments.h" #include "components/autofill/core/common/autofill_features.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/ios/browser/autofill_switches.h" #include "components/dom_distiller/core/dom_distiller_switches.h" #include "components/feature_engagement/public/feature_constants.h" @@ -39,6 +40,7 @@ #include "components/signin/core/browser/profile_management_switches.h" #include "components/signin/core/browser/signin_switches.h" #include "components/strings/grit/components_strings.h" +#include "components/sync/driver/sync_driver_switches.h" #include "ios/chrome/browser/browsing_data/browsing_data_features.h" #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/drag_and_drop/drag_and_drop_flag.h" @@ -244,6 +246,19 @@ kEnableAutofillCreditCardUploadUpdatePromptExplanationDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(autofill::kAutofillUpstreamUpdatePromptExplanation)}, + {"use-sync-sandbox", flag_descriptions::kSyncSandboxName, + flag_descriptions::kSyncSandboxDescription, flags_ui::kOsIos, + SINGLE_VALUE_TYPE_AND_VALUE( + switches::kSyncServiceURL, + "https://chrome-sync.sandbox.google.com/chrome-sync/alpha")}, + {"wallet-service-use-sandbox", + flag_descriptions::kWalletServiceUseSandboxName, + flag_descriptions::kWalletServiceUseSandboxDescription, flags_ui::kOsIos, + ENABLE_DISABLE_VALUE_TYPE_AND_VALUE( + autofill::switches::kWalletServiceUseSandbox, + "1", + autofill::switches::kWalletServiceUseSandbox, + "0")}, {"show-autofill-type-predictions", flag_descriptions::kShowAutofillTypePredictionsName, flag_descriptions::kShowAutofillTypePredictionsDescription, @@ -296,6 +311,12 @@ flag_descriptions::kAutofillPrefilledFieldsName, flag_descriptions::kAutofillPrefilledFieldsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(autofill::features::kAutofillPrefilledFields)}, + {"autofill-show-all-profiles-on-prefilled-forms", + flag_descriptions::kAutofillShowAllSuggestionsOnPrefilledFormsName, + flag_descriptions::kAutofillShowAllSuggestionsOnPrefilledFormsDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillShowAllSuggestionsOnPrefilledForms)}, {"autofill-restrict-formless-form-extraction", flag_descriptions::kAutofillRestrictUnownedFieldsToFormlessCheckoutName, flag_descriptions::
diff --git a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h index cf742ed..c004b16 100644 --- a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h +++ b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.h
@@ -6,15 +6,17 @@ #define IOS_CHROME_BROWSER_APP_LAUNCHER_APP_LAUNCHER_TAB_HELPER_H_ #include "base/macros.h" +#import "ios/web/public/web_state/web_state_policy_decider.h" #import "ios/web/public/web_state/web_state_user_data.h" @protocol AppLauncherTabHelperDelegate; -@class ExternalAppsLaunchPolicyDecider; +@class AppLauncherAbuseDetector; class GURL; // A tab helper that handles requests to launch another application. class AppLauncherTabHelper - : public web::WebStateUserData<AppLauncherTabHelper> { + : public web::WebStatePolicyDecider, + public web::WebStateUserData<AppLauncherTabHelper> { public: ~AppLauncherTabHelper() override; @@ -23,7 +25,7 @@ // |delegate| can launch applications and present UI and is not retained by // TabHelper. static void CreateForWebState(web::WebState* web_state, - ExternalAppsLaunchPolicyDecider* policy_decider, + AppLauncherAbuseDetector* abuse_detector, id<AppLauncherTabHelperDelegate> delegate); // Requests to open the application with |url|. @@ -39,15 +41,21 @@ const GURL& source_page_url, bool link_tapped); + // web::WebStatePolicyDecider implementation + bool ShouldAllowRequest( + NSURLRequest* request, + const web::WebStatePolicyDecider::RequestInfo& request_info) override; + private: - // Constructor for AppLauncherTabHelper. |policy_decider| provides policy for + // Constructor for AppLauncherTabHelper. |abuse_detector| provides policy for // launching apps. |delegate| can launch applications and present UI and is // not retained by TabHelper. - AppLauncherTabHelper(ExternalAppsLaunchPolicyDecider* policy_decider, + AppLauncherTabHelper(web::WebState* web_state, + AppLauncherAbuseDetector* abuse_detector, id<AppLauncherTabHelperDelegate> delegate); // Used to check for repeated launches and provide policy for launching apps. - ExternalAppsLaunchPolicyDecider* policy_decider_ = nil; + AppLauncherAbuseDetector* abuse_detector_ = nil; // Used to launch apps and present UI. __weak id<AppLauncherTabHelperDelegate> delegate_ = nil;
diff --git a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm index 7dc3062..82897d17 100644 --- a/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm +++ b/ios/chrome/browser/app_launcher/app_launcher_tab_helper.mm
@@ -7,8 +7,12 @@ #import <UIKit/UIKit.h> #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" #import "ios/chrome/browser/app_launcher/app_launcher_tab_helper_delegate.h" -#import "ios/chrome/browser/web/external_apps_launch_policy_decider.h" +#import "ios/chrome/browser/web/app_launcher_abuse_detector.h" +#import "ios/web/public/url_scheme_util.h" +#import "ios/web/public/web_client.h" +#import "net/base/mac/url_conversions.h" #include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -17,22 +21,35 @@ DEFINE_WEB_STATE_USER_DATA_KEY(AppLauncherTabHelper); +// This enum used by the Applauncher to log to UMA, if App launching request was +// allowed or blocked. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class ExternalURLRequestStatus { + kMainFrameRequestAllowed = 0, + kSubFrameRequestAllowed = 1, + kSubFrameRequestBlocked = 2, + kCount, +}; + void AppLauncherTabHelper::CreateForWebState( web::WebState* web_state, - ExternalAppsLaunchPolicyDecider* policy_decider, + AppLauncherAbuseDetector* abuse_detector, id<AppLauncherTabHelperDelegate> delegate) { DCHECK(web_state); if (!FromWebState(web_state)) { - web_state->SetUserData( - UserDataKey(), - base::WrapUnique(new AppLauncherTabHelper(policy_decider, delegate))); + web_state->SetUserData(UserDataKey(), + base::WrapUnique(new AppLauncherTabHelper( + web_state, abuse_detector, delegate))); } } AppLauncherTabHelper::AppLauncherTabHelper( - ExternalAppsLaunchPolicyDecider* policy_decider, + web::WebState* web_state, + AppLauncherAbuseDetector* abuse_detector, id<AppLauncherTabHelperDelegate> delegate) - : policy_decider_(policy_decider), + : web::WebStatePolicyDecider(web_state), + abuse_detector_(abuse_detector), delegate_(delegate), weak_factory_(this) {} @@ -54,10 +71,10 @@ if (is_prompt_active_) return false; - [policy_decider_ didRequestLaunchExternalAppURL:url + [abuse_detector_ didRequestLaunchExternalAppURL:url fromSourcePageURL:source_page_url]; ExternalAppLaunchPolicy policy = - [policy_decider_ launchPolicyForURL:url + [abuse_detector_ launchPolicyForURL:url fromSourcePageURL:source_page_url]; switch (policy) { case ExternalAppLaunchPolicyBlock: { @@ -88,7 +105,7 @@ } else { // TODO(crbug.com/674649): Once non modal dialogs are implemented, // update this to always prompt instead of blocking the app. - [policy_decider_ blockLaunchingAppURL:copied_url + [abuse_detector_ blockLaunchingAppURL:copied_url fromSourcePageURL:copied_source_page_url]; } is_prompt_active_ = false; @@ -97,3 +114,35 @@ } } } + +bool AppLauncherTabHelper::ShouldAllowRequest( + NSURLRequest* request, + const web::WebStatePolicyDecider::RequestInfo& request_info) { + GURL requestURL = net::GURLWithNSURL(request.URL); + if (web::UrlHasWebScheme(requestURL) || + web::GetWebClient()->IsAppSpecificURL(requestURL) || + requestURL.SchemeIs(url::kFileScheme) || + requestURL.SchemeIs(url::kAboutScheme)) { + // This URL can be handled by the WebState and doesn't require App launcher + // handling. + return true; + } + + ExternalURLRequestStatus request_status = ExternalURLRequestStatus::kCount; + + if (request_info.target_frame_is_main) { + // TODO(crbug.com/852489): Check if the source frame should also be + // considered. + request_status = ExternalURLRequestStatus::kMainFrameRequestAllowed; + } else { + request_status = request_info.has_user_gesture + ? ExternalURLRequestStatus::kSubFrameRequestAllowed + : ExternalURLRequestStatus::kSubFrameRequestBlocked; + } + + DCHECK_NE(request_status, ExternalURLRequestStatus::kCount); + UMA_HISTOGRAM_ENUMERATION("WebController.ExternalURLRequestBlocking", + request_status, ExternalURLRequestStatus::kCount); + + return request_status != ExternalURLRequestStatus::kSubFrameRequestBlocked; +}
diff --git a/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm b/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm index 35c9a12..6cd04b11 100644 --- a/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm +++ b/ios/chrome/browser/app_launcher/app_launcher_tab_helper_unittest.mm
@@ -6,8 +6,9 @@ #include <memory> +#include "base/compiler_specific.h" #import "ios/chrome/browser/app_launcher/app_launcher_tab_helper_delegate.h" -#import "ios/chrome/browser/web/external_apps_launch_policy_decider.h" +#import "ios/chrome/browser/web/app_launcher_abuse_detector.h" #import "ios/web/public/test/fakes/test_web_state.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" @@ -52,12 +53,12 @@ } @end -// An ExternalAppsLaunchPolicyDecider for testing. -@interface FakeExternalAppsLaunchPolicyDecider : ExternalAppsLaunchPolicyDecider +// An AppLauncherAbuseDetector for testing. +@interface FakeAppLauncherAbuseDetector : AppLauncherAbuseDetector @property(nonatomic, assign) ExternalAppLaunchPolicy policy; @end -@implementation FakeExternalAppsLaunchPolicyDecider +@implementation FakeAppLauncherAbuseDetector @synthesize policy = _policy; - (ExternalAppLaunchPolicy)launchPolicyForURL:(const GURL&)URL fromSourcePageURL:(const GURL&)sourcePageURL { @@ -69,15 +70,26 @@ class AppLauncherTabHelperTest : public PlatformTest { protected: AppLauncherTabHelperTest() - : policy_decider_([[FakeExternalAppsLaunchPolicyDecider alloc] init]), + : abuse_detector_([[FakeAppLauncherAbuseDetector alloc] init]), delegate_([[FakeAppLauncherTabHelperDelegate alloc] init]) { - AppLauncherTabHelper::CreateForWebState(&web_state_, policy_decider_, + AppLauncherTabHelper::CreateForWebState(&web_state_, abuse_detector_, delegate_); tab_helper_ = AppLauncherTabHelper::FromWebState(&web_state_); } + bool VerifyRequestAllowed(NSString* url_string, + bool target_frame_is_main, + bool has_user_gesture) WARN_UNUSED_RESULT { + NSURL* url = [NSURL URLWithString:url_string]; + web::WebStatePolicyDecider::RequestInfo request_info( + ui::PageTransition::PAGE_TRANSITION_LINK, target_frame_is_main, + has_user_gesture); + return tab_helper_->ShouldAllowRequest([NSURLRequest requestWithURL:url], + request_info); + } + web::TestWebState web_state_; - FakeExternalAppsLaunchPolicyDecider* policy_decider_ = nil; + FakeAppLauncherAbuseDetector* abuse_detector_ = nil; FakeAppLauncherTabHelperDelegate* delegate_ = nil; AppLauncherTabHelper* tab_helper_; }; @@ -98,7 +110,7 @@ // Tests that a valid URL does launch app. TEST_F(AppLauncherTabHelperTest, ValidUrl) { - policy_decider_.policy = ExternalAppLaunchPolicyAllow; + abuse_detector_.policy = ExternalAppLaunchPolicyAllow; tab_helper_->RequestToLaunchApp(GURL("valid://1234"), GURL::EmptyGURL(), false); EXPECT_EQ(1U, delegate_.countOfAppsLaunched); @@ -107,7 +119,7 @@ // Tests that a valid URL does not launch app when launch policy is to block. TEST_F(AppLauncherTabHelperTest, ValidUrlBlocked) { - policy_decider_.policy = ExternalAppLaunchPolicyBlock; + abuse_detector_.policy = ExternalAppLaunchPolicyBlock; tab_helper_->RequestToLaunchApp(GURL("valid://1234"), GURL::EmptyGURL(), false); EXPECT_EQ(0U, delegate_.countOfAlertsShown); @@ -117,7 +129,7 @@ // Tests that a valid URL shows an alert and launches app when launch policy is // to prompt and user accepts. TEST_F(AppLauncherTabHelperTest, ValidUrlPromptUserAccepts) { - policy_decider_.policy = ExternalAppLaunchPolicyPrompt; + abuse_detector_.policy = ExternalAppLaunchPolicyPrompt; delegate_.simulateUserAcceptingPrompt = YES; tab_helper_->RequestToLaunchApp(GURL("valid://1234"), GURL::EmptyGURL(), false); @@ -129,9 +141,39 @@ // Tests that a valid URL does not launch app when launch policy is to prompt // and user rejects. TEST_F(AppLauncherTabHelperTest, ValidUrlPromptUserRejects) { - policy_decider_.policy = ExternalAppLaunchPolicyPrompt; + abuse_detector_.policy = ExternalAppLaunchPolicyPrompt; delegate_.simulateUserAcceptingPrompt = NO; tab_helper_->RequestToLaunchApp(GURL("valid://1234"), GURL::EmptyGURL(), false); EXPECT_EQ(0U, delegate_.countOfAppsLaunched); } + +// Tests that ShouldAllowRequest only allows requests for App Urls in main +// frame, or iframe when there was a recent user interaction. +TEST_F(AppLauncherTabHelperTest, ShouldAllowRequestWithAppUrl) { + NSString* url_string = @"itms-apps://itunes.apple.com/us/app/appname/id123"; + EXPECT_TRUE(VerifyRequestAllowed(url_string, /*target_frame_is_main=*/true, + /*has_user_gesture=*/false)); + EXPECT_TRUE(VerifyRequestAllowed(url_string, /*target_frame_is_main=*/true, + /*has_user_gesture=*/true)); + EXPECT_FALSE(VerifyRequestAllowed(url_string, /*target_frame_is_main=*/false, + /*has_user_gesture=*/false)); + EXPECT_TRUE(VerifyRequestAllowed(url_string, /*target_frame_is_main=*/false, + /*has_user_gesture=*/true)); +} + +// Tests that ShouldAllowRequest always allows requests for non App Urls. +TEST_F(AppLauncherTabHelperTest, ShouldAllowRequestWithNonAppUrl) { + EXPECT_TRUE(VerifyRequestAllowed( + @"http://itunes.apple.com/us/app/appname/id123", + /*target_frame_is_main=*/true, /*has_user_gesture=*/false)); + EXPECT_TRUE(VerifyRequestAllowed(@"file://a/b/c", + /*target_frame_is_main=*/true, + /*has_user_gesture=*/true)); + EXPECT_TRUE(VerifyRequestAllowed(@"about://test", + /*target_frame_is_main=*/false, + /*has_user_gesture=*/false)); + EXPECT_TRUE(VerifyRequestAllowed(@"data://test", + /*target_frame_is_main=*/false, + /*has_user_gesture=*/true)); +}
diff --git a/ios/chrome/browser/autofill/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_unittest.mm index ff581e6..f3b0fee 100644 --- a/ios/chrome/browser/autofill/autofill_controller_unittest.mm +++ b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
@@ -28,6 +28,7 @@ #import "ios/chrome/browser/autofill/form_suggestion_controller.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h" +#include "ios/chrome/browser/ssl/ios_security_state_tab_helper.h" #import "ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h" #include "ios/chrome/browser/ui/settings/personal_data_manager_data_changed_observer.h" #include "ios/chrome/browser/web/chrome_web_client.h" @@ -211,6 +212,7 @@ initWithPrefService:chrome_browser_state_->GetPrefs() webState:web_state()]; InfoBarManagerImpl::CreateForWebState(web_state()); + IOSSecurityStateTabHelper::CreateForWebState(web_state()); autofill_controller_ = [[AutofillController alloc] initWithBrowserState:chrome_browser_state_.get() webState:web_state()
diff --git a/ios/chrome/browser/autofill/form_structure_browsertest.mm b/ios/chrome/browser/autofill/form_structure_browsertest.mm index aabc3dbef..7224073 100644 --- a/ios/chrome/browser/autofill/form_structure_browsertest.mm +++ b/ios/chrome/browser/autofill/form_structure_browsertest.mm
@@ -24,6 +24,7 @@ #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h" +#include "ios/chrome/browser/ssl/ios_security_state_tab_helper.h" #include "ios/chrome/browser/web/chrome_web_client.h" #import "ios/chrome/browser/web/chrome_web_test.h" #import "ios/web/public/web_state/web_state.h" @@ -138,6 +139,7 @@ void FormStructureBrowserTest::SetUp() { ChromeWebTest::SetUp(); + IOSSecurityStateTabHelper::CreateForWebState(web_state()); InfoBarManagerImpl::CreateForWebState(web_state()); AutofillAgent* autofillAgent = [[AutofillAgent alloc] initWithPrefService:chrome_browser_state_->GetPrefs()
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h index b4ff3fb..f3d328f 100644 --- a/ios/chrome/browser/experimental_flags.h +++ b/ios/chrome/browser/experimental_flags.h
@@ -66,6 +66,9 @@ // Whether the Bookmarks UI Reboot is enabled. bool IsBookmarksUIRebootEnabled(); +// Whether the Reading List UI Reboot is enabled. +bool IsReadingListUIRebootEnabled(); + // Whether the Collections UI Reboot is enabled. bool IsCollectionsUIRebootEnabled();
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index a40f037..ce9001b 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -143,6 +143,10 @@ return base::FeatureList::IsEnabled(kUIRefreshPhase1); } +bool IsReadingListUIRebootEnabled() { + return base::FeatureList::IsEnabled(kCollectionsUIReboot); +} + bool IsCollectionsUIRebootEnabled() { return base::FeatureList::IsEnabled(kCollectionsUIReboot); }
diff --git a/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.cc b/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.cc index 7087f3fb..0e89afc 100644 --- a/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.cc +++ b/ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.cc
@@ -13,6 +13,7 @@ #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/favicon/favicon_service_factory.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace { std::unique_ptr<KeyedService> BuildLargeIconService( @@ -24,7 +25,7 @@ browser_state, ServiceAccessType::EXPLICIT_ACCESS), std::make_unique<image_fetcher::ImageFetcherImpl>( image_fetcher::CreateIOSImageDecoder(), - browser_state->GetRequestContext())); + browser_state->GetSharedURLLoaderFactory())); } } // namespace
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index eb98d83..26f33e5 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -35,6 +35,14 @@ "If enabled, changes the server save card prompt's explanation to mention " "the saving of the billing address."; +const char kSyncSandboxName[] = "Use Chrome Sync sandbox"; +const char kSyncSandboxDescription[] = + "Connects to the testing server for Chrome Sync."; + +const char kWalletServiceUseSandboxName[] = "Use Google Payments sandbox"; +const char kWalletServiceUseSandboxDescription[] = + "Uses the sandbox service for Google Payments API calls."; + const char kAutofillDynamicFormsName[] = "Autofill dynamic forms"; const char kAutofillDynamicFormsDescription[] = "Refills forms that dynamically change after an initial fill"; @@ -71,6 +79,12 @@ "When enabled, it shows the autofill UI with manual fallback when filling " "forms."; +const char kAutofillShowAllSuggestionsOnPrefilledFormsName[] = + "Enable showing all suggestions when focusing prefilled field"; +const char kAutofillShowAllSuggestionsOnPrefilledFormsDescription[] = + "When enabled: show all suggestions when the focused field value has not " + "been entered by the user. When disabled: use the field value as a filter."; + const char kAutofillRestrictUnownedFieldsToFormlessCheckoutName[] = "Restrict formless form extraction"; const char kAutofillRestrictUnownedFieldsToFormlessCheckoutDescription[] =
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index 041d6ca2..ca3696f 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -26,6 +26,16 @@ extern const char kEnableAutofillCreditCardUploadUpdatePromptExplanationDescription[]; +// Title and description for the flag to control if Chrome Sync should use the +// sandbox servers. +extern const char kSyncSandboxName[]; +extern const char kSyncSandboxDescription[]; + +// Title and description for the flag to control if Google Payments API calls +// should use the sandbox servers. +extern const char kWalletServiceUseSandboxName[]; +extern const char kWalletServiceUseSandboxDescription[]; + // Title and description for the flag to control the dynamic autofill. extern const char kAutofillDynamicFormsName[]; extern const char kAutofillDynamicFormsDescription[]; @@ -50,6 +60,11 @@ extern const char kAutofillManualFallbackName[]; extern const char kAutofillManualFallbackDescription[]; +// Title and description for the flag to control if prefilled value filter +// profiles. +extern const char kAutofillShowAllSuggestionsOnPrefilledFormsName[]; +extern const char kAutofillShowAllSuggestionsOnPrefilledFormsDescription[]; + // Title and description for the flag to restrict extraction of formless forms // to checkout flows. extern const char kAutofillRestrictUnownedFieldsToFormlessCheckoutName[];
diff --git a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm index 8678da22..43c272a6 100644 --- a/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm +++ b/ios/chrome/browser/itunes_urls/itunes_urls_handler_tab_helper_unittest.mm
@@ -43,7 +43,8 @@ fake_launcher_.launchedProductID = nil; fake_launcher_.launchedProductParams = nil; web::WebStatePolicyDecider::RequestInfo request_info( - ui::PageTransition::PAGE_TRANSITION_LINK, main_frame); + ui::PageTransition::PAGE_TRANSITION_LINK, main_frame, + /*has_user_gesture=*/false); bool request_allowed = web_state_.ShouldAllowRequest( [NSURLRequest requestWithURL:[NSURL URLWithString:url_string]], request_info);
diff --git a/ios/chrome/browser/net/ios_chrome_network_delegate.cc b/ios/chrome/browser/net/ios_chrome_network_delegate.cc index 7abc1d3..c0f0fb2f 100644 --- a/ios/chrome/browser/net/ios_chrome_network_delegate.cc +++ b/ios/chrome/browser/net/ios_chrome_network_delegate.cc
@@ -13,7 +13,6 @@ #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/metrics/histogram_functions.h" -#include "base/metrics/user_metrics.h" #include "base/path_service.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" @@ -29,11 +28,6 @@ const char kDNTHeader[] = "DNT"; -void ReportInvalidReferrerSendOnUI() { - base::RecordAction( - base::UserMetricsAction("Net.URLRequest_StartJob_InvalidReferrer")); -} - void ReportInvalidReferrerSend(const GURL& target_url, const GURL& referrer_url) { LOG(ERROR) << "Cancelling request to " << target_url @@ -41,8 +35,6 @@ // Record information to help debug http://crbug.com/422871 if (!target_url.SchemeIsHTTPOrHTTPS()) return; - web::WebThread::PostTask(web::WebThread::UI, FROM_HERE, - base::Bind(&ReportInvalidReferrerSendOnUI)); base::debug::DumpWithoutCrashing(); NOTREACHED(); }
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc index 2fdf9291..cc1d3799 100644 --- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc +++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.cc
@@ -175,7 +175,7 @@ std::string api_key; // This API needs whitelisted API keys. Get the key only if it is not a // dummy key. - if (google_apis::HasKeysConfigured()) { + if (google_apis::HasAPIKeyConfigured()) { bool is_stable_channel = GetChannel() == version_info::Channel::STABLE; api_key = is_stable_channel ? google_apis::GetAPIKey() : google_apis::GetNonStableAPIKey(); @@ -192,8 +192,8 @@ service, prefs, GetApplicationContext()->GetApplicationLocale(), service->category_ranker(), service->remote_suggestions_scheduler(), std::move(suggestions_fetcher), - std::make_unique<ImageFetcherImpl>(CreateIOSImageDecoder(), - request_context.get()), + std::make_unique<ImageFetcherImpl>( + CreateIOSImageDecoder(), browser_state->GetSharedURLLoaderFactory()), std::make_unique<RemoteSuggestionsDatabase>(database_dir), std::make_unique<RemoteSuggestionsStatusServiceImpl>( identity_manager->HasPrimaryAccount(), prefs, pref_name),
diff --git a/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc b/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc index 6f26a4f..5c86553a 100644 --- a/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc +++ b/ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.cc
@@ -17,6 +17,7 @@ #include "ios/chrome/browser/history/top_sites_factory.h" #include "ios/chrome/browser/ntp_tiles/ios_popular_sites_factory.h" #include "ios/chrome/browser/suggestions/suggestions_service_factory.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" std::unique_ptr<ntp_tiles::MostVisitedSites> IOSMostVisitedSitesFactory::NewForBrowserState( @@ -32,6 +33,6 @@ IOSChromeLargeIconServiceFactory::GetForBrowserState(browser_state), std::make_unique<image_fetcher::ImageFetcherImpl>( image_fetcher::CreateIOSImageDecoder(), - browser_state->GetRequestContext())), + browser_state->GetSharedURLLoaderFactory())), nil); }
diff --git a/ios/chrome/browser/passwords/notify_auto_signin_view_controller.h b/ios/chrome/browser/passwords/notify_auto_signin_view_controller.h index 7d95ab4..1b9c04b 100644 --- a/ios/chrome/browser/passwords/notify_auto_signin_view_controller.h +++ b/ios/chrome/browser/passwords/notify_auto_signin_view_controller.h
@@ -7,8 +7,10 @@ #import <UIKit/UIKit.h> -namespace net { -class URLRequestContextGetter; +#include "base/memory/scoped_refptr.h" + +namespace network { +class SharedURLLoaderFactory; } // namespace net class GURL; @@ -18,8 +20,9 @@ - (instancetype)initWithUsername:(NSString*)username iconURL:(GURL)iconURL - contextGetter:(net::URLRequestContextGetter*)contextGetter - NS_DESIGNATED_INITIALIZER; + URLLoaderFactory: + (scoped_refptr<network::SharedURLLoaderFactory>) + URLLoaderFactory NS_DESIGNATED_INITIALIZER; - (instancetype)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/passwords/notify_auto_signin_view_controller.mm b/ios/chrome/browser/passwords/notify_auto_signin_view_controller.mm index ec53fab..7c15c4d 100644 --- a/ios/chrome/browser/passwords/notify_auto_signin_view_controller.mm +++ b/ios/chrome/browser/passwords/notify_auto_signin_view_controller.mm
@@ -13,6 +13,7 @@ #include "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image.h" @@ -79,13 +80,15 @@ - (instancetype)initWithUsername:(NSString*)username iconURL:(GURL)iconURL - contextGetter:(net::URLRequestContextGetter*)contextGetter { + URLLoaderFactory: + (scoped_refptr<network::SharedURLLoaderFactory>) + URLLoaderFactory { self = [super initWithNibName:nil bundle:nil]; if (self) { _username = username; _iconURL = iconURL; _imageFetcher = std::make_unique<image_fetcher::ImageFetcherImpl>( - image_fetcher::CreateIOSImageDecoder(), contextGetter); + image_fetcher::CreateIOSImageDecoder(), URLLoaderFactory); } return self; }
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index 8d3d81ec..38ccc46 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -54,6 +54,7 @@ #include "ios/web/public/url_scheme_util.h" #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" #import "ios/web/public/web_state/web_state.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/base/l10n/l10n_util_mac.h" #include "url/gurl.h" @@ -783,7 +784,8 @@ [NotifyUserAutoSigninViewController alloc] initWithUsername:base::SysUTF16ToNSString(formSignedIn->username_value) iconURL:formSignedIn->icon_url - contextGetter:webState_->GetBrowserState()->GetRequestContext()]; + URLLoaderFactory:webState_->GetBrowserState() + ->GetSharedURLLoaderFactory()]; TabIdTabHelper* tabIdHelper = TabIdTabHelper::FromWebState(webState_); if (![_delegate displaySignInNotification:self.notifyAutoSigninViewController fromTabId:tabIdHelper->tab_id()]) {
diff --git a/ios/chrome/browser/payments/BUILD.gn b/ios/chrome/browser/payments/BUILD.gn index 0905a199..e3c48928 100644 --- a/ios/chrome/browser/payments/BUILD.gn +++ b/ios/chrome/browser/payments/BUILD.gn
@@ -87,6 +87,7 @@ "//ios/web", "//ios/web/public/test/fakes", "//net:test_support", + "//services/network:test_support", "//testing/gmock", "//testing/gtest", "//url",
diff --git a/ios/chrome/browser/payments/ios_payment_instrument_finder.h b/ios/chrome/browser/payments/ios_payment_instrument_finder.h index 292ac03e96..172820f 100644 --- a/ios/chrome/browser/payments/ios_payment_instrument_finder.h +++ b/ios/chrome/browser/payments/ios_payment_instrument_finder.h
@@ -29,6 +29,10 @@ class URLRequestContextGetter; } // namespace net +namespace network { +class SharedURLLoaderFactory; +} // namespace network + @protocol PaymentRequestUIDelegate; namespace payments { @@ -72,10 +76,12 @@ // Initializes an IOSPaymentInstrumentFinder with a |context_getter| which is // used for making URL requests with the PaymentManifestDownloader class and - // the IOSImageDataFetcherWrapper class. |payment_request_ui_delegate| is + // |url_loader_factory| which is used for requests with the + // IOSImageDataFetcherWrapper class. |payment_request_ui_delegate| is // passed to the created IOSPaymentInstrument objects. IOSPaymentInstrumentFinder( net::URLRequestContextGetter* context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, id<PaymentRequestUIDelegate> payment_request_ui_delegate); ~IOSPaymentInstrumentFinder();
diff --git a/ios/chrome/browser/payments/ios_payment_instrument_finder.mm b/ios/chrome/browser/payments/ios_payment_instrument_finder.mm index 022dc96..28743e7 100644 --- a/ios/chrome/browser/payments/ios_payment_instrument_finder.mm +++ b/ios/chrome/browser/payments/ios_payment_instrument_finder.mm
@@ -17,6 +17,7 @@ #include "ios/chrome/browser/payments/ios_payment_instrument.h" #include "ios/chrome/browser/payments/payment_request.h" #include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -48,9 +49,10 @@ IOSPaymentInstrumentFinder::IOSPaymentInstrumentFinder( net::URLRequestContextGetter* context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, id<PaymentRequestUIDelegate> payment_request_ui_delegate) : downloader_(context_getter), - image_fetcher_(context_getter), + image_fetcher_(url_loader_factory), payment_request_ui_delegate_(payment_request_ui_delegate), num_instruments_to_find_(0), weak_factory_(this) {}
diff --git a/ios/chrome/browser/payments/ios_payment_instrument_finder_unittest.mm b/ios/chrome/browser/payments/ios_payment_instrument_finder_unittest.mm index 3ca1d94..6ffe716e 100644 --- a/ios/chrome/browser/payments/ios_payment_instrument_finder_unittest.mm +++ b/ios/chrome/browser/payments/ios_payment_instrument_finder_unittest.mm
@@ -10,6 +10,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "ios/chrome/browser/payments/ios_payment_instrument.h" #include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -23,8 +25,11 @@ class TestIOSPaymentInstrumentFinder final : public IOSPaymentInstrumentFinder { public: TestIOSPaymentInstrumentFinder( - net::TestURLRequestContextGetter* context_getter) - : IOSPaymentInstrumentFinder(context_getter, nil) {} + net::TestURLRequestContextGetter* context_getter, + scoped_refptr<network::SharedURLLoaderFactory> test_url_loader_factory) + : IOSPaymentInstrumentFinder(context_getter, + test_url_loader_factory, + nil) {} std::vector<GURL> FilterUnsupportedURLPaymentMethods( const std::vector<GURL>& queried_url_payment_method_identifiers) @@ -40,11 +45,15 @@ PaymentRequestIOSPaymentInstrumentFinderTest() : scoped_task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::IO), + shared_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)), context_getter_(new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get())), ios_payment_instrument_finder_( std::make_unique<TestIOSPaymentInstrumentFinder>( - context_getter_.get())) {} + context_getter_.get(), + shared_factory_)) {} ~PaymentRequestIOSPaymentInstrumentFinderTest() override {} @@ -146,8 +155,14 @@ run_loop_->Run(); } + network::TestURLLoaderFactory* test_url_loader_factory() { + return &test_url_loader_factory_; + } + private: base::test::ScopedTaskEnvironment scoped_task_environment_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; scoped_refptr<net::TestURLRequestContextGetter> context_getter_; std::unique_ptr<TestIOSPaymentInstrumentFinder> @@ -617,6 +632,9 @@ // to the caller. TEST_F(PaymentRequestIOSPaymentInstrumentFinderTest, OneValidMethodSuppliedOneInstrument) { + test_url_loader_factory()->AddResponse( + "https://bobpay.xyz/bob/images/homescreen32.png", /* content = */ "", + net::HTTP_NOT_FOUND); FindInstrumentsWithWebAppManifest( GURL("https://emerald-eon.appspot.com/bobpay"), "{"
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm index b5cbfa9..6437087 100644 --- a/ios/chrome/browser/payments/payment_request.mm +++ b/ios/chrome/browser/payments/payment_request.mm
@@ -35,6 +35,7 @@ #import "ios/chrome/browser/payments/payment_request_util.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/web/public/web_state/web_state.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "third_party/libaddressinput/chromium/chrome_metadata_source.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h" @@ -99,6 +100,7 @@ payment_instruments_ready_(false), ios_instrument_finder_( GetApplicationContext()->GetSystemURLRequestContext(), + GetApplicationContext()->GetSharedURLLoaderFactory(), payment_request_ui_delegate_) { PopulateAvailableShippingOptions(); PopulateProfileCache();
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.h b/ios/chrome/browser/signin/ios_chrome_signin_client.h index dbb3a9f..7f2126c 100644 --- a/ios/chrome/browser/signin/ios_chrome_signin_client.h +++ b/ios/chrome/browser/signin/ios_chrome_signin_client.h
@@ -50,10 +50,10 @@ scoped_refptr<TokenWebData> GetDatabase() override; PrefService* GetPrefs() override; net::URLRequestContextGetter* GetURLRequestContext() override; + scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; void DoFinalInit() override; bool CanRevokeCredentials() override; std::string GetSigninScopedDeviceId() override; - bool ShouldMergeSigninCredentialsIntoCookieJar() override; bool IsFirstRun() const override; bool AreSigninCookiesAllowed() override; void AddContentSettingsObserver(
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.mm b/ios/chrome/browser/signin/ios_chrome_signin_client.mm index 682a6ea..45b0f41 100644 --- a/ios/chrome/browser/signin/ios_chrome_signin_client.mm +++ b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
@@ -17,6 +17,7 @@ #include "ios/chrome/browser/signin/gaia_auth_fetcher_ios.h" #include "ios/chrome/browser/web_data_service_factory.h" #include "ios/chrome/common/channel_info.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -102,6 +103,11 @@ return browser_state_->GetRequestContext(); } +scoped_refptr<network::SharedURLLoaderFactory> +IOSChromeSigninClient::GetURLLoaderFactory() { + return browser_state_->GetSharedURLLoaderFactory(); +} + void IOSChromeSigninClient::DoFinalInit() {} bool IOSChromeSigninClient::CanRevokeCredentials() { @@ -112,10 +118,6 @@ return GetOrCreateScopedDeviceIdPref(GetPrefs()); } -bool IOSChromeSigninClient::ShouldMergeSigninCredentialsIntoCookieJar() { - return false; -} - bool IOSChromeSigninClient::IsFirstRun() const { return false; }
diff --git a/ios/chrome/browser/suggestions/suggestions_service_factory.mm b/ios/chrome/browser/suggestions/suggestions_service_factory.mm index e70feb5..a8835b3e 100644 --- a/ios/chrome/browser/suggestions/suggestions_service_factory.mm +++ b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
@@ -28,6 +28,7 @@ #include "ios/web/public/browser_state.h" #include "ios/web/public/web_thread.h" #include "services/identity/public/cpp/identity_manager.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -88,7 +89,7 @@ std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher = std::make_unique<image_fetcher::ImageFetcherImpl>( image_fetcher::CreateIOSImageDecoder(), - browser_state->GetRequestContext()); + browser_state->GetSharedURLLoaderFactory()); std::unique_ptr<ImageManager> thumbnail_manager( new ImageManager(std::move(image_fetcher), std::move(db), database_dir));
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h index 466c093..5d2b5fa 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
@@ -50,6 +50,7 @@ ukm::UkmRecorder* GetUkmRecorder() override; ukm::SourceId GetUkmSourceId() override; AddressNormalizer* GetAddressNormalizer() override; + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, UnmaskCardReason reason,
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm index cf15b2a..6d7f5f4 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -28,6 +28,7 @@ #include "ios/chrome/browser/metrics/ukm_url_recorder.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #import "ios/chrome/browser/ssl/insecure_input_tab_helper.h" +#include "ios/chrome/browser/ssl/ios_security_state_tab_helper.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h" #include "ios/chrome/browser/ui/autofill/save_card_infobar_controller.h" @@ -119,6 +120,20 @@ return nullptr; } +security_state::SecurityLevel +ChromeAutofillClientIOS::GetSecurityLevelForUmaHistograms() { + auto* ios_security_state_tab_helper = + IOSSecurityStateTabHelper::FromWebState(web_state_); + + // If there is no helper, return SECURITY_LEVEL_COUNT which won't be logged. + if (!ios_security_state_tab_helper) + return security_state::SecurityLevel::SECURITY_LEVEL_COUNT; + + security_state::SecurityInfo result; + ios_security_state_tab_helper->GetSecurityInfo(&result); + return result.security_level; +} + void ChromeAutofillClientIOS::ShowAutofillSettings() { NOTREACHED(); }
diff --git a/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm b/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm index f4ea9d75..ef75f76 100644 --- a/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm +++ b/ios/chrome/browser/ui/autofill/save_card_infobar_view.mm
@@ -14,6 +14,7 @@ #import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h" #import "ios/chrome/browser/ui/util/label_link_controller.h" +#import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ui/base/l10n/l10n_util.h" @@ -82,6 +83,9 @@ // Allows styled and clickable links in the legal message label. May be nil. @property(nonatomic, strong) LabelLinkController* legalMessageLinkController; +// Constraint used to add bottom margin to the view. +@property(nonatomic) NSLayoutConstraint* footerViewBottomAnchorConstraint; + // Creates and adds subviews. - (void)setupSubviews; @@ -137,12 +141,14 @@ @synthesize confirmButtonTitle = _confirmButtonTitle; @synthesize messageLinkController = _messageLinkController; @synthesize legalMessageLinkController = _legalMessageLinkController; +@synthesize footerViewBottomAnchorConstraint = + _footerViewBottomAnchorConstraint; #pragma mark - UIView - (void)willMoveToSuperview:(UIView*)newSuperview { // Create and add subviews the first time this moves to a superview. - if (newSuperview && self.subviews.count == 0) { + if (newSuperview && !self.subviews.count) { [self setupSubviews]; } } @@ -150,6 +156,21 @@ - (void)layoutSubviews { [super layoutSubviews]; + // Return early if no subviews have been added yet. + if (!self.subviews.count) + return; + + // Set a bottom margin equal to the height of the secondary toolbar, if any. + // Deduct the bottom safe area inset as it is already included in the height + // of the secondary toolbar. + NamedGuide* layoutGuide = + [NamedGuide guideWithName:kSecondaryToolbar view:self]; + CGFloat bottomSafeAreaInset = SafeAreaInsetsForView(self).bottom; + self.footerViewBottomAnchorConstraint.constant = + layoutGuide.constrained + ? layoutGuide.layoutFrame.size.height - bottomSafeAreaInset + : 0; + [self.sizingDelegate didSetInfoBarTargetHeight:CGRectGetHeight(self.frame)]; } @@ -318,14 +339,16 @@ footerView.layoutMargins = UIEdgeInsetsMake(kButtonsTopPadding, kPadding, kPadding, kPadding); [self addSubview:footerView]; + + self.footerViewBottomAnchorConstraint = [safeAreaLayoutGuide.bottomAnchor + constraintEqualToAnchor:footerView.bottomAnchor]; [NSLayoutConstraint activateConstraints:@[ [safeAreaLayoutGuide.leadingAnchor constraintEqualToAnchor:footerView.leadingAnchor], [safeAreaLayoutGuide.trailingAnchor constraintEqualToAnchor:footerView.trailingAnchor], [contentView.bottomAnchor constraintEqualToAnchor:footerView.topAnchor], - [safeAreaLayoutGuide.bottomAnchor - constraintEqualToAnchor:footerView.bottomAnchor], + self.footerViewBottomAnchorConstraint ]]; // Dummy view that expands so that the action buttons are aligned to the
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 343a075..7ef7b17 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -225,9 +225,9 @@ #import "ios/chrome/browser/ui/voice/text_to_speech_player.h" #include "ios/chrome/browser/upgrade/upgrade_center.h" #import "ios/chrome/browser/voice/voice_search_navigations_tab_helper.h" +#import "ios/chrome/browser/web/app_launcher_abuse_detector.h" #import "ios/chrome/browser/web/blocked_popup_tab_helper.h" #import "ios/chrome/browser/web/error_page_content.h" -#import "ios/chrome/browser/web/external_apps_launch_policy_decider.h" #import "ios/chrome/browser/web/load_timing_tab_helper.h" #import "ios/chrome/browser/web/page_placeholder_tab_helper.h" #include "ios/chrome/browser/web/print_tab_helper.h" @@ -273,6 +273,7 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/ssl/ssl_info.h" #include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "third_party/google_toolbox_for_mac/src/iPhone/GTMUIImage+Resize.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -2001,7 +2002,7 @@ [self installDelegatesForTab:[_model tabAtIndex:index]]; _imageFetcher = std::make_unique<image_fetcher::IOSImageDataFetcherWrapper>( - _browserState->GetRequestContext()); + _browserState->GetSharedURLLoaderFactory()); self.imageSaver = [[ImageSaver alloc] initWithBaseViewController:self]; // Register for bookmark changed notification (BookmarkModel may be null @@ -2923,7 +2924,7 @@ CaptivePortalDetectorTabHelper::CreateForWebState(tab.webState, self); PassKitTabHelper::CreateForWebState(tab.webState, _passKitCoordinator); AppLauncherTabHelper::CreateForWebState( - tab.webState, [[ExternalAppsLaunchPolicyDecider alloc] init], + tab.webState, [[AppLauncherAbuseDetector alloc] init], _appLauncherCoordinator); // DownloadManagerTabHelper cannot function without delegate.
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index 9dea3342..746fb36 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -197,6 +197,7 @@ "//ios/chrome/browser/ui/favicon:favicon_ui", "//ios/chrome/browser/ui/overscroll_actions", "//ios/chrome/browser/ui/toolbar", + "//ios/chrome/browser/ui/toolbar/buttons", "//ios/chrome/browser/web_state_list", "//ios/chrome/common", "//ios/chrome/common/app_group",
diff --git a/ios/chrome/browser/ui/ntp/incognito_view.mm b/ios/chrome/browser/ui/ntp/incognito_view.mm index 04ff1c8..b306b21 100644 --- a/ios/chrome/browser/ui/ntp/incognito_view.mm +++ b/ios/chrome/browser/ui/ntp/incognito_view.mm
@@ -8,6 +8,7 @@ #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/ui/rtl_geometry.h" +#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/url_loader.h" @@ -133,6 +134,10 @@ UILayoutGuide* _bottomUnsafeAreaGuide; UILayoutGuide* _bottomUnsafeAreaGuideInSuperview; + // Height constraints for adding margins for the toolbars. + NSLayoutConstraint* _topToolbarMarginHeight; + NSLayoutConstraint* _bottomToolbarMarginHeight; + // Constraint ensuring that |containerView| is at least as high as the // superview of the IncognitoNTPView, i.e. the Incognito panel. // This ensures that if the Incognito panel is higher than a compact @@ -204,19 +209,41 @@ [_containerView addLayoutGuide:bottomGuide]; [_containerView addLayoutGuide:_bottomUnsafeAreaGuide]; + // Those layout guide are used to prevent the content from being displayed + // below the toolbars. + UILayoutGuide* bottomToolbarMarginGuide = [[UILayoutGuide alloc] init]; + UILayoutGuide* topToolbarMarginGuide = [[UILayoutGuide alloc] init]; + [_containerView addLayoutGuide:bottomToolbarMarginGuide]; + [_containerView addLayoutGuide:topToolbarMarginGuide]; + + _bottomToolbarMarginHeight = + [bottomToolbarMarginGuide.heightAnchor constraintEqualToConstant:0]; + _topToolbarMarginHeight = + [topToolbarMarginGuide.heightAnchor constraintEqualToConstant:0]; + // Updates the constraints to the correct value. + [self updateToolbarMargins]; + [self addSubview:_containerView]; [NSLayoutConstraint activateConstraints:@[ - // Position the stackview between the two guides. + // Position the two toolbar margin guides between the two guides used to + // have the correct centering margin. [topGuide.topAnchor constraintEqualToAnchor:_containerView.topAnchor], - [_stackView.topAnchor constraintEqualToAnchor:topGuide.bottomAnchor - constant:kLayoutGuideVerticalMargin], + [topToolbarMarginGuide.topAnchor + constraintEqualToAnchor:topGuide.bottomAnchor + constant:kLayoutGuideVerticalMargin], [bottomGuide.topAnchor - constraintEqualToAnchor:_stackView.bottomAnchor + constraintEqualToAnchor:bottomToolbarMarginGuide.bottomAnchor constant:kLayoutGuideVerticalMargin], [_containerView.bottomAnchor constraintEqualToAnchor:bottomGuide.bottomAnchor], + // Position the stack view between the two toolbar margin guides. + [topToolbarMarginGuide.bottomAnchor + constraintEqualToAnchor:_stackView.topAnchor], + [bottomToolbarMarginGuide.topAnchor + constraintEqualToAnchor:_stackView.bottomAnchor], + // Center the stackview horizontally with a minimum margin. [_stackView.leadingAnchor constraintGreaterThanOrEqualToAnchor:_containerView.leadingAnchor @@ -241,6 +268,10 @@ [_stackView.widthAnchor constraintLessThanOrEqualToConstant:kStackViewMaxWidth], + // Activate the height constraints. + _bottomToolbarMarginHeight, + _topToolbarMarginHeight, + // Set a minimum top margin and make the bottom guide twice as tall as the // top guide. [topGuide.heightAnchor @@ -297,6 +328,12 @@ [super willMoveToSuperview:newSuperview]; } +- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + + [self updateToolbarMargins]; +} + #pragma mark - Notifications - (void)contentSizeCategoryDidChange { @@ -314,6 +351,25 @@ #pragma mark - Private +// Updates the height of the margins for the top and bottom toolbars. +- (void)updateToolbarMargins { + if (!IsUIRefreshPhase1Enabled()) + return; + + if (IsRegularXRegularSizeClass(self)) { + _topToolbarMarginHeight.constant = 0; + } else { + _topToolbarMarginHeight.constant = + StatusBarHeight() + kAdaptiveToolbarHeight; + } + + if (IsSplitToolbarMode(self)) { + _bottomToolbarMarginHeight.constant = kAdaptiveToolbarHeight; + } else { + _bottomToolbarMarginHeight.constant = 0; + } +} + // Triggers a navigation to the help page. - (void)learnMoreButtonPressed { web::NavigationManager::WebLoadParams params(
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn index a225e6e9..d34f92c 100644 --- a/ios/chrome/browser/ui/omnibox/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -92,6 +92,7 @@ ":omnibox_popup_shared", ":omnibox_util", "resources:omnibox_background", + "resources:omnibox_clear_icon", "resources:omnibox_transparent_background", "//base", "//components/favicon/ios",
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm index 66b26b3..1b9544b 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -130,8 +130,7 @@ [self setKeyboardType:(UIKeyboardType)UIKeyboardTypeWebSearch]; if (IsRefreshLocationBarEnabled()) { - [self setClearButtonMode:UITextFieldViewModeWhileEditing]; - [self setRightViewMode:UITextFieldViewModeNever]; + // The right view mode is managed by the view controller. } else { [self setClearButtonMode:UITextFieldViewModeNever]; [self setRightViewMode:UITextFieldViewModeAlways];
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm index 150c5e0..66af3bb 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm
@@ -10,12 +10,19 @@ #include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.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 +namespace { + +const CGFloat kClearButtonSize = 28.0f; + +} // namespace + @interface OmniboxViewController () // Override of UIViewController's view with a different type. @@ -63,12 +70,10 @@ - (void)viewDidLoad { [super viewDidLoad]; - if (self.incognito) { - self.textField.placeholderTextColor = [UIColor colorWithWhite:1 alpha:0.5]; - } else { - self.textField.placeholderTextColor = [UIColor colorWithWhite:0 alpha:0.3]; - } + + self.textField.placeholderTextColor = [self placeholderAndClearButtonColor]; self.textField.placeholder = l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT); + [self setupClearButton]; } - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { @@ -90,8 +95,49 @@ #pragma mark - private +- (void)setupClearButton { + // Do not use the system clear button. Use a custom "right view" instead. + // Note that |rightView| is an incorrect name, it's really a trailing view. + [self.textField setClearButtonMode:UITextFieldViewModeNever]; + [self.textField setRightViewMode:UITextFieldViewModeAlways]; + + UIButton* clearButton = [UIButton buttonWithType:UIButtonTypeSystem]; + clearButton.frame = CGRectMake(0, 0, kClearButtonSize, kClearButtonSize); + [clearButton setImage:[self clearButtonIcon] forState:UIControlStateNormal]; + [clearButton addTarget:self + action:@selector(clearButtonPressed) + forControlEvents:UIControlEventTouchUpInside]; + self.textField.rightView = clearButton; + + clearButton.tintColor = [self placeholderAndClearButtonColor]; + SetA11yLabelAndUiAutomationName(clearButton, IDS_IOS_ACCNAME_CLEAR_TEXT, + @"Clear Text"); +} + +- (UIImage*)clearButtonIcon { + UIImage* image = [[UIImage imageNamed:@"omnibox_clear_icon"] + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + + return image; +} + +- (void)clearButtonPressed { + // Emulate a system button clear callback. + BOOL shouldClear = + [self.textField.delegate textFieldShouldClear:self.textField]; + if (shouldClear) { + [self.textField setText:@""]; + } +} + - (void)updateLeadingImageVisibility { [self.view setLeadingImageHidden:!IsRegularXRegularSizeClass(self)]; } +// Tint color for the textfield placeholder and the clear button. +- (UIColor*)placeholderAndClearButtonColor { + return self.incognito ? [UIColor colorWithWhite:1 alpha:0.5] + : [UIColor colorWithWhite:0 alpha:0.3]; +} + @end
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm index 292c4db..6ee8b06 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
@@ -786,7 +786,7 @@ void OmniboxViewIOS::CreateClearTextIcon(bool is_incognito) { if (IsRefreshLocationBarEnabled()) { - // In UI Refresh, the system clear button is used. + // In UI Refresh, the view controller sets up the clear button. return; }
diff --git a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn index 13b742fc..65d6473 100644 --- a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
@@ -6,6 +6,9 @@ sources = [ "omnibox_popup_coordinator.h", "omnibox_popup_coordinator.mm", + "omnibox_popup_generic_presenter.h", + "omnibox_popup_legacy_presenter.h", + "omnibox_popup_legacy_presenter.mm", "omnibox_popup_mediator.h", "omnibox_popup_mediator.mm", "omnibox_popup_positioner.h",
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 e18c325..87f4e569 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
@@ -8,10 +8,13 @@ #include "components/omnibox/browser/autocomplete_result.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" +#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.h" #include "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.h" +#include "ios/chrome/browser/ui/ui_util.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -48,7 +51,7 @@ - (void)start { std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper> imageFetcher = std::make_unique<image_fetcher::IOSImageDataFetcherWrapper>( - self.browserState->GetRequestContext()); + self.browserState->GetSharedURLLoaderFactory()); self.mediator = [[OmniboxPopupMediator alloc] initWithFetcher:std::move(imageFetcher) @@ -58,10 +61,15 @@ self.mediator.incognito = self.browserState->IsOffTheRecord(); self.mediator.consumer = self.popupViewController; - self.mediator.presenter = [[OmniboxPopupPresenter alloc] - initWithPopupPositioner:self.positioner - popupViewController:self.popupViewController]; - + if (IsUIRefreshPhase1Enabled()) { + self.mediator.presenter = [[OmniboxPopupPresenter alloc] + initWithPopupPositioner:self.positioner + popupViewController:self.popupViewController]; + } else { + self.mediator.presenter = [[OmniboxPopupLegacyPresenter alloc] + initWithPopupPositioner:self.positioner + popupViewController:self.popupViewController]; + } self.popupViewController.imageRetriever = self.mediator; self.popupViewController.delegate = self.mediator; [self.dispatcher
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_generic_presenter.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_generic_presenter.h new file mode 100644 index 0000000..6894023 --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_generic_presenter.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_OMNIBOX_POPUP_GENERIC_PRESENTER_H_ +#define IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_OMNIBOX_POPUP_GENERIC_PRESENTER_H_ + +#import <UIKit/UIKit.h> + +@protocol OmniboxPopupPositioner; + +// A generic omnibox popup presenter, serving as a common API for the UI Refresh +// and Legacy implementations. +@protocol OmniboxPopupGenericPresenter<NSObject> + +// Updates appearance depending on the content size of the presented view +// controller by changing the visible height of the popup. When the popup was +// not previously shown, it will appear with "expansion" animation. +- (void)updateHeightAndAnimateAppearanceIfNecessary; +// Call this to hide the popup with animation. +- (void)animateCollapse; + +@end + +#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_OMNIBOX_POPUP_GENERIC_PRESENTER_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.h new file mode 100644 index 0000000..d48f9a1 --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.h
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_OMNIBOX_POPUP_LEGACY_PRESENTER_H_ +#define IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_OMNIBOX_POPUP_LEGACY_PRESENTER_H_ + +#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_generic_presenter.h" + +// The pre-UI Refresh implementation of the popup presenter. +@interface OmniboxPopupLegacyPresenter : NSObject<OmniboxPopupGenericPresenter> + +- (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner + popupViewController:(UIViewController*)viewController; + +@end + +#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_OMNIBOX_POPUP_LEGACY_PRESENTER_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.mm new file mode 100644 index 0000000..2e2367a --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.mm
@@ -0,0 +1,166 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_legacy_presenter.h" + +#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_positioner.h" +#import "ios/chrome/browser/ui/toolbar/public/features.h" +#include "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" +#include "ios/chrome/browser/ui/util/constraints_ui_util.h" +#import "ios/chrome/browser/ui/util/named_guide.h" +#include "ios/chrome/grit/ios_theme_resources.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +const CGFloat kExpandAnimationDuration = 0.1; +const CGFloat kCollapseAnimationDuration = 0.05; +const CGFloat kShadowHeight = 10; +const CGFloat kiPadVerticalOffset = 3; +NS_INLINE CGFloat BottomPadding() { + return IsIPadIdiom() ? kShadowHeight : 0; +} +} // namespace + +@interface OmniboxPopupLegacyPresenter () +// Constraint for the bottom anchor of the popup. +@property(nonatomic, strong) NSLayoutConstraint* bottomConstraint; + +@property(nonatomic, weak) id<OmniboxPopupPositioner> positioner; +@property(nonatomic, weak) UIViewController* viewController; +@property(nonatomic, strong) UIView* popupContainerView; +@end + +@implementation OmniboxPopupLegacyPresenter +@synthesize viewController = _viewController; +@synthesize positioner = _positioner; +@synthesize popupContainerView = _popupContainerView; +@synthesize bottomConstraint = _bottomConstraint; + +- (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner + popupViewController:(UIViewController*)viewController { + self = [super init]; + if (self) { + _positioner = positioner; + _viewController = viewController; + + // Set up a container for presentation. + UIView* popupContainer = [[UIView alloc] init]; + _popupContainerView = popupContainer; + popupContainer.translatesAutoresizingMaskIntoConstraints = NO; + popupContainer.layoutMargins = UIEdgeInsetsMake(0, 0, BottomPadding(), 0); + + // Add the view controller's view to the container. + [popupContainer addSubview:viewController.view]; + viewController.view.translatesAutoresizingMaskIntoConstraints = NO; + AddSameConstraintsToSidesWithInsets( + viewController.view, popupContainer, + LayoutSides::kLeading | LayoutSides::kTrailing | LayoutSides::kBottom | + LayoutSides::kTop, + ChromeDirectionalEdgeInsetsMake(0, 0, BottomPadding(), 0)); + + // Add a shadow. + UIImageView* shadowView = [[UIImageView alloc] + initWithImage:NativeImage(IDR_IOS_TOOLBAR_SHADOW_FULL_BLEED)]; + [shadowView setUserInteractionEnabled:NO]; + [shadowView setTranslatesAutoresizingMaskIntoConstraints:NO]; + [popupContainer addSubview:shadowView]; + + // On iPhone, the shadow is on the top of the popup, as if it's cast by + // the omnibox; on iPad, the shadow is cast by the popup instead, so it's + // below the popup. + AddSameConstraintsToSides(shadowView, popupContainer, + LayoutSides::kLeading | LayoutSides::kTrailing); + AddSameConstraintsToSides( + shadowView, popupContainer, + IsIPadIdiom() ? LayoutSides::kBottom : LayoutSides::kTop); + } + return self; +} + +- (void)updateHeightAndAnimateAppearanceIfNecessary { + UIView* popup = self.popupContainerView; + if (!popup.superview) { + UIViewController* parentVC = [self.positioner popupParentViewController]; + [parentVC addChildViewController:self.viewController]; + [[self.positioner popupParentView] addSubview:popup]; + [self.viewController didMoveToParentViewController:parentVC]; + + [self initialLayout]; + } + + if (!IsIPadIdiom()) { + self.bottomConstraint.active = YES; + } + + if (popup.bounds.size.height == 0) { + // Animate if it expanding. + [UIView animateWithDuration:kExpandAnimationDuration + delay:0 + options:UIViewAnimationOptionCurveEaseInOut + animations:^{ + [[popup superview] layoutIfNeeded]; + } + completion:nil]; + } +} + +- (void)animateCollapse { + UIView* retainedPopupView = self.popupContainerView; + UIViewController* retainedViewController = self.viewController; + if (!IsIPadIdiom()) { + self.bottomConstraint.active = NO; + } + + [UIView animateWithDuration:kCollapseAnimationDuration + delay:0 + options:UIViewAnimationOptionCurveEaseInOut + animations:^{ + [[self.popupContainerView superview] layoutIfNeeded]; + } + completion:^(BOOL) { + [retainedViewController willMoveToParentViewController:nil]; + [retainedPopupView removeFromSuperview]; + [retainedViewController removeFromParentViewController]; + }]; +} + +#pragma mark - Private + +// Layouts the popup when it is just added to the view hierarchy. +- (void)initialLayout { + UIView* popup = self.popupContainerView; + // Creates the constraints if the view is newly added to the view hierarchy. + // On iPad the height of the popup is fixed. + + // This constraint will only be activated on iPhone as the popup is taking + // the full height. + self.bottomConstraint = [popup.bottomAnchor + constraintEqualToAnchor:[popup superview].bottomAnchor]; + + // Position the top anchor of the popup relatively to the layout guide + // positioned on the omnibox. + UILayoutGuide* topLayout = + [NamedGuide guideWithName:kOmniboxGuide view:popup]; + NSLayoutConstraint* topConstraint = + [popup.topAnchor constraintEqualToAnchor:topLayout.bottomAnchor]; + if (IsIPadIdiom()) { + topConstraint.constant = kiPadVerticalOffset; + } + + [NSLayoutConstraint activateConstraints:@[ + [popup.leadingAnchor constraintEqualToAnchor:popup.superview.leadingAnchor], + [popup.trailingAnchor + constraintEqualToAnchor:popup.superview.trailingAnchor], + topConstraint, + ]]; + + [popup layoutIfNeeded]; + [[popup superview] layoutIfNeeded]; +} + +@end
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.h index 625210e9..025c961 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.h +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.h
@@ -11,7 +11,7 @@ #import "ios/chrome/browser/ui/omnibox/autocomplete_result_consumer.h" #import "ios/chrome/browser/ui/omnibox/image_retriever.h" -@class OmniboxPopupPresenter; +@protocol OmniboxPopupGenericPresenter; namespace image_fetcher { class IOSImageDataFetcherWrapper; @@ -54,7 +54,7 @@ @property(nonatomic, assign, getter=isOpen) BOOL open; // Presenter for the popup, handling the positioning and the presentation // animations. -@property(nonatomic, strong) OmniboxPopupPresenter* presenter; +@property(nonatomic, strong) id<OmniboxPopupGenericPresenter> presenter; @end
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm index 7af5846..d013d3a 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm
@@ -11,7 +11,7 @@ #include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/autocomplete_result.h" #import "ios/chrome/browser/ui/omnibox/autocomplete_match_formatter.h" -#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h" +#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_generic_presenter.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h index 488e023..8018fcc 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
@@ -1,26 +1,18 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// 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_OMNIBOX_POPUP_PRESENTER_H_ #define IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_PRESENTER_H_ -#import <UIKit/UIKit.h> +#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_generic_presenter.h" -@protocol OmniboxPopupPositioner; - -@interface OmniboxPopupPresenter : NSObject +// The UI Refresh implementation of the popup presenter. +@interface OmniboxPopupPresenter : NSObject<OmniboxPopupGenericPresenter> - (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner popupViewController:(UIViewController*)viewController; -// Updates appearance depending on the content size of the presented view -// controller by changing the visible height of the popup. When the popup was -// not previously shown, it will appear with "expansion" animation. -- (void)updateHeightAndAnimateAppearanceIfNecessary; -// Call this to hide the popup with animation. -- (void)animateCollapse; - @end #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_PRESENTER_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm index d31a0902..5ba907f 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
@@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// 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. @@ -20,8 +20,7 @@ const CGFloat kExpandAnimationDuration = 0.1; const CGFloat kCollapseAnimationDuration = 0.05; const CGFloat kShadowHeight = 10; -const CGFloat kiPadVerticalOffset = 3; -const CGFloat kRefreshVerticalOffset = 6; +const CGFloat kVerticalOffset = 6; NS_INLINE CGFloat BottomPadding() { return IsIPadIdiom() ? kShadowHeight : 0; } @@ -149,13 +148,7 @@ [NamedGuide guideWithName:kOmniboxGuide view:popup]; NSLayoutConstraint* topConstraint = [popup.topAnchor constraintEqualToAnchor:topLayout.bottomAnchor]; - if (IsUIRefreshPhase1Enabled()) { - // TODO(crbug.com/846337) Remove this workaround and clean up popup - // presentation. - topConstraint.constant = kRefreshVerticalOffset; - } else if (IsIPadIdiom()) { - topConstraint.constant = kiPadVerticalOffset; - } + topConstraint.constant = kVerticalOffset; [NSLayoutConstraint activateConstraints:@[ [popup.leadingAnchor constraintEqualToAnchor:popup.superview.leadingAnchor],
diff --git a/ios/chrome/browser/ui/omnibox/resources/BUILD.gn b/ios/chrome/browser/ui/omnibox/resources/BUILD.gn index bc3d303..0b5f79f 100644 --- a/ios/chrome/browser/ui/omnibox/resources/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/resources/BUILD.gn
@@ -21,3 +21,12 @@ "omnibox_background.imageset/omnibox_background@3x.png", ] } + +imageset("omnibox_clear_icon") { + sources = [ + "omnibox_clear_icon.imageset/Contents.json", + "omnibox_clear_icon.imageset/omnibox_clear_icon.png", + "omnibox_clear_icon.imageset/omnibox_clear_icon@2x.png", + "omnibox_clear_icon.imageset/omnibox_clear_icon@3x.png", + ] +}
diff --git a/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/Contents.json b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/Contents.json new file mode 100644 index 0000000..0cf51af --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/Contents.json
@@ -0,0 +1,23 @@ +{ + "images": [ + { + "idiom": "universal", + "scale": "1x", + "filename": "omnibox_clear_icon.png" + }, + { + "idiom": "universal", + "scale": "2x", + "filename": "omnibox_clear_icon@2x.png" + }, + { + "idiom": "universal", + "scale": "3x", + "filename": "omnibox_clear_icon@3x.png" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +}
diff --git a/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon.png b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon.png new file mode 100644 index 0000000..e044741 --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon.png Binary files differ
diff --git a/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon@2x.png b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon@2x.png new file mode 100644 index 0000000..200a810 --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon@3x.png b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon@3x.png new file mode 100644 index 0000000..f25b1da --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/resources/omnibox_clear_icon.imageset/omnibox_clear_icon@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm index 56e1e00..95b0ab5f 100644 --- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -106,8 +106,8 @@ [[TableViewTextButtonItem alloc] initWithType:ItemTypeTextButton]; textActionButtonItem.text = @"Hello, you should do something."; textActionButtonItem.buttonText = @"Do something"; - [model setFooter:textActionButtonItem - forSectionWithIdentifier:SectionIdentifierText]; + [model addItem:textActionButtonItem + toSectionWithIdentifier:SectionIdentifierText]; // SectionIdentifierURL. TableViewURLItem* item =
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm index b2967cb..3edb1063 100644 --- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm +++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
@@ -99,7 +99,8 @@ // Tests signing in with one account, switching sync account to a second and // choosing to keep the browsing data separate during the switch. -- (void)testSignInSwitchAccountsAndKeepDataSeparate { +// TODO(crbug.com/854446): Enable after fixing. +- (void)DISABLED_testSignInSwitchAccountsAndKeepDataSeparate { // Set up the fake identities. ios::FakeChromeIdentityService* identity_service = ios::FakeChromeIdentityService::GetInstanceFromChromeProvider(); @@ -136,7 +137,8 @@ // Tests signing in with one account, switching sync account to a second and // choosing to import the browsing data during the switch. -- (void)testSignInSwitchAccountsAndImportData { +// TODO(crbug.com/854446): Enable after fixing. +- (void)DISABLED_testSignInSwitchAccountsAndImportData { // Set up the fake identities. ios::FakeChromeIdentityService* identity_service = ios::FakeChromeIdentityService::GetInstanceFromChromeProvider(); @@ -174,7 +176,8 @@ // Tests that switching from a managed account to a non-managed account works // correctly and displays the expected warnings. -- (void)testSignInSwitchManagedAccount { +// TODO(crbug.com/854446): Enable after fixing. +- (void)DISABLED_testSignInSwitchManagedAccount { // Set up the fake identities. ios::FakeChromeIdentityService* identity_service = ios::FakeChromeIdentityService::GetInstanceFromChromeProvider();
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm index 8325d6b..7e20336 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -128,6 +128,8 @@ } - (void)stopChildCoordinatorsWithCompletion:(ProceduralBlock)completion { + // Recent tabs context menu may be presented on top of the tab grid. + [self.mainViewController.remoteTabsViewController dismissModals]; // History may be presented on top of the tab grid. if (self.historyCoordinator) { [self.historyCoordinator stopWithCompletion:completion];
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm index b592fa36..6850a35 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm
@@ -37,6 +37,9 @@ namespace { +using chrome_test_util::BackButton; +using chrome_test_util::ForwardButton; + const char kPageURL[] = "/test-page.html"; const char kPageURL2[] = "/test-page-2.html"; const char kPageURL3[] = "/test-page-3.html"; @@ -44,6 +47,13 @@ const char kTextID[] = "textID"; const char kPageLoadedString[] = "Page loaded!"; +// Defines the visibility of an element, in relation to the toolbar. +typedef NS_ENUM(NSInteger, ButtonVisibility) { + ButtonVisibilityNone, + ButtonVisibilityPrimary, + ButtonVisibilitySecondary +}; + // Provides responses for redirect and changed window location URLs. std::unique_ptr<net::test_server::HttpResponse> StandardResponse( const net::test_server::HttpRequest& request) { @@ -79,6 +89,34 @@ grey_sufficientlyVisible(), nil); } +// Returns a matcher for the reload button. +id<GREYMatcher> ReloadButton() { + return chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_ACCNAME_RELOAD); +} + +// Returns a matcher for the tools menu button. +id<GREYMatcher> ToolsMenuButton() { + return chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_TOOLBAR_SETTINGS); +} + +// Returns a matcher for the cancel button. +id<GREYMatcher> CancelButton() { + return chrome_test_util::ButtonWithAccessibilityLabelId(IDS_CANCEL); +} + +// Returns a matcher for the search button. +id<GREYMatcher> SearchButton() { + return grey_accessibilityID(kToolbarOmniboxButtonIdentifier); +} + +// Returns a matcher for the tab grid button. +id<GREYMatcher> TabGridButton() { + return chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_IOS_TOOLBAR_SHOW_TABS); +} + // Returns a matcher for a UIResponder object being first responder. id<GREYMatcher> firstResponder() { MatchesBlock matches = ^BOOL(UIResponder* responder) { @@ -109,6 +147,26 @@ grey_sufficientlyVisible(), nil); } +// Checks that the element designated by |matcher| is |visible| in the primary +// toolbar. +void CheckVisibleInPrimaryToolbar(id<GREYMatcher> matcher, BOOL visible) { + id<GREYMatcher> assertionMatcher = visible ? grey_notNil() : grey_nil(); + [[EarlGrey + selectElementWithMatcher:grey_allOf(matcher, VisibleInPrimaryToolbar(), + nil)] + assertWithMatcher:assertionMatcher]; +} + +// Checks that the element designed by |matcher| is |visible| in the secondary +// toolbar. +void CheckVisibleInSecondaryToolbar(id<GREYMatcher> matcher, BOOL visible) { + id<GREYMatcher> assertionMatcher = visible ? grey_notNil() : grey_nil(); + [[EarlGrey + selectElementWithMatcher:grey_allOf(matcher, VisibleInSecondaryToolbar(), + nil)] + assertWithMatcher:assertionMatcher]; +} + // Returns a matcher for a UIControl object being spotlighted. id<GREYMatcher> Spotlighted() { MatchesBlock matches = ^BOOL(UIControl* control) { @@ -160,117 +218,135 @@ return secondTraitCollection; } +// Checks that the element associated with |matcher| is visible in the toolbar +// defined by |visibility|. +void CheckVisibilityInToolbar(id<GREYMatcher> matcher, + ButtonVisibility visibility) { + CheckVisibleInPrimaryToolbar(matcher, visibility == ButtonVisibilityPrimary); + CheckVisibleInSecondaryToolbar(matcher, + visibility == ButtonVisibilitySecondary); +} + +// Checks the visibility of the different part of the omnibox, depending on it +// being focused or not. +void CheckOmniboxVisibility(BOOL omniboxFocused) { + // Check omnibox/steady view visibility. + if (omniboxFocused) { + // Check that the omnibox is visible. + CheckVisibleInPrimaryToolbar(chrome_test_util::Omnibox(), YES); + } else { + // Check that location view is visible. + if (IsRefreshLocationBarEnabled()) { + CheckVisibleInPrimaryToolbar(chrome_test_util::DefocusedLocationView(), + YES); + } else { + CheckVisibleInPrimaryToolbar(chrome_test_util::Omnibox(), YES); + } + } +} + +// Check the visibility of the buttons if the device is an iPhone in portrait or +// an iPad in multitasking. +void CheckButtonsVisibilityIPhonePortrait(BOOL omniboxFocused) { + // Check that the cancel button visibility. + if (omniboxFocused) { + CheckVisibilityInToolbar(CancelButton(), ButtonVisibilityPrimary); + + CheckVisibilityInToolbar(ShareButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ReloadButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityNone); + + // Those buttons are hidden by the keyboard. + CheckVisibilityInToolbar(BackButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityNone); + } else { + CheckVisibilityInToolbar(CancelButton(), ButtonVisibilityNone); + + CheckVisibilityInToolbar(ShareButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ReloadButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityNone); + + CheckVisibilityInToolbar(BackButton(), ButtonVisibilitySecondary); + CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilitySecondary); + CheckVisibilityInToolbar(SearchButton(), ButtonVisibilitySecondary); + CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilitySecondary); + CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilitySecondary); + } +} + +// Check the visibility of the buttons if the device is an iPhone in landscape. +void CheckButtonsVisibilityIPhoneLandscape(BOOL omniboxFocused) { + if (omniboxFocused) { + // Omnibox focused in iPhone landscape. + CheckVisibilityInToolbar(CancelButton(), ButtonVisibilityPrimary); + + CheckVisibilityInToolbar(ShareButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ReloadButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityNone); + + CheckVisibilityInToolbar(BackButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityNone); + } else { + CheckVisibilityInToolbar(CancelButton(), ButtonVisibilityNone); + + CheckVisibilityInToolbar(ShareButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(ReloadButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityNone); + + CheckVisibilityInToolbar(BackButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityPrimary); + } + // The secondary toolbar is not visible. + [[EarlGrey + selectElementWithMatcher:grey_kindOfClass([SecondaryToolbarView class])] + assertWithMatcher:grey_not(grey_sufficientlyVisible())]; +} + +// Check the visibility of the buttons if the device is an iPad not in +// multitasking. +void CheckButtonsVisibilityIPad() { + CheckVisibilityInToolbar(CancelButton(), ButtonVisibilityNone); + + CheckVisibilityInToolbar(ShareButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(ReloadButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(BookmarkButton(), ButtonVisibilityPrimary); + + CheckVisibilityInToolbar(BackButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityPrimary); + CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityPrimary); + + // The secondary toolbar is not visible. + [[EarlGrey + selectElementWithMatcher:grey_kindOfClass([SecondaryToolbarView class])] + assertWithMatcher:grey_not(grey_sufficientlyVisible())]; +} + // Check that the button displayed are the ones which should be displayed in the // environment described by |traitCollection| and with |omniboxFocused|. void CheckToolbarButtonVisibility(UITraitCollection* traitCollection, BOOL omniboxFocused) { + CheckOmniboxVisibility(omniboxFocused); + + // Button checks. if (traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact && traitCollection.verticalSizeClass != UIUserInterfaceSizeClassCompact) { - // Split toolbar. - if (omniboxFocused) { - // Check that the omnibox and the cancel button are shown. - [[EarlGrey - selectElementWithMatcher: - grey_allOf( - chrome_test_util::ButtonWithAccessibilityLabelId(IDS_CANCEL), - VisibleInPrimaryToolbar(), nil)] - assertWithMatcher:grey_notNil()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - - } else { - // Test the visibility of the primary toolbar buttons. - if (IsRefreshLocationBarEnabled()) { - [[EarlGrey - selectElementWithMatcher:chrome_test_util::DefocusedLocationView()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - } else { - [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - } - - // Test the visibility of the secondary toolbar buttons. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - assertWithMatcher:VisibleInSecondaryToolbar()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()] - assertWithMatcher:VisibleInSecondaryToolbar()]; - [[EarlGrey selectElementWithMatcher:grey_accessibilityID( - kToolbarOmniboxButtonIdentifier)] - assertWithMatcher:VisibleInSecondaryToolbar()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLBAR_SHOW_TABS)] - assertWithMatcher:VisibleInSecondaryToolbar()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLBAR_SETTINGS)] - assertWithMatcher:VisibleInSecondaryToolbar()]; - } - + CheckButtonsVisibilityIPhonePortrait(omniboxFocused); + } else if (traitCollection.verticalSizeClass == + UIUserInterfaceSizeClassCompact) { + CheckButtonsVisibilityIPhoneLandscape(omniboxFocused); } else { - // Unsplit toolbar. - if (omniboxFocused) { - // Check that the omnibox is visible. - [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - - } else { - // Check that location view is visible. - if (IsRefreshLocationBarEnabled()) { - [[EarlGrey - selectElementWithMatcher:chrome_test_util::DefocusedLocationView()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - } else { - [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - } - } - // Check that the cancel button is hidden. - [[EarlGrey - selectElementWithMatcher: - grey_allOf( - chrome_test_util::ButtonWithAccessibilityLabelId(IDS_CANCEL), - VisibleInPrimaryToolbar(), nil)] assertWithMatcher:grey_nil()]; - - // Test the visibility of the primary toolbar buttons. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - [[EarlGrey selectElementWithMatcher:ShareButton()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - ButtonWithAccessibilityLabelId( - IDS_IOS_ACCNAME_RELOAD)] - assertWithMatcher:VisibleInPrimaryToolbar()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLBAR_SETTINGS)] - assertWithMatcher:VisibleInPrimaryToolbar()]; - - // The secondary toolbar is not visible. - [[EarlGrey - selectElementWithMatcher:grey_kindOfClass([SecondaryToolbarView class])] - assertWithMatcher:grey_not(grey_sufficientlyVisible())]; - - if (traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) { - // Unsplit in compact height, the stack view button is visible. - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLBAR_SHOW_TABS)] - assertWithMatcher:VisibleInPrimaryToolbar()]; - } else { - // Unsplit in Regular x Regular, the bookmark button is visible, the stack - // view button is hidden. - [[EarlGrey - selectElementWithMatcher: - grey_allOf(chrome_test_util::ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLBAR_SHOW_TABS), - VisibleInPrimaryToolbar(), nil)] - assertWithMatcher:grey_nil()]; - [[EarlGrey selectElementWithMatcher:BookmarkButton()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - } + CheckButtonsVisibilityIPad(); } }
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm index 9fa85b9..42017e9 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm
@@ -119,8 +119,8 @@ - (void)transitionToLocationBarFocusedState:(BOOL)focused { [self.orchestrator transitionToStateOmniboxFocused:focused - toolbarExpanded:focused && - IsSplitToolbarMode(self.viewController) + toolbarExpanded:focused && !IsRegularXRegularSizeClass( + self.viewController) animated:YES]; } @@ -133,7 +133,8 @@ [self.orchestrator transitionToStateOmniboxFocused:omniboxFocused toolbarExpanded:omniboxFocused && - IsSplitToolbarMode(self.viewController) + !IsRegularXRegularSizeClass( + self.viewController) animated:NO]; }
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm index 9a4bab5..df0e9fc 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
@@ -389,12 +389,7 @@ [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] assertWithMatcher:chrome_test_util::OmniboxText("foo")]; - id<GREYMatcher> cancelButton = nil; - if (IsRefreshLocationBarEnabled()) { - cancelButton = grey_accessibilityLabel(@"Clear text"); - } else { - cancelButton = grey_accessibilityLabel(@"Clear Text"); - } + id<GREYMatcher> cancelButton = grey_accessibilityLabel(@"Clear Text"); [[EarlGrey selectElementWithMatcher:cancelButton] performAction:grey_tap()];
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index 5e41f5c..36ea085 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -155,6 +155,10 @@ source_set("web_internal") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ + "app_launcher_abuse_detector.h", + "app_launcher_abuse_detector.mm", + "app_launching_state.h", + "app_launching_state.mm", "blocked_popup_tab_helper.h", "blocked_popup_tab_helper.mm", "chrome_web_client.h", @@ -163,10 +167,6 @@ "error_page_content.mm", "error_page_generator.h", "error_page_generator.mm", - "external_app_launching_state.h", - "external_app_launching_state.mm", - "external_apps_launch_policy_decider.h", - "external_apps_launch_policy_decider.mm", "print_tab_helper.h", "print_tab_helper.mm", "web_state_printer.h", @@ -237,11 +237,11 @@ configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ + "app_launcher_abuse_detector_unittest.mm", + "app_launching_state_unittest.mm", "blocked_popup_tab_helper_unittest.mm", "chrome_web_client_unittest.mm", "error_page_generator_unittest.mm", - "external_app_launching_state_unittest.mm", - "external_apps_launch_policy_decider_unittest.mm", ] deps = [ ":test_support",
diff --git a/ios/chrome/browser/web/external_apps_launch_policy_decider.h b/ios/chrome/browser/web/app_launcher_abuse_detector.h similarity index 86% rename from ios/chrome/browser/web/external_apps_launch_policy_decider.h rename to ios/chrome/browser/web/app_launcher_abuse_detector.h index 3179f54..fac40d7 100644 --- a/ios/chrome/browser/web/external_apps_launch_policy_decider.h +++ b/ios/chrome/browser/web/app_launcher_abuse_detector.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 IOS_CHROME_BROWSER_WEB_EXTERNAL_APPS_LAUNCH_POLICY_DECIDER_H_ -#define IOS_CHROME_BROWSER_WEB_EXTERNAL_APPS_LAUNCH_POLICY_DECIDER_H_ +#ifndef IOS_CHROME_BROWSER_WEB_APP_LAUNCHER_ABUSE_DETECTOR_H_ +#define IOS_CHROME_BROWSER_WEB_APP_LAUNCHER_ABUSE_DETECTOR_H_ #import <Foundation/Foundation.h> @@ -28,7 +28,7 @@ // application launching. // Each key is a space separated combination of the absloute string for the // original source URL, and the scheme of the external Application URL. -@interface ExternalAppsLaunchPolicyDecider : NSObject +@interface AppLauncherAbuseDetector : NSObject // Updates the state for external application |gURL| and |sourcePageURL| with a // new app launch request. @@ -46,4 +46,4 @@ fromSourcePageURL:(const GURL&)sourcePageURL; @end -#endif // IOS_CHROME_BROWSER_WEB_EXTERNAL_APPS_LAUNCH_POLICY_DECIDER_H_ +#endif // IOS_CHROME_BROWSER_WEB_APP_LAUNCHER_ABUSE_DETECTOR_H_
diff --git a/ios/chrome/browser/web/external_apps_launch_policy_decider.mm b/ios/chrome/browser/web/app_launcher_abuse_detector.mm similarity index 81% rename from ios/chrome/browser/web/external_apps_launch_policy_decider.mm rename to ios/chrome/browser/web/app_launcher_abuse_detector.mm index c37202e..7ec2df2 100644 --- a/ios/chrome/browser/web/external_apps_launch_policy_decider.mm +++ b/ios/chrome/browser/web/app_launcher_abuse_detector.mm
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/web/external_apps_launch_policy_decider.h" +#import "ios/chrome/browser/web/app_launcher_abuse_detector.h" #include "base/strings/sys_string_conversions.h" -#import "ios/chrome/browser/web/external_app_launching_state.h" +#import "ios/chrome/browser/web/app_launching_state.h" #include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -14,20 +14,19 @@ const int kMaxAllowedConsecutiveExternalAppLaunches = 2; -@interface ExternalAppsLaunchPolicyDecider () +@interface AppLauncherAbuseDetector () // Maps between external application redirection key and state. // the key is a space separated combination of the absolute string for the // original source URL, and the scheme of the external Application URL. @property(nonatomic, strong) - NSMutableDictionary<NSString*, ExternalAppLaunchingState*>* - appLaunchingStates; + NSMutableDictionary<NSString*, AppLaunchingState*>* appLaunchingStates; // Generates key for |appURL| and |sourceURL| to be used to retrieve state from // |appLaunchingStates|. + (NSString*)stateKeyForAppURL:(const GURL&)appURL sourceURL:(const GURL&)sourceURL; @end -@implementation ExternalAppsLaunchPolicyDecider +@implementation AppLauncherAbuseDetector @synthesize appLaunchingStates = _appLaunchingStates; @@ -50,18 +49,18 @@ fromSourcePageURL:(const GURL&)sourcePageURL { NSString* key = [[self class] stateKeyForAppURL:gURL sourceURL:sourcePageURL]; if (!_appLaunchingStates[key]) - _appLaunchingStates[key] = [[ExternalAppLaunchingState alloc] init]; + _appLaunchingStates[key] = [[AppLaunchingState alloc] init]; [_appLaunchingStates[key] updateWithLaunchRequest]; } - (ExternalAppLaunchPolicy)launchPolicyForURL:(const GURL&)gURL fromSourcePageURL:(const GURL&)sourcePageURL { NSString* key = [[self class] stateKeyForAppURL:gURL sourceURL:sourcePageURL]; - // Don't block apps that are not registered with the policy decider. + // Don't block apps that are not registered with the abuse detector. if (!_appLaunchingStates[key]) return ExternalAppLaunchPolicyAllow; - ExternalAppLaunchingState* state = _appLaunchingStates[key]; + AppLaunchingState* state = _appLaunchingStates[key]; if ([state isAppLaunchingBlocked]) return ExternalAppLaunchPolicyBlock;
diff --git a/ios/chrome/browser/web/external_apps_launch_policy_decider_unittest.mm b/ios/chrome/browser/web/app_launcher_abuse_detector_unittest.mm similarity index 60% rename from ios/chrome/browser/web/external_apps_launch_policy_decider_unittest.mm rename to ios/chrome/browser/web/app_launcher_abuse_detector_unittest.mm index 4d79f7b..8dba326c 100644 --- a/ios/chrome/browser/web/external_apps_launch_policy_decider_unittest.mm +++ b/ios/chrome/browser/web/app_launcher_abuse_detector_unittest.mm
@@ -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 "ios/chrome/browser/web/external_apps_launch_policy_decider.h" +#include "ios/chrome/browser/web/app_launcher_abuse_detector.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -24,125 +24,125 @@ } // namespace -using ExternalAppsLaunchPolicyDeciderTest = PlatformTest; +using AppLauncherAbuseDetectorTest = PlatformTest; // Tests cases when the same app is launched repeatedly from same source. -TEST_F(ExternalAppsLaunchPolicyDeciderTest, +TEST_F(AppLauncherAbuseDetectorTest, TestRepeatedAppLaunches_SameAppSameSource) { - ExternalAppsLaunchPolicyDecider* policyDecider = - [[ExternalAppsLaunchPolicyDecider alloc] init]; + AppLauncherAbuseDetector* abuseDetector = + [[AppLauncherAbuseDetector alloc] init]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:GURL("facetime://+154") + [abuseDetector launchPolicyForURL:GURL("facetime://+154") fromSourcePageURL:kSourceUrl1]); - [policyDecider didRequestLaunchExternalAppURL:GURL("facetime://+1354") + [abuseDetector didRequestLaunchExternalAppURL:GURL("facetime://+1354") fromSourcePageURL:kSourceUrl1]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:GURL("facetime://+12354") + [abuseDetector launchPolicyForURL:GURL("facetime://+12354") fromSourcePageURL:kSourceUrl1]); - [policyDecider didRequestLaunchExternalAppURL:GURL("facetime://+154") + [abuseDetector didRequestLaunchExternalAppURL:GURL("facetime://+154") fromSourcePageURL:kSourceUrl1]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:GURL("facetime://+13454") + [abuseDetector launchPolicyForURL:GURL("facetime://+13454") fromSourcePageURL:kSourceUrl1]); - [policyDecider didRequestLaunchExternalAppURL:GURL("facetime://+14") + [abuseDetector didRequestLaunchExternalAppURL:GURL("facetime://+14") fromSourcePageURL:kSourceUrl1]; // App was launched more than the max allowed times, the policy should change // to Prompt. EXPECT_EQ(ExternalAppLaunchPolicyPrompt, - [policyDecider launchPolicyForURL:GURL("facetime://+14") + [abuseDetector launchPolicyForURL:GURL("facetime://+14") fromSourcePageURL:kSourceUrl1]); } // Tests cases when same app is launched repeatedly from different sources. -TEST_F(ExternalAppsLaunchPolicyDeciderTest, +TEST_F(AppLauncherAbuseDetectorTest, TestRepeatedAppLaunches_SameAppDifferentSources) { - ExternalAppsLaunchPolicyDecider* policyDecider = - [[ExternalAppsLaunchPolicyDecider alloc] init]; + AppLauncherAbuseDetector* abuseDetector = + [[AppLauncherAbuseDetector alloc] init]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl1 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl1 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl1 fromSourcePageURL:kSourceUrl2]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl2]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl1 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl1 fromSourcePageURL:kSourceUrl3]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl3]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl1 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl1 fromSourcePageURL:kSourceUrl4]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl4]); } // Tests cases when different apps are launched from different sources. -TEST_F(ExternalAppsLaunchPolicyDeciderTest, +TEST_F(AppLauncherAbuseDetectorTest, TestRepeatedAppLaunches_DifferentAppsDifferentSources) { - ExternalAppsLaunchPolicyDecider* policyDecider = - [[ExternalAppsLaunchPolicyDecider alloc] init]; + AppLauncherAbuseDetector* abuseDetector = + [[AppLauncherAbuseDetector alloc] init]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl1 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl2 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl2 + [abuseDetector launchPolicyForURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl3 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl3 fromSourcePageURL:kSourceUrl3]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl3 + [abuseDetector launchPolicyForURL:kAppUrl3 fromSourcePageURL:kSourceUrl3]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl4 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl4 fromSourcePageURL:kSourceUrl4]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl4 + [abuseDetector launchPolicyForURL:kAppUrl4 fromSourcePageURL:kSourceUrl4]); } -// Tests blocking App launch only when the app have been launched through the -// policy decider before. -TEST_F(ExternalAppsLaunchPolicyDeciderTest, TestBlockLaunchingApp) { - ExternalAppsLaunchPolicyDecider* policyDecider = - [[ExternalAppsLaunchPolicyDecider alloc] init]; +// Tests blocking App launch only when the app have been allowed through the +// abuse detector before. +TEST_F(AppLauncherAbuseDetectorTest, TestBlockLaunchingApp) { + AppLauncherAbuseDetector* abuseDetector = + [[AppLauncherAbuseDetector alloc] init]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]); // Don't block for apps that have not been registered. - [policyDecider blockLaunchingAppURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]; + [abuseDetector blockLaunchingAppURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl1 + [abuseDetector launchPolicyForURL:kAppUrl1 fromSourcePageURL:kSourceUrl1]); // Block for apps that have been registered EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl2 + [abuseDetector launchPolicyForURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]); - [policyDecider didRequestLaunchExternalAppURL:kAppUrl2 + [abuseDetector didRequestLaunchExternalAppURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]; EXPECT_EQ(ExternalAppLaunchPolicyAllow, - [policyDecider launchPolicyForURL:kAppUrl2 + [abuseDetector launchPolicyForURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]); - [policyDecider blockLaunchingAppURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]; + [abuseDetector blockLaunchingAppURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]; EXPECT_EQ(ExternalAppLaunchPolicyBlock, - [policyDecider launchPolicyForURL:kAppUrl2 + [abuseDetector launchPolicyForURL:kAppUrl2 fromSourcePageURL:kSourceUrl2]); }
diff --git a/ios/chrome/browser/web/external_app_launching_state.h b/ios/chrome/browser/web/app_launching_state.h similarity index 70% rename from ios/chrome/browser/web/external_app_launching_state.h rename to ios/chrome/browser/web/app_launching_state.h index 82f7a7f0..368e12e 100644 --- a/ios/chrome/browser/web/external_app_launching_state.h +++ b/ios/chrome/browser/web/app_launching_state.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 IOS_CHROME_BROWSER_WEB_EXTERNAL_APP_LAUNCHING_STATE_H_ -#define IOS_CHROME_BROWSER_WEB_EXTERNAL_APP_LAUNCHING_STATE_H_ +#ifndef IOS_CHROME_BROWSER_WEB_APP_LAUNCHING_STATE_H_ +#define IOS_CHROME_BROWSER_WEB_APP_LAUNCHING_STATE_H_ #import <Foundation/Foundation.h> @@ -11,15 +11,15 @@ // consecutive. extern const double kDefaultMaxSecondsBetweenConsecutiveExternalAppLaunches; -// ExternalAppLaunchingState is a state for a single external application +// AppLaunchingState is a state for a single external application // represented by timestamp of the last time the app was launched, and the // number of consecutive launches. Launches are considered consecutive when the // time difference between them are less than // |kDefaultMaxSecondsBetweenConsecutiveExternalAppLaunches|. -// The ExternalAppLaunchingState doesn't know the source URL nor the destination -// URL, the ExternalAppsLaunchPolicyDecider object will have an -// ExternalAppLaunchingState object for each sourceURL/Application Scheme pair. -@interface ExternalAppLaunchingState : NSObject +// The AppLaunchingState doesn't know the source URL nor the destination +// URL, the AppLauncherAbuseDetector object will have an +// AppLaunchingState object for each sourceURL/Application Scheme pair. +@interface AppLaunchingState : NSObject // The max allowed seconds between 2 launches to be considered consecutive. @property(class, nonatomic) double maxSecondsBetweenConsecutiveLaunches; // Counts the number of current consecutive launches for the app. @@ -33,4 +33,4 @@ - (void)updateWithLaunchRequest; @end -#endif // IOS_CHROME_BROWSER_WEB_EXTERNAL_APP_LAUNCHING_STATE_H_ +#endif // IOS_CHROME_BROWSER_WEB_APP_LAUNCHING_STATE_H_
diff --git a/ios/chrome/browser/web/external_app_launching_state.mm b/ios/chrome/browser/web/app_launching_state.mm similarity index 91% rename from ios/chrome/browser/web/external_app_launching_state.mm rename to ios/chrome/browser/web/app_launching_state.mm index 4455e4a..8440236d 100644 --- a/ios/chrome/browser/web/external_app_launching_state.mm +++ b/ios/chrome/browser/web/app_launching_state.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/web/external_app_launching_state.h" +#import "ios/chrome/browser/web/app_launching_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -10,7 +10,7 @@ const double kDefaultMaxSecondsBetweenConsecutiveExternalAppLaunches = 30.0; -@implementation ExternalAppLaunchingState { +@implementation AppLaunchingState { // Timestamp of the last app launch request. NSDate* _lastAppLaunchTime; }
diff --git a/ios/chrome/browser/web/external_app_launching_state_unittest.mm b/ios/chrome/browser/web/app_launching_state_unittest.mm similarity index 80% rename from ios/chrome/browser/web/external_app_launching_state_unittest.mm rename to ios/chrome/browser/web/app_launching_state_unittest.mm index e39e8411..d6fd00c 100644 --- a/ios/chrome/browser/web/external_app_launching_state_unittest.mm +++ b/ios/chrome/browser/web/app_launching_state_unittest.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/web/external_app_launching_state.h" +#import "ios/chrome/browser/web/app_launching_state.h" #include "base/test/ios/wait_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -12,17 +12,17 @@ #error "This file requires ARC support." #endif -using ExternalAppLaunchingStateTest = PlatformTest; +using AppLaunchingStateTest = PlatformTest; // Tests that updateWithLaunchRequest counts the number of consecutive launches // correctly and also reset when the time between launches is more than the // predefined max allowed time between consecutive launches. -TEST_F(ExternalAppLaunchingStateTest, TestUpdateWithLaunchRequest) { - ExternalAppLaunchingState* state = [[ExternalAppLaunchingState alloc] init]; +TEST_F(AppLaunchingStateTest, TestUpdateWithLaunchRequest) { + AppLaunchingState* state = [[AppLaunchingState alloc] init]; EXPECT_EQ(kDefaultMaxSecondsBetweenConsecutiveExternalAppLaunches, - [ExternalAppLaunchingState maxSecondsBetweenConsecutiveLaunches]); + [AppLaunchingState maxSecondsBetweenConsecutiveLaunches]); double maxSecondsBetweenLaunches = 0.25; - [ExternalAppLaunchingState + [AppLaunchingState setMaxSecondsBetweenConsecutiveLaunches:maxSecondsBetweenLaunches]; EXPECT_EQ(0, state.consecutiveLaunchesCount); @@ -41,7 +41,7 @@ [state updateWithLaunchRequest]; EXPECT_EQ(2, state.consecutiveLaunchesCount); // reset back to the default value. - [ExternalAppLaunchingState + [AppLaunchingState setMaxSecondsBetweenConsecutiveLaunches: kDefaultMaxSecondsBetweenConsecutiveExternalAppLaunches]; }
diff --git a/ios/chrome/search_widget_extension/strings/resources/ios_search_widget_extension_strings_en-GB.xtb b/ios/chrome/search_widget_extension/strings/resources/ios_search_widget_extension_strings_en-GB.xtb index 1b009bc..11cc62a 100644 --- a/ios/chrome/search_widget_extension/strings/resources/ios_search_widget_extension_strings_en-GB.xtb +++ b/ios/chrome/search_widget_extension/strings/resources/ios_search_widget_extension_strings_en-GB.xtb
@@ -5,7 +5,7 @@ <translation id="1545749641540134597">Scan QR Code</translation> <translation id="2204254829203467991">New Search</translation> <translation id="4503488423518423533">Links that you copy will appear here.</translation> -<translation id="6120021866613542190">Incognito search</translation> +<translation id="6120021866613542190">Incognito Search</translation> <translation id="6196207969502475924">Voice Search</translation> <translation id="8637032741633610621">No copied link</translation> </translationbundle> \ No newline at end of file
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index dc710023..770a9778 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -59,6 +59,7 @@ "//ios/web", "//ios/web/public/test", "//net", + "//services/network:test_support", "//testing/gmock", "//testing/gtest", "//ui/base",
diff --git a/ios/chrome/test/testing_application_context.h b/ios/chrome/test/testing_application_context.h index d55c1ac..ea8b4d2 100644 --- a/ios/chrome/test/testing_application_context.h +++ b/ios/chrome/test/testing_application_context.h
@@ -13,9 +13,7 @@ #include "ios/chrome/browser/application_context.h" namespace network { -namespace mojom { -class URLLoaderFactory; -} +class TestURLLoaderFactory; class WeakWrapperSharedURLLoaderFactory; } // namespace network @@ -63,14 +61,13 @@ override; private: - network::mojom::URLLoaderFactory* GetSystemURLLoaderFactory(); - base::ThreadChecker thread_checker_; std::string application_locale_; PrefService* local_state_; ios::ChromeBrowserStateManager* chrome_browser_state_manager_; std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_; bool was_last_shutdown_clean_; + std::unique_ptr<network::TestURLLoaderFactory> test_url_loader_factory_; scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> system_shared_url_loader_factory_;
diff --git a/ios/chrome/test/testing_application_context.mm b/ios/chrome/test/testing_application_context.mm index e14a0e7..85c7afd 100644 --- a/ios/chrome/test/testing_application_context.mm +++ b/ios/chrome/test/testing_application_context.mm
@@ -13,6 +13,7 @@ #include "net/url_request/url_request_context_getter.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -22,14 +23,12 @@ : application_locale_("en"), local_state_(nullptr), chrome_browser_state_manager_(nullptr), - was_last_shutdown_clean_(false) { - // This is lazily-constructed, so it will fail via the NOTREACHED in - // GetSystemURLLoaderFactory() if it's actually used rather than just - // injected. - system_shared_url_loader_factory_ = - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - base::BindOnce(&TestingApplicationContext::GetSystemURLLoaderFactory, - base::Unretained(this) /* safe due to Detach call */)); + was_last_shutdown_clean_(false), + test_url_loader_factory_( + std::make_unique<network::TestURLLoaderFactory>()), + system_shared_url_loader_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + test_url_loader_factory_.get())) { DCHECK(!GetApplicationContext()); SetApplicationContext(this); } @@ -180,10 +179,3 @@ DCHECK(thread_checker_.CalledOnValidThread()); return nullptr; } - -network::mojom::URLLoaderFactory* -TestingApplicationContext::GetSystemURLLoaderFactory() { - DCHECK(thread_checker_.CalledOnValidThread()); - NOTREACHED(); - return nullptr; -}
diff --git a/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.h b/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.h index 3980168..4b4faba 100644 --- a/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.h +++ b/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.h
@@ -29,13 +29,6 @@ // Unregisters the mailto handler for browser state. virtual void RemoveMailtoHandling(); - // Deprecated: Set up mailto handling for the current user. - // The Signed-In Identity Block should return the primary signed in user. - // The Signed-In Identities Block should return all users signed in to Chrome. - virtual void PrepareMailtoHandling( - SignedInIdentityBlock signed_in_identity_block, - SignedInIdentitiesBlock signed_in_identities_block); - // Returns a properly localized title for the menu item or button used to open // the settings for this handler. Returns nil if mailto handling is not // supported by the provider.
diff --git a/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.mm b/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.mm index bb8bdd6..58989a0 100644 --- a/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.mm +++ b/ios/public/provider/chrome/browser/mailto/mailto_handler_provider.mm
@@ -17,10 +17,6 @@ void MailtoHandlerProvider::RemoveMailtoHandling() {} -void MailtoHandlerProvider::PrepareMailtoHandling( - SignedInIdentityBlock signed_in_identity_block, - SignedInIdentitiesBlock signed_in_identities_block) {} - NSString* MailtoHandlerProvider::MailtoHandlerSettingsTitle() const { return nil; }
diff --git a/ios/web/features.mm b/ios/web/features.mm index e72c9c9..899cc9a8 100644 --- a/ios/web/features.mm +++ b/ios/web/features.mm
@@ -8,7 +8,7 @@ namespace features { const base::Feature kContextMenuElementPostMessage{ - "ContextMenuElementPostMessage", base::FEATURE_ENABLED_BY_DEFAULT}; + "ContextMenuElementPostMessage", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kWebFrameMessaging{"WebFrameMessaging", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -20,7 +20,7 @@ base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kWebErrorPages{"WebErrorPages", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kWKHTTPSystemCookieStore{"WKHTTPSystemCookieStore", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/web/public/web_state/web_state_policy_decider.h b/ios/web/public/web_state/web_state_policy_decider.h index 975431f7..fac0fe34 100644 --- a/ios/web/public/web_state/web_state_policy_decider.h +++ b/ios/web/public/web_state/web_state_policy_decider.h
@@ -21,14 +21,19 @@ // Data Transfer Object for the additional information about navigation // request passed to WebStatePolicyDecider::ShouldAllowRequest(). struct RequestInfo { - RequestInfo(ui::PageTransition transition_type, bool target_frame_is_main) + RequestInfo(ui::PageTransition transition_type, + bool target_frame_is_main, + bool has_user_gesture) : transition_type(transition_type), - target_frame_is_main(target_frame_is_main) {} + target_frame_is_main(target_frame_is_main), + has_user_gesture(has_user_gesture) {} // The navigation page transition type. ui::PageTransition transition_type = ui::PageTransition::PAGE_TRANSITION_FIRST; // Indicates whether the navigation target frame is the main frame. bool target_frame_is_main = false; + // Indicates if there was a recent user interaction with the request frame. + bool has_user_gesture = false; }; // Removes self as a policy decider of |web_state_|.
diff --git a/ios/web/web_state/navigation_and_load_callbacks_inttest.mm b/ios/web/web_state/navigation_and_load_callbacks_inttest.mm index 80708c2..fa8b11c6 100644 --- a/ios/web/web_state/navigation_and_load_callbacks_inttest.mm +++ b/ios/web/web_state/navigation_and_load_callbacks_inttest.mm
@@ -5,6 +5,7 @@ #include <memory> #include <string> +#include "base/ios/ios_util.h" #include "base/scoped_observer.h" #include "base/strings/stringprintf.h" #include "ios/testing/embedded_test_server_handlers.h" @@ -1159,6 +1160,10 @@ // Tests going forward to a page rendered from post response. TEST_F(NavigationAndLoadCallbacksTest, ForwardPostNavigation) { + // TODO(crbug.com/854615): Test fails on iOS12. + if (base::ios::IsRunningOnIOS12OrLater()) { + return; + } const GURL url = test_server_->GetURL("/form?echo"); const GURL action = test_server_->GetURL("/echo");
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 9812e34d..1721a42 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -192,15 +192,6 @@ // stored errors is not expected to be high. const CertVerificationErrorsCacheType::size_type kMaxCertErrorsCount = 100; -// States for external URL requests. This enum is used in UMA and -// entries should not be re-ordered or deleted. -enum ExternalURLRequestStatus { - MAIN_FRAME_ALLOWED = 0, - SUBFRAME_ALLOWED, - SUBFRAME_BLOCKED, - NUM_EXTERNAL_URL_REQUEST_STATUS -}; - // Utility function for getting the source of NSErrors received by WKWebViews. WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { DCHECK(error); @@ -3701,29 +3692,6 @@ } - (BOOL)shouldOpenExternalURLForNavigationAction:(WKNavigationAction*)action { - ExternalURLRequestStatus requestStatus = NUM_EXTERNAL_URL_REQUEST_STATUS; - if ([self isMainFrameNavigationAction:action]) { - requestStatus = MAIN_FRAME_ALLOWED; - } else { - // If the request's main document URL differs from that at the time of the - // last user interaction, then the page has changed since the user last - // interacted. - BOOL userInteractedWithRequestMainFrame = - [self userClickedRecently] && - net::GURLWithNSURL(action.request.mainDocumentURL) == - _lastUserInteraction->main_document_url; - // Prevent subframe requests from opening an external URL if the user has - // not interacted with the request's main frame. - requestStatus = userInteractedWithRequestMainFrame ? SUBFRAME_ALLOWED - : SUBFRAME_BLOCKED; - } - DCHECK_NE(requestStatus, NUM_EXTERNAL_URL_REQUEST_STATUS); - UMA_HISTOGRAM_ENUMERATION("WebController.ExternalURLRequestBlocking", - requestStatus, NUM_EXTERNAL_URL_REQUEST_STATUS); - if (requestStatus == SUBFRAME_BLOCKED) { - return NO; - } - GURL requestURL = net::GURLWithNSURL(action.request.URL); return [_delegate respondsToSelector:@selector(webController: shouldOpenExternalURL:)] && @@ -4339,8 +4307,14 @@ ui::PageTransition transition = [self pageTransitionFromNavigationType:action.navigationType]; + BOOL userInteractedWithRequestMainFrame = + [self userClickedRecently] && + net::GURLWithNSURL(action.request.mainDocumentURL) == + _lastUserInteraction->main_document_url; + web::WebStatePolicyDecider::RequestInfo requestInfo( - transition, isMainFrameNavigationAction); + transition, [self isMainFrameNavigationAction:action], + userInteractedWithRequestMainFrame); BOOL allowLoad = self.webStateImpl->ShouldAllowRequest(action.request, requestInfo); if (!allowLoad && action.targetFrame.mainFrame) {
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm index 8e8361a..b67c176 100644 --- a/ios/web/web_state/web_state_impl_unittest.mm +++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -683,13 +683,12 @@ // A Google Mock matcher which matches WebStatePolicyDecider::RequestInfo. // This is needed because WebStatePolicyDecider::RequestInfo doesn't support // operator==. -MATCHER_P2(RequestInfoMatch, - expected_transition_type, - target_main_frame, - /* argument_name = */ "") { +MATCHER_P(RequestInfoMatch, expected_request_info, /* argument_name = */ "") { return ui::PageTransitionTypeIncludingQualifiersIs( - arg.transition_type, expected_transition_type) && - arg.target_frame_is_main == target_main_frame; + arg.transition_type, expected_request_info.transition_type) && + arg.target_frame_is_main == + expected_request_info.target_frame_is_main && + arg.has_user_gesture == expected_request_info.has_user_gesture; } // Verifies that policy deciders are correctly called by the web state. @@ -706,44 +705,34 @@ textEncodingName:nil]; // Test that ShouldAllowRequest() is called for the same parameters. - EXPECT_CALL( - decider, - ShouldAllowRequest( - request, RequestInfoMatch(ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_main_frame=*/true))) + WebStatePolicyDecider::RequestInfo request_info_main_frame( + ui::PageTransition::PAGE_TRANSITION_LINK, /*target_main_frame=*/true, + /*has_user_gesture=*/false); + EXPECT_CALL(decider, ShouldAllowRequest( + request, RequestInfoMatch(request_info_main_frame))) .Times(1) .WillOnce(Return(true)); - EXPECT_CALL( - decider2, - ShouldAllowRequest( - request, RequestInfoMatch(ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_main_frame=*/true))) + EXPECT_CALL(decider2, ShouldAllowRequest( + request, RequestInfoMatch(request_info_main_frame))) .Times(1) .WillOnce(Return(true)); - WebStatePolicyDecider::RequestInfo request_info_main_frame( - ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_frame_is_main=*/true); EXPECT_TRUE(web_state_->ShouldAllowRequest(request, request_info_main_frame)); - EXPECT_CALL( - decider, - ShouldAllowRequest( - request, RequestInfoMatch(ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_main_frame=*/false))) + WebStatePolicyDecider::RequestInfo request_info_iframe( + ui::PageTransition::PAGE_TRANSITION_LINK, /*target_main_frame=*/false, + /*has_user_gesture=*/false); + + EXPECT_CALL(decider, ShouldAllowRequest( + request, RequestInfoMatch(request_info_iframe))) .Times(1) .WillOnce(Return(true)); - EXPECT_CALL( - decider2, - ShouldAllowRequest( - request, RequestInfoMatch(ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_main_frame=*/false))) + EXPECT_CALL(decider2, ShouldAllowRequest( + request, RequestInfoMatch(request_info_iframe))) + .Times(1) .WillOnce(Return(true)); - WebStatePolicyDecider::RequestInfo request_info_iframe( - ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_frame_is_main=*/false); EXPECT_TRUE(web_state_->ShouldAllowRequest(request, request_info_iframe)); // Test that ShouldAllowRequest() is stopping on negative answer. Only one @@ -753,16 +742,12 @@ bool decider2_called = false; EXPECT_CALL( decider, - ShouldAllowRequest( - request, RequestInfoMatch(ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_main_frame=*/true))) + ShouldAllowRequest(request, RequestInfoMatch(request_info_main_frame))) .Times(AtMost(1)) .WillOnce(DoAll(Assign(&decider_called, true), Return(false))); EXPECT_CALL( decider2, - ShouldAllowRequest( - request, RequestInfoMatch(ui::PageTransition::PAGE_TRANSITION_LINK, - /*target_main_frame=*/true))) + ShouldAllowRequest(request, RequestInfoMatch(request_info_main_frame))) .Times(AtMost(1)) .WillOnce(DoAll(Assign(&decider2_called, true), Return(false)));
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h index 6199136..c34197e3a 100644 --- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h +++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
@@ -42,6 +42,7 @@ ukm::UkmRecorder* GetUkmRecorder() override; ukm::SourceId GetUkmSourceId() override; AddressNormalizer* GetAddressNormalizer() override; + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, UnmaskCardReason reason,
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm index 6756839..b5f282d 100644 --- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm +++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
@@ -66,6 +66,13 @@ return nullptr; } +security_state::SecurityLevel +WebViewAutofillClientIOS::GetSecurityLevelForUmaHistograms() { + // The metrics are not recorded for iOS webview, so return the count value + // which will not be recorded. + return security_state::SecurityLevel::SECURITY_LEVEL_COUNT; +} + void WebViewAutofillClientIOS::ShowAutofillSettings() { NOTREACHED(); }
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.h b/ios/web_view/internal/signin/ios_web_view_signin_client.h index 29233a7c..31d43582 100644 --- a/ios/web_view/internal/signin/ios_web_view_signin_client.h +++ b/ios/web_view/internal/signin/ios_web_view_signin_client.h
@@ -15,6 +15,7 @@ #include "components/signin/ios/browser/wait_for_network_callback_helper.h" #include "net/cookies/cookie_change_dispatcher.h" #include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" // iOS WebView specific signin client. class IOSWebViewSigninClient : public SigninClient, @@ -23,6 +24,7 @@ IOSWebViewSigninClient( PrefService* pref_service, net::URLRequestContextGetter* url_request_context, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, SigninErrorController* signin_error_controller, scoped_refptr<content_settings::CookieSettings> cookie_settings, scoped_refptr<HostContentSettingsMap> host_content_settings_map, @@ -39,10 +41,10 @@ scoped_refptr<TokenWebData> GetDatabase() override; PrefService* GetPrefs() override; net::URLRequestContextGetter* GetURLRequestContext() override; + scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; void DoFinalInit() override; bool CanRevokeCredentials() override; std::string GetSigninScopedDeviceId() override; - bool ShouldMergeSigninCredentialsIntoCookieJar() override; bool IsFirstRun() const override; bool AreSigninCookiesAllowed() override; void AddContentSettingsObserver( @@ -72,6 +74,7 @@ PrefService* pref_service_; // The URLRequestContext associated with this service. net::URLRequestContextGetter* url_request_context_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; // Used to check for errors related to signing in. SigninErrorController* signin_error_controller_; // Used to check if sign in cookies are allowed.
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.mm b/ios/web_view/internal/signin/ios_web_view_signin_client.mm index 6777550..2c4d469 100644 --- a/ios/web_view/internal/signin/ios_web_view_signin_client.mm +++ b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
@@ -15,6 +15,7 @@ IOSWebViewSigninClient::IOSWebViewSigninClient( PrefService* pref_service, net::URLRequestContextGetter* url_request_context, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, SigninErrorController* signin_error_controller, scoped_refptr<content_settings::CookieSettings> cookie_settings, scoped_refptr<HostContentSettingsMap> host_content_settings_map, @@ -23,6 +24,7 @@ std::make_unique<WaitForNetworkCallbackHelper>()), pref_service_(pref_service), url_request_context_(url_request_context), + url_loader_factory_(url_loader_factory), signin_error_controller_(signin_error_controller), cookie_settings_(cookie_settings), host_content_settings_map_(host_content_settings_map), @@ -62,6 +64,11 @@ return url_request_context_; } +scoped_refptr<network::SharedURLLoaderFactory> +IOSWebViewSigninClient::GetURLLoaderFactory() { + return url_loader_factory_; +} + void IOSWebViewSigninClient::DoFinalInit() {} bool IOSWebViewSigninClient::CanRevokeCredentials() { @@ -72,10 +79,6 @@ return GetOrCreateScopedDeviceIdPref(GetPrefs()); } -bool IOSWebViewSigninClient::ShouldMergeSigninCredentialsIntoCookieJar() { - return false; -} - bool IOSWebViewSigninClient::IsFirstRun() const { return false; }
diff --git a/ios/web_view/internal/signin/web_view_signin_client_factory.mm b/ios/web_view/internal/signin/web_view_signin_client_factory.mm index 2efa771..03a9d87 100644 --- a/ios/web_view/internal/signin/web_view_signin_client_factory.mm +++ b/ios/web_view/internal/signin/web_view_signin_client_factory.mm
@@ -48,6 +48,7 @@ WebViewBrowserState::FromBrowserState(context); return std::make_unique<IOSWebViewSigninClient>( browser_state->GetPrefs(), browser_state->GetRequestContext(), + browser_state->GetSharedURLLoaderFactory(), WebViewSigninErrorControllerFactory::GetForBrowserState(browser_state), WebViewCookieSettingsFactory::GetForBrowserState(browser_state), WebViewHostContentSettingsMapFactory::GetForBrowserState(browser_state),
diff --git a/mash/catalog_viewer/catalog_viewer.cc b/mash/catalog_viewer/catalog_viewer.cc index 5d84e3e..22518a6c 100644 --- a/mash/catalog_viewer/catalog_viewer.cc +++ b/mash/catalog_viewer/catalog_viewer.cc
@@ -222,9 +222,11 @@ } void CatalogViewer::OnStart() { - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) context()->QuitNow(); }
diff --git a/mash/example/views_examples/views_examples.cc b/mash/example/views_examples/views_examples.cc index d69f351..0347849 100644 --- a/mash/example/views_examples/views_examples.cc +++ b/mash/example/views_examples/views_examples.cc
@@ -31,10 +31,11 @@ private: // service_manager::Service: void OnStart() override { - aura_init_ = - views::AuraInit::Create(context()->connector(), context()->identity(), - "views_mus_resources.pak", std::string(), - nullptr, views::AuraInit::Mode::AURA_MUS); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) context()->QuitNow(); }
diff --git a/mash/example/window_type_launcher/window_type_launcher.cc b/mash/example/window_type_launcher/window_type_launcher.cc index bcf0119..609c009 100644 --- a/mash/example/window_type_launcher/window_type_launcher.cc +++ b/mash/example/window_type_launcher/window_type_launcher.cc
@@ -453,9 +453,11 @@ } void WindowTypeLauncher::OnStart() { - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) context()->QuitNow(); }
diff --git a/mash/simple_wm/simple_wm.cc b/mash/simple_wm/simple_wm.cc index e636552f..6370eac 100644 --- a/mash/simple_wm/simple_wm.cc +++ b/mash/simple_wm/simple_wm.cc
@@ -366,9 +366,11 @@ started_ = true; screen_ = std::make_unique<display::ScreenBase>(); display::Screen::SetScreenInstance(screen_.get()); - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS_WINDOW_MANAGER); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS_WINDOW_MANAGER; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) { context()->QuitNow(); return;
diff --git a/mash/task_viewer/task_viewer.cc b/mash/task_viewer/task_viewer.cc index 88f68c3..dee6a844 100644 --- a/mash/task_viewer/task_viewer.cc +++ b/mash/task_viewer/task_viewer.cc
@@ -297,9 +297,11 @@ } void TaskViewer::OnStart() { - aura_init_ = views::AuraInit::Create( - context()->connector(), context()->identity(), "views_mus_resources.pak", - std::string(), nullptr, views::AuraInit::Mode::AURA_MUS); + views::AuraInit::InitParams params; + params.connector = context()->connector(); + params.identity = context()->identity(); + params.mode = views::AuraInit::Mode::AURA_MUS; + aura_init_ = views::AuraInit::Create(params); if (!aura_init_) context()->QuitNow(); }
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 72c9abc..d8505db 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -155,6 +155,13 @@ // kExternalClearKeyForTesting. const char kClearKeyCdmPathForTesting[] = "clear-key-cdm-path-for-testing"; +// Enables hardware secure codecs support for testing. Codecs are separated by +// comma. Valid codecs are "vp8", "vp9" and "avc1". For example: +// --enable-hardware-secure-codecs-for-testing=vp8,vp9 +// --enable-hardware-secure-codecs-for-testing=avc1 +const char kEnableHardwareSecureCodecsForTesting[] = + "enable-hardware-secure-codecs-for-testing"; + // Overrides the default enabled library CDM interface version(s) with the one // specified with this switch, which will be the only version enabled. For // example, on a build where CDM 8, CDM 9 and CDM 10 are all supported
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index fac4289..3d65c34 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -81,6 +81,7 @@ MEDIA_EXPORT extern const char kMSEVideoBufferSizeLimitMb[]; MEDIA_EXPORT extern const char kClearKeyCdmPathForTesting[]; +MEDIA_EXPORT extern const char kEnableHardwareSecureCodecsForTesting[]; MEDIA_EXPORT extern const char kOverrideEnabledCdmInterfaceVersion[]; #if !defined(OS_ANDROID)
diff --git a/media/capabilities/BUILD.gn b/media/capabilities/BUILD.gn index a39858f..9dcfb7d 100644 --- a/media/capabilities/BUILD.gn +++ b/media/capabilities/BUILD.gn
@@ -20,10 +20,14 @@ sources = [ "bucket_utility.cc", "bucket_utility.h", + "in_memory_video_decode_stats_db_impl.cc", + "in_memory_video_decode_stats_db_impl.h", "video_decode_stats_db.cc", "video_decode_stats_db.h", "video_decode_stats_db_impl.cc", "video_decode_stats_db_impl.h", + "video_decode_stats_db_provider.cc", + "video_decode_stats_db_provider.h", ] public_deps = [ @@ -40,6 +44,7 @@ source_set("unit_tests") { testonly = true sources = [ + "in_memory_video_decode_stats_db_unittest.cc", "video_decode_stats_db_unittest.cc", ]
diff --git a/media/capabilities/in_memory_video_decode_stats_db_impl.cc b/media/capabilities/in_memory_video_decode_stats_db_impl.cc new file mode 100644 index 0000000..e01adfb --- /dev/null +++ b/media/capabilities/in_memory_video_decode_stats_db_impl.cc
@@ -0,0 +1,211 @@ +// 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 "media/capabilities/in_memory_video_decode_stats_db_impl.h" + +#include <memory> +#include <tuple> + +#include "base/files/file_path.h" +#include "base/format_macros.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/sequence_checker.h" +#include "base/strings/stringprintf.h" +#include "base/task_scheduler/post_task.h" +#include "media/base/bind_to_current_loop.h" +#include "media/capabilities/video_decode_stats_db_provider.h" + +namespace media { + +InMemoryVideoDecodeStatsDBFactory::InMemoryVideoDecodeStatsDBFactory( + VideoDecodeStatsDBProvider* seed_db_provider) + : seed_db_provider_(seed_db_provider) { + DVLOG(2) << __func__ << " has_seed_provider:" << !!seed_db_provider_; +} + +InMemoryVideoDecodeStatsDBFactory::~InMemoryVideoDecodeStatsDBFactory() = + default; + +std::unique_ptr<VideoDecodeStatsDB> +InMemoryVideoDecodeStatsDBFactory::CreateDB() { + return std::make_unique<InMemoryVideoDecodeStatsDBImpl>(seed_db_provider_); +} + +InMemoryVideoDecodeStatsDBImpl::InMemoryVideoDecodeStatsDBImpl( + VideoDecodeStatsDBProvider* seed_db_provider) + : seed_db_provider_(seed_db_provider), weak_ptr_factory_(this) { + DVLOG(2) << __func__; +} + +InMemoryVideoDecodeStatsDBImpl::~InMemoryVideoDecodeStatsDBImpl() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +void InMemoryVideoDecodeStatsDBImpl::Initialize(InitializeCB init_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(init_cb); + DCHECK(!db_init_); + + // Fetch an *initialized* seed DB. + if (seed_db_provider_) { + seed_db_provider_->GetVideoDecodeStatsDB( + base::BindOnce(&InMemoryVideoDecodeStatsDBImpl::OnGotSeedDB, + weak_ptr_factory_.GetWeakPtr(), std::move(init_cb))); + } else { + // No seed DB provider (e.g. guest session) means no work to do. + DVLOG(2) << __func__ << " NO seed db"; + db_init_ = true; + + // Bind to avoid reentrancy. + std::move(BindToCurrentLoop(std::move(init_cb))).Run(true); + } +} + +void InMemoryVideoDecodeStatsDBImpl::OnGotSeedDB(InitializeCB init_cb, + VideoDecodeStatsDB* db) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DVLOG(2) << __func__ << (db ? " has" : " null") << " seed db"; + + db_init_ = true; + seed_db_ = db; + + // Hard coding success = true. There are rare cases (e.g. disk corruption) + // where an incognito profile may fail to acquire a reference to the base + // profile's DB. But this just means incognito is in the same boat as guest + // profiles (never have a seed DB) and is not a show stopper. + std::move(init_cb).Run(true); +} + +void InMemoryVideoDecodeStatsDBImpl::AppendDecodeStats( + const VideoDescKey& key, + const DecodeStatsEntry& entry, + AppendDecodeStatsCB append_done_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(db_init_); + + DVLOG(3) << __func__ << " Reading key " << key.ToLogString() + << " from DB with intent to update with " << entry.ToLogString(); + + auto it = in_memory_db_.find(key.Serialize()); + if (it == in_memory_db_.end()) { + if (seed_db_) { + // |seed_db_| exists and no in-memory entry is found for this key, means + // we haven't checked the |seed_db_| yet. Query |seed_db_| and append new + // stats to any seed values. + seed_db_->GetDecodeStats( + key, base::BindOnce( + &InMemoryVideoDecodeStatsDBImpl::CompleteAppendWithSeedData, + weak_ptr_factory_.GetWeakPtr(), key, entry, + std::move(append_done_cb))); + return; + } + + // Otherwise, these are the first stats for this key. Add a a copy of + // |entry| to the database. + in_memory_db_.emplace(key.Serialize(), entry); + } else { + // We've already asked the |seed_db_| for its data. Just add the new stats + // to our local copy via the iterators reference. + it->second += entry; + } + + // Bind to avoid reentrancy. + std::move(BindToCurrentLoop(std::move(append_done_cb))).Run(true); +} + +void InMemoryVideoDecodeStatsDBImpl::GetDecodeStats( + const VideoDescKey& key, + GetDecodeStatsCB get_stats_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(db_init_); + + DVLOG(3) << __func__ << " " << key.ToLogString(); + + auto it = in_memory_db_.find(key.Serialize()); + if (it == in_memory_db_.end()) { + if (seed_db_) { + // |seed_db_| exists and no in-memory entry is found for this key, means + // we haven't checked the |seed_db_| yet. + seed_db_->GetDecodeStats( + key, base::BindOnce(&InMemoryVideoDecodeStatsDBImpl::OnGotSeedEntry, + weak_ptr_factory_.GetWeakPtr(), key, + std::move(get_stats_cb))); + } else { + // No seed data. Return an empty entry. Bind to avoid reentrancy. + std::move(BindToCurrentLoop(std::move(get_stats_cb))) + .Run(true, std::make_unique<DecodeStatsEntry>(0, 0, 0)); + } + } else { + // Return whatever what we found. Bind to avoid reentrancy. + std::move(BindToCurrentLoop(std::move(get_stats_cb))) + .Run(true, std::make_unique<DecodeStatsEntry>(it->second)); + } +} + +void InMemoryVideoDecodeStatsDBImpl::CompleteAppendWithSeedData( + const VideoDescKey& key, + const DecodeStatsEntry& entry, + AppendDecodeStatsCB append_done_cb, + bool read_success, + std::unique_ptr<DecodeStatsEntry> seed_entry) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(db_init_); + + if (!read_success) { + // Not a show stopper. Log it and carry on as if the seed DB were empty. + DVLOG(2) << __func__ << " FAILED seed DB read for " << key.ToLogString(); + DCHECK(!seed_entry); + } + + if (!seed_entry) + seed_entry = std::make_unique<DecodeStatsEntry>(0, 0, 0); + + // Add new stats to the seed entry and store in memory. + *seed_entry += entry; + in_memory_db_.emplace(key.Serialize(), *seed_entry); + + DVLOG(3) << __func__ << " Updating " << key.ToLogString() << " with " + << entry.ToLogString() << " aggregate:" << seed_entry->ToLogString(); + + std::move(append_done_cb).Run(true); +} + +void InMemoryVideoDecodeStatsDBImpl::OnGotSeedEntry( + const VideoDescKey& key, + GetDecodeStatsCB get_stats_cb, + bool success, + std::unique_ptr<DecodeStatsEntry> seed_entry) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // Failure is not a show stopper. Just a debug log... + DVLOG(3) << __func__ << " read " << (success ? "succeeded" : "FAILED!") + << " entry: " << (seed_entry ? seed_entry->ToLogString() : "null"); + + if (!seed_entry) + seed_entry = std::make_unique<DecodeStatsEntry>(0, 0, 0); + + // Always write to |in_memory_db_| to avoid querying |seed_db_| for this key + // going forward. + in_memory_db_.emplace(key.Serialize(), *seed_entry); + + std::move(get_stats_cb).Run(true, std::move(seed_entry)); +} + +void InMemoryVideoDecodeStatsDBImpl::DestroyStats( + base::OnceClosure destroy_done_cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DVLOG(2) << __func__; + + // Really, this is not reachable code because user's can't clear the history + // for a guest/incognito account. But if that ever changes, the reasonable + // thing is to wipe only the |in_memory_db_|. |seed_db_| can be cleared by the + // profile that owns it. + in_memory_db_.clear(); + + // Bind to avoid reentrancy. + std::move(BindToCurrentLoop(std::move(destroy_done_cb))).Run(); +} + +} // namespace media
diff --git a/media/capabilities/in_memory_video_decode_stats_db_impl.h b/media/capabilities/in_memory_video_decode_stats_db_impl.h new file mode 100644 index 0000000..bd93873 --- /dev/null +++ b/media/capabilities/in_memory_video_decode_stats_db_impl.h
@@ -0,0 +1,126 @@ +// 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 MEDIA_CAPABILITIES_IN_MEMORY_VIDEO_DECODE_STATS_DB_IMPL_H_ +#define MEDIA_CAPABILITIES_IN_MEMORY_VIDEO_DECODE_STATS_DB_IMPL_H_ + +#include <map> +#include <memory> + +#include "base/files/file_path.h" +#include "base/memory/weak_ptr.h" +#include "components/leveldb_proto/proto_database.h" +#include "media/base/media_export.h" +#include "media/base/video_codecs.h" +#include "media/capabilities/video_decode_stats_db.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +class VideoDecodeStatsDBProvider; + +// The in-memory database disappears with profile shutdown to preserve the +// privacy of off-the-record (OTR) browsing profiles (Guest and Incognito). It +// also allows the MediaCapabilities API to behave the same both on and +// off-the-record which prevents sites from detecting when users are OTR modes. +// VideoDecodeStatsDBProvider gives incognito profiles a hook to read the stats +// of the of the originating profile. Guest profiles are conceptually a blank +// slate and will not have a "seed" DB. +class MEDIA_EXPORT InMemoryVideoDecodeStatsDBFactory + : public VideoDecodeStatsDBFactory { + public: + // |seed_db_provider| provides access to a seed (read-only) DB instance. + // Callers must ensure the |seed_db_provider| outlives this factory and any + // databases it creates via CreateDB(). |seed_db_provider| may be null when no + // seed DB is available. + explicit InMemoryVideoDecodeStatsDBFactory( + VideoDecodeStatsDBProvider* seed_db_provider); + ~InMemoryVideoDecodeStatsDBFactory() override; + + // DB is not thread-safe and is bound to the sequence used at construction. + std::unique_ptr<VideoDecodeStatsDB> CreateDB() override; + + private: + // Provided at construction. Callers must ensure that object outlives this + // class. + VideoDecodeStatsDBProvider* seed_db_provider_; + + DISALLOW_COPY_AND_ASSIGN(InMemoryVideoDecodeStatsDBFactory); +}; + +class MEDIA_EXPORT InMemoryVideoDecodeStatsDBImpl : public VideoDecodeStatsDB { + public: + // Constructs the database. NOTE: must call Initialize() before using. + // |db| injects the level_db database instance for storing capabilities info. + // |dir| specifies where to store LevelDB files to disk. LevelDB generates a + // handful of files, so its recommended to provide a dedicated directory to + // keep them isolated. + explicit InMemoryVideoDecodeStatsDBImpl( + VideoDecodeStatsDBProvider* seed_db_provider); + ~InMemoryVideoDecodeStatsDBImpl() override; + + // Implement VideoDecodeStatsDB. + void Initialize(InitializeCB init_cb) override; + void AppendDecodeStats(const VideoDescKey& key, + const DecodeStatsEntry& entry, + AppendDecodeStatsCB append_done_cb) override; + void GetDecodeStats(const VideoDescKey& key, + GetDecodeStatsCB get_stats_cb) override; + void DestroyStats(base::OnceClosure destroy_done_cb) override; + + private: + // Called when the |seed_db_provider_| returns an initialized seed DB. Will + // run |init_cb|, marking the completion of Initialize(). + void OnGotSeedDB(base::OnceCallback<void(bool)> init_cb, + VideoDecodeStatsDB* seed_db); + + // Passed as the callback for |OnGotDecodeStats| by |AppendDecodeStats| to + // update the database once we've read the existing stats entry. + void CompleteAppendWithSeedData(const VideoDescKey& key, + const DecodeStatsEntry& entry, + AppendDecodeStatsCB append_done_cb, + bool read_success, + std::unique_ptr<DecodeStatsEntry> seed_entry); + + // Called when GetDecodeStats() operation was performed. |get_stats_cb| + // will be run with |success| and a |DecodeStatsEntry| created from + // |stats_proto| or nullptr if no entry was found for the requested key. + void OnGotSeedEntry(const VideoDescKey& key, + GetDecodeStatsCB get_stats_cb, + bool success, + std::unique_ptr<DecodeStatsEntry> seed_entry); + + // Indicates whether initialization is completed. + bool db_init_ = false; + + // Lazily provides |seed_db_| from original profile. Owned by original profile + // and may be null. + VideoDecodeStatsDBProvider* seed_db_provider_ = nullptr; + + // On-disk DB owned by the base profile for the off-the-record session. For + // incognito sessions, this will contain the original profile's stats. For + // guest sessions, this will be null (no notion of base profile). See + // |in_memory_db_|. + VideoDecodeStatsDB* seed_db_ = nullptr; + + // In-memory DB, mapping VideoDescKey strings -> DecodeStatsEntries. This is + // the primary storage (read and write) for this class. The |seed_db_| is + // read-only, and will only be queried when the |in_memory_db_| lacks an + // entry for a given key. + std::map<std::string, DecodeStatsEntry> in_memory_db_; + + // Ensures all access to class members come on the same sequence. API calls + // and callbacks should occur on the same sequence used during construction. + // LevelDB operations happen on a separate task runner, but all LevelDB + // callbacks to this happen on the checked sequence. + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<InMemoryVideoDecodeStatsDBImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(InMemoryVideoDecodeStatsDBImpl); +}; + +} // namespace media + +#endif // MEDIA_CAPABILITIES_IN_MEMORY_VIDEO_DECODE_STATS_DB_IMPL_H_
diff --git a/media/capabilities/in_memory_video_decode_stats_db_unittest.cc b/media/capabilities/in_memory_video_decode_stats_db_unittest.cc new file mode 100644 index 0000000..6f6264bf --- /dev/null +++ b/media/capabilities/in_memory_video_decode_stats_db_unittest.cc
@@ -0,0 +1,391 @@ +// 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 <memory> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/test/scoped_task_environment.h" +#include "media/capabilities/in_memory_video_decode_stats_db_impl.h" +#include "media/capabilities/video_decode_stats_db_provider.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::Eq; +using testing::Pointee; +using testing::IsNull; + +namespace media { + +static VideoDecodeStatsDB::VideoDescKey kTestKey() { + return VideoDecodeStatsDB::VideoDescKey::MakeBucketedKey( + VP9PROFILE_PROFILE3, gfx::Size(1024, 768), 60); +} + +static VideoDecodeStatsDB::DecodeStatsEntry kEmtpyEntry() { + return VideoDecodeStatsDB::DecodeStatsEntry(0, 0, 0); +} + +class MockSeedDB : public VideoDecodeStatsDB { + public: + MockSeedDB() = default; + ~MockSeedDB() override = default; + + MOCK_METHOD1(Initialize, void(InitializeCB init_cb)); + MOCK_METHOD3(AppendDecodeStats, + void(const VideoDescKey& key, + const DecodeStatsEntry& entry, + AppendDecodeStatsCB append_done_cb)); + MOCK_METHOD2(GetDecodeStats, + void(const VideoDescKey& key, GetDecodeStatsCB get_stats_cb)); + MOCK_METHOD1(DestroyStats, void(base::OnceClosure destroy_done_cb)); +}; + +class MockDBProvider : public VideoDecodeStatsDBProvider { + public: + MockDBProvider() = default; + ~MockDBProvider() override = default; + + MOCK_METHOD1(GetVideoDecodeStatsDB, void(GetCB get_db_b)); +}; + +template <bool WithSeedDB> +class InMemoryDBTestBase : public testing::Test { + public: + InMemoryDBTestBase() + : seed_db_(WithSeedDB ? new MockSeedDB() : nullptr), + db_provider_(WithSeedDB ? new MockDBProvider() : nullptr), + in_memory_db_(new InMemoryVideoDecodeStatsDBImpl(db_provider_.get())) { + // Setup MockDBProvider to provide the seed DB. No need to initialize the + // DB here since it too is a Mock. + if (db_provider_) { + using GetCB = VideoDecodeStatsDBProvider::GetCB; + ON_CALL(*db_provider_, GetVideoDecodeStatsDB(_)) + .WillByDefault([&](GetCB cb) { std::move(cb).Run(seed_db_.get()); }); + } + + // The InMemoryDB should NEVER modify the seed DB. + if (seed_db_) { + EXPECT_CALL(*seed_db_, AppendDecodeStats(_, _, _)).Times(0); + EXPECT_CALL(*seed_db_, DestroyStats(_)).Times(0); + } + } + + void InitializeEmptyDB() { + if (seed_db_) + EXPECT_CALL(*db_provider_, GetVideoDecodeStatsDB(_)); + + EXPECT_CALL(*this, InitializeCB(true)); + + in_memory_db_->Initialize(base::BindOnce(&InMemoryDBTestBase::InitializeCB, + base::Unretained(this))); + scoped_task_environment_.RunUntilIdle(); + } + + MOCK_METHOD1(InitializeCB, void(bool success)); + MOCK_METHOD1(AppendDecodeStatsCB, void(bool success)); + MOCK_METHOD2( + GetDecodeStatsCB, + void(bool success, + std::unique_ptr<VideoDecodeStatsDB::DecodeStatsEntry> entry)); + MOCK_METHOD0(DestroyStatsCB, void()); + + protected: + using VideoDescKey = media::VideoDecodeStatsDB::VideoDescKey; + using DecodeStatsEntry = media::VideoDecodeStatsDB::DecodeStatsEntry; + + base::test::ScopedTaskEnvironment scoped_task_environment_; + std::unique_ptr<MockSeedDB> seed_db_; + std::unique_ptr<MockDBProvider> db_provider_; + std::unique_ptr<InMemoryVideoDecodeStatsDBImpl> in_memory_db_; +}; + +// Specialization for tests that have/lack a seed DB. Some tests only make sense +// with seed DB, so we separate them. +class SeededInMemoryDBTest : public InMemoryDBTestBase<true> {}; +class SeedlessInMemoryDBTest : public InMemoryDBTestBase<false> {}; + +TEST_F(SeedlessInMemoryDBTest, ReadExpectingEmpty) { + InitializeEmptyDB(); + + // Database is empty, seed DB is empty => expect empty stats entry. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry())))); + + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(SeededInMemoryDBTest, ReadExpectingEmpty) { + InitializeEmptyDB(); + + // Make seed DB return null (empty) for this request. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)) + .WillOnce([](const auto& key, auto get_cb) { + std::move(get_cb).Run(true, nullptr); + }); + + // Database is empty, seed DB is empty => expect empty stats entry. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry())))); + + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(SeededInMemoryDBTest, ReadExpectingSeedData) { + InitializeEmptyDB(); + + // Setup seed DB to return an entry for the test key. + DecodeStatsEntry seed_entry(1000, 2, 10); + + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)) + .WillOnce([&](const auto& key, auto get_cb) { + std::move(get_cb).Run(true, + std::make_unique<DecodeStatsEntry>(seed_entry)); + }); + + // Seed DB has a an entry for the test key. Expect it! + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(seed_entry)))); + + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Verify a second GetDecodeStats() call with the same key does not trigger a + // second call to the seed DB (we cache it). + EXPECT_CALL(*seed_db_, GetDecodeStats(_, _)).Times(0); + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(seed_entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(SeededInMemoryDBTest, AppendReadAndDestroy) { + const DecodeStatsEntry seed_entry(1000, 2, 10); + const DecodeStatsEntry double_seed_entry(2000, 4, 20); + const DecodeStatsEntry triple_seed_entry(3000, 6, 30); + + InitializeEmptyDB(); + + // Setup seed DB to always return an entry for the test key. + ON_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)) + .WillByDefault([&](const auto& key, auto get_cb) { + std::move(get_cb).Run(true, + std::make_unique<DecodeStatsEntry>(seed_entry)); + }); + + // First append should trigger a request for the same key from the seed DB. + // Simulate a successful read providing seed_entry for that key. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)); + + // Append the same seed entry, doubling the stats for this key. + EXPECT_CALL(*this, AppendDecodeStatsCB(true)); + in_memory_db_->AppendDecodeStats( + kTestKey(), seed_entry, + base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Seed DB should not be queried again for this key. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)).Times(0); + + // Now verify that the stats were doubled by the append above. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(double_seed_entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Append the same seed entry again to triple the stats. Additional appends + // should not trigger queries the seed DB for this key. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)).Times(0); + in_memory_db_->AppendDecodeStats( + kTestKey(), seed_entry, + base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB, + base::Unretained(this))); + + // Verify we have 3x the stats. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(triple_seed_entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + // Now destroy the in-memory stats... + EXPECT_CALL(*this, DestroyStatsCB()); + in_memory_db_->DestroyStats(base::BindOnce( + &InMemoryDBTestBase::DestroyStatsCB, base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // With in-memory stats now gone, GetDecodeStats(kTestKey()) should again + // trigger a call to the seed DB and return the un-doubled seed stats. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)); + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(seed_entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(SeedlessInMemoryDBTest, AppendReadAndDestroy) { + const DecodeStatsEntry entry(50, 1, 5); + const DecodeStatsEntry double_entry(100, 2, 10); + + InitializeEmptyDB(); + + // Expect successful append to the empty seedless DB. + EXPECT_CALL(*this, AppendDecodeStatsCB(true)); + in_memory_db_->AppendDecodeStats( + kTestKey(), entry, + base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB, + base::Unretained(this))); + + // Verify stats can be read back. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Append same stats again to test summation. + EXPECT_CALL(*this, AppendDecodeStatsCB(true)); + in_memory_db_->AppendDecodeStats( + kTestKey(), entry, + base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB, + base::Unretained(this))); + + // Verify doubled stats can be read back. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(double_entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Now destroy the in-memory stats... + EXPECT_CALL(*this, DestroyStatsCB()); + in_memory_db_->DestroyStats(base::BindOnce( + &InMemoryDBTestBase::DestroyStatsCB, base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Verify DB now empty for this key. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry())))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(SeededInMemoryDBTest, ProvidedNullSeedDB) { + // DB provider may provide a null seed DB if it encounters some error. + EXPECT_CALL(*db_provider_, GetVideoDecodeStatsDB(_)) + .WillOnce([](auto get_db_cb) { std::move(get_db_cb).Run(nullptr); }); + + // Failing to obtain the seed DB is not a show stopper. The in-memory DB + // should simply carry on in a seedless fashion. + EXPECT_CALL(*this, InitializeCB(true)); + in_memory_db_->Initialize(base::BindOnce(&InMemoryDBTestBase::InitializeCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Writes still succeed. + EXPECT_CALL(*this, AppendDecodeStatsCB(true)); + const DecodeStatsEntry entry(50, 1, 5); + in_memory_db_->AppendDecodeStats( + kTestKey(), entry, + base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB, + base::Unretained(this))); + + // Reads should still succeed. + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(SeededInMemoryDBTest, SeedReadFailureOnGettingStats) { + // Everything seems fine at initialization... + InitializeEmptyDB(); + + // But seed DB will repeatedly fail to provide stats. + ON_CALL(*seed_db_, GetDecodeStats(_, _)) + .WillByDefault([](const auto& key, auto get_cb) { + std::move(get_cb).Run(false, nullptr); + }); + + // Reading the in-memory will still try to read the seed DB, and the read + // callback will simply report that the DB is empty for this key. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)); + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(kEmtpyEntry())))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(SeededInMemoryDBTest, SeedReadFailureOnAppendingingStats) { + // Everything seems fine at initialization... + InitializeEmptyDB(); + + // But seed DB will repeatedly fail to provide stats. + ON_CALL(*seed_db_, GetDecodeStats(_, _)) + .WillByDefault([](const auto& key, auto get_cb) { + std::move(get_cb).Run(false, nullptr); + }); + + // Appending to the in-memory will still try to read the seed DB, and the + // append will proceed successfully as if the seed DB were empty. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)); + EXPECT_CALL(*this, AppendDecodeStatsCB(true)); + const DecodeStatsEntry entry(50, 1, 5); + in_memory_db_->AppendDecodeStats( + kTestKey(), entry, + base::BindOnce(&InMemoryDBTestBase::AppendDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + ::testing::Mock::VerifyAndClear(this); + + // Reading the appended data works without issue and does not trigger new + // queries to the seed DB. + EXPECT_CALL(*seed_db_, GetDecodeStats(Eq(kTestKey()), _)).Times(0); + EXPECT_CALL(*this, GetDecodeStatsCB(true, Pointee(Eq(entry)))); + in_memory_db_->GetDecodeStats( + kTestKey(), base::BindOnce(&InMemoryDBTestBase::GetDecodeStatsCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); +} + +} // namespace media
diff --git a/media/capabilities/video_decode_stats_db.cc b/media/capabilities/video_decode_stats_db.cc index a3e5b85..2978a28f 100644 --- a/media/capabilities/video_decode_stats_db.cc +++ b/media/capabilities/video_decode_stats_db.cc
@@ -4,6 +4,8 @@ #include "media/capabilities/video_decode_stats_db.h" +#include "base/format_macros.h" +#include "base/strings/stringprintf.h" #include "media/capabilities/bucket_utility.h" namespace media { @@ -25,12 +27,72 @@ int frame_rate) : codec_profile(codec_profile), size(size), frame_rate(frame_rate) {} +std::string VideoDecodeStatsDB::VideoDescKey::Serialize() const { + return base::StringPrintf("%d|%s|%d", static_cast<int>(codec_profile), + size.ToString().c_str(), frame_rate); +} + +std::string VideoDecodeStatsDB::VideoDescKey::ToLogString() const { + return "Key {" + Serialize() + "}"; +} + VideoDecodeStatsDB::DecodeStatsEntry::DecodeStatsEntry( uint64_t frames_decoded, uint64_t frames_dropped, uint64_t frames_decoded_power_efficient) : frames_decoded(frames_decoded), frames_dropped(frames_dropped), - frames_decoded_power_efficient(frames_decoded_power_efficient) {} + frames_decoded_power_efficient(frames_decoded_power_efficient) { + DCHECK_GE(frames_decoded, 0u); + DCHECK_GE(frames_dropped, 0u); + DCHECK_GE(frames_decoded_power_efficient, 0u); +} + +VideoDecodeStatsDB::DecodeStatsEntry::DecodeStatsEntry( + const DecodeStatsEntry& entry) + : frames_decoded(entry.frames_decoded), + frames_dropped(entry.frames_dropped), + frames_decoded_power_efficient(entry.frames_decoded_power_efficient) {} + +std::string VideoDecodeStatsDB::DecodeStatsEntry::ToLogString() const { + return base::StringPrintf( + "DecodeStatsEntry {frames decoded:%" PRIu64 ", dropped:%" PRIu64 + ", power efficient decoded:%" PRIu64 "}", + frames_decoded, frames_dropped, frames_decoded_power_efficient); +} + +VideoDecodeStatsDB::DecodeStatsEntry& VideoDecodeStatsDB::DecodeStatsEntry:: +operator+=(const DecodeStatsEntry& right) { + DCHECK_GE(right.frames_decoded, 0u); + DCHECK_GE(right.frames_dropped, 0u); + DCHECK_GE(right.frames_decoded_power_efficient, 0u); + + frames_decoded += right.frames_decoded; + frames_dropped += right.frames_dropped; + frames_decoded_power_efficient += right.frames_decoded_power_efficient; + return *this; +} + +bool operator==(const VideoDecodeStatsDB::VideoDescKey& x, + const VideoDecodeStatsDB::VideoDescKey& y) { + return x.codec_profile == y.codec_profile && x.size == y.size && + x.frame_rate == y.frame_rate; +} +bool operator!=(const VideoDecodeStatsDB::VideoDescKey& x, + const VideoDecodeStatsDB::VideoDescKey& y) { + return !(x == y); +} + +bool operator==(const VideoDecodeStatsDB::DecodeStatsEntry& x, + const VideoDecodeStatsDB::DecodeStatsEntry& y) { + return x.frames_decoded == y.frames_decoded && + x.frames_dropped == y.frames_dropped && + x.frames_decoded_power_efficient == y.frames_decoded_power_efficient; +} + +bool operator!=(const VideoDecodeStatsDB::DecodeStatsEntry& x, + const VideoDecodeStatsDB::DecodeStatsEntry& y) { + return !(x == y); +} } // namespace media
diff --git a/media/capabilities/video_decode_stats_db.h b/media/capabilities/video_decode_stats_db.h index 83f3d30..7656cc1 100644 --- a/media/capabilities/video_decode_stats_db.h +++ b/media/capabilities/video_decode_stats_db.h
@@ -6,8 +6,10 @@ #define MEDIA_CAPABILITIES_VIDEO_DECODE_STATS_DB_H_ #include <memory> +#include <string> -#include "base/callback.h" +#include "base/callback_forward.h" +#include "base/logging.h" #include "base/macros.h" #include "media/base/media_export.h" #include "media/base/video_codecs.h" @@ -26,11 +28,19 @@ const gfx::Size& size, int frame_rate); + // Returns a concise string representation of the key for storing in DB. + std::string Serialize() const; + + // For debug logging. NOT interchangeable with Serialize(). + std::string ToLogString() const; + + // Note: operator == and != are defined outside this class. const VideoCodecProfile codec_profile; const gfx::Size size; const int frame_rate; private: + // All key's should be "bucketed" using MakeBucketedKey(...). VideoDescKey(VideoCodecProfile codec_profile, const gfx::Size& size, int frame_rate); @@ -42,6 +52,15 @@ DecodeStatsEntry(uint64_t frames_decoded, uint64_t frames_dropped, uint64_t frames_decoded_power_efficient); + DecodeStatsEntry(const DecodeStatsEntry& entry); + + // Add stats from |right| to |this| entry. + DecodeStatsEntry& operator+=(const DecodeStatsEntry& right); + + // For debug logging. + std::string ToLogString() const; + + // Note: operator == and != are defined outside this class. uint64_t frames_decoded; uint64_t frames_dropped; uint64_t frames_decoded_power_efficient; @@ -53,7 +72,8 @@ // before calling other APIs. Initialization must be RE-RUN after calling // DestroyStats() and receiving its completion callback. |init_cb| must not be // a null callback. - virtual void Initialize(base::OnceCallback<void(bool)> init_cb) = 0; + using InitializeCB = base::OnceCallback<void(bool)>; + virtual void Initialize(InitializeCB init_cb) = 0; // Appends `stats` to existing entry associated with `key`. Will create a new // entry if none exists. The operation is asynchronous. The caller should be @@ -79,6 +99,15 @@ virtual void DestroyStats(base::OnceClosure destroy_done_cb) = 0; }; +MEDIA_EXPORT bool operator==(const VideoDecodeStatsDB::VideoDescKey& x, + const VideoDecodeStatsDB::VideoDescKey& y); +MEDIA_EXPORT bool operator!=(const VideoDecodeStatsDB::VideoDescKey& x, + const VideoDecodeStatsDB::VideoDescKey& y); +MEDIA_EXPORT bool operator==(const VideoDecodeStatsDB::DecodeStatsEntry& x, + const VideoDecodeStatsDB::DecodeStatsEntry& y); +MEDIA_EXPORT bool operator!=(const VideoDecodeStatsDB::DecodeStatsEntry& x, + const VideoDecodeStatsDB::DecodeStatsEntry& y); + // Factory interface to create a DB instance. class MEDIA_EXPORT VideoDecodeStatsDBFactory { public:
diff --git a/media/capabilities/video_decode_stats_db_impl.cc b/media/capabilities/video_decode_stats_db_impl.cc index 0dc22b6..b184ebc 100644 --- a/media/capabilities/video_decode_stats_db_impl.cc +++ b/media/capabilities/video_decode_stats_db_impl.cc
@@ -8,10 +8,9 @@ #include <tuple> #include "base/files/file_path.h" -#include "base/format_macros.h" +#include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/sequence_checker.h" -#include "base/strings/stringprintf.h" #include "base/task_scheduler/post_task.h" #include "components/leveldb_proto/proto_database_impl.h" #include "media/capabilities/video_decode_stats.pb.h" @@ -24,26 +23,6 @@ // See comments in components/leveldb_proto/leveldb_database.h const char kDatabaseClientName[] = "VideoDecodeStatsDB"; -// Serialize the |entry| to a string to use as a key in the database. -std::string SerializeKey(const VideoDecodeStatsDB::VideoDescKey& key) { - return base::StringPrintf("%d|%s|%d", static_cast<int>(key.codec_profile), - key.size.ToString().c_str(), key.frame_rate); -} - -// For debug logging. -std::string KeyToString(const VideoDecodeStatsDB::VideoDescKey& key) { - return "Key {" + SerializeKey(key) + "}"; -} - -// For debug logging. -std::string EntryToString(const VideoDecodeStatsDB::DecodeStatsEntry& entry) { - return base::StringPrintf("DecodeStatsEntry {frames decoded:%" PRIu64 - ", dropped:%" PRIu64 - ", power efficient decoded:%" PRIu64 "}", - entry.frames_decoded, entry.frames_dropped, - entry.frames_decoded_power_efficient); -} - }; // namespace VideoDecodeStatsDBImplFactory::VideoDecodeStatsDBImplFactory( @@ -57,13 +36,13 @@ std::unique_ptr<VideoDecodeStatsDB> VideoDecodeStatsDBImplFactory::CreateDB() { std::unique_ptr<leveldb_proto::ProtoDatabase<DecodeStatsProto>> db_; - auto inner_db = + auto proto_db = std::make_unique<leveldb_proto::ProtoDatabaseImpl<DecodeStatsProto>>( base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskPriority::BACKGROUND, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})); - return std::make_unique<VideoDecodeStatsDBImpl>(std::move(inner_db), db_dir_); + return std::make_unique<VideoDecodeStatsDBImpl>(std::move(proto_db), db_dir_); } VideoDecodeStatsDBImpl::VideoDecodeStatsDBImpl( @@ -78,8 +57,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } -void VideoDecodeStatsDBImpl::Initialize( - base::OnceCallback<void(bool)> init_cb) { +void VideoDecodeStatsDBImpl::Initialize(InitializeCB init_cb) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(init_cb); DCHECK(!IsInitialized()); @@ -94,8 +72,7 @@ weak_ptr_factory_.GetWeakPtr(), std::move(init_cb))); } -void VideoDecodeStatsDBImpl::OnInit(base::OnceCallback<void(bool)> init_cb, - bool success) { +void VideoDecodeStatsDBImpl::OnInit(InitializeCB init_cb, bool success) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOG(2) << __func__ << (success ? " succeeded" : " FAILED!"); UMA_HISTOGRAM_BOOLEAN("Media.VideoDecodeStatsDB.OpSuccess.Initialize", @@ -122,10 +99,10 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(IsInitialized()); - DVLOG(3) << __func__ << " Reading key " << KeyToString(key) - << " from DB with intent to update with " << EntryToString(entry); + DVLOG(3) << __func__ << " Reading key " << key.ToLogString() + << " from DB with intent to update with " << entry.ToLogString(); - db_->GetEntry(SerializeKey(key), + db_->GetEntry(key.Serialize(), base::BindOnce(&VideoDecodeStatsDBImpl::WriteUpdatedEntry, weak_ptr_factory_.GetWeakPtr(), key, entry, std::move(append_done_cb))); @@ -136,10 +113,10 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(IsInitialized()); - DVLOG(3) << __func__ << " " << KeyToString(key); + DVLOG(3) << __func__ << " " << key.ToLogString(); db_->GetEntry( - SerializeKey(key), + key.Serialize(), base::BindOnce(&VideoDecodeStatsDBImpl::OnGotDecodeStats, weak_ptr_factory_.GetWeakPtr(), std::move(get_stats_cb))); } @@ -158,7 +135,7 @@ read_success); if (!read_success) { - DVLOG(2) << __func__ << " FAILED DB read for " << KeyToString(key) + DVLOG(2) << __func__ << " FAILED DB read for " << key.ToLogString() << "; ignoring update!"; std::move(append_done_cb).Run(false); return; @@ -184,17 +161,17 @@ prev_stats_proto->set_frames_decoded_power_efficient( sum_frames_decoded_power_efficient); - DVLOG(3) << __func__ << " Updating " << KeyToString(key) << " with " - << EntryToString(entry) << " aggregate:" - << EntryToString( - DecodeStatsEntry(sum_frames_decoded, sum_frames_dropped, - sum_frames_decoded_power_efficient)); + DVLOG(3) << __func__ << " Updating " << key.ToLogString() << " with " + << entry.ToLogString() << " aggregate:" + << DecodeStatsEntry(sum_frames_decoded, sum_frames_dropped, + sum_frames_decoded_power_efficient) + .ToLogString(); using ProtoDecodeStatsEntry = leveldb_proto::ProtoDatabase<DecodeStatsProto>; std::unique_ptr<ProtoDecodeStatsEntry::KeyEntryVector> entries = std::make_unique<ProtoDecodeStatsEntry::KeyEntryVector>(); - entries->emplace_back(SerializeKey(key), *prev_stats_proto); + entries->emplace_back(key.Serialize(), *prev_stats_proto); db_->UpdateEntries(std::move(entries), std::make_unique<leveldb_proto::KeyVector>(), @@ -227,7 +204,7 @@ } DVLOG(3) << __func__ << " read " << (success ? "succeeded" : "FAILED!") - << " entry: " << (entry ? EntryToString(*entry) : "nullptr"); + << " entry: " << (entry ? entry->ToLogString() : "nullptr"); std::move(get_stats_cb).Run(success, std::move(entry)); }
diff --git a/media/capabilities/video_decode_stats_db_impl.h b/media/capabilities/video_decode_stats_db_impl.h index 43f2e46..f83289c 100644 --- a/media/capabilities/video_decode_stats_db_impl.h +++ b/media/capabilities/video_decode_stats_db_impl.h
@@ -27,6 +27,9 @@ class MEDIA_EXPORT VideoDecodeStatsDBImplFactory : public VideoDecodeStatsDBFactory { public: + // |db_dir| specifies where to store LevelDB files to disk. LevelDB generates + // a handful of files, so its recommended to provide a dedicated directory to + // keep them isolated. explicit VideoDecodeStatsDBImplFactory(base::FilePath db_dir); ~VideoDecodeStatsDBImplFactory() override; std::unique_ptr<VideoDecodeStatsDB> CreateDB() override; @@ -53,7 +56,7 @@ ~VideoDecodeStatsDBImpl() override; // Implement VideoDecodeStatsDB. - void Initialize(base::OnceCallback<void(bool)> init_cb) override; + void Initialize(InitializeCB init_cb) override; void AppendDecodeStats(const VideoDescKey& key, const DecodeStatsEntry& entry, AppendDecodeStatsCB append_done_cb) override; @@ -66,7 +69,7 @@ // Called when the database has been initialized. Will immediately call // |init_cb| to forward |success|. - void OnInit(base::OnceCallback<void(bool)> init_cb, bool success); + void OnInit(InitializeCB init_cb, bool success); // Returns true if the DB is successfully initialized. bool IsInitialized();
diff --git a/media/capabilities/video_decode_stats_db_provider.cc b/media/capabilities/video_decode_stats_db_provider.cc new file mode 100644 index 0000000..b58e44c7 --- /dev/null +++ b/media/capabilities/video_decode_stats_db_provider.cc
@@ -0,0 +1,11 @@ +// 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 "media/capabilities/video_decode_stats_db_provider.h" + +namespace media { + +VideoDecodeStatsDBProvider::~VideoDecodeStatsDBProvider() = default; + +} // namespace media
diff --git a/media/capabilities/video_decode_stats_db_provider.h b/media/capabilities/video_decode_stats_db_provider.h new file mode 100644 index 0000000..6e56d9c --- /dev/null +++ b/media/capabilities/video_decode_stats_db_provider.h
@@ -0,0 +1,36 @@ +// 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 MEDIA_CAPABILITIES_VIDEO_DECODE_STATS_DB_PROVIDER_H_ +#define MEDIA_CAPABILITIES_VIDEO_DECODE_STATS_DB_PROVIDER_H_ + +#include "base/callback_forward.h" +#include "media/base/media_export.h" + +namespace media { + +class VideoDecodeStatsDB; + +// Interface for extracting a pointer to the DB from its owner. DB lifetime is +// assumed to match that of the provider. Callers must not use DB after provider +// has been destroyed. This allows sharing a "seed" DB instance between an +// Incognito profile and the original profile, which re-uses the in-memory +// cache for that DB and avoids race conditions of instantiating a second DB +// that reads the same files. +class MEDIA_EXPORT VideoDecodeStatsDBProvider { + public: + // Request a pointer to the *initialized* DB owned by this provider. Call + // lazily to avoid triggering unnecessary DB initialization. |db| is null in + // the event of an error. Callback may be run immediately if |db| is already + // initialized by provider. + using GetCB = base::OnceCallback<void(VideoDecodeStatsDB* db)>; + virtual void GetVideoDecodeStatsDB(GetCB get_db_b) = 0; + + protected: + virtual ~VideoDecodeStatsDBProvider(); +}; + +} // namespace media + +#endif // MEDIA_CAPABILITIES_VIDEO_DECODE_STATS_DB_PROVIDER_H_ \ No newline at end of file
diff --git a/media/capabilities/video_decode_stats_db_unittest.cc b/media/capabilities/video_decode_stats_db_unittest.cc index 33444625..6bb83107 100644 --- a/media/capabilities/video_decode_stats_db_unittest.cc +++ b/media/capabilities/video_decode_stats_db_unittest.cc
@@ -83,13 +83,6 @@ DISALLOW_COPY_AND_ASSIGN(VideoDecodeStatsDBImplTest); }; -MATCHER_P(EntryEq, other_entry, "") { - return arg.frames_decoded == other_entry.frames_decoded && - arg.frames_dropped == other_entry.frames_dropped && - arg.frames_decoded_power_efficient == - other_entry.frames_decoded_power_efficient; -} - TEST_F(VideoDecodeStatsDBImplTest, ReadExpectingNothing) { EXPECT_CALL(*this, OnInitialize(true)); fake_db_->InitCallback(true); @@ -122,7 +115,7 @@ fake_db_->GetCallback(true); fake_db_->UpdateCallback(true); - EXPECT_CALL(*this, MockGetDecodeStatsCb(true, Pointee(EntryEq(entry)))); + EXPECT_CALL(*this, MockGetDecodeStatsCb(true, Pointee(Eq(entry)))); stats_db_->GetDecodeStats( key, base::BindOnce(&VideoDecodeStatsDBImplTest::GetDecodeStatsCb, base::Unretained(this))); @@ -139,8 +132,7 @@ // Expect to read what was written (2x the initial entry). VideoDecodeStatsDB::DecodeStatsEntry aggregate_entry(2000, 4, 20); - EXPECT_CALL(*this, - MockGetDecodeStatsCb(true, Pointee(EntryEq(aggregate_entry)))); + EXPECT_CALL(*this, MockGetDecodeStatsCb(true, Pointee(Eq(aggregate_entry)))); stats_db_->GetDecodeStats( key, base::BindOnce(&VideoDecodeStatsDBImplTest::GetDecodeStatsCb, base::Unretained(this)));
diff --git a/media/capture/video/video_capture_jpeg_decoder_impl.cc b/media/capture/video/video_capture_jpeg_decoder_impl.cc index bb5d16f..b82bae9 100644 --- a/media/capture/video/video_capture_jpeg_decoder_impl.cc +++ b/media/capture/video/video_capture_jpeg_decoder_impl.cc
@@ -11,7 +11,7 @@ VideoCaptureJpegDecoderImpl::VideoCaptureJpegDecoderImpl( MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory, - scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner, + scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, DecodeDoneCB decode_done_cb, base::RepeatingCallback<void(const std::string&)> send_log_message_cb) : jpeg_decoder_factory_(std::move(jpeg_decoder_factory)),
diff --git a/media/capture/video/video_capture_jpeg_decoder_impl.h b/media/capture/video/video_capture_jpeg_decoder_impl.h index b3010fb..a1bfcee 100644 --- a/media/capture/video/video_capture_jpeg_decoder_impl.h +++ b/media/capture/video/video_capture_jpeg_decoder_impl.h
@@ -43,7 +43,7 @@ // VideoCaptureGpuJpegDecoder is destroyed. VideoCaptureJpegDecoderImpl( MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory, - scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner, + scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, DecodeDoneCB decode_done_cb, base::RepeatingCallback<void(const std::string&)> send_log_message_cb); ~VideoCaptureJpegDecoderImpl() override; @@ -78,7 +78,7 @@ void DestroyDecoderOnIOThread(base::WaitableEvent* event); MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_; - scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_; + scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_; // The underlying JPEG decode accelerator. std::unique_ptr<media::JpegDecodeAccelerator> decoder_;
diff --git a/media/capture/video/win/video_capture_device_factory_win.cc b/media/capture/video/win/video_capture_device_factory_win.cc index 9b3a88c..97851a3 100644 --- a/media/capture/video/win/video_capture_device_factory_win.cc +++ b/media/capture/video/win/video_capture_device_factory_win.cc
@@ -488,7 +488,7 @@ PlatformSupportsMediaFoundation() ? MFEnumDeviceSources : nullptr; direct_show_enum_devices_func_ = base::BindRepeating(&EnumerateDirectShowDevices); - if (!PlatformSupportsMediaFoundation()) { + if (use_media_foundation_ && !PlatformSupportsMediaFoundation()) { use_media_foundation_ = false; LogVideoCaptureWinBackendUsed( VideoCaptureWinBackendUsed::kUsingDirectShowAsFallback);
diff --git a/media/cdm/BUILD.gn b/media/cdm/BUILD.gn index f3dbef7..deff5005 100644 --- a/media/cdm/BUILD.gn +++ b/media/cdm/BUILD.gn
@@ -98,12 +98,6 @@ "cdm_host_files.cc", "cdm_host_files.h", ] - deps += [ - # Needed for finding CDM path from CDM adapter path. - # TODO(xhwang): Remove this dependency when CDM adapter is deprecated. - # See http://crbug.com/403462 - "//third_party/widevine/cdm:headers", - ] } } }
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 0e3e9813..6eb3ac6 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -105,6 +105,7 @@ "gpu_video_decode_accelerator_factory.h", "gpu_video_encode_accelerator_factory.cc", "gpu_video_encode_accelerator_factory.h", + "image_processor.h", ] public_deps = [
diff --git a/media/gpu/image_processor.h b/media/gpu/image_processor.h new file mode 100644 index 0000000..aadfec3 --- /dev/null +++ b/media/gpu/image_processor.h
@@ -0,0 +1,74 @@ +// 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 MEDIA_GPU_IMAGE_PROCESSOR_H_ +#define MEDIA_GPU_IMAGE_PROCESSOR_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/files/scoped_file.h" +#include "media/base/video_frame.h" +#include "media/base/video_types.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +// An image processor is used to convert from one image format to another (e.g. +// I420 to NV12) while optionally scaling. It is useful in situations where +// a given video hardware (e.g. decoder or encoder) accepts or produces data +// in a format different from what the rest of the pipeline expects. +// +// This class exposes the interface that an image processor should implement. +class ImageProcessor { + public: + // Initializes the processor to convert from |input_format| to |output_format| + // and/or scale from |input_visible_size| to |output_visible_size|. + // Request the input buffers to be of at least |input_allocated_size| and the + // output buffers to be of at least |output_allocated_size|. The number of + // input buffers and output buffers will be |num_buffers|. Provided |error_cb| + // will be posted to the child thread if an error occurs after initialization. + // Return true if the requested configuration is supported. + virtual bool Initialize(VideoPixelFormat input_format, + VideoPixelFormat output_format, + gfx::Size input_visible_size, + gfx::Size input_allocated_size, + gfx::Size output_visible_size, + gfx::Size output_allocated_size, + int num_buffers, + const base::Closure& error_cb) = 0; + + // Returns input allocated size required by the processor to be fed with. + virtual gfx::Size input_allocated_size() const = 0; + + // Returns output allocated size required by the processor. + virtual gfx::Size output_allocated_size() const = 0; + + // Callback to be used to return the index of a processed image to the + // client. After the client is done with the frame, call Process with the + // index to return the output buffer to the image processor. + using FrameReadyCB = base::OnceCallback<void(scoped_refptr<VideoFrame>)>; + + // Called by client to process |frame|. The resulting processed frame will be + // stored in |output_buffer_index| output buffer and notified via |cb|. The + // processor will drop all its references to |frame| after it finishes + // accessing it. If the input buffers are DMA-backed, the caller + // should pass non-empty |output_dmabuf_fds| and the processed frame will be + // stored in those buffers. If the number of |output_dmabuf_fds| is not + // expected, this function will return false. + virtual bool Process(const scoped_refptr<VideoFrame>& frame, + int output_buffer_index, + std::vector<base::ScopedFD> output_dmabuf_fds, + FrameReadyCB cb) = 0; + + // Reset all processing frames. After this method returns, no more callbacks + // will be invoked. ImageProcessor is ready to process more frames. + virtual bool Reset() = 0; + + virtual ~ImageProcessor() = default; +}; + +} // namespace media + +#endif // MEDIA_GPU_IMAGE_PROCESSOR_H_
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc index 407eeb9..dd2f144 100644 --- a/media/gpu/v4l2/v4l2_image_processor.cc +++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -63,11 +63,13 @@ V4L2ImageProcessor::JobRecord::~JobRecord() {} -V4L2ImageProcessor::V4L2ImageProcessor(const scoped_refptr<V4L2Device>& device) +V4L2ImageProcessor::V4L2ImageProcessor(const scoped_refptr<V4L2Device>& device, + v4l2_memory input_memory_type, + v4l2_memory output_memory_type) : input_format_(PIXEL_FORMAT_UNKNOWN), output_format_(PIXEL_FORMAT_UNKNOWN), - input_memory_type_(V4L2_MEMORY_USERPTR), - output_memory_type_(V4L2_MEMORY_MMAP), + input_memory_type_(input_memory_type), + output_memory_type_(output_memory_type), input_format_fourcc_(0), output_format_fourcc_(0), input_planes_count_(0), @@ -82,11 +84,18 @@ output_buffer_queued_count_(0), num_buffers_(0), weak_this_factory_(this) { + DCHECK(input_memory_type == V4L2_MEMORY_USERPTR || + input_memory_type == V4L2_MEMORY_DMABUF); + DCHECK(output_memory_type == V4L2_MEMORY_MMAP || + output_memory_type == V4L2_MEMORY_DMABUF); weak_this_ = weak_this_factory_.GetWeakPtr(); } V4L2ImageProcessor::~V4L2ImageProcessor() { DCHECK(child_task_runner_->BelongsToCurrentThread()); + + Destroy(); + DCHECK(!device_thread_.IsRunning()); DCHECK(!device_poll_thread_.IsRunning()); @@ -110,8 +119,6 @@ bool V4L2ImageProcessor::Initialize(VideoPixelFormat input_format, VideoPixelFormat output_format, - v4l2_memory input_memory_type, - v4l2_memory output_memory_type, gfx::Size input_visible_size, gfx::Size input_allocated_size, gfx::Size output_visible_size, @@ -121,10 +128,6 @@ VLOGF(2); DCHECK(!error_cb.is_null()); DCHECK_GT(num_buffers, 0); - DCHECK(input_memory_type == V4L2_MEMORY_USERPTR || - input_memory_type == V4L2_MEMORY_DMABUF); - DCHECK(output_memory_type == V4L2_MEMORY_MMAP || - output_memory_type == V4L2_MEMORY_DMABUF); error_cb_ = error_cb; input_format_ = input_format; @@ -139,8 +142,6 @@ return false; } - input_memory_type_ = input_memory_type; - output_memory_type_ = output_memory_type; input_visible_size_ = input_visible_size; input_allocated_size_ = input_allocated_size; output_visible_size_ = output_visible_size; @@ -291,8 +292,8 @@ return false; device_thread_.task_runner()->PostTask( - FROM_HERE, base::Bind(&V4L2ImageProcessor::ProcessTask, - base::Unretained(this), base::Passed(&job_record))); + FROM_HERE, base::BindOnce(&V4L2ImageProcessor::ProcessTask, + base::Unretained(this), std::move(job_record))); return true; } @@ -345,8 +346,6 @@ // Otherwise DestroyTask() is not needed. DCHECK(!device_poll_thread_.IsRunning()); } - - delete this; } bool V4L2ImageProcessor::CreateInputBuffers() {
diff --git a/media/gpu/v4l2/v4l2_image_processor.h b/media/gpu/v4l2/v4l2_image_processor.h index a6849ae..b9796cc 100644 --- a/media/gpu/v4l2/v4l2_image_processor.h +++ b/media/gpu/v4l2/v4l2_image_processor.h
@@ -17,6 +17,7 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" #include "media/base/video_frame.h" +#include "media/gpu/image_processor.h" #include "media/gpu/media_gpu_export.h" #include "media/gpu/v4l2/v4l2_device.h" @@ -25,9 +26,11 @@ // Handles image processing accelerators that expose a V4L2 memory-to-memory // interface. The threading model of this class is the same as for other V4L2 // hardware accelerators (see V4L2VideoDecodeAccelerator) for more details. -class MEDIA_GPU_EXPORT V4L2ImageProcessor { +class MEDIA_GPU_EXPORT V4L2ImageProcessor : public ImageProcessor { public: - explicit V4L2ImageProcessor(const scoped_refptr<V4L2Device>& device); + explicit V4L2ImageProcessor(const scoped_refptr<V4L2Device>& device, + v4l2_memory input_memory_type, + v4l2_memory output_memory_type); virtual ~V4L2ImageProcessor(); // Initializes the processor to convert from |input_format| to |output_format| @@ -39,14 +42,12 @@ // configuration is supported. bool Initialize(VideoPixelFormat input_format, VideoPixelFormat output_format, - v4l2_memory input_memory_type, - v4l2_memory output_memory_type, gfx::Size input_visible_size, gfx::Size input_allocated_size, gfx::Size output_visible_size, gfx::Size output_allocated_size, int num_buffers, - const base::Closure& error_cb); + const base::Closure& error_cb) override; // Returns true if image processing is supported on this platform. static bool IsSupported(); @@ -66,14 +67,12 @@ gfx::Size* size, size_t* num_planes); - // Returns input allocated size required by the processor to be fed with. - gfx::Size input_allocated_size() const { return input_allocated_size_; } - - // Returns output allocated size required by the processor. - gfx::Size output_allocated_size() const { return output_allocated_size_; } - - // Callback to be used to return the processed image to the client. - typedef base::OnceCallback<void(scoped_refptr<VideoFrame>)> FrameReadyCB; + gfx::Size input_allocated_size() const override { + return input_allocated_size_; + } + gfx::Size output_allocated_size() const override { + return output_allocated_size_; + } // Called by client to process |frame|. The resulting processed frame will be // stored in |output_buffer_index| output buffer and notified via |cb|. The @@ -85,16 +84,11 @@ bool Process(const scoped_refptr<VideoFrame>& frame, int output_buffer_index, std::vector<base::ScopedFD> output_dmabuf_fds, - FrameReadyCB cb); + FrameReadyCB cb) override; // Reset all processing frames. After this method returns, no more callbacks // will be invoked. V4L2ImageProcessor is ready to process more frames. - bool Reset(); - - // Stop all processing and clean up. After this method returns no more - // callbacks will be invoked. Deletes |this| unconditionally, so make sure - // to drop all pointers to it! - void Destroy(); + bool Reset() override; private: // Record for input buffers. @@ -159,6 +153,10 @@ // A processed frame is ready. void FrameReady(FrameReadyCB cb, scoped_refptr<VideoFrame> frame); + // Stop all processing and clean up. After this method returns no more + // callbacks will be invoked. + void Destroy(); + // Size and format-related members remain constant after initialization. // The visible/allocated sizes of the input frame. gfx::Size input_visible_size_;
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc index c7724c04..7cac10b 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -25,6 +25,7 @@ #include "media/base/media_switches.h" #include "media/base/scopedfd_helper.h" #include "media/base/unaligned_shared_memory.h" +#include "media/gpu/v4l2/v4l2_image_processor.h" #include "media/video/h264_parser.h" #include "ui/gfx/geometry/rect.h" #include "ui/gl/gl_context.h" @@ -1854,8 +1855,7 @@ decoder_input_queue_.pop(); decoder_flushing_ = false; - if (image_processor_) - image_processor_.release()->Destroy(); + image_processor_ = nullptr; // Set our state to kError. Just in case. decoder_state_ = kError; @@ -1976,8 +1976,7 @@ return; } - if (image_processor_) - image_processor_.release()->Destroy(); + image_processor_ = nullptr; if (!DestroyOutputBuffers()) { VLOGF(1) << "Failed destroying output buffers."; @@ -2394,17 +2393,18 @@ bool V4L2VideoDecodeAccelerator::CreateImageProcessor() { VLOGF(2); DCHECK(!image_processor_); - image_processor_.reset(new V4L2ImageProcessor(image_processor_device_)); v4l2_memory output_memory_type = (output_mode_ == Config::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP : V4L2_MEMORY_DMABUF); + image_processor_.reset(new V4L2ImageProcessor( + image_processor_device_, V4L2_MEMORY_DMABUF, output_memory_type)); // Unretained is safe because |this| owns image processor and there will be // no callbacks after processor destroys. if (!image_processor_->Initialize( V4L2Device::V4L2PixFmtToVideoPixelFormat(output_format_fourcc_), V4L2Device::V4L2PixFmtToVideoPixelFormat(egl_image_format_fourcc_), - V4L2_MEMORY_DMABUF, output_memory_type, visible_size_, coded_size_, - visible_size_, egl_image_size_, output_buffer_map_.size(), + visible_size_, coded_size_, visible_size_, egl_image_size_, + output_buffer_map_.size(), base::Bind(&V4L2VideoDecodeAccelerator::ImageProcessorError, base::Unretained(this)))) { VLOGF(1) << "Initialize image processor failed";
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h index b81c6b1..9cd9fa3 100644 --- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h +++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
@@ -25,9 +25,9 @@ #include "media/base/limits.h" #include "media/base/video_decoder_config.h" #include "media/gpu/gpu_video_decode_accelerator_helpers.h" +#include "media/gpu/image_processor.h" #include "media/gpu/media_gpu_export.h" #include "media/gpu/v4l2/v4l2_device.h" -#include "media/gpu/v4l2/v4l2_image_processor.h" #include "media/video/picture.h" #include "media/video/video_decode_accelerator.h" #include "ui/gfx/geometry/size.h" @@ -566,7 +566,7 @@ // Image processor device, if one is in use. scoped_refptr<V4L2Device> image_processor_device_; // Image processor. Accessed on |decoder_thread_|. - std::unique_ptr<V4L2ImageProcessor> image_processor_; + std::unique_ptr<ImageProcessor> image_processor_; // The V4L2Device EGLImage is created from. scoped_refptr<V4L2Device> egl_image_device_;
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index 7405f96..5d7631a 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -25,6 +25,7 @@ #include "media/base/bitstream_buffer.h" #include "media/base/scopedfd_helper.h" #include "media/base/unaligned_shared_memory.h" +#include "media/gpu/v4l2/v4l2_image_processor.h" #include "media/video/h264_parser.h" #define VLOGF(level) VLOG(level) << __func__ << "(): " @@ -204,16 +205,16 @@ } scoped_refptr<V4L2Device> device = V4L2Device::Create(); - image_processor_.reset(new V4L2ImageProcessor(device)); + image_processor_.reset( + new V4L2ImageProcessor(device, V4L2_MEMORY_USERPTR, V4L2_MEMORY_MMAP)); // Convert from input_format to device_input_format_, keeping the size // at visible_size_ and requiring the output buffers to be of at least // input_allocated_size_. Unretained is safe because |this| owns image // processor and there will be no callbacks after processor destroys. if (!image_processor_->Initialize( - input_format, device_input_format_, V4L2_MEMORY_USERPTR, - V4L2_MEMORY_MMAP, visible_size_, visible_size_, visible_size_, - input_allocated_size_, kImageProcBufferCount, + input_format, device_input_format_, visible_size_, visible_size_, + visible_size_, input_allocated_size_, kImageProcBufferCount, base::Bind(&V4L2VideoEncodeAccelerator::ImageProcessorError, base::Unretained(this)))) { VLOGF(1) << "Failed initializing image processor"; @@ -343,8 +344,7 @@ client_ptr_factory_.reset(); weak_this_ptr_factory_.InvalidateWeakPtrs(); - if (image_processor_.get()) - image_processor_.release()->Destroy(); + image_processor_ = nullptr; // If the encoder thread is running, destroy using posted task. if (encoder_thread_.IsRunning()) {
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/media/gpu/v4l2/v4l2_video_encode_accelerator.h index c5d4a95..d90b9f4 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.h +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -18,9 +18,9 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" #include "base/time/time.h" +#include "media/gpu/image_processor.h" #include "media/gpu/media_gpu_export.h" #include "media/gpu/v4l2/v4l2_device.h" -#include "media/gpu/v4l2/v4l2_image_processor.h" #include "media/video/video_encode_accelerator.h" #include "ui/gfx/geometry/size.h" @@ -36,7 +36,7 @@ // device exposed by the codec hardware driver. The threading model of this // class is the same as in the V4L2VideoDecodeAccelerator (from which class this // was designed). -// This class may try to instantiate and use a V4L2ImageProcessor for input +// This class may try to instantiate and use a ImageProcessor for input // format conversion, if the input format requested via Initialize() is not // accepted by the hardware codec. class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator @@ -192,7 +192,7 @@ // Try to set up the device to the input format we were Initialized() with, // or if the device doesn't support it, use one it can support, so that we - // can later instantiate a V4L2ImageProcessor to convert to it. + // can later instantiate an ImageProcessor to convert to it. bool NegotiateInputFormat(VideoPixelFormat input_format); // Set up the device to the output format requested in Initialize(). @@ -296,7 +296,7 @@ FlushCallback flush_callback_; // Image processor, if one is in use. - std::unique_ptr<V4L2ImageProcessor> image_processor_; + std::unique_ptr<ImageProcessor> image_processor_; // Indexes of free image processor output buffers. Only accessed on child // thread. std::vector<int> free_image_processor_output_buffers_;
diff --git a/media/gpu/vaapi/vaapi_picture.cc b/media/gpu/vaapi/vaapi_picture.cc index 58c1bc09..65d35bf 100644 --- a/media/gpu/vaapi/vaapi_picture.cc +++ b/media/gpu/vaapi/vaapi_picture.cc
@@ -4,6 +4,8 @@ #include "media/gpu/vaapi/vaapi_picture.h" +#include <va/va.h> + #include "media/gpu/vaapi/vaapi_wrapper.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_implementation.h" @@ -36,4 +38,8 @@ return false; } +VASurfaceID VaapiPicture::va_surface_id() const { + return VA_INVALID_ID; +} + } // namespace media
diff --git a/media/gpu/vaapi/vaapi_picture.h b/media/gpu/vaapi/vaapi_picture.h index 5ee61a9..d9a296b 100644 --- a/media/gpu/vaapi/vaapi_picture.h +++ b/media/gpu/vaapi/vaapi_picture.h
@@ -22,6 +22,8 @@ namespace media { +using VASurfaceID = unsigned int; + class VASurface; class VaapiWrapper; @@ -49,6 +51,9 @@ virtual bool DownloadFromSurface( const scoped_refptr<VASurface>& va_surface) = 0; + // Returns the associated VASurfaceID, if any, or VA_INVALID_ID. + virtual VASurfaceID va_surface_id() const; + protected: VaapiPicture(const scoped_refptr<VaapiWrapper>& vaapi_wrapper, const MakeGLContextCurrentCallback& make_context_current_cb,
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc index 64b0b8d5..3a6cfdd 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
@@ -46,6 +46,10 @@ return true; } +VASurfaceID VaapiPictureNativePixmap::va_surface_id() const { + return va_surface_->id(); +} + unsigned VaapiPictureNativePixmap::BufferFormatToInternalFormat( gfx::BufferFormat format) const { switch (format) {
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.h b/media/gpu/vaapi/vaapi_picture_native_pixmap.h index ab852425..5d6c38ba 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap.h +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include "base/memory/ref_counted.h" +#include "media/gpu/vaapi/va_surface.h" #include "media/gpu/vaapi/vaapi_picture.h" #include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/size.h" @@ -41,6 +42,7 @@ // VaapiPicture implementation. bool DownloadFromSurface(const scoped_refptr<VASurface>& va_surface) override; bool AllowOverlay() const override; + VASurfaceID va_surface_id() const override; unsigned BufferFormatToInternalFormat(gfx::BufferFormat format) const;
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc index 6f5a5b40..7ef044a 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -128,6 +128,8 @@ } } +// TODO(mcasas): consider removing this method and just use +// DCHECK(base::ContainsValue()) on callsites. VaapiPicture* VaapiVideoDecodeAccelerator::PictureById( int32_t picture_buffer_id) { Pictures::iterator it = pictures_.find(picture_buffer_id); @@ -146,6 +148,7 @@ input_ready_(&lock_), vaapi_picture_factory_(new VaapiPictureFactory()), surfaces_available_(&lock_), + decode_using_client_picture_buffers_(false), task_runner_(base::ThreadTaskRunnerHandle::Get()), decoder_thread_("VaapiDecoderThread"), num_frames_at_client_(0), @@ -220,15 +223,36 @@ void VaapiVideoDecodeAccelerator::OutputPicture( const scoped_refptr<VASurface>& va_surface, int32_t input_id, - gfx::Rect visible_rect, - VaapiPicture* picture) { + gfx::Rect visible_rect) { DCHECK(task_runner_->BelongsToCurrentThread()); - int32_t output_id = picture->picture_buffer_id(); + const VASurfaceID va_surface_id = va_surface->id(); - VLOGF(4) << "Outputting VASurface " << va_surface->id() - << " into pixmap bound to picture buffer id " << output_id; + VaapiPicture* picture = nullptr; { + base::AutoLock auto_lock(lock_); + int32_t picture_buffer_id = available_picture_buffers_.front(); + if (decode_using_client_picture_buffers_) { + // Find the |pictures_| entry matching |va_surface_id|. + for (const auto& id_and_picture : pictures_) { + if (id_and_picture.second->va_surface_id() == va_surface_id) { + picture_buffer_id = id_and_picture.first; + break; + } + } + } + picture = PictureById(picture_buffer_id); + DCHECK(base::ContainsValue(available_picture_buffers_, picture_buffer_id)); + base::Erase(available_picture_buffers_, picture_buffer_id); + } + + DCHECK(picture) << " could not find " << va_surface_id << " available"; + const int32_t output_id = picture->picture_buffer_id(); + + VLOGF(4) << "Outputting VASurface " << va_surface_id + << " into pixmap bound to picture buffer id " << output_id; + + if (!decode_using_client_picture_buffers_) { TRACE_EVENT2("media,gpu", "VAVDA::DownloadFromSurface", "input_id", input_id, "output_id", output_id); RETURN_AND_NOTIFY_ON_FAILURE(picture->DownloadFromSurface(va_surface), @@ -248,24 +272,20 @@ } } -void VaapiVideoDecodeAccelerator::TryOutputSurface() { +void VaapiVideoDecodeAccelerator::TryOutputPicture() { DCHECK(task_runner_->BelongsToCurrentThread()); // Handle Destroy() arriving while pictures are queued for output. if (!client_) return; - if (pending_output_cbs_.empty() || output_buffers_.empty()) + if (pending_output_cbs_.empty() || available_picture_buffers_.empty()) return; - OutputCB output_cb = pending_output_cbs_.front(); + auto output_cb = std::move(pending_output_cbs_.front()); pending_output_cbs_.pop(); - VaapiPicture* picture = PictureById(output_buffers_.front()); - DCHECK(picture); - output_buffers_.pop(); - - output_cb.Run(picture); + std::move(output_cb).Run(); if (finish_flush_pending_ && pending_output_cbs_.empty()) FinishFlush(); @@ -562,6 +582,7 @@ available_va_surfaces_.push_back(va_surface_id); surfaces_available_.Signal(); + TryOutputPicture(); } void VaapiVideoDecodeAccelerator::AssignPictureBuffers( @@ -570,8 +591,7 @@ base::AutoLock auto_lock(lock_); DCHECK(pictures_.empty()); - while (!output_buffers_.empty()) - output_buffers_.pop(); + available_picture_buffers_.clear(); RETURN_AND_NOTIFY_ON_FAILURE( buffers.size() >= requested_num_pics_, @@ -581,11 +601,6 @@ const unsigned int va_format = GetVaFormatForVideoCodecProfile(profile_); std::vector<VASurfaceID> va_surface_ids; - RETURN_AND_NOTIFY_ON_FAILURE( - vaapi_wrapper_->CreateSurfaces(va_format, requested_pic_size_, - buffers.size(), &va_surface_ids), - "Failed creating VA Surfaces", PLATFORM_FAILURE, ); - DCHECK_EQ(va_surface_ids.size(), buffers.size()); for (size_t i = 0; i < buffers.size(); ++i) { DCHECK(requested_pic_size_ == buffers[i].size()); @@ -599,17 +614,42 @@ RETURN_AND_NOTIFY_ON_FAILURE( picture->Allocate(vaapi_picture_factory_->GetBufferFormat()), "Failed to allocate memory for a VaapiPicture", PLATFORM_FAILURE, ); - output_buffers_.push(buffers[i].id()); - } - bool inserted = - pictures_.insert(std::make_pair(buffers[i].id(), std::move(picture))) - .second; - DCHECK(inserted); + available_picture_buffers_.push_back(buffers[i].id()); - available_va_surfaces_.push_back(va_surface_ids[i]); + VASurfaceID va_surface_id = picture->va_surface_id(); + if (va_surface_id != VA_INVALID_ID) + va_surface_ids.push_back(va_surface_id); + } + + DCHECK(!base::ContainsKey(pictures_, buffers[i].id())); + pictures_[buffers[i].id()] = std::move(picture); + surfaces_available_.Signal(); } + decode_using_client_picture_buffers_ = !va_surface_ids.empty() && + profile_ != VP9PROFILE_PROFILE2 && + profile_ != VP9PROFILE_PROFILE3; + + // If we have some |va_surface_ids|, use them for decode, otherwise ask + // |vaapi_wrapper_| to allocate them for us. + if (decode_using_client_picture_buffers_) { + RETURN_AND_NOTIFY_ON_FAILURE( + vaapi_wrapper_->CreateContext(va_format, requested_pic_size_, + va_surface_ids), + "Failed creating VA Context", PLATFORM_FAILURE, ); + } else { + va_surface_ids.clear(); + RETURN_AND_NOTIFY_ON_FAILURE( + vaapi_wrapper_->CreateSurfaces(va_format, requested_pic_size_, + buffers.size(), &va_surface_ids), + "Failed creating VA Surfaces", PLATFORM_FAILURE, ); + } + DCHECK_EQ(va_surface_ids.size(), buffers.size()); + + for (const auto id : va_surface_ids) + available_va_surfaces_.push_back(id); + // Resume DecodeTask if it is still in decoding state. if (state_ == kDecoding) { decoder_thread_task_runner_->PostTask( @@ -679,9 +719,11 @@ --num_frames_at_client_; TRACE_COUNTER1("media,gpu", "Vaapi frames at client", num_frames_at_client_); - - output_buffers_.push(picture_buffer_id); - TryOutputSurface(); + { + base::AutoLock auto_lock(lock_); + available_picture_buffers_.push_back(picture_buffer_id); + } + TryOutputPicture(); } void VaapiVideoDecodeAccelerator::FlushTask() { @@ -906,7 +948,7 @@ base::Bind(&VaapiVideoDecodeAccelerator::OutputPicture, weak_this_, va_surface, bitstream_id, visible_rect)); - TryOutputSurface(); + TryOutputPicture(); } scoped_refptr<VASurface> VaapiVideoDecodeAccelerator::CreateVASurface() { @@ -917,12 +959,32 @@ return nullptr; DCHECK(!awaiting_va_surfaces_recycle_); - scoped_refptr<VASurface> va_surface(new VASurface( - available_va_surfaces_.front(), requested_pic_size_, - vaapi_wrapper_->va_surface_format(), va_surface_release_cb_)); - available_va_surfaces_.pop_front(); + if (!decode_using_client_picture_buffers_) { + const VASurfaceID id = available_va_surfaces_.front(); + available_va_surfaces_.pop_front(); + return new VASurface(id, requested_pic_size_, + vaapi_wrapper_->va_surface_format(), + va_surface_release_cb_); + } - return va_surface; + // Find the first |available_va_surfaces_| id such that the associated + // |pictures_| entry is marked as |available_picture_buffers_|. In practice, + // we will quickly find an available |va_surface_id|. + for (const VASurfaceID va_surface_id : available_va_surfaces_) { + for (const auto& id_and_picture : pictures_) { + if (id_and_picture.second->va_surface_id() == va_surface_id && + base::ContainsValue(available_picture_buffers_, + id_and_picture.first)) { + // Remove |va_surface_id| from the list of availables, and use the id + // to return a new VASurface. + base::Erase(available_va_surfaces_, va_surface_id); + return new VASurface(va_surface_id, requested_pic_size_, + vaapi_wrapper_->va_surface_format(), + va_surface_release_cb_); + } + } + } + return nullptr; } // static
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.h b/media/gpu/vaapi/vaapi_video_decode_accelerator.h index 271bcc00..be012add 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.h +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.h
@@ -18,6 +18,7 @@ #include <vector> #include "base/containers/queue.h" +#include "base/containers/small_map.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -163,18 +164,16 @@ // or return false on failure. bool InitializeFBConfig(); - // Callback to be executed once we have a |va_surface| to be output and - // an available |picture| to use for output. - // Puts contents of |va_surface| into given |picture|, releases the surface - // and passes the resulting picture to client to output the given - // |visible_rect| part of it. + // Callback to be executed once we have a |va_surface| to be output and an + // available VaapiPicture in |available_picture_buffers_| for output. Puts + // contents of |va_surface| into the latter, releases the surface and passes + // the resulting picture to |client_| along with |visible_rect|. void OutputPicture(const scoped_refptr<VASurface>& va_surface, int32_t input_id, - gfx::Rect visible_rect, - VaapiPicture* picture); + gfx::Rect visible_rect); // Try to OutputPicture() if we have both a ready surface and picture. - void TryOutputSurface(); + void TryOutputPicture(); // Called when a VASurface is no longer in use by the decoder or is not being // synced/waiting to be synced to a picture. Returns it to available surfaces @@ -202,12 +201,13 @@ kDestroying, }; - // Protects input buffer and surface queues and state_. + // |lock_| protects |input_buffers_|, |curr_input_buffer_|, |state_| and + // |available_picture_buffers_|. base::Lock lock_; State state_; Config::OutputMode output_mode_; - // Queue of available InputBuffers (picture_buffer_ids). + // Queue of available InputBuffers. base::queue<std::unique_ptr<InputBuffer>> input_buffers_; // Signalled when input buffers are queued onto |input_buffers_| queue. base::ConditionVariable input_ready_; @@ -215,9 +215,9 @@ // Current input buffer at decoder. std::unique_ptr<InputBuffer> curr_input_buffer_; - // Queue for incoming output buffers (texture ids). - using OutputBuffers = base::queue<int32_t>; - OutputBuffers output_buffers_; + // List of PictureBuffer ids available to be sent to |client_| via + // OutputPicture() (|client_| returns them via ReusePictureBuffer()). + std::list<int32_t> available_picture_buffers_; std::unique_ptr<VaapiPictureFactory> vaapi_picture_factory_; @@ -229,17 +229,17 @@ // allocated once using |create_vaapi_picture_callback_| and destroyed at the // end of decode. Comes after |vaapi_wrapper_| to ensure all pictures are // destroyed before said |vaapi_wrapper_| is destroyed. - using Pictures = std::map<int32_t, std::unique_ptr<VaapiPicture>>; + using Pictures = + base::small_map<std::map<int32_t, std::unique_ptr<VaapiPicture>>>; Pictures pictures_; // Return a VaapiPicture associated with given client-provided id. VaapiPicture* PictureById(int32_t picture_buffer_id); - // VA Surfaces no longer in use that can be passed back to the decoder for + // VASurfaceIDs no longer in use that can be passed back to |decoder_| for // reuse, once it requests them. std::list<VASurfaceID> available_va_surfaces_; - // Signalled when output surfaces are queued onto the available_va_surfaces_ - // queue. + // Signalled when output surfaces are queued into |available_va_surfaces_|. base::ConditionVariable surfaces_available_; // Pending output requests from the decoder. When it indicates that we should @@ -248,14 +248,16 @@ // will put the contents of the surface into the picture and return it to // the client, releasing the surface as well. // If we don't have any available Pictures at the time when the decoder - // requests output, we'll store the request on pending_output_cbs_ queue for - // later and run it once the client gives us more textures - // via ReusePictureBuffer(). - using OutputCB = base::Callback<void(VaapiPicture*)>; - base::queue<OutputCB> pending_output_cbs_; + // requests output, we'll store the request in this queue for later and run it + // once the client gives us more textures via ReusePictureBuffer(). + base::queue<base::OnceClosure> pending_output_cbs_; + + // Under some circumstances, we can pass to libva our own VASurfaceIDs to + // decode onto, which skips one copy. + bool decode_using_client_picture_buffers_; // ChildThread's task runner. - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; // WeakPtr<> pointing to |this| for use in posting tasks from the decoder // thread back to the ChildThread. Because the decoder thread is a member of
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc index 76907a6..820c106 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -233,7 +233,6 @@ ASSERT_TRUE(vda_.curr_input_buffer_) << "QueueInputBuffer() should have been called"; - ::testing::InSequence s; base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); @@ -249,6 +248,7 @@ MockCreateVaapiPicture(mock_vaapi_wrapper_.get(), picture_size)) .Times(num_pictures); + ::testing::InSequence s; EXPECT_CALL(*mock_decoder_, Decode()) .WillOnce(Return(AcceleratedVideoDecoder::kRanOutOfStreamData)); EXPECT_CALL(*this, NotifyEndOfBitstreamBuffer(bitstream_id))
diff --git a/media/gpu/windows/d3d11_cdm_proxy.cc b/media/gpu/windows/d3d11_cdm_proxy.cc index 70a0d3f..f19b1a1 100644 --- a/media/gpu/windows/d3d11_cdm_proxy.cc +++ b/media/gpu/windows/d3d11_cdm_proxy.cc
@@ -9,6 +9,10 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/power_monitor/power_monitor.h" +#include "base/power_monitor/power_observer.h" +#include "base/synchronization/waitable_event.h" +#include "base/win/object_watcher.h" #include "media/base/callback_registry.h" #include "media/base/cdm_context.h" #include "media/base/cdm_proxy_context.h" @@ -118,6 +122,62 @@ } // namespace +// Watches for any content protection teardown events. +// If the instance has been started for watching, the destructor will +// automatically stop watching. +class D3D11CdmProxy::HardwareEventWatcher + : public base::win::ObjectWatcher::Delegate, + public base::PowerObserver { + public: + ~HardwareEventWatcher() override; + + // |teardown_callback| is called on the current sequence. + // Returns an instance if it starts watching for events, otherwise returns + // nullptr. + static std::unique_ptr<HardwareEventWatcher> Create( + ComPtr<ID3D11Device> device, + base::RepeatingClosure teardown_callback); + + private: + HardwareEventWatcher(ComPtr<ID3D11Device> device, + base::RepeatingClosure teardown_callback); + + // Start watching for events. + bool StartWatching(); + + // Registers for hardware content protection teardown events. + // Return true on success. + bool RegisterHardwareContentProtectionTeardown(ComPtr<ID3D11Device> device); + + // Regiesters for power events, specifically power suspend event. + // Returns true on success. + bool RegisterPowerEvents(); + + // base::win::ObjectWatcher::Delegate implementation. + void OnObjectSignaled(HANDLE object) override; + + // base::PowerObserver implementation. Other power events are not relevant to + // this class. + void OnSuspend() override; + + // Stops watching for events. Good for clean up. + void StopWatching(); + + // IDXGIAdapter3::RegisterHardwareContentProtectionTeardownStatusEvent + // allows watching for teardown events. It is queried thru the following + // Devices. + ComPtr<ID3D11Device> device_; + ComPtr<IDXGIDevice2> dxgi_device_; + ComPtr<IDXGIAdapter3> dxgi_adapter_; + + // Cookie, event, and watcher used for watching events from + // RegisterHardwareContentProtectionTeardownStatusEvent. + DWORD teardown_event_cookie_ = 0u; + base::WaitableEvent content_protection_teardown_event_; + base::RepeatingClosure teardown_callback_; + base::win::ObjectWatcher teardown_status_watcher_; +}; + class D3D11CdmContext : public CdmContext { public: explicit D3D11CdmContext(const GUID& key_info_guid) @@ -173,7 +233,8 @@ protocol_(protocol), function_id_map_(function_id_map), cdm_context_(std::make_unique<D3D11CdmContext>(crypto_type)), - create_device_func_(base::BindRepeating(D3D11CreateDevice)) {} + create_device_func_(base::BindRepeating(D3D11CreateDevice)), + weak_factory_(this) {} D3D11CdmProxy::~D3D11CdmProxy() {} @@ -209,6 +270,19 @@ return; } + // TODO(rkuroiwa): This should be registered iff + // D3D11_CONTENT_PROTECTION_CAPS_HARDWARE_TEARDOWN is set in the capabilties. + hardware_event_watcher_ = HardwareEventWatcher::Create( + device_, base::BindRepeating( + &D3D11CdmProxy::NotifyHardwareContentProtectionTeardown, + weak_factory_.GetWeakPtr())); + if (!hardware_event_watcher_) { + DLOG(ERROR) + << "Failed to start waching for content protection teardown events."; + failed(); + return; + } + hresult = device_.CopyTo(video_device_.GetAddressOf()); if (FAILED(hresult)) { DLOG(ERROR) << "Failed to get ID3D11VideoDevice: " << hresult; @@ -243,7 +317,7 @@ return; } - Microsoft::WRL::ComPtr<ID3D11CryptoSession> csme_crypto_session; + ComPtr<ID3D11CryptoSession> csme_crypto_session; hresult = video_device_->CreateCryptoSession( &crypto_type_, &D3D11_DECODER_PROFILE_H264_VLD_NOFGT, &D3D11_KEY_EXCHANGE_HW_PROTECTION, csme_crypto_session.GetAddressOf()); @@ -298,8 +372,7 @@ return; } - Microsoft::WRL::ComPtr<ID3D11CryptoSession>& crypto_session = - crypto_session_it->second; + ComPtr<ID3D11CryptoSession>& crypto_session = crypto_session_it->second; D3D11_KEY_EXCHANGE_HW_PROTECTION_DATA key_exchange_data = {}; key_exchange_data.HWProtectionFunctionID = function_id_it->second; @@ -363,7 +436,7 @@ return; } - Microsoft::WRL::ComPtr<ID3D11CryptoSession> media_crypto_session; + ComPtr<ID3D11CryptoSession> media_crypto_session; HRESULT hresult = video_device_->CreateCryptoSession( &crypto_type_, &D3D11_DECODER_PROFILE_H264_VLD_NOFGT, &crypto_type_, media_crypto_session.GetAddressOf()); @@ -432,4 +505,106 @@ create_device_func_ = std::move(callback); } +void D3D11CdmProxy::NotifyHardwareContentProtectionTeardown() { + if (client_) + client_->NotifyHardwareReset(); +} + +D3D11CdmProxy::HardwareEventWatcher::~HardwareEventWatcher() { + StopWatching(); +} + +std::unique_ptr<D3D11CdmProxy::HardwareEventWatcher> +D3D11CdmProxy::HardwareEventWatcher::Create( + Microsoft::WRL::ComPtr<ID3D11Device> device, + base::RepeatingClosure teardown_callback) { + std::unique_ptr<HardwareEventWatcher> event_watcher = base::WrapUnique( + new HardwareEventWatcher(device, std::move(teardown_callback))); + if (!event_watcher->StartWatching()) + return nullptr; + return event_watcher; +} + +D3D11CdmProxy::HardwareEventWatcher::HardwareEventWatcher( + Microsoft::WRL::ComPtr<ID3D11Device> device, + base::RepeatingClosure teardown_callback) + : device_(device), teardown_callback_(std::move(teardown_callback)) {} + +bool D3D11CdmProxy::HardwareEventWatcher::StartWatching() { + if (!RegisterPowerEvents() || + !RegisterHardwareContentProtectionTeardown(device_)) { + StopWatching(); + return false; + } + + return true; +} + +bool D3D11CdmProxy::HardwareEventWatcher:: + RegisterHardwareContentProtectionTeardown(ComPtr<ID3D11Device> device) { + device_ = device; + HRESULT hresult = device_.CopyTo(dxgi_device_.ReleaseAndGetAddressOf()); + if (FAILED(hresult)) { + DVLOG(1) << "Failed to get dxgi device from device: " + << logging::SystemErrorCodeToString(hresult); + return false; + } + + hresult = dxgi_device_->GetParent( + IID_PPV_ARGS(dxgi_adapter_.ReleaseAndGetAddressOf())); + if (FAILED(hresult)) { + DVLOG(1) << "Failed to get dxgi adapter from dxgi device: " + << logging::SystemErrorCodeToString(hresult); + return false; + } + + if (!teardown_status_watcher_.StartWatchingOnce( + content_protection_teardown_event_.handle(), this)) { + DVLOG(1) << "Failed to watch tear down event."; + return false; + } + + hresult = dxgi_adapter_->RegisterHardwareContentProtectionTeardownStatusEvent( + content_protection_teardown_event_.handle(), &teardown_event_cookie_); + if (FAILED(hresult)) { + DVLOG(1) + << "Failed to register for HardwareContentProtectionTeardownStatus: " + << logging::SystemErrorCodeToString(hresult); + return false; + } + + return true; +} + +bool D3D11CdmProxy::HardwareEventWatcher::RegisterPowerEvents() { + base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); + if (!power_monitor) { + DVLOG(1) << "Power monitor not available."; + return false; + } + + power_monitor->AddObserver(this); + return true; +} + +void D3D11CdmProxy::HardwareEventWatcher::OnObjectSignaled(HANDLE object) { + DCHECK_EQ(object, content_protection_teardown_event_.handle()); + teardown_callback_.Run(); +} + +void D3D11CdmProxy::HardwareEventWatcher::OnSuspend() { + teardown_callback_.Run(); +} + +void D3D11CdmProxy::HardwareEventWatcher::StopWatching() { + if (dxgi_adapter_) { + dxgi_adapter_->UnregisterHardwareContentProtectionTeardownStatus( + teardown_event_cookie_); + } + teardown_status_watcher_.StopWatching(); + base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); + if (power_monitor) + power_monitor->RemoveObserver(this); +} + } // namespace media
diff --git a/media/gpu/windows/d3d11_cdm_proxy.h b/media/gpu/windows/d3d11_cdm_proxy.h index ce444ed..bdca2fc 100644 --- a/media/gpu/windows/d3d11_cdm_proxy.h +++ b/media/gpu/windows/d3d11_cdm_proxy.h
@@ -8,12 +8,14 @@ #include "media/cdm/cdm_proxy.h" #include <d3d11_1.h> +#include <dxgi1_4.h> #include <wrl/client.h> #include <map> #include <vector> #include "base/callback.h" +#include "base/memory/weak_ptr.h" #include "media/gpu/media_gpu_export.h" namespace media { @@ -79,6 +81,10 @@ template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>; + class HardwareEventWatcher; + + void NotifyHardwareContentProtectionTeardown(); + const GUID crypto_type_; const CdmProxy::Protocol protocol_; const FunctionIdMap function_id_map_; @@ -108,6 +114,8 @@ ComPtr<ID3D11VideoContext> video_context_; ComPtr<ID3D11VideoContext1> video_context1_; + std::unique_ptr<HardwareEventWatcher> hardware_event_watcher_; + // Crypto session ID -> actual crypto session. std::map<uint32_t, ComPtr<ID3D11CryptoSession>> crypto_session_map_; @@ -116,6 +124,8 @@ UINT private_input_size_ = 0; UINT private_output_size_ = 0; + base::WeakPtrFactory<D3D11CdmProxy> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(D3D11CdmProxy); };
diff --git a/media/gpu/windows/d3d11_cdm_proxy_unittest.cc b/media/gpu/windows/d3d11_cdm_proxy_unittest.cc index a07eda4..d0829867 100644 --- a/media/gpu/windows/d3d11_cdm_proxy_unittest.cc +++ b/media/gpu/windows/d3d11_cdm_proxy_unittest.cc
@@ -9,6 +9,10 @@ #include <initguid.h> #include "base/bind.h" +#include "base/power_monitor/power_monitor.h" +#include "base/power_monitor/power_monitor_source.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" #include "media/base/cdm_proxy_context.h" #include "media/gpu/windows/d3d11_mocks.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,6 +34,23 @@ namespace { +// TODO(rkuroiwa): Although inheriting from different classes, there are several +// mock CdmProxy clients already. They all have NotifyHardwareReset(), so share +// a single mock class that inherits from all the CdmProxy client classes. +class MockProxyClient : public CdmProxy::Client { + public: + MOCK_METHOD0(NotifyHardwareReset, void()); +}; + +class MockPowerMonitorSource : public base::PowerMonitorSource { + public: + // Use this method to send a power suspend event. + void Suspend() { ProcessPowerEvent(SUSPEND_EVENT); } + + MOCK_METHOD0(Shutdown, void()); + MOCK_METHOD0(IsOnBatteryPowerImpl, bool()); +}; + // The values doesn't matter as long as this is consistently used thruout the // test. const CdmProxy::Protocol kTestProtocol = @@ -66,6 +87,11 @@ std::map<CdmProxy::Function, uint32_t> function_id_map; function_id_map[kTestFunction] = kTestFunctionId; + auto mock_power_monitor_source = std::make_unique<MockPowerMonitorSource>(); + mock_power_monitor_source_ = mock_power_monitor_source.get(); + power_monitor_ = std::make_unique<base::PowerMonitor>( + std::move(mock_power_monitor_source)); + proxy_ = std::make_unique<D3D11CdmProxy>(CRYPTO_TYPE_GUID, kTestProtocol, function_id_map); @@ -76,6 +102,8 @@ device_context_mock_ = CreateD3D11Mock<D3D11DeviceContextMock>(); video_context_mock_ = CreateD3D11Mock<D3D11VideoContextMock>(); video_context1_mock_ = CreateD3D11Mock<D3D11VideoContext1Mock>(); + dxgi_device_ = CreateD3D11Mock<DXGIDevice2Mock>(); + dxgi_adapter_ = CreateD3D11Mock<DXGIAdapter3Mock>(); // These flags are a reasonable subset of flags to get HARDWARE protected // playback. @@ -120,6 +148,18 @@ DoAll(AddRefAndSetArgPointee<1>(video_device1_mock_.Get()), Return(S_OK))); + ON_CALL(*device_mock_.Get(), QueryInterface(IID_IDXGIDevice2, _)) + .WillByDefault( + DoAll(AddRefAndSetArgPointee<1>(dxgi_device_.Get()), Return(S_OK))); + + ON_CALL(*dxgi_device_.Get(), GetParent(IID_IDXGIAdapter3, _)) + .WillByDefault(DoAll(AddRefAndSetArgPointee<1>(dxgi_adapter_.Get()), + Return(S_OK))); + + ON_CALL(*dxgi_adapter_.Get(), + RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) + .WillByDefault(DoAll(SaveArg<0>(&teardown_event_), Return(S_OK))); + ON_CALL(*device_context_mock_.Get(), QueryInterface(IID_ID3D11VideoContext, _)) .WillByDefault( @@ -155,9 +195,9 @@ Return(S_OK))); } - // Helper method to do Initialize(), sets up EXPECT_CALLs for a successful - // initialization. - void Initialize(CdmProxy::InitializeCB callback) { + // Helper method to do Initialize(). Only useful if the test doesn't require + // access to the mocks later. + void Initialize(CdmProxy::Client* client, CdmProxy::InitializeCB callback) { EXPECT_CALL(create_device_mock_, Create(_, D3D_DRIVER_TYPE_HARDWARE, _, _, _, _, _, _, _, _)) .WillOnce(DoAll(AddRefAndSetArgPointee<7>(device_mock_.Get()), @@ -169,6 +209,21 @@ .WillRepeatedly(DoAll( AddRefAndSetArgPointee<1>(video_device_mock_.Get()), Return(S_OK))); + EXPECT_CALL(*device_mock_.Get(), QueryInterface(IID_IDXGIDevice2, _)) + .Times(AtLeast(1)) + .WillRepeatedly( + DoAll(AddRefAndSetArgPointee<1>(dxgi_device_.Get()), Return(S_OK))); + + EXPECT_CALL(*dxgi_device_.Get(), GetParent(IID_IDXGIAdapter3, _)) + .Times(AtLeast(1)) + .WillRepeatedly(DoAll(AddRefAndSetArgPointee<1>(dxgi_adapter_.Get()), + Return(S_OK))); + + EXPECT_CALL(*dxgi_adapter_.Get(), + RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) + .Times(AtLeast(1)) + .WillRepeatedly(DoAll(SaveArg<0>(&teardown_event_), Return(S_OK))); + EXPECT_CALL(*device_mock_.Get(), QueryInterface(IID_ID3D11VideoDevice1, _)) .Times(AtLeast(1)) .WillRepeatedly( @@ -202,7 +257,7 @@ .WillOnce(DoAll(SetArgPointee<3>(kPrivateInputSize), SetArgPointee<4>(kPrivateOutputSize), Return(S_OK))); - proxy_->Initialize(nullptr, std::move(callback)); + proxy_->Initialize(client, std::move(callback)); ::testing::Mock::VerifyAndClearExpectations(device_mock_.Get()); ::testing::Mock::VerifyAndClearExpectations(video_device_mock_.Get()); ::testing::Mock::VerifyAndClearExpectations(video_device1_mock_.Get()); @@ -213,6 +268,10 @@ } std::unique_ptr<D3D11CdmProxy> proxy_; + std::unique_ptr<base::PowerMonitor> power_monitor_; + // Owned by power_monitor_. Use this to simulate a power-suspend. + MockPowerMonitorSource* mock_power_monitor_source_; + D3D11CreateDeviceMock create_device_mock_; CallbackMock callback_mock_; @@ -223,12 +282,22 @@ Microsoft::WRL::ComPtr<D3D11DeviceContextMock> device_context_mock_; Microsoft::WRL::ComPtr<D3D11VideoContextMock> video_context_mock_; Microsoft::WRL::ComPtr<D3D11VideoContext1Mock> video_context1_mock_; + Microsoft::WRL::ComPtr<DXGIDevice2Mock> dxgi_device_; + Microsoft::WRL::ComPtr<DXGIAdapter3Mock> dxgi_adapter_; + D3D11_VIDEO_CONTENT_PROTECTION_CAPS content_protection_caps_ = {}; + // Event captured in Initialize(). Used in tests to notify hardware content + // protection teardown. + HANDLE teardown_event_; + // These size values are arbitrary. Used for mocking // GetCryptoSessionPrivateDataSize(). const UINT kPrivateInputSize = 10; const UINT kPrivateOutputSize = 40; + + // ObjectWatcher uses SequencedTaskRunnerHandle. + base::test::ScopedTaskEnvironment scoped_task_environment_; }; // Verifies that if device creation fails, then the call fails. @@ -245,8 +314,69 @@ // Initialize() success case. TEST_F(D3D11CdmProxyTest, Initialize) { EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, _, _)); - ASSERT_NO_FATAL_FAILURE(Initialize(base::BindOnce( - &CallbackMock::InitializeCallback, base::Unretained(&callback_mock_)))); + ASSERT_NO_FATAL_FAILURE( + Initialize(nullptr, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); +} + +// Hardware content protection teardown is notified to the proxy. +// Verify that the client is notified. +TEST_F(D3D11CdmProxyTest, HardwareContentProtectionTeardown) { + base::RunLoop run_loop; + MockProxyClient client; + EXPECT_CALL(client, NotifyHardwareReset()).WillOnce(Invoke([&run_loop]() { + run_loop.Quit(); + })); + + EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, _, _)); + ASSERT_NO_FATAL_FAILURE( + Initialize(&client, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); + SetEvent(teardown_event_); + run_loop.Run(); +} + +// Verify that failing to register to hardware content protection teardown +// status event results in initializaion failure. +TEST_F(D3D11CdmProxyTest, FailedToRegisterForContentProtectionTeardown) { + EXPECT_CALL(callback_mock_, + InitializeCallback(CdmProxy::Status::kFail, _, _)); + + EXPECT_CALL(*dxgi_adapter_.Get(), + RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) + .Times(AtLeast(1)) + .WillRepeatedly(Return(E_FAIL)); + + proxy_->Initialize(nullptr, + base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_))); +} + +// Verify that the client is notified on power suspend. +TEST_F(D3D11CdmProxyTest, PowerSuspend) { + base::RunLoop run_loop; + MockProxyClient client; + EXPECT_CALL(client, NotifyHardwareReset()).WillOnce(Invoke([&run_loop]() { + run_loop.Quit(); + })); + + EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, _, _)); + ASSERT_NO_FATAL_FAILURE( + Initialize(&client, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); + mock_power_monitor_source_->Suspend(); + run_loop.Run(); +} + +// Verify that if there isn't a power monitor, initialization fails. +TEST_F(D3D11CdmProxyTest, NoPowerMonitor) { + power_monitor_ = nullptr; + EXPECT_CALL(callback_mock_, + InitializeCallback(CdmProxy::Status::kFail, _, _)); + + proxy_->Initialize(nullptr, + base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_))); } // Initialization failure because HW key exchange is not available. @@ -282,8 +412,9 @@ uint32_t crypto_session_id = 0; EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, _, _)) .WillOnce(SaveArg<2>(&crypto_session_id)); - ASSERT_NO_FATAL_FAILURE(Initialize(base::BindOnce( - &CallbackMock::InitializeCallback, base::Unretained(&callback_mock_)))); + ASSERT_NO_FATAL_FAILURE( + Initialize(nullptr, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); ::testing::Mock::VerifyAndClearExpectations(&callback_mock_); // The size nor value here matter, so making non empty non zero vector. @@ -374,8 +505,9 @@ EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, kTestProtocol, _)) .WillOnce(SaveArg<2>(&crypto_session_id)); - ASSERT_NO_FATAL_FAILURE(Initialize(base::BindOnce( - &CallbackMock::InitializeCallback, base::Unretained(&callback_mock_)))); + ASSERT_NO_FATAL_FAILURE( + Initialize(nullptr, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); ::testing::Mock::VerifyAndClearExpectations(&callback_mock_); // The size nor value here matter, so making non empty non zero vector. @@ -454,8 +586,9 @@ EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, kTestProtocol, _)) .WillOnce(SaveArg<2>(&crypto_session_id_from_initialize)); - ASSERT_NO_FATAL_FAILURE(Initialize(base::BindOnce( - &CallbackMock::InitializeCallback, base::Unretained(&callback_mock_)))); + ASSERT_NO_FATAL_FAILURE( + Initialize(nullptr, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); ::testing::Mock::VerifyAndClearExpectations(&callback_mock_); // Expect a new crypto session. @@ -502,8 +635,9 @@ EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, kTestProtocol, _)) .WillOnce(SaveArg<2>(&crypto_session_id_from_initialize)); - ASSERT_NO_FATAL_FAILURE(Initialize(base::BindOnce( - &CallbackMock::InitializeCallback, base::Unretained(&callback_mock_)))); + ASSERT_NO_FATAL_FAILURE( + Initialize(nullptr, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); ::testing::Mock::VerifyAndClearExpectations(&callback_mock_); // Expect a new crypto session. @@ -567,8 +701,9 @@ EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, kTestProtocol, _)) .WillOnce(SaveArg<2>(&crypto_session_id_from_initialize)); - ASSERT_NO_FATAL_FAILURE(Initialize(base::BindOnce( - &CallbackMock::InitializeCallback, base::Unretained(&callback_mock_)))); + ASSERT_NO_FATAL_FAILURE( + Initialize(nullptr, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); ::testing::Mock::VerifyAndClearExpectations(&callback_mock_); std::vector<uint8_t> kKeyId = { @@ -604,8 +739,9 @@ EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kOk, kTestProtocol, _)) .WillOnce(SaveArg<2>(&crypto_session_id_from_initialize)); - ASSERT_NO_FATAL_FAILURE(Initialize(base::BindOnce( - &CallbackMock::InitializeCallback, base::Unretained(&callback_mock_)))); + ASSERT_NO_FATAL_FAILURE( + Initialize(nullptr, base::BindOnce(&CallbackMock::InitializeCallback, + base::Unretained(&callback_mock_)))); ::testing::Mock::VerifyAndClearExpectations(&callback_mock_); std::vector<uint8_t> kKeyId = {
diff --git a/media/gpu/windows/d3d11_mocks.cc b/media/gpu/windows/d3d11_mocks.cc index e934709..4b02e19 100644 --- a/media/gpu/windows/d3d11_mocks.cc +++ b/media/gpu/windows/d3d11_mocks.cc
@@ -14,6 +14,12 @@ D3D11DeviceMock::D3D11DeviceMock() = default; D3D11DeviceMock::~D3D11DeviceMock() = default; +DXGIDevice2Mock::DXGIDevice2Mock() = default; +DXGIDevice2Mock::~DXGIDevice2Mock() = default; + +DXGIAdapter3Mock::DXGIAdapter3Mock() = default; +DXGIAdapter3Mock::~DXGIAdapter3Mock() = default; + D3D11VideoDeviceMock::D3D11VideoDeviceMock() = default; D3D11VideoDeviceMock::~D3D11VideoDeviceMock() = default;
diff --git a/media/gpu/windows/d3d11_mocks.h b/media/gpu/windows/d3d11_mocks.h index 11260d8..4a79489f 100644 --- a/media/gpu/windows/d3d11_mocks.h +++ b/media/gpu/windows/d3d11_mocks.h
@@ -6,6 +6,7 @@ #include <d3d11.h> #include <d3d11_1.h> +#include <dxgi1_4.h> #include <wrl/client.h> #include <wrl/implements.h> @@ -268,6 +269,71 @@ MOCK_STDCALL_METHOD0(GetExceptionMode, UINT()); }; +class DXGIDevice2Mock : public MockCOMInterface<IDXGIDevice2> { + public: + DXGIDevice2Mock(); + ~DXGIDevice2Mock() override; + + MOCK_STDCALL_METHOD1(EnqueueSetEvent, HRESULT(HANDLE)); + MOCK_STDCALL_METHOD3(OfferResources, + HRESULT(UINT, + IDXGIResource* const*, + DXGI_OFFER_RESOURCE_PRIORITY)); + MOCK_STDCALL_METHOD3(ReclaimResources, + HRESULT(UINT, IDXGIResource* const*, BOOL*)); + MOCK_STDCALL_METHOD1(GetMaximumFrameLatency, HRESULT(UINT*)); + MOCK_STDCALL_METHOD1(SetMaximumFrameLatency, HRESULT(UINT)); + + MOCK_STDCALL_METHOD5(CreateSurface, + HRESULT(const DXGI_SURFACE_DESC*, + UINT, + DXGI_USAGE, + const DXGI_SHARED_RESOURCE*, + IDXGISurface**)); + MOCK_STDCALL_METHOD1(GetAdapter, HRESULT(IDXGIAdapter**)); + MOCK_STDCALL_METHOD1(GetGPUThreadPriority, HRESULT(INT*)); + MOCK_STDCALL_METHOD3(QueryResourceResidency, + HRESULT(IUnknown* const*, DXGI_RESIDENCY*, UINT)); + MOCK_STDCALL_METHOD1(SetGPUThreadPriority, HRESULT(INT)); + + MOCK_STDCALL_METHOD2(GetParent, HRESULT(REFIID, void**)); + MOCK_STDCALL_METHOD3(GetPrivateData, HRESULT(REFGUID, UINT*, void*)); + MOCK_STDCALL_METHOD3(SetPrivateData, HRESULT(REFGUID, UINT, const void*)); + MOCK_STDCALL_METHOD2(SetPrivateDataInterface, + HRESULT(REFGUID, const IUnknown*)); +}; + +class DXGIAdapter3Mock : public MockCOMInterface<IDXGIAdapter3> { + public: + DXGIAdapter3Mock(); + ~DXGIAdapter3Mock() override; + + MOCK_STDCALL_METHOD3(QueryVideoMemoryInfo, + HRESULT(UINT, + DXGI_MEMORY_SEGMENT_GROUP, + DXGI_QUERY_VIDEO_MEMORY_INFO*)); + MOCK_STDCALL_METHOD2(RegisterHardwareContentProtectionTeardownStatusEvent, + HRESULT(HANDLE, DWORD*)); + MOCK_STDCALL_METHOD2(RegisterVideoMemoryBudgetChangeNotificationEvent, + HRESULT(HANDLE, DWORD*)); + MOCK_STDCALL_METHOD3(SetVideoMemoryReservation, + HRESULT(UINT, DXGI_MEMORY_SEGMENT_GROUP, UINT64)); + MOCK_STDCALL_METHOD1(UnregisterHardwareContentProtectionTeardownStatus, + void(DWORD)); + MOCK_STDCALL_METHOD1(UnregisterVideoMemoryBudgetChangeNotification, + void(DWORD)); + MOCK_STDCALL_METHOD1(GetDesc2, HRESULT(DXGI_ADAPTER_DESC2*)); + MOCK_STDCALL_METHOD1(GetDesc1, HRESULT(DXGI_ADAPTER_DESC1*)); + MOCK_STDCALL_METHOD2(CheckInterfaceSupport, HRESULT(REFGUID, LARGE_INTEGER*)); + MOCK_STDCALL_METHOD2(EnumOutputs, HRESULT(UINT, IDXGIOutput**)); + MOCK_STDCALL_METHOD1(GetDesc, HRESULT(DXGI_ADAPTER_DESC*)); + MOCK_STDCALL_METHOD2(GetParent, HRESULT(REFIID, void**)); + MOCK_STDCALL_METHOD3(GetPrivateData, HRESULT(REFGUID, UINT*, void*)); + MOCK_STDCALL_METHOD3(SetPrivateData, HRESULT(REFGUID, UINT, const void*)); + MOCK_STDCALL_METHOD2(SetPrivateDataInterface, + HRESULT(REFGUID, const IUnknown*)); +}; + // TODO(crbug.com/788880): This may not be necessary. Tyr out and see if // D3D11VideoDevice1Mock is sufficient. and if so, remove this. class D3D11VideoDeviceMock : public MockCOMInterface<ID3D11VideoDevice> {
diff --git a/media/mojo/clients/mojo_jpeg_decode_accelerator.cc b/media/mojo/clients/mojo_jpeg_decode_accelerator.cc index 88d3908..3d1ff5fdb 100644 --- a/media/mojo/clients/mojo_jpeg_decode_accelerator.cc +++ b/media/mojo/clients/mojo_jpeg_decode_accelerator.cc
@@ -17,13 +17,13 @@ namespace media { MojoJpegDecodeAccelerator::MojoJpegDecodeAccelerator( - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SequencedTaskRunner> io_task_runner, mojom::JpegDecodeAcceleratorPtrInfo jpeg_decoder) : io_task_runner_(std::move(io_task_runner)), jpeg_decoder_info_(std::move(jpeg_decoder)) {} MojoJpegDecodeAccelerator::~MojoJpegDecodeAccelerator() { - DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); } bool MojoJpegDecodeAccelerator::Initialize( @@ -34,7 +34,7 @@ void MojoJpegDecodeAccelerator::InitializeAsync(Client* client, InitCB init_cb) { - DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); jpeg_decoder_.Bind(std::move(jpeg_decoder_info_)); @@ -50,7 +50,7 @@ void MojoJpegDecodeAccelerator::Decode( const BitstreamBuffer& bitstream_buffer, const scoped_refptr<VideoFrame>& video_frame) { - DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); DCHECK(jpeg_decoder_.is_bound()); DCHECK( @@ -86,7 +86,7 @@ InitCB init_cb, JpegDecodeAccelerator::Client* client, bool success) { - DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); if (success) client_ = client; @@ -97,7 +97,7 @@ void MojoJpegDecodeAccelerator::OnDecodeAck( int32_t bitstream_buffer_id, ::media::JpegDecodeAccelerator::Error error) { - DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); if (!client_) return; @@ -116,7 +116,7 @@ } void MojoJpegDecodeAccelerator::OnLostConnectionToJpegDecoder() { - DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); OnDecodeAck(kInvalidBitstreamBufferId, ::media::JpegDecodeAccelerator::Error::PLATFORM_FAILURE); }
diff --git a/media/mojo/clients/mojo_jpeg_decode_accelerator.h b/media/mojo/clients/mojo_jpeg_decode_accelerator.h index 6b67a907..6d8e78b 100644 --- a/media/mojo/clients/mojo_jpeg_decode_accelerator.h +++ b/media/mojo/clients/mojo_jpeg_decode_accelerator.h
@@ -14,18 +14,18 @@ #include "media/video/jpeg_decode_accelerator.h" namespace base { -class SingleThreadTaskRunner; +class SequencedTaskRunner; } namespace media { // A JpegDecodeAccelerator, for use in the browser process, that proxies to a // mojom::JpegDecodeAccelerator. Created on the owner's thread, otherwise -// operating and deleted on the IO thread. +// operating and deleted on |io_task_runner|. class MojoJpegDecodeAccelerator : public JpegDecodeAccelerator { public: MojoJpegDecodeAccelerator( - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + scoped_refptr<base::SequencedTaskRunner> io_task_runner, mojom::JpegDecodeAcceleratorPtrInfo jpeg_decoder); ~MojoJpegDecodeAccelerator() override; @@ -46,8 +46,7 @@ ::media::JpegDecodeAccelerator::Error error); void OnLostConnectionToJpegDecoder(); - // Browser IO task runner. - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; + scoped_refptr<base::SequencedTaskRunner> io_task_runner_; Client* client_ = nullptr;
diff --git a/media/mojo/services/video_decode_perf_history.cc b/media/mojo/services/video_decode_perf_history.cc index f074b4e..f94886a1 100644 --- a/media/mojo/services/video_decode_perf_history.cc +++ b/media/mojo/services/video_decode_perf_history.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" +#include "media/base/bind_to_current_loop.h" #include "media/base/video_codecs.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/metrics/public/cpp/ukm_builders.h" @@ -111,7 +112,7 @@ // this will be janky. // No stats? Lets be optimistic. - if (!stats) { + if (!stats || stats->frames_decoded == 0) { *is_power_efficient = true; *is_smooth = true; return; @@ -144,7 +145,7 @@ AssessStats(stats.get(), &is_smooth, &is_power_efficient); - if (stats) { + if (stats && stats->frames_decoded) { DCHECK(database_success); percent_dropped = static_cast<double>(stats->frames_dropped) / stats->frames_decoded; @@ -362,4 +363,27 @@ std::move(clear_done_cb).Run(); } +void VideoDecodePerfHistory::GetVideoDecodeStatsDB(GetCB get_db_cb) { + DVLOG(3) << __func__; + DCHECK(get_db_cb); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (db_init_status_ == FAILED) { + std::move(get_db_cb).Run(nullptr); + return; + } + + // Defer this request until the DB is initialized. + if (db_init_status_ != COMPLETE) { + init_deferred_api_calls_.push_back( + base::BindOnce(&VideoDecodePerfHistory::GetVideoDecodeStatsDB, + weak_ptr_factory_.GetWeakPtr(), std::move(get_db_cb))); + InitDatabase(); + return; + } + + // DB is already initialized. BindToCurrentLoop to avoid reentrancy. + std::move(BindToCurrentLoop(std::move(get_db_cb))).Run(db_.get()); +} + } // namespace media
diff --git a/media/mojo/services/video_decode_perf_history.h b/media/mojo/services/video_decode_perf_history.h index 8fe4f9e..1aa68ab 100644 --- a/media/mojo/services/video_decode_perf_history.h +++ b/media/mojo/services/video_decode_perf_history.h
@@ -15,6 +15,7 @@ #include "base/supports_user_data.h" #include "media/base/video_codecs.h" #include "media/capabilities/video_decode_stats_db.h" +#include "media/capabilities/video_decode_stats_db_provider.h" #include "media/mojo/interfaces/video_decode_perf_history.mojom.h" #include "media/mojo/services/media_mojo_export.h" #include "mojo/public/cpp/bindings/binding_set.h" @@ -45,7 +46,8 @@ // sequence. class MEDIA_MOJO_EXPORT VideoDecodePerfHistory : public mojom::VideoDecodePerfHistory, - public base::SupportsUserData::Data { + public base::SupportsUserData::Data, + public VideoDecodeStatsDBProvider { public: explicit VideoDecodePerfHistory( std::unique_ptr<VideoDecodeStatsDBFactory> db_factory); @@ -73,6 +75,10 @@ // complete. void ClearHistory(base::OnceClosure clear_done_cb); + // From VideoDecodeStatsDBProvider. |cb| receives a pointer to the + // *initialized* VideoDecodeStatsDB, or null in case of error. + void GetVideoDecodeStatsDB(GetCB cb) override; + private: friend class VideoDecodePerfHistoryTest;
diff --git a/media/mojo/services/video_decode_perf_history_unittest.cc b/media/mojo/services/video_decode_perf_history_unittest.cc index fa36b55..61b320a 100644 --- a/media/mojo/services/video_decode_perf_history_unittest.cc +++ b/media/mojo/services/video_decode_perf_history_unittest.cc
@@ -20,6 +20,9 @@ #include "url/origin.h" using UkmEntry = ukm::builders::Media_VideoDecodePerfRecord; +using testing::Eq; +using testing::IsNull; +using testing::_; namespace { @@ -158,6 +161,8 @@ // the operation has completed. See CompleteDBInitOnClearedHistory(). MOCK_METHOD0(MockOnClearedHistory, void()); + MOCK_METHOD1(MockGetVideoDecodeStatsDBCB, void(VideoDecodeStatsDB* db)); + mojom::PredictionFeatures MakeFeatures(VideoCodecProfile profile, gfx::Size video_size, int frames_per_sec) { @@ -279,9 +284,7 @@ GetFakeDB()->CompleteInitialize(true); // Allow initialize-deferred API calls to complete. - base::RunLoop run_loop; - base::PostTask(FROM_HERE, base::BindOnce(run_loop.QuitWhenIdleClosure())); - run_loop.Run(); + scoped_task_environment_.RunUntilIdle(); } } @@ -373,9 +376,7 @@ GetFakeDB()->CompleteInitialize(true); // Allow initialize-deferred API calls to complete. - base::RunLoop run_loop; - base::PostTask(FROM_HERE, base::BindOnce(run_loop.QuitWhenIdleClosure())); - run_loop.Run(); + scoped_task_environment_.RunUntilIdle(); } } @@ -402,9 +403,7 @@ GetFakeDB()->CompleteInitialize(false); // Allow initialize-deferred API calls to complete. - base::RunLoop run_loop; - base::PostTask(FROM_HERE, base::BindOnce(run_loop.QuitWhenIdleClosure())); - run_loop.Run(); + scoped_task_environment_.RunUntilIdle(); } } @@ -459,9 +458,7 @@ GetFakeDB()->CompleteInitialize(true); // Allow initialize-deferred API calls to complete. - base::RunLoop run_loop; - base::PostTask(FROM_HERE, base::BindOnce(run_loop.QuitWhenIdleClosure())); - run_loop.Run(); + scoped_task_environment_.RunUntilIdle(); } const auto& entries = test_recorder_->GetEntriesByName(UkmEntry::kEntryName); @@ -482,6 +479,70 @@ } } +TEST_P(VideoDecodePerfHistoryParamTest, GetVideoDecodeStatsDB) { + // NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then + // delayed until we db_->CompleteInitialize(). testing::InSequence enforces + // that EXPECT_CALLs arrive in top-to-bottom order. + bool defer_initialize = GetParam(); + testing::InSequence dummy; + + // Complete initialization in advance of API calls when not asked to defer. + if (!defer_initialize) + PreInitializeDB(/* success */ true); + + // Request a pointer to VideoDecodeStatsDB and verify the callback. + EXPECT_CALL(*this, MockGetVideoDecodeStatsDBCB(_)) + .WillOnce([&](const auto* db_ptr) { + // Not able to simply use a matcher because the DB does not exist at the + // time we setup the EXPECT_CALL. + EXPECT_EQ(GetFakeDB(), db_ptr); + }); + + perf_history_->GetVideoDecodeStatsDB( + base::BindOnce(&VideoDecodePerfHistoryTest::MockGetVideoDecodeStatsDBCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + + // Complete successful deferred DB initialization (see comment at top of test) + if (defer_initialize) { + GetFakeDB()->CompleteInitialize(true); + + // Allow initialize-deferred API calls to complete. + scoped_task_environment_.RunUntilIdle(); + } +} + +TEST_P(VideoDecodePerfHistoryParamTest, + GetVideoDecodeStatsDB_FailedInitialize) { + // NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then + // delayed until we db_->CompleteInitialize(). testing::InSequence enforces + // that EXPECT_CALLs arrive in top-to-bottom order. + bool defer_initialize = GetParam(); + testing::InSequence dummy; + + // Complete initialization in advance of API calls when not asked to defer. + if (!defer_initialize) + PreInitializeDB(/* success */ false); + + // Request a pointer to VideoDecodeStatsDB and verify the callback provides + // a nullptr due to failed initialization. + EXPECT_CALL(*this, MockGetVideoDecodeStatsDBCB(IsNull())); + perf_history_->GetVideoDecodeStatsDB( + base::BindOnce(&VideoDecodePerfHistoryTest::MockGetVideoDecodeStatsDBCB, + base::Unretained(this))); + + scoped_task_environment_.RunUntilIdle(); + + // Complete failed deferred DB initialization (see comment at top of test) + if (defer_initialize) { + GetFakeDB()->CompleteInitialize(false); + + // Allow initialize-deferred API calls to complete. + scoped_task_environment_.RunUntilIdle(); + } +} + INSTANTIATE_TEST_CASE_P(VaryDBInitTiming, VideoDecodePerfHistoryParamTest, ::testing::Values(true, false)); @@ -527,9 +588,7 @@ GetFakeDB()->CompleteInitialize(/* success */ true); // Allow initialize-deferred API calls to complete. - base::RunLoop run_loop; - base::PostTask(FROM_HERE, base::BindOnce(run_loop.QuitWhenIdleClosure())); - run_loop.Run(); + scoped_task_environment_.RunUntilIdle(); } } // namespace media
diff --git a/media/test/data/test_key_system_instantiation.html b/media/test/data/test_key_system_instantiation.html index 5ad38e61..e965cfaa 100644 --- a/media/test/data/test_key_system_instantiation.html +++ b/media/test/data/test_key_system_instantiation.html
@@ -18,7 +18,7 @@ // if they match, an error message if they don't. function verifyCapabilitiesAreEqual(actual, expected) { if (actual.length != expected.length) - return "mismatched lengths"; + return "mismatched lengths; not all capabilities are supported"; for (var i = 0; i < actual.length; i++) { // Only compare |contentType|. Other properties are ignored. if (actual[i].contentType !== expected[i].contentType)
diff --git a/mojo/edk/system/channel_fuchsia.cc b/mojo/edk/system/channel_fuchsia.cc index c52e602..2f01fec 100644 --- a/mojo/edk/system/channel_fuchsia.cc +++ b/mojo/edk/system/channel_fuchsia.cc
@@ -397,6 +397,11 @@ zx_status_t result = zx_channel_write(handle_.get().as_handle(), 0, message_view.data(), write_bytes, handles, handles_count); + // zx_channel_write() consumes |handles| whether or not it succeeds, so + // release() our copies now, to avoid them being double-closed. + for (auto& outgoing_handle : outgoing_handles) + ignore_result(outgoing_handle.release()); + if (result != ZX_OK) { // TODO(fuchsia): Handle ZX_ERR_SHOULD_WAIT flow-control errors, once // the platform starts generating them. See crbug.com/754084. @@ -406,10 +411,6 @@ return false; } - // |handles| have been transferred to the peer process, so release() - // them, to avoid them being double-closed. - for (auto& outgoing_handle : outgoing_handles) - ignore_result(outgoing_handle.release()); } while (write_bytes < message_view.data_num_bytes()); return true;
diff --git a/mojo/public/cpp/bindings/interface_ptr.h b/mojo/public/cpp/bindings/interface_ptr.h index 1de84b783..3ec522d 100644 --- a/mojo/public/cpp/bindings/interface_ptr.h +++ b/mojo/public/cpp/bindings/interface_ptr.h
@@ -48,15 +48,15 @@ InterfacePtr(decltype(nullptr)) {} // Takes over the binding of another InterfacePtr. - InterfacePtr(InterfacePtr&& other) { + InterfacePtr(InterfacePtr&& other) noexcept { internal_state_.Swap(&other.internal_state_); } - explicit InterfacePtr(PtrInfoType&& info) { Bind(std::move(info)); } + explicit InterfacePtr(PtrInfoType&& info) noexcept { Bind(std::move(info)); } // Takes over the binding of another InterfacePtr, and closes any message pipe // already bound to this pointer. - InterfacePtr& operator=(InterfacePtr&& other) { + InterfacePtr& operator=(InterfacePtr&& other) noexcept { reset(); internal_state_.Swap(&other.internal_state_); return *this;
diff --git a/mojo/public/cpp/bindings/sync_call_restrictions.h b/mojo/public/cpp/bindings/sync_call_restrictions.h index 439a450..e72cb1d 100644 --- a/mojo/public/cpp/bindings/sync_call_restrictions.h +++ b/mojo/public/cpp/bindings/sync_call_restrictions.h
@@ -23,7 +23,6 @@ namespace content { class BlinkTestController; -class VizProcessTransportFactory; } namespace display { @@ -40,6 +39,7 @@ namespace ui { class ClipboardClient; +class HostContextFactoryPrivate; } // namespace ui namespace viz { @@ -104,7 +104,7 @@ friend class content::BlinkTestController; // For preventing frame swaps of wrong size during resize on Windows. // (https://crbug.com/811945) - friend class content::VizProcessTransportFactory; + friend class ui::HostContextFactoryPrivate; // END ALLOWED USAGE. // BEGIN USAGE THAT NEEDS TO BE FIXED.
diff --git a/net/base/layered_network_delegate.cc b/net/base/layered_network_delegate.cc index 754ce8f..1e8f84c 100644 --- a/net/base/layered_network_delegate.cc +++ b/net/base/layered_network_delegate.cc
@@ -128,12 +128,13 @@ void LayeredNetworkDelegate::OnCompleted(URLRequest* request, bool started, int net_error) { - OnCompletedInternal(request, started); + OnCompletedInternal(request, started, net_error); nested_network_delegate_->NotifyCompleted(request, started, net_error); } void LayeredNetworkDelegate::OnCompletedInternal(URLRequest* request, - bool started) {} + bool started, + int net_error) {} void LayeredNetworkDelegate::OnURLRequestDestroyed(URLRequest* request) { OnURLRequestDestroyedInternal(request); @@ -231,18 +232,19 @@ const URLRequest& request, const GURL& target_url, const GURL& referrer_url) const { - OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( - request, target_url, referrer_url); - return nested_network_delegate_ - ->CancelURLRequestWithPolicyViolatingReferrerHeader(request, target_url, - referrer_url); + return OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( + request, target_url, referrer_url) || + nested_network_delegate_ + ->CancelURLRequestWithPolicyViolatingReferrerHeader( + request, target_url, referrer_url); } -void LayeredNetworkDelegate:: +bool LayeredNetworkDelegate:: OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( const URLRequest& request, const GURL& target_url, const GURL& referrer_url) const { + return false; } bool LayeredNetworkDelegate::OnCanQueueReportingReport(
diff --git a/net/base/layered_network_delegate.h b/net/base/layered_network_delegate.h index 0e7d3a039..531cf24 100644 --- a/net/base/layered_network_delegate.h +++ b/net/base/layered_network_delegate.h
@@ -134,7 +134,9 @@ virtual void OnNetworkBytesSentInternal(URLRequest* request, int64_t bytes_sent); - virtual void OnCompletedInternal(URLRequest* request, bool started); + virtual void OnCompletedInternal(URLRequest* request, + bool started, + int net_error); virtual void OnURLRequestDestroyedInternal(URLRequest* request); @@ -163,7 +165,9 @@ virtual void OnAreExperimentalCookieFeaturesEnabledInternal() const; - virtual void OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( + // If this returns false, it short circuits the corresponding call in any + // nested NetworkDelegates. + virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( const URLRequest& request, const GURL& target_url, const GURL& referrer_url) const;
diff --git a/net/base/layered_network_delegate_unittest.cc b/net/base/layered_network_delegate_unittest.cc index 2de65e4..3d97b66 100644 --- a/net/base/layered_network_delegate_unittest.cc +++ b/net/base/layered_network_delegate_unittest.cc
@@ -271,7 +271,9 @@ EXPECT_EQ(1, (*counters_)["on_network_bytes_sent_count"]); } - void OnCompletedInternal(URLRequest* request, bool started) override { + void OnCompletedInternal(URLRequest* request, + bool started, + int net_error) override { ++(*counters_)["on_completed_count"]; EXPECT_EQ(1, (*counters_)["on_completed_count"]); } @@ -322,7 +324,7 @@ EXPECT_EQ(1, (*counters_)["on_can_enable_privacy_mode_count"]); } - void OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( + bool OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( const URLRequest& request, const GURL& target_url, const GURL& referrer_url) const override { @@ -332,6 +334,7 @@ EXPECT_EQ(1, (*counters_) ["on_cancel_url_request_with_policy_" "violating_referrer_header_count"]); + return false; } void OnCanQueueReportingReportInternal(
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc index d0e8b6dc..1410a39 100644 --- a/net/base/network_change_notifier.cc +++ b/net/base/network_change_notifier.cc
@@ -744,6 +744,7 @@ void NetworkChangeNotifier::InitHistogramWatcher() { if (!g_network_change_notifier) return; + DCHECK(!g_network_change_notifier->histogram_watcher_); g_network_change_notifier->histogram_watcher_.reset(new HistogramWatcher()); g_network_change_notifier->histogram_watcher_->Init(); } @@ -752,6 +753,7 @@ void NetworkChangeNotifier::ShutdownHistogramWatcher() { if (!g_network_change_notifier) return; + DCHECK(g_network_change_notifier->histogram_watcher_); g_network_change_notifier->histogram_watcher_.reset(); }
diff --git a/net/base/network_change_notifier_fuchsia_unittest.cc b/net/base/network_change_notifier_fuchsia_unittest.cc index 9dc34c3..33e9e3a 100644 --- a/net/base/network_change_notifier_fuchsia_unittest.cc +++ b/net/base/network_change_notifier_fuchsia_unittest.cc
@@ -160,6 +160,9 @@ SetDhcpClientStatusCallback callback) override {} void BridgeInterfaces(::fidl::VectorPtr<uint32_t> nicids, BridgeInterfacesCallback callback) override {} + void SetFilterStatus(bool enabled, + SetFilterStatusCallback callback) override {} + void GetFilterStatus(GetFilterStatusCallback callback) override {} fuchsia::netstack::NotificationListenerSyncPtr listener_; ::fidl::VectorPtr<fuchsia::netstack::NetInterface> interfaces_ =
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index eb0064f..949de47 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -2510,16 +2510,6 @@ EVENT_TYPE(CHROME_EXTENSION_PROVIDE_AUTH_CREDENTIALS) // ------------------------------------------------------------------------ -// HostBlacklistManager -// ------------------------------------------------------------------------ - -// TODO(joaodasilva): Layering violation, see comment above. -// http://crbug.com/90674. - -// This event is created when a request is blocked by a policy. -EVENT_TYPE(CHROME_POLICY_ABORTED_REQUEST) - -// ------------------------------------------------------------------------ // CertVerifier // ------------------------------------------------------------------------ @@ -2598,180 +2588,6 @@ // } EVENT_TYPE(TRIAL_CERT_VERIFIER_JOB_COMPARISON_STARTED) -// ------------------------------------------------------------------------ -// Download start events. -// ------------------------------------------------------------------------ - -// This event is created when a download is started, and lets the URL request -// event source know what download source it is using. -// { -// "source_dependency": <Source id of the download>, -// } -EVENT_TYPE(DOWNLOAD_STARTED) - -// This event is created when a download is started, and lets the download -// event source know what URL request it's associated with. -// { -// "source_dependency": <Source id of the request being waited on>, -// } -EVENT_TYPE(DOWNLOAD_URL_REQUEST) - -// ------------------------------------------------------------------------ -// DownloadItem events. -// ------------------------------------------------------------------------ - -// This event lives for as long as a download item is active. -// The BEGIN event occurs right after construction, and has the following -// parameters: -// { -// "type": <New/history/save page>, -// "id": <Download ID>, -// "original_url": <URL that initiated the download>, -// "final_url": <URL of the actual download file>, -// "file_name": <initial file name, based on DownloadItem's members: -// For History downloads it's the |full_path_| -// For other downloads, uses the first non-empty variable of: -// |state_info.force_filename| -// |suggested_filename_| -// the filename specified in the final URL>, -// "danger_type": <NOT_DANGEROUS, DANGEROUS_FILE, DANGEROUS_URL, -// DANGEROUS_CONTENT, MAYBE_DANGEROUS_CONTENT, -// UNCOMMON_CONTENT, USER_VALIDATED, DANGEROUS_HOST, -// POTENTIALLY_UNWANTED>, -// "start_offset": <Where to start writing (defaults to 0)>, -// "has_user_gesture": <Whether or not we think the user initiated -// the download> -// } -// The END event will occur when the download is interrupted, canceled or -// completed. -// DownloadItems that are loaded from history and are never active simply ADD -// one of these events. -EVENT_TYPE(DOWNLOAD_ITEM_ACTIVE) - -// Recorded when the DownloadFile is created. -// { -// "source_dependency": <Source ID of DownloadFile> -// } -EVENT_TYPE(DOWNLOAD_FILE_CREATED) - -// This event is created when a download item's danger type -// has been modified. -// { -// "danger_type": <The new danger type. See above for possible values.>, -// } -EVENT_TYPE(DOWNLOAD_ITEM_SAFETY_STATE_UPDATED) - -// This event is created when a download item is updated. -// { -// "bytes_so_far": <Number of bytes received>, -// "hash_state": <Current hash state, as a hex-encoded binary string>, -// } -EVENT_TYPE(DOWNLOAD_ITEM_UPDATED) - -// This event is created when a download item is renamed. -// { -// "old_filename": <Old file name>, -// "new_filename": <New file name>, -// } -EVENT_TYPE(DOWNLOAD_ITEM_RENAMED) - -// This event is created when a download item is interrupted. -// { -// "interrupt_reason": <The reason for the interruption>, -// "bytes_so_far": <Number of bytes received>, -// "hash_state": <Current hash state, as a hex-encoded binary string>, -// } -EVENT_TYPE(DOWNLOAD_ITEM_INTERRUPTED) - -// This event is created when a download item is resumed. -// { -// "user_initiated": <True if user initiated resume>, -// "reason": <The reason for the interruption>, -// "bytes_so_far": <Number of bytes received>, -// "hash_state": <Current hash state, as a hex-encoded binary string>, -// } -EVENT_TYPE(DOWNLOAD_ITEM_RESUMED) - -// This event is created when a download item is completing. -// { -// "bytes_so_far": <Number of bytes received>, -// "final_hash": <Final hash, as a hex-encoded binary string>, -// } -EVENT_TYPE(DOWNLOAD_ITEM_COMPLETING) - -// This event is created when a download item is finished. -// { -// "auto_opened": <Whether or not the download was auto-opened> -// } -EVENT_TYPE(DOWNLOAD_ITEM_FINISHED) - -// This event is created when a download item is canceled. -// { -// "bytes_so_far": <Number of bytes received>, -// "hash_state": <Current hash state, as a hex-encoded binary string>, -// } -EVENT_TYPE(DOWNLOAD_ITEM_CANCELED) - -// ------------------------------------------------------------------------ -// DownloadFile events. -// ------------------------------------------------------------------------ - -// A new download file was created. -// { -// "source_dependency": <Source ID of owning DownloadItem> -// } -EVENT_TYPE(DOWNLOAD_FILE_ACTIVE) - -// This event is created when a download file is opened, and lasts until -// the file is closed. -// The BEGIN event has the following parameters: -// { -// "file_name": <The name of the file>, -// "start_offset": <The position at which to start writing>, -// } -EVENT_TYPE(DOWNLOAD_FILE_OPENED) - -// This event is created when the stream between download source -// and download file is drained. -// { -// "stream_size": <Total size of all bytes drained from the stream> -// "num_buffers": <How many separate buffers those bytes were in> -// } -EVENT_TYPE(DOWNLOAD_STREAM_DRAINED) - -// Created when a buffer is written to the download file. The END event has the -// following paramters: -// { -// "bytes": <Count of bytes written> -// } -EVENT_TYPE(DOWNLOAD_FILE_WRITTEN) - -// This event is created when a download file is renamed. -// { -// "old_filename": <Old filename>, -// "new_filename": <New filename>, -// } -EVENT_TYPE(DOWNLOAD_FILE_RENAMED) - -// This event is created when a download file is detached. -EVENT_TYPE(DOWNLOAD_FILE_DETACHED) - -// This event is created when a download file is deleted. -EVENT_TYPE(DOWNLOAD_FILE_DELETED) - -// This event is created when a download file operation has an error. -// { -// "operation": <open, write, close, etc>, -// "net_error": <net::Error code>, -// "os_error": <OS dependent error code> -// "interrupt_reason": <Download interrupt reason> -// } -EVENT_TYPE(DOWNLOAD_FILE_ERROR) - -// This event is created when a download file is annotating with source -// information (for Mark Of The Web and anti-virus integration). -EVENT_TYPE(DOWNLOAD_FILE_ANNOTATED) - // ----------------------------------------------------------------------------- // FTP events. // -----------------------------------------------------------------------------
diff --git a/net/log/net_log_source_type_list.h b/net/log/net_log_source_type_list.h index 73ffe2aa..0302d1ef 100644 --- a/net/log/net_log_source_type_list.h +++ b/net/log/net_log_source_type_list.h
@@ -29,13 +29,9 @@ SOURCE_TYPE(EXPONENTIAL_BACKOFF_THROTTLING) SOURCE_TYPE(UDP_SOCKET) SOURCE_TYPE(CERT_VERIFIER_JOB) -SOURCE_TYPE(DOWNLOAD) -SOURCE_TYPE(DOWNLOAD_FILE) SOURCE_TYPE(PROXY_CLIENT_SOCKET) SOURCE_TYPE(PROXY_CLIENT_SOCKET_WRAPPER) SOURCE_TYPE(DATA_REDUCTION_PROXY) -SOURCE_TYPE(IOS_WEB_VIEW_CERT_VERIFIER) -SOURCE_TYPE(SAFE_BROWSING) SOURCE_TYPE(BIDIRECTIONAL_STREAM) SOURCE_TYPE(NETWORK_QUALITY_ESTIMATOR) SOURCE_TYPE(HTTP_STREAM_JOB_CONTROLLER)
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index 127fda81a..35b72a5 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -1782,4 +1782,11 @@ params_->socket_watchers_min_notification_interval()); } +void NetworkQualityEstimator::SimulateNetworkQualityChangeForTesting( + net::EffectiveConnectionType type) { + DCHECK(thread_checker_.CalledOnValidThread()); + params_->SetForcedEffectiveConnectionTypeForTesting(type); + ComputeEffectiveConnectionType(); +} + } // namespace net
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h index df96745..71fe10a 100644 --- a/net/nqe/network_quality_estimator.h +++ b/net/nqe/network_quality_estimator.h
@@ -223,6 +223,13 @@ void EnableGetNetworkIdAsynchronously(); #endif // defined(OS_CHROMEOS) + // Forces the effective connection type to be recomputed as |type|. Once + // called, effective connection type would always be computed as |type|. + // Calling this also notifies all the observers of the effective connection + // type as |type|. + void SimulateNetworkQualityChangeForTesting( + net::EffectiveConnectionType type); + typedef nqe::internal::Observation Observation; typedef nqe::internal::ObservationBuffer ObservationBuffer;
diff --git a/net/nqe/network_quality_estimator_params.cc b/net/nqe/network_quality_estimator_params.cc index 3dd5166..3df5f2a 100644 --- a/net/nqe/network_quality_estimator_params.cc +++ b/net/nqe/network_quality_estimator_params.cc
@@ -516,6 +516,14 @@ return use_small_responses_; }; +void NetworkQualityEstimatorParams::SetForcedEffectiveConnectionTypeForTesting( + EffectiveConnectionType type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!forced_effective_connection_type_); + DCHECK(!forced_effective_connection_type_on_cellular_only_); + forced_effective_connection_type_ = type; +} + base::Optional<EffectiveConnectionType> NetworkQualityEstimatorParams::GetForcedEffectiveConnectionType( NetworkChangeNotifier::ConnectionType connection_type) {
diff --git a/net/nqe/network_quality_estimator_params.h b/net/nqe/network_quality_estimator_params.h index 8dba248..cd551c22 100644 --- a/net/nqe/network_quality_estimator_params.h +++ b/net/nqe/network_quality_estimator_params.h
@@ -214,6 +214,9 @@ return socket_watchers_min_notification_interval_; } + // Sets the forced effective connection type as |type|. + void SetForcedEffectiveConnectionTypeForTesting(EffectiveConnectionType type); + private: // Map containing all field trial parameters related to // NetworkQualityEstimator field trial.
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc index 37a5dcf..4a34a04 100644 --- a/net/nqe/network_quality_estimator_unittest.cc +++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -2335,6 +2335,31 @@ } } +// Tests that the value of the effective connection type can be forced after +// network quality estimator has been initialized. +TEST_F(NetworkQualityEstimatorTest, SimulateNetworkQualityChangeForTesting) { + for (int i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { + EffectiveConnectionType ect_type = static_cast<EffectiveConnectionType>(i); + TestNetworkQualityEstimator estimator; + + TestEffectiveConnectionTypeObserver ect_observer; + estimator.AddEffectiveConnectionTypeObserver(&ect_observer); + + // |observer| may be notified as soon as it is added. Run the loop to so + // that the notification to |observer| is finished. + base::RunLoop().RunUntilIdle(); + + TestDelegate test_delegate; + TestURLRequestContext context(true); + context.set_network_quality_estimator(&estimator); + context.Init(); + estimator.SimulateNetworkQualityChangeForTesting(ect_type); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(ect_type, ect_observer.effective_connection_types().back()); + } +} + // Test that the typical network qualities are set correctly. TEST_F(NetworkQualityEstimatorTest, TypicalNetworkQualities) { TestNetworkQualityEstimator estimator;
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index dcfda6f2..4a769cd 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -783,11 +783,12 @@ bool disconnected); void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected); void TestMigrationOnNetworkDisconnected(bool async_write_before); - void OnNetworkMadeDefault(bool async_write_before); + void TestMigrationOnNetworkMadeDefault(IoMode write_mode); + void TestMigrationOnPathDegrading(bool async_write_before); void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode); - void TestMigrationOnWriteErrorWithNetworkAddedBeforeNotification( + void TestMigrationOnWriteErrorWithMultipleNotifications( IoMode write_error_mode, - bool disconnected); + bool disconnect_before_connect); QuicFlagSaver flags_; // Save/restore all QUIC flag values. MockHostResolver host_resolver_; @@ -2137,37 +2138,64 @@ EXPECT_TRUE(socket_data.AllWriteDataConsumed()); } -TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultWithSynchronousWriteBefore) { - OnNetworkMadeDefault(/*async_write_before=*/false); +TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) { + TestMigrationOnNetworkMadeDefault(SYNCHRONOUS); } -TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultWithAsyncWriteBefore) { - OnNetworkMadeDefault(/*async_write_before=*/true); +TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) { + TestMigrationOnNetworkMadeDefault(ASYNC); } -void QuicStreamFactoryTestBase::OnNetworkMadeDefault(bool async_write_before) { - InitializeConnectionMigrationTest( - {kDefaultNetworkForTests, kNewNetworkForTests}); +// Sets up a test which attempts connection migration successfully after probing +// when a new network is made as default and the old default is still available. +// |write_mode| specifies the write mode for the last write before +// OnNetworkMadeDefault is delivered to session. +void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault( + IoMode write_mode) { + InitializeConnectionMigrationV2Test({kDefaultNetworkForTests}); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - int packet_number = 1; - MockQuicData socket_data; + // Using a testing task runner so that we can control time. + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get()); + + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->QueueNetworkMadeDefault(kDefaultNetworkForTests); + + MockQuicData quic_data1; quic::QuicStreamOffset header_stream_offset = 0; - socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - SYNCHRONOUS, - ConstructInitialSettingsPacket(packet_number++, &header_stream_offset)); - socket_data.AddWrite( - SYNCHRONOUS, ConstructGetRequestPacket( - packet_number++, GetNthClientInitiatedStreamId(0), true, - true, &header_stream_offset)); - if (async_write_before) { - socket_data.AddWrite(ASYNC, OK); - packet_number++; - } - socket_data.AddSocketDataToFactory(socket_factory_.get()); + quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read. + quic_data1.AddWrite(SYNCHRONOUS, + ConstructInitialSettingsPacket(1, &header_stream_offset)); + quic_data1.AddWrite( + write_mode, ConstructGetRequestPacket(2, GetNthClientInitiatedStreamId(0), + true, true, &header_stream_offset)); + quic_data1.AddSocketDataToFactory(socket_factory_.get()); + + // Set up the second socket data provider that is used after migration. + // The response to the earlier request is read on the new socket. + MockQuicData quic_data2; + // Connectivity probe to be sent on the new path. + quic_data2.AddWrite( + SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(3, true, 1338)); + quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause + // Connectivity probe to receive from the server. + quic_data2.AddRead( + ASYNC, server_maker_.MakeConnectivityProbingPacket(1, false, 1338)); + // Ping packet to send after migration is completed. + quic_data2.AddWrite(ASYNC, + client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1)); + quic_data2.AddRead( + ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0), + false, false)); + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddWrite(SYNCHRONOUS, + client_maker_.MakeAckAndRstPacket( + 5, false, GetNthClientInitiatedStreamId(0), + quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true)); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); // Create request and QuicHttpStream. QuicStreamRequest request(factory_.get()); @@ -2200,81 +2228,89 @@ EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, callback_.callback())); - // Do an async write to leave writer blocked. - if (async_write_before) { - session->SendPing(); - } + // Deliver a signal that a alternate network is connected now, this should + // cause the connection to start early migration on path degrading. + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->SetConnectedNetworksList( + {kDefaultNetworkForTests, kNewNetworkForTests}); + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->NotifyNetworkConnected(kNewNetworkForTests); - // Set up second socket data provider that is used after migration. - // The response to the earlier request is read on this new socket. - MockQuicData socket_data1; - socket_data1.AddWrite( - SYNCHRONOUS, - client_maker_.MakePingPacket(packet_number++, /*include_version=*/true)); - socket_data1.AddRead( - ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0), - false, false)); - socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite( - SYNCHRONOUS, client_maker_.MakeAckAndRstPacket( - packet_number++, false, GetNthClientInitiatedStreamId(0), - quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true)); - socket_data1.AddSocketDataToFactory(socket_factory_.get()); - - // Trigger connection migration. This should cause a PING frame - // to be emitted. + // Cause the connection to report path degrading to the session. + // Due to lack of alternate network, session will not mgirate connection. + EXPECT_EQ(0u, task_runner->GetPendingTaskCount()); scoped_mock_network_change_notifier_->mock_network_change_notifier() ->NotifyNetworkMadeDefault(kNewNetworkForTests); - // The session should now be marked as going away. Ensure that - // while it is still alive, it is no longer active. + // A task will be posted to migrate to the new default network. + EXPECT_EQ(1u, task_runner->GetPendingTaskCount()); + EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay()); + + // Execute the posted task to migrate back to the default network. + task_runner->RunUntilIdle(); + // Another task to try send a new connectivity probe is posted. And a task to + // retry migrate back to default network is scheduled. + EXPECT_EQ(2u, task_runner->GetPendingTaskCount()); + // Next connectivity probe is scheduled to be sent in 2 * + // kDefaultRTTMilliSecs. + base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay(); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs), + next_task_delay); + + // The connection should still be alive, and not marked as going away. EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); - EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveSession(host_port_pair_)); + EXPECT_EQ(1u, session->GetNumActiveStreams()); + EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback())); + + // Resume quic data and a connectivity probe response will be read on the new + // socket, declare probing as successful. And a new task to WriteToNewSocket + // will be posted to complete migration. + quic_data2.Resume(); + + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_TRUE(HasActiveSession(host_port_pair_)); EXPECT_EQ(1u, session->GetNumActiveStreams()); - // Verify that response headers on the migrated socket were delivered to the - // stream. - EXPECT_THAT(stream->ReadResponseHeaders(callback_.callback()), IsOk()); + // There should be three pending tasks, the nearest one will complete + // migration to the new network. + EXPECT_EQ(3u, task_runner->GetPendingTaskCount()); + next_task_delay = task_runner->NextPendingTaskDelay(); + EXPECT_EQ(base::TimeDelta(), next_task_delay); + task_runner->FastForwardBy(next_task_delay); + + // Response headers are received over the new network. + EXPECT_THAT(callback_.WaitForResult(), IsOk()); EXPECT_EQ(200, response.headers->response_code()); - // Create a new request for the same destination and verify that a - // new session is created. - MockQuicData socket_data2; - socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); - socket_data2.AddSocketDataToFactory(socket_factory_.get()); + // Now there are two pending tasks, the nearest one was to send connectivity + // probe and has been cancelled due to successful migration. + EXPECT_EQ(2u, task_runner->GetPendingTaskCount()); + next_task_delay = task_runner->NextPendingTaskDelay(); + EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs), + next_task_delay); + task_runner->FastForwardBy(next_task_delay); - QuicStreamRequest request2(factory_.get()); - EXPECT_EQ(ERR_IO_PENDING, - request2.Request(host_port_pair_, version_, privacy_mode_, - DEFAULT_PRIORITY, SocketTag(), - /*cert_verify_flags=*/0, url_, net_log_, - &net_error_details_, callback_.callback())); - EXPECT_THAT(callback_.WaitForResult(), IsOk()); - std::unique_ptr<HttpStream> stream2 = CreateStream(&request2); - EXPECT_TRUE(stream2.get()); + // There's one more task to mgirate back to the default network in 0.4s, which + // is also cancelled due to the success migration on the previous trial. + EXPECT_EQ(1u, task_runner->GetPendingTaskCount()); + next_task_delay = task_runner->NextPendingTaskDelay(); + base::TimeDelta expected_delay = + base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) - + base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs); + EXPECT_EQ(expected_delay, next_task_delay); + task_runner->FastForwardBy(next_task_delay); + EXPECT_EQ(0u, task_runner->GetPendingTaskCount()); - EXPECT_TRUE(HasActiveSession(host_port_pair_)); - QuicChromiumClientSession* new_session = GetActiveSession(host_port_pair_); - EXPECT_NE(session, new_session); - - // On a DISCONNECTED notification, nothing happens to the migrated - // session, but the new session is closed since it has no open - // streams. - scoped_mock_network_change_notifier_->mock_network_change_notifier() - ->NotifyNetworkDisconnected(kDefaultNetworkForTests); + // Verify that the session is still alive. EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); - EXPECT_EQ(1u, session->GetNumActiveStreams()); - EXPECT_FALSE( - QuicStreamFactoryPeer::IsLiveSession(factory_.get(), new_session)); - stream.reset(); + EXPECT_TRUE(HasActiveSession(host_port_pair_)); - EXPECT_TRUE(socket_data.AllReadDataConsumed()); - EXPECT_TRUE(socket_data.AllWriteDataConsumed()); - EXPECT_TRUE(socket_data1.AllReadDataConsumed()); - EXPECT_TRUE(socket_data1.AllWriteDataConsumed()); - EXPECT_TRUE(socket_data2.AllReadDataConsumed()); - EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); + stream.reset(); + EXPECT_TRUE(quic_data1.AllReadDataConsumed()); + EXPECT_TRUE(quic_data1.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); } // This test verifies that session times out connection migration attempt @@ -2721,9 +2757,8 @@ EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, callback_.callback())); - if (async_write_before) { + if (async_write_before) session->SendPing(); - } // Set up second socket data provider that is used after migration. // The response to the earlier request is read on this new socket. @@ -2903,8 +2938,21 @@ } // This test verifies that the connection migrates to the alternate network -// early when path degrading is detected. -TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegrading) { +// early when path degrading is detected with an ASYNCHRONOUS write before +// migration. +TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) { + TestMigrationOnPathDegrading(/*async_write_before_migration*/ true); +} + +// This test verifies that the connection migrates to the alternate network +// early when path degrading is detected with a SYNCHRONOUS write before +// migration. +TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) { + TestMigrationOnPathDegrading(/*async_write_before_migration*/ false); +} + +void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading( + bool async_write_before) { InitializeConnectionMigrationV2Test( {kDefaultNetworkForTests, kNewNetworkForTests}); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -2918,34 +2966,42 @@ scoped_mock_network_change_notifier_->mock_network_change_notifier() ->QueueNetworkMadeDefault(kDefaultNetworkForTests); + int packet_number = 1; MockQuicData quic_data1; quic::QuicStreamOffset header_stream_offset = 0; quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read. - quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset)); - quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket( - 2, GetNthClientInitiatedStreamId(0), true, true, &header_stream_offset)); + quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket( + packet_number++, &header_stream_offset)); + quic_data1.AddWrite( + SYNCHRONOUS, ConstructGetRequestPacket( + packet_number++, GetNthClientInitiatedStreamId(0), true, + true, &header_stream_offset)); + if (async_write_before) { + quic_data1.AddWrite(ASYNC, OK); + packet_number++; + } quic_data1.AddSocketDataToFactory(socket_factory_.get()); // Set up the second socket data provider that is used after migration. // The response to the earlier request is read on the new socket. MockQuicData quic_data2; // Connectivity probe to be sent on the new path. - quic_data2.AddWrite(SYNCHRONOUS, - client_maker_.MakeConnectivityProbingPacket(3, true, 1338)); + quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket( + packet_number++, true, 1338)); quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause // Connectivity probe to receive from the server. quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1, false, 1338)); // Ping packet to send after migration is completed. - quic_data2.AddWrite(ASYNC, - client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1)); + quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket( + packet_number++, false, 1, 1, 1)); quic_data2.AddRead(ASYNC, ConstructOkResponsePacket( 2, GetNthClientInitiatedStreamId(0), false, false)); quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - quic_data2.AddWrite(SYNCHRONOUS, - client_maker_.MakeAckAndRstPacket( - 5, false, GetNthClientInitiatedStreamId(0), - quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true)); + quic_data2.AddWrite( + SYNCHRONOUS, client_maker_.MakeAckAndRstPacket( + packet_number++, false, GetNthClientInitiatedStreamId(0), + quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true)); quic_data2.AddSocketDataToFactory(socket_factory_.get()); // Create request and QuicHttpStream. @@ -2979,6 +3035,9 @@ EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, callback_.callback())); + if (async_write_before) + session->SendPing(); + // Cause the connection to report path degrading to the session. // Session will start to probe the alternate network. session->connection()->OnPathDegradingTimeout(); @@ -3465,9 +3524,11 @@ EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); } +// This test verifies that multiple sessions are migrated on connection +// migration signal. TEST_P(QuicStreamFactoryTest, - OnNetworkChangeDisconnectedPauseBeforeConnectedMultipleSessions) { - InitializeConnectionMigrationTest({kDefaultNetworkForTests}); + MigrateMultipleSessionsToBadSocketsAfterDisconnected) { + InitializeConnectionMigrationV2Test({kDefaultNetworkForTests}); MockQuicData socket_data1; socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); @@ -3551,7 +3612,8 @@ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1)); EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2)); - // Add new sockets to use post migration. + // Add new sockets to use post migration. Those are bad sockets and will cause + // migration to fail. MockConnect connect_result = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED); SequencedSocketData socket_data3(connect_result, base::span<MockRead>(), @@ -3561,8 +3623,8 @@ base::span<MockWrite>()); socket_factory_->AddSocketDataProvider(&socket_data4); - // Add a new network and cause migration to bad sockets, causing sessions to - // close. + // Connect the new network and cause migration to bad sockets, causing + // sessions to close. scoped_mock_network_change_notifier_->mock_network_change_notifier() ->SetConnectedNetworksList({kNewNetworkForTests}); scoped_mock_network_change_notifier_->mock_network_change_notifier() @@ -3577,22 +3639,38 @@ EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); } -TEST_P(QuicStreamFactoryTest, MigrateSessionEarly) { - InitializeConnectionMigrationTest( - {kDefaultNetworkForTests, kNewNetworkForTests}); +// This test verifies that session attempts connection migration with signals +// delivered in the following order (no alternate network is available): +// - path degrading is detected: session attempts connection migration but no +// alternate network is available, session caches path degrading signal in +// connection and stays on the original network. +// - original network backs up, request is served in the orignal network, +// session is not marked as going away. +TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) { + InitializeConnectionMigrationV2Test({kDefaultNetworkForTests}); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - MockQuicData socket_data; + MockQuicData quic_data; quic::QuicStreamOffset header_stream_offset = 0; - socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset)); - socket_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket( - 2, GetNthClientInitiatedStreamId(0), - true, true, &header_stream_offset)); - socket_data.AddSocketDataToFactory(socket_factory_.get()); + quic_data.AddWrite(SYNCHRONOUS, + ConstructInitialSettingsPacket(1, &header_stream_offset)); + quic_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket( + 2, GetNthClientInitiatedStreamId(0), true, + true, &header_stream_offset)); + quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal. + + // The rest of the data will still flow in the original socket as there is no + // new network after path degrading. + quic_data.AddRead( + ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0), + false, false)); + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, + client_maker_.MakeAckAndRstPacket( + 3, false, GetNthClientInitiatedStreamId(0), + quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true)); + quic_data.AddSocketDataToFactory(socket_factory_.get()); // Create request and QuicHttpStream. QuicStreamRequest request(factory_.get()); @@ -3625,140 +3703,27 @@ EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, callback_.callback())); - MockQuicData socket_data1; - socket_data1.AddWrite( - SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true)); - socket_data1.AddRead( - ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0), - false, false)); - socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite(SYNCHRONOUS, - client_maker_.MakeAckAndRstPacket( - 4, false, GetNthClientInitiatedStreamId(0), - quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true)); - socket_data1.AddSocketDataToFactory(socket_factory_.get()); - - // Trigger early connection migration. This should cause a PING frame - // to be emitted. - session->OnPathDegrading(); - - // Run the message loop so that data queued in the new socket is read by the - // packet reader. - base::RunLoop().RunUntilIdle(); - - // The session should now be marked as going away. Ensure that - // while it is still alive, it is no longer active. - EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); - EXPECT_FALSE(HasActiveSession(host_port_pair_)); - EXPECT_EQ(1u, session->GetNumActiveStreams()); - - // Verify that response headers on the migrated socket were delivered to the - // stream. - EXPECT_THAT(stream->ReadResponseHeaders(callback_.callback()), IsOk()); - EXPECT_EQ(200, response.headers->response_code()); - - // Create a new request for the same destination and verify that a - // new session is created. - MockQuicData socket_data2; - socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); - socket_data2.AddSocketDataToFactory(socket_factory_.get()); - - QuicStreamRequest request2(factory_.get()); - EXPECT_EQ(ERR_IO_PENDING, - request2.Request(host_port_pair_, version_, privacy_mode_, - DEFAULT_PRIORITY, SocketTag(), - /*cert_verify_flags=*/0, url_, net_log_, - &net_error_details_, callback_.callback())); - EXPECT_THAT(callback_.WaitForResult(), IsOk()); - std::unique_ptr<HttpStream> stream2 = CreateStream(&request2); - EXPECT_TRUE(stream2.get()); + // Trigger connection migration on path degrading. Since there are no networks + // to migrate to, the session will remain on the original network, not marked + // as going away. + session->connection()->OnPathDegradingTimeout(); + EXPECT_TRUE(session->connection()->IsPathDegrading()); EXPECT_TRUE(HasActiveSession(host_port_pair_)); - QuicChromiumClientSession* new_session = GetActiveSession(host_port_pair_); - EXPECT_NE(session, new_session); - - // On a NETWORK_MADE_DEFAULT notification, nothing happens to the - // migrated session, but the new session is closed since it has no - // open streams. - scoped_mock_network_change_notifier_->mock_network_change_notifier() - ->NotifyNetworkMadeDefault(kNewNetworkForTests); EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); EXPECT_EQ(1u, session->GetNumActiveStreams()); - EXPECT_FALSE( - QuicStreamFactoryPeer::IsLiveSession(factory_.get(), new_session)); + EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback())); - // On a DISCONNECTED notification, nothing happens to the migrated session. - scoped_mock_network_change_notifier_->mock_network_change_notifier() - ->NotifyNetworkDisconnected(kDefaultNetworkForTests); - EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); - EXPECT_EQ(1u, session->GetNumActiveStreams()); - - stream.reset(); - stream2.reset(); - - EXPECT_TRUE(socket_data.AllReadDataConsumed()); - EXPECT_TRUE(socket_data.AllWriteDataConsumed()); - EXPECT_TRUE(socket_data1.AllReadDataConsumed()); - EXPECT_TRUE(socket_data1.AllWriteDataConsumed()); - EXPECT_TRUE(socket_data2.AllReadDataConsumed()); - EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); -} - -TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyNoNewNetwork) { - InitializeConnectionMigrationTest({kDefaultNetworkForTests}); - ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); - crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - - MockQuicData socket_data; - socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); - socket_data.AddWrite( - SYNCHRONOUS, - client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0), - quic::QUIC_STREAM_CANCELLED)); - socket_data.AddSocketDataToFactory(socket_factory_.get()); - - // Create request and QuicHttpStream. - QuicStreamRequest request(factory_.get()); - EXPECT_EQ(ERR_IO_PENDING, - request.Request(host_port_pair_, version_, privacy_mode_, - DEFAULT_PRIORITY, SocketTag(), - /*cert_verify_flags=*/0, url_, net_log_, - &net_error_details_, callback_.callback())); - EXPECT_THAT(callback_.WaitForResult(), IsOk()); - std::unique_ptr<HttpStream> stream = CreateStream(&request); - EXPECT_TRUE(stream.get()); - - // Cause QUIC stream to be created. - HttpRequestInfo request_info; - request_info.traffic_annotation = - MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY, - net_log_, CompletionOnceCallback())); - - // Ensure that session is alive and active. - QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); - EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); - EXPECT_TRUE(HasActiveSession(host_port_pair_)); - - // Trigger connection migration. Since there are no networks - // to migrate to, this should cause session to be continue but be marked as - // going away. - session->OnPathDegrading(); - - // Run the message loop so that data queued in the new socket is read by the - // packet reader. - base::RunLoop().RunUntilIdle(); + // Resume so that rest of the data will flow in the original socket. + quic_data.Resume(); EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); EXPECT_TRUE(HasActiveSession(host_port_pair_)); EXPECT_EQ(1u, session->GetNumActiveStreams()); stream.reset(); - - EXPECT_TRUE(socket_data.AllReadDataConsumed()); - EXPECT_TRUE(socket_data.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); } TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyNonMigratableStream) { @@ -4697,10 +4662,57 @@ TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC); } +// Migrate on asynchronous write error, old network disconnects after alternate +// network connects. +TEST_P(QuicStreamFactoryTest, + MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) { + TestMigrationOnWriteErrorWithMultipleNotifications( + ASYNC, /*disconnect_before_connect*/ false); +} + +// Migrate on synchronous write error, old network disconnects after alternate +// network connects. +TEST_P(QuicStreamFactoryTest, + MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) { + TestMigrationOnWriteErrorWithMultipleNotifications( + SYNCHRONOUS, /*disconnect_before_connect*/ false); +} + +// Migrate on asynchronous write error, old network disconnects before alternate +// network connects. +TEST_P(QuicStreamFactoryTest, + MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) { + TestMigrationOnWriteErrorWithMultipleNotifications( + ASYNC, /*disconnect_before_connect*/ true); +} + +// Migrate on synchronous write error, old network disconnects before alternate +// network connects. +TEST_P(QuicStreamFactoryTest, + MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) { + TestMigrationOnWriteErrorWithMultipleNotifications( + SYNCHRONOUS, /*disconnect_before_connect*/ true); +} + +// Setps up test which verifies that session successfully migrate to alternate +// network with signals delivered in the following order: +// *NOTE* Signal (A) and (B) can reverse order based on +// |disconnect_before_connect|. +// - (No alternate network is connected) session connects to +// kDefaultNetworkForTests. +// - An async/sync write error is encountered based on |write_error_mode|: +// session posted task to migrate session on write error. +// - Posted task is executed, miration moves to pending state due to lack of +// alternate network. +// - (A) An alternate network is connected, pending migration completes. +// - (B) Old default network disconnects, no migration will be attempted as +// session +// has already migrate to the alternate network. +// - The alternate network is made default. void QuicStreamFactoryTestBase:: - TestMigrationOnWriteErrorWithNetworkAddedBeforeNotification( + TestMigrationOnWriteErrorWithMultipleNotifications( IoMode write_error_mode, - bool disconnected) { + bool disconnect_before_connect) { InitializeConnectionMigrationTest({kDefaultNetworkForTests}); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); @@ -4711,7 +4723,7 @@ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); socket_data.AddWrite( SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset)); - socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED); + socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error. socket_data.AddSocketDataToFactory(socket_factory_.get()); // Create request and QuicHttpStream. @@ -4745,9 +4757,8 @@ HttpRequestHeaders request_headers; EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, callback_.callback())); - - // Run the message loop so that data queued in the new socket is read by the - // packet reader. + // Run the message loop so that posted task to migrate to socket will be + // executed. A new task will be posted to wait for a new network. base::RunLoop().RunUntilIdle(); // In this particular code path, the network will not yet be marked @@ -4777,17 +4788,26 @@ scoped_mock_network_change_notifier_->mock_network_change_notifier() ->SetConnectedNetworksList( {kDefaultNetworkForTests, kNewNetworkForTests}); - - // A notification triggers and completes migration. - if (disconnected) { + if (disconnect_before_connect) { + // Now deliver a DISCONNECT notification. scoped_mock_network_change_notifier_->mock_network_change_notifier() ->NotifyNetworkDisconnected(kDefaultNetworkForTests); - } else { + + // Now deliver a CONNECTED notification and completes migration. scoped_mock_network_change_notifier_->mock_network_change_notifier() - ->NotifyNetworkMadeDefault(kNewNetworkForTests); + ->NotifyNetworkConnected(kNewNetworkForTests); + } else { + // Now deliver a CONNECTED notification and completes migration. + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->NotifyNetworkConnected(kNewNetworkForTests); + + // Now deliver a DISCONNECT notification. + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->NotifyNetworkDisconnected(kDefaultNetworkForTests); } - // The session should now be marked as going away. Ensure that - // while it is still alive, it is no longer active. + // The session should now be marked as going away because the migration is + // caused by write error. Ensure that while it is still alive, it is no + // longer active. EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); EXPECT_FALSE(HasActiveSession(host_port_pair_)); EXPECT_EQ(1u, session->GetNumActiveStreams()); @@ -4798,10 +4818,9 @@ EXPECT_THAT(callback_.WaitForResult(), IsOk()); EXPECT_EQ(200, response.headers->response_code()); - // Now deliver a CONNECTED notification. Nothing happens since - // migration was already finished earlier. + // Deliver a MADEDEFAULT notification. scoped_mock_network_change_notifier_->mock_network_change_notifier() - ->NotifyNetworkConnected(kNewNetworkForTests); + ->NotifyNetworkMadeDefault(kNewNetworkForTests); // Create a new request for the same destination and verify that a // new session is created. @@ -4835,28 +4854,6 @@ EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); } -TEST_P(QuicStreamFactoryTest, - MigrateSessionOnWriteErrorWithNetworkAddedBeforeDisconnectedSync) { - TestMigrationOnWriteErrorWithNetworkAddedBeforeNotification(SYNCHRONOUS, - true); -} - -TEST_P(QuicStreamFactoryTest, - MigrateSessionOnWriteErrorWithNetworkAddedBeforeDisconnectedAsync) { - TestMigrationOnWriteErrorWithNetworkAddedBeforeNotification(ASYNC, true); -} - -TEST_P(QuicStreamFactoryTest, - MigrateSessionOnWriteErrorWithNetworkAddedBeforeMadeDefaultSync) { - TestMigrationOnWriteErrorWithNetworkAddedBeforeNotification(SYNCHRONOUS, - false); -} - -TEST_P(QuicStreamFactoryTest, - MigrateSessionOnWriteErrorWithNetworkAddedBeforeMadeDefaultAsync) { - TestMigrationOnWriteErrorWithNetworkAddedBeforeNotification(ASYNC, false); -} - TEST_P(QuicStreamFactoryTest, ServerMigration) { allow_server_migration_ = true; Initialize();
diff --git a/net/third_party/quic/core/quic_flags_list.h b/net/third_party/quic/core/quic_flags_list.h index d767fe6..980d623 100644 --- a/net/third_party/quic/core/quic_flags_list.h +++ b/net/third_party/quic/core/quic_flags_list.h
@@ -195,7 +195,7 @@ QUIC_FLAG(int32_t, FLAGS_quic_pace_time_into_future_ms, 10) // If true, enable QUIC v44. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_44, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_44, true) // If true, export packet write results in QuicConnection. QUIC_FLAG(
diff --git a/net/third_party/quic/core/quic_sent_packet_manager.cc b/net/third_party/quic/core/quic_sent_packet_manager.cc index 747be62..065b2ef 100644 --- a/net/third_party/quic/core/quic_sent_packet_manager.cc +++ b/net/third_party/quic/core/quic_sent_packet_manager.cc
@@ -42,7 +42,7 @@ // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. static const size_t kDefaultMaxTailLossProbes = 2; -bool HasCryptoHandshake(const QuicTransmissionInfo& transmission_info) { +inline bool HasCryptoHandshake(const QuicTransmissionInfo& transmission_info) { DCHECK(!transmission_info.has_crypto_handshake || !transmission_info.retransmittable_frames.empty()); return transmission_info.has_crypto_handshake; @@ -241,18 +241,6 @@ } } -void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { - pacing_sender_.set_max_pacing_rate(max_pacing_rate); -} - -QuicBandwidth QuicSentPacketManager::MaxPacingRate() const { - return pacing_sender_.max_pacing_rate(); -} - -void QuicSentPacketManager::SetHandshakeConfirmed() { - handshake_confirmed_ = true; -} - bool QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, QuicTime ack_receive_time) { DCHECK_LE(LargestAcked(ack_frame), unacked_packets_.largest_sent_packet()); @@ -512,10 +500,6 @@ } } -bool QuicSentPacketManager::HasPendingRetransmissions() const { - return !pending_retransmissions_.empty(); -} - QuicPendingRetransmission QuicSentPacketManager::NextPendingRetransmission() { QUIC_BUG_IF(pending_retransmissions_.empty()) << "Unexpected call to NextPendingRetransmission() with empty pending " @@ -606,18 +590,6 @@ info->state = ACKED; } -bool QuicSentPacketManager::HasUnackedPackets() const { - return unacked_packets_.HasUnackedPackets(); -} - -bool QuicSentPacketManager::HasUnackedCryptoPackets() const { - return unacked_packets_.HasPendingCryptoPackets(); -} - -QuicPacketNumber QuicSentPacketManager::GetLeastUnacked() const { - return unacked_packets_.GetLeastUnacked(); -} - bool QuicSentPacketManager::OnPacketSent( SerializedPacket* serialized_packet, QuicPacketNumber original_packet_number, @@ -723,13 +695,6 @@ } } -bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() { - if (pending_timer_transmission_count_ == 0) { - return false; - } - return MaybeRetransmitOldestPacket(TLP_RETRANSMISSION); -} - bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) { QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); @@ -974,10 +939,6 @@ return std::max(min_tlp_timeout_, 2 * srtt); } -const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { - return GetTailLossProbeDelay(consecutive_tlp_count_); -} - const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay( size_t consecutive_rto_count) const { QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero(); @@ -1004,50 +965,10 @@ return retransmission_delay; } -const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { - return GetRetransmissionDelay(consecutive_rto_count_); -} - -const RttStats* QuicSentPacketManager::GetRttStats() const { - return &rtt_stats_; -} - -QuicBandwidth QuicSentPacketManager::BandwidthEstimate() const { - // TODO(ianswett): Remove BandwidthEstimate from SendAlgorithmInterface - // and implement the logic here. - return send_algorithm_->BandwidthEstimate(); -} - -const QuicSustainedBandwidthRecorder* -QuicSentPacketManager::SustainedBandwidthRecorder() const { - return &sustained_bandwidth_recorder_; -} - -QuicPacketCount QuicSentPacketManager::EstimateMaxPacketsInFlight( - QuicByteCount max_packet_length) const { - return send_algorithm_->GetCongestionWindow() / max_packet_length; -} - -QuicPacketCount QuicSentPacketManager::GetCongestionWindowInTcpMss() const { - return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS; -} - -QuicByteCount QuicSentPacketManager::GetCongestionWindowInBytes() const { - return send_algorithm_->GetCongestionWindow(); -} - -QuicPacketCount QuicSentPacketManager::GetSlowStartThresholdInTcpMss() const { - return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS; -} - QuicString QuicSentPacketManager::GetDebugState() const { return send_algorithm_->GetDebugState(); } -QuicByteCount QuicSentPacketManager::GetBytesInFlight() const { - return unacked_packets_.bytes_in_flight(); -} - void QuicSentPacketManager::CancelRetransmissionsForStream( QuicStreamId stream_id) { if (session_decides_what_to_write()) { @@ -1190,33 +1111,6 @@ debug_delegate_ = debug_delegate; } -QuicPacketNumber QuicSentPacketManager::GetLargestObserved() const { - return unacked_packets_.largest_observed(); -} - -QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket() const { - return unacked_packets_.largest_sent_packet(); -} - -void QuicSentPacketManager::SetNetworkChangeVisitor( - NetworkChangeVisitor* visitor) { - DCHECK(!network_change_visitor_); - DCHECK(visitor); - network_change_visitor_ = visitor; -} - -bool QuicSentPacketManager::InSlowStart() const { - return send_algorithm_->InSlowStart(); -} - -size_t QuicSentPacketManager::GetConsecutiveRtoCount() const { - return consecutive_rto_count_; -} - -size_t QuicSentPacketManager::GetConsecutiveTlpCount() const { - return consecutive_tlp_count_; -} - void QuicSentPacketManager::OnApplicationLimited() { if (using_pacing_) { pacing_sender_.OnApplicationLimited(); @@ -1224,15 +1118,6 @@ send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); } -const SendAlgorithmInterface* QuicSentPacketManager::GetSendAlgorithm() const { - return send_algorithm_.get(); -} - -void QuicSentPacketManager::SetSessionNotifier( - SessionNotifierInterface* session_notifier) { - unacked_packets_.SetSessionNotifier(session_notifier); -} - QuicTime QuicSentPacketManager::GetNextReleaseTime() const { return using_pacing_ ? pacing_sender_.ideal_next_packet_send_time() : QuicTime::Zero(); @@ -1246,18 +1131,4 @@ rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt))); } -void QuicSentPacketManager::SetSessionDecideWhatToWrite( - bool session_decides_what_to_write) { - unacked_packets_.SetSessionDecideWhatToWrite(session_decides_what_to_write); -} - -bool QuicSentPacketManager::session_decides_what_to_write() const { - return unacked_packets_.session_decides_what_to_write(); -} - -void QuicSentPacketManager::SetPacingAlarmGranularity( - QuicTime::Delta alarm_granularity) { - pacing_sender_.set_alarm_granularity(alarm_granularity); -} - } // namespace quic
diff --git a/net/third_party/quic/core/quic_sent_packet_manager.h b/net/third_party/quic/core/quic_sent_packet_manager.h index a2c4860..3cc31155 100644 --- a/net/third_party/quic/core/quic_sent_packet_manager.h +++ b/net/third_party/quic/core/quic_sent_packet_manager.h
@@ -100,11 +100,15 @@ void SetNumOpenStreams(size_t num_streams); - void SetMaxPacingRate(QuicBandwidth max_pacing_rate); + void SetMaxPacingRate(QuicBandwidth max_pacing_rate) { + pacing_sender_.set_max_pacing_rate(max_pacing_rate); + } - QuicBandwidth MaxPacingRate() const; + QuicBandwidth MaxPacingRate() const { + return pacing_sender_.max_pacing_rate(); + } - void SetHandshakeConfirmed(); + void SetHandshakeConfirmed() { handshake_confirmed_ = true; } // Processes the incoming ack. Returns true if a previously-unacked packet is // acked. @@ -126,7 +130,12 @@ // Retransmits the oldest pending packet there is still a tail loss probe // pending. Invoked after OnRetransmissionTimeout. - bool MaybeRetransmitTailLossProbe(); + bool MaybeRetransmitTailLossProbe() { + if (pending_timer_transmission_count_ == 0) { + return false; + } + return MaybeRetransmitOldestPacket(TLP_RETRANSMISSION); + } // Retransmits the oldest pending packet. bool MaybeRetransmitOldestPacket(TransmissionType type); @@ -137,20 +146,28 @@ // Returns true if there are pending retransmissions. // Not const because retransmissions may be cancelled before returning. - bool HasPendingRetransmissions() const; + bool HasPendingRetransmissions() const { + return !pending_retransmissions_.empty(); + } // Retrieves the next pending retransmission. You must ensure that // there are pending retransmissions prior to calling this function. QuicPendingRetransmission NextPendingRetransmission(); - bool HasUnackedPackets() const; + bool HasUnackedPackets() const { + return unacked_packets_.HasUnackedPackets(); + } // Returns true if there's outstanding crypto data. - bool HasUnackedCryptoPackets() const; + bool HasUnackedCryptoPackets() const { + return unacked_packets_.HasPendingCryptoPackets(); + } // Returns the smallest packet number of a serialized packet which has not // been acked by the peer. - QuicPacketNumber GetLeastUnacked() const; + QuicPacketNumber GetLeastUnacked() const { + return unacked_packets_.GetLeastUnacked(); + } // Called when we have sent bytes to the peer. This informs the manager both // the number of bytes sent and if they were retransmitted. Returns true if @@ -180,39 +197,53 @@ // notify the session that this connection is degrading. const QuicTime::Delta GetPathDegradingDelay() const; - const RttStats* GetRttStats() const; + const RttStats* GetRttStats() const { return &rtt_stats_; } // Returns the estimated bandwidth calculated by the congestion algorithm. - QuicBandwidth BandwidthEstimate() const; + QuicBandwidth BandwidthEstimate() const { + return send_algorithm_->BandwidthEstimate(); + } - const QuicSustainedBandwidthRecorder* SustainedBandwidthRecorder() const; + const QuicSustainedBandwidthRecorder* SustainedBandwidthRecorder() const { + return &sustained_bandwidth_recorder_; + } // Returns the size of the current congestion window in number of // kDefaultTCPMSS-sized segments. Note, this is not the *available* window. // Some send algorithms may not use a congestion window and will return 0. - QuicPacketCount GetCongestionWindowInTcpMss() const; + QuicPacketCount GetCongestionWindowInTcpMss() const { + return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS; + } // Returns the number of packets of length |max_packet_length| which fit in // the current congestion window. More packets may end up in flight if the // congestion window has been recently reduced, of if non-full packets are // sent. QuicPacketCount EstimateMaxPacketsInFlight( - QuicByteCount max_packet_length) const; + QuicByteCount max_packet_length) const { + return send_algorithm_->GetCongestionWindow() / max_packet_length; + } // Returns the size of the current congestion window size in bytes. - QuicByteCount GetCongestionWindowInBytes() const; + QuicByteCount GetCongestionWindowInBytes() const { + return send_algorithm_->GetCongestionWindow(); + } // Returns the size of the slow start congestion window in nume of 1460 byte // TCP segments, aka ssthresh. Some send algorithms do not define a slow // start threshold and will return 0. - QuicPacketCount GetSlowStartThresholdInTcpMss() const; + QuicPacketCount GetSlowStartThresholdInTcpMss() const { + return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS; + } // Returns debugging information about the state of the congestion controller. QuicString GetDebugState() const; // Returns the number of bytes that are considered in-flight, i.e. not lost or // acknowledged. - QuicByteCount GetBytesInFlight() const; + QuicByteCount GetBytesInFlight() const { + return unacked_packets_.bytes_in_flight(); + } // No longer retransmit data for |stream_id|. void CancelRetransmissionsForStream(QuicStreamId stream_id); @@ -234,29 +265,45 @@ bool OnAckFrameEnd(QuicTime ack_receive_time); // Called to enable/disable letting session decide what to write. - void SetSessionDecideWhatToWrite(bool session_decides_what_to_write); + void SetSessionDecideWhatToWrite(bool session_decides_what_to_write) { + unacked_packets_.SetSessionDecideWhatToWrite(session_decides_what_to_write); + } void SetDebugDelegate(DebugDelegate* debug_delegate); - void SetPacingAlarmGranularity(QuicTime::Delta alarm_granularity); + void SetPacingAlarmGranularity(QuicTime::Delta alarm_granularity) { + pacing_sender_.set_alarm_granularity(alarm_granularity); + } - QuicPacketNumber GetLargestObserved() const; + QuicPacketNumber GetLargestObserved() const { + return unacked_packets_.largest_observed(); + } - QuicPacketNumber GetLargestSentPacket() const; + QuicPacketNumber GetLargestSentPacket() const { + return unacked_packets_.largest_sent_packet(); + } - void SetNetworkChangeVisitor(NetworkChangeVisitor* visitor); + void SetNetworkChangeVisitor(NetworkChangeVisitor* visitor) { + DCHECK(!network_change_visitor_); + DCHECK(visitor); + network_change_visitor_ = visitor; + } - bool InSlowStart() const; + bool InSlowStart() const { return send_algorithm_->InSlowStart(); } - size_t GetConsecutiveRtoCount() const; + size_t GetConsecutiveRtoCount() const { return consecutive_rto_count_; } - size_t GetConsecutiveTlpCount() const; + size_t GetConsecutiveTlpCount() const { return consecutive_tlp_count_; } void OnApplicationLimited(); - const SendAlgorithmInterface* GetSendAlgorithm() const; + const SendAlgorithmInterface* GetSendAlgorithm() const { + return send_algorithm_.get(); + } - void SetSessionNotifier(SessionNotifierInterface* session_notifier); + void SetSessionNotifier(SessionNotifierInterface* session_notifier) { + unacked_packets_.SetSessionNotifier(session_notifier); + } QuicTime GetNextReleaseTime() const; @@ -270,7 +317,9 @@ bool handshake_confirmed() const { return handshake_confirmed_; } - bool session_decides_what_to_write() const; + bool session_decides_what_to_write() const { + return unacked_packets_.session_decides_what_to_write(); + } size_t pending_timer_transmission_count() const { return pending_timer_transmission_count_; @@ -326,7 +375,9 @@ // Calls GetTailLossProbeDelay() with values from the current state of this // packet manager as its params. - const QuicTime::Delta GetTailLossProbeDelay() const; + const QuicTime::Delta GetTailLossProbeDelay() const { + return GetTailLossProbeDelay(consecutive_tlp_count_); + } // Returns the retransmission timeout, after which a full RTO occurs. // |consecutive_rto_count| is the number of consecutive RTOs that have already @@ -336,7 +387,9 @@ // Calls GetRetransmissionDelay() with values from the current state of this // packet manager as its params. - const QuicTime::Delta GetRetransmissionDelay() const; + const QuicTime::Delta GetRetransmissionDelay() const { + return GetRetransmissionDelay(consecutive_rto_count_); + } // Returns the newest transmission associated with a packet. QuicPacketNumber GetNewestRetransmission(
diff --git a/net/tools/huffman_trie/BUILD.gn b/net/tools/huffman_trie/BUILD.gn index 5c9790c..a4d1e3a 100644 --- a/net/tools/huffman_trie/BUILD.gn +++ b/net/tools/huffman_trie/BUILD.gn
@@ -12,6 +12,10 @@ "huffman/huffman_builder.h", "trie/trie_bit_buffer.cc", "trie/trie_bit_buffer.h", + "trie/trie_writer.cc", + "trie/trie_writer.h", + "trie_entry.cc", + "trie_entry.h", ] deps = [ "//base",
diff --git a/net/tools/huffman_trie/trie/trie_writer.cc b/net/tools/huffman_trie/trie/trie_writer.cc new file mode 100644 index 0000000..9f85f132 --- /dev/null +++ b/net/tools/huffman_trie/trie/trie_writer.cc
@@ -0,0 +1,193 @@ +// Copyright (c) 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/tools/huffman_trie/trie/trie_writer.h" + +#include <algorithm> + +#include "base/logging.h" +#include "net/tools/huffman_trie/trie/trie_bit_buffer.h" + +namespace net { + +namespace huffman_trie { + +namespace { + +bool CompareReversedEntries( + const std::unique_ptr<net::huffman_trie::ReversedEntry>& lhs, + const std::unique_ptr<net::huffman_trie::ReversedEntry>& rhs) { + return lhs->reversed_name < rhs->reversed_name; +} + +// Searches for the longest common prefix for all entries between |start| and +// |end|. +std::vector<uint8_t> LongestCommonPrefix(ReversedEntries::const_iterator start, + ReversedEntries::const_iterator end) { + if (start == end) { + return std::vector<uint8_t>(); + } + + std::vector<uint8_t> prefix; + for (size_t i = 0;; ++i) { + if (i > (*start)->reversed_name.size()) { + break; + } + + uint8_t candidate = (*start)->reversed_name.at(i); + if (candidate == kTerminalValue) { + break; + } + + bool ok = true; + for (ReversedEntries::const_iterator it = start + 1; it != end; ++it) { + if (i > (*it)->reversed_name.size() || + (*it)->reversed_name.at(i) != candidate) { + ok = false; + break; + } + } + + if (!ok) { + break; + } + + prefix.push_back(candidate); + } + + return prefix; +} + +// Returns the reversed |hostname| as a vector of bytes. The reversed hostname +// will be terminated by |kTerminalValue|. +std::vector<uint8_t> ReverseName(const std::string& hostname) { + size_t hostname_size = hostname.size(); + std::vector<uint8_t> reversed_name(hostname_size + 1); + + for (size_t i = 0; i < hostname_size; ++i) { + reversed_name[i] = hostname[hostname_size - i - 1]; + } + + reversed_name[reversed_name.size() - 1] = kTerminalValue; + return reversed_name; +} + +// Removes the first |length| characters from all entries between |start| and +// |end|. +void RemovePrefix(size_t length, + ReversedEntries::iterator start, + ReversedEntries::iterator end) { + for (ReversedEntries::iterator it = start; it != end; ++it) { + (*it)->reversed_name.erase((*it)->reversed_name.begin(), + (*it)->reversed_name.begin() + length); + } +} + +} // namespace + +ReversedEntry::ReversedEntry(std::vector<uint8_t> reversed_name, + const TrieEntry* entry) + : reversed_name(reversed_name), entry(entry) {} + +ReversedEntry::~ReversedEntry() = default; + +TrieWriter::TrieWriter( + const huffman_trie::HuffmanRepresentationTable& huffman_table, + huffman_trie::HuffmanBuilder* huffman_builder) + : huffman_table_(huffman_table), huffman_builder_(huffman_builder) {} + +TrieWriter::~TrieWriter() = default; + +bool TrieWriter::WriteEntries(const TrieEntries& entries, + uint32_t* root_position) { + if (entries.empty()) + return false; + + ReversedEntries reversed_entries; + for (auto* const entry : entries) { + std::unique_ptr<ReversedEntry> reversed_entry( + new ReversedEntry(ReverseName(entry->name()), entry)); + reversed_entries.push_back(std::move(reversed_entry)); + } + + std::stable_sort(reversed_entries.begin(), reversed_entries.end(), + CompareReversedEntries); + + return WriteDispatchTables(reversed_entries.begin(), reversed_entries.end(), + root_position); +} + +bool TrieWriter::WriteDispatchTables(ReversedEntries::iterator start, + ReversedEntries::iterator end, + uint32_t* position) { + DCHECK(start != end) << "No entries passed to WriteDispatchTables"; + + huffman_trie::TrieBitBuffer writer; + + std::vector<uint8_t> prefix = LongestCommonPrefix(start, end); + for (size_t i = 0; i < prefix.size(); ++i) { + writer.WriteBit(1); + } + writer.WriteBit(0); + + if (prefix.size()) { + for (size_t i = 0; i < prefix.size(); ++i) { + writer.WriteChar(prefix.at(i), huffman_table_, huffman_builder_); + } + } + + RemovePrefix(prefix.size(), start, end); + int32_t last_position = -1; + + while (start != end) { + uint8_t candidate = (*start)->reversed_name.at(0); + ReversedEntries::iterator sub_entries_end = start + 1; + + for (; sub_entries_end != end; sub_entries_end++) { + if ((*sub_entries_end)->reversed_name.at(0) != candidate) { + break; + } + } + + writer.WriteChar(candidate, huffman_table_, huffman_builder_); + + if (candidate == kTerminalValue) { + if (sub_entries_end - start != 1) { + return false; + } + if (!(*start)->entry->WriteEntry(&writer)) { + return false; + } + } else { + RemovePrefix(1, start, sub_entries_end); + uint32_t table_position; + if (!WriteDispatchTables(start, sub_entries_end, &table_position)) { + return false; + } + + writer.WritePosition(table_position, &last_position); + } + + start = sub_entries_end; + } + + writer.WriteChar(kEndOfTableValue, huffman_table_, huffman_builder_); + + *position = buffer_.position(); + writer.Flush(); + writer.WriteToBitWriter(&buffer_); + return true; +} + +uint32_t TrieWriter::position() const { + return buffer_.position(); +} + +void TrieWriter::Flush() { + buffer_.Flush(); +} + +} // namespace huffman_trie + +} // namespace net
diff --git a/net/tools/huffman_trie/trie/trie_writer.h b/net/tools/huffman_trie/trie/trie_writer.h new file mode 100644 index 0000000..6bf3e9bedb --- /dev/null +++ b/net/tools/huffman_trie/trie/trie_writer.h
@@ -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. + +#ifndef NET_TOOLS_HUFFMAN_TRIE_TRIE_TRIE_WRITER_H_ +#define NET_TOOLS_HUFFMAN_TRIE_TRIE_TRIE_WRITER_H_ + +#include <string> +#include <vector> + +#include "net/tools/huffman_trie/bit_writer.h" +#include "net/tools/huffman_trie/huffman/huffman_builder.h" +#include "net/tools/huffman_trie/trie_entry.h" + +namespace net { + +namespace huffman_trie { + +enum : uint8_t { kTerminalValue = 0, kEndOfTableValue = 127 }; + +class TrieWriter { + public: + TrieWriter(const huffman_trie::HuffmanRepresentationTable& huffman_table, + huffman_trie::HuffmanBuilder* huffman_builder); + ~TrieWriter(); + + // Constructs a trie containing all |entries|. The output is written to + // |buffer_| and |*position| is set to the position of the trie root. Returns + // true on success and false on failure. + bool WriteEntries(const TrieEntries& entries, uint32_t* position); + + // Returns the position |buffer_| is currently at. The returned value + // represents the number of bits. + uint32_t position() const; + + // Flushes |buffer_|. + void Flush(); + + // Returns the trie bytes. Call Flush() first to ensure the buffer is + // complete. + const std::vector<uint8_t>& bytes() const { return buffer_.bytes(); } + + private: + bool WriteDispatchTables(ReversedEntries::iterator start, + ReversedEntries::iterator end, + uint32_t* position); + + huffman_trie::BitWriter buffer_; + const huffman_trie::HuffmanRepresentationTable& huffman_table_; + huffman_trie::HuffmanBuilder* huffman_builder_; +}; + +} // namespace huffman_trie + +} // namespace net + +#endif // NET_TOOLS_TRANSPORT_SECURITY_STATE_GENERATOR_TRIE_TRIE_WRITER_H_
diff --git a/net/tools/huffman_trie/trie_entry.cc b/net/tools/huffman_trie/trie_entry.cc new file mode 100644 index 0000000..d1a24c0 --- /dev/null +++ b/net/tools/huffman_trie/trie_entry.cc
@@ -0,0 +1,17 @@ +// 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 "net/tools/huffman_trie/trie_entry.h" + +namespace net { + +namespace huffman_trie { + +TrieEntry::TrieEntry() = default; + +TrieEntry::~TrieEntry() = default; + +} // namespace huffman_trie + +} // namespace net \ No newline at end of file
diff --git a/net/tools/huffman_trie/trie_entry.h b/net/tools/huffman_trie/trie_entry.h new file mode 100644 index 0000000..79273ed --- /dev/null +++ b/net/tools/huffman_trie/trie_entry.h
@@ -0,0 +1,45 @@ +// 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 NET_TOOLS_HUFFMAN_TRIE_TRIE_ENTRY_H_ +#define NET_TOOLS_HUFFMAN_TRIE_TRIE_ENTRY_H_ + +#include <memory> +#include <string> +#include <vector> + +namespace net { + +namespace huffman_trie { + +class TrieBitBuffer; + +class TrieEntry { + public: + TrieEntry(); + virtual ~TrieEntry(); + + virtual std::string name() const = 0; + virtual bool WriteEntry(huffman_trie::TrieBitBuffer* writer) const = 0; +}; + +// std::unique_ptr's are not covariant, so operations on TrieEntry uses a vector +// of raw pointers instead. +using TrieEntries = std::vector<TrieEntry*>; + +struct ReversedEntry { + ReversedEntry(std::vector<uint8_t> reversed_name, const TrieEntry* entry); + ~ReversedEntry(); + + std::vector<uint8_t> reversed_name; + const TrieEntry* entry; +}; + +using ReversedEntries = std::vector<std::unique_ptr<ReversedEntry>>; + +} // namespace huffman_trie + +} // namespace net + +#endif // NET_TOOLS_HUFFMAN_TRIE_TRIE_ENTRY_H_
diff --git a/net/tools/transport_security_state_generator/BUILD.gn b/net/tools/transport_security_state_generator/BUILD.gn index 259d44f8..9c80262 100644 --- a/net/tools/transport_security_state_generator/BUILD.gn +++ b/net/tools/transport_security_state_generator/BUILD.gn
@@ -20,8 +20,6 @@ "spki_hash.h", "transport_security_state_entry.cc", "transport_security_state_entry.h", - "trie/trie_writer.cc", - "trie/trie_writer.h", ] deps = [ "//base",
diff --git a/net/tools/transport_security_state_generator/preloaded_state_generator.cc b/net/tools/transport_security_state_generator/preloaded_state_generator.cc index da6cd80..938dc4911 100644 --- a/net/tools/transport_security_state_generator/preloaded_state_generator.cc +++ b/net/tools/transport_security_state_generator/preloaded_state_generator.cc
@@ -115,8 +115,8 @@ huffman_builder.RecordUsage(c); } - huffman_builder.RecordUsage(TrieWriter::kTerminalValue); - huffman_builder.RecordUsage(TrieWriter::kEndOfTableValue); + huffman_builder.RecordUsage(huffman_trie::kTerminalValue); + huffman_builder.RecordUsage(huffman_trie::kEndOfTableValue); } return huffman_builder.ToTable(); @@ -145,6 +145,17 @@ NameIDMap pinsets_map; ProcessPinsets(pinsets, &pinsets_map, &output); + std::vector<std::unique_ptr<TransportSecurityStateTrieEntry>> trie_entries; + std::vector<huffman_trie::TrieEntry*> raw_trie_entries; + for (const auto& entry : entries) { + std::unique_ptr<TransportSecurityStateTrieEntry> trie_entry( + new TransportSecurityStateTrieEntry(expect_ct_report_uri_map, + expect_staple_report_uri_map, + pinsets_map, entry.get())); + raw_trie_entries.push_back(trie_entry.get()); + trie_entries.push_back(std::move(trie_entry)); + } + // The trie generation process is ran twice, the first time using an // approximate Huffman table. During this first run, the correct character // frequencies are collected which are then used to calculate the most space @@ -152,20 +163,17 @@ // second run. huffman_trie::HuffmanRepresentationTable table = ApproximateHuffman(entries); huffman_trie::HuffmanBuilder huffman_builder; - TrieWriter writer(table, expect_ct_report_uri_map, - expect_staple_report_uri_map, pinsets_map, - &huffman_builder); + huffman_trie::TrieWriter writer(table, &huffman_builder); uint32_t root_position; - if (!writer.WriteEntries(entries, &root_position)) { + if (!writer.WriteEntries(raw_trie_entries, &root_position)) { return std::string(); } huffman_trie::HuffmanRepresentationTable optimal_table = huffman_builder.ToTable(); - TrieWriter new_writer(optimal_table, expect_ct_report_uri_map, - expect_staple_report_uri_map, pinsets_map, nullptr); + huffman_trie::TrieWriter new_writer(optimal_table, nullptr); - if (!new_writer.WriteEntries(entries, &root_position)) { + if (!new_writer.WriteEntries(raw_trie_entries, &root_position)) { return std::string(); }
diff --git a/net/tools/transport_security_state_generator/preloaded_state_generator.h b/net/tools/transport_security_state_generator/preloaded_state_generator.h index 1850f54..e4e2b57 100644 --- a/net/tools/transport_security_state_generator/preloaded_state_generator.h +++ b/net/tools/transport_security_state_generator/preloaded_state_generator.h
@@ -10,10 +10,10 @@ #include <memory> #include <string> +#include "net/tools/huffman_trie/trie/trie_writer.h" #include "net/tools/transport_security_state_generator/pinset.h" #include "net/tools/transport_security_state_generator/pinsets.h" #include "net/tools/transport_security_state_generator/transport_security_state_entry.h" -#include "net/tools/transport_security_state_generator/trie/trie_writer.h" namespace net {
diff --git a/net/tools/transport_security_state_generator/transport_security_state_entry.cc b/net/tools/transport_security_state_generator/transport_security_state_entry.cc index ac1c9db..b00c737b 100644 --- a/net/tools/transport_security_state_generator/transport_security_state_entry.cc +++ b/net/tools/transport_security_state_generator/transport_security_state_entry.cc
@@ -3,14 +3,136 @@ // found in the LICENSE file. #include "net/tools/transport_security_state_generator/transport_security_state_entry.h" +#include "net/tools/huffman_trie/trie/trie_bit_buffer.h" namespace net { namespace transport_security_state { +namespace { + +// Returns true if the entry only configures HSTS with includeSubdomains. +// Such entries, when written, can be represented more compactly, and thus +// reduce the overall size of the trie. +bool IsSimpleEntry(const TransportSecurityStateEntry* entry) { + return entry->force_https && entry->include_subdomains && + entry->pinset.empty() && !entry->expect_ct && !entry->expect_staple; +} + +} // namespace + TransportSecurityStateEntry::TransportSecurityStateEntry() = default; TransportSecurityStateEntry::~TransportSecurityStateEntry() = default; +TransportSecurityStateTrieEntry::TransportSecurityStateTrieEntry( + const NameIDMap& expect_ct_report_uri_map, + const NameIDMap& expect_staple_report_uri_map, + const NameIDMap& pinsets_map, + TransportSecurityStateEntry* entry) + : expect_ct_report_uri_map_(expect_ct_report_uri_map), + expect_staple_report_uri_map_(expect_staple_report_uri_map), + pinsets_map_(pinsets_map), + entry_(entry) {} + +TransportSecurityStateTrieEntry::~TransportSecurityStateTrieEntry() {} + +std::string TransportSecurityStateTrieEntry::name() const { + return entry_->hostname; +} + +bool TransportSecurityStateTrieEntry::WriteEntry( + huffman_trie::TrieBitBuffer* writer) const { + if (IsSimpleEntry(entry_)) { + writer->WriteBit(1); + return true; + } else { + writer->WriteBit(0); + } + + uint8_t include_subdomains = 0; + if (entry_->include_subdomains) { + include_subdomains = 1; + } + writer->WriteBit(include_subdomains); + + uint8_t force_https = 0; + if (entry_->force_https) { + force_https = 1; + } + writer->WriteBit(force_https); + + if (entry_->pinset.size()) { + writer->WriteBit(1); + + NameIDMap::const_iterator pin_id_it = pinsets_map_.find(entry_->pinset); + if (pin_id_it == pinsets_map_.cend()) { + return false; + } + + const uint8_t& pin_id = pin_id_it->second; + if (pin_id > 15) { + return false; + } + + writer->WriteBits(pin_id, 4); + + if (!entry_->include_subdomains) { + uint8_t include_subdomains_for_pinning = 0; + if (entry_->hpkp_include_subdomains) { + include_subdomains_for_pinning = 1; + } + writer->WriteBit(include_subdomains_for_pinning); + } + } else { + writer->WriteBit(0); + } + + if (entry_->expect_ct) { + writer->WriteBit(1); + NameIDMap::const_iterator expect_ct_report_uri_it = + expect_ct_report_uri_map_.find(entry_->expect_ct_report_uri); + if (expect_ct_report_uri_it == expect_ct_report_uri_map_.cend()) { + return false; + } + + const uint8_t& expect_ct_report_id = expect_ct_report_uri_it->second; + if (expect_ct_report_id > 15) { + return false; + } + + writer->WriteBits(expect_ct_report_id, 4); + } else { + writer->WriteBit(0); + } + + if (entry_->expect_staple) { + writer->WriteBit(1); + + if (entry_->expect_staple_include_subdomains) { + writer->WriteBit(1); + } else { + writer->WriteBit(0); + } + + NameIDMap::const_iterator expect_staple_report_uri_it = + expect_staple_report_uri_map_.find(entry_->expect_staple_report_uri); + if (expect_staple_report_uri_it == expect_staple_report_uri_map_.cend()) { + return false; + } + + const uint8_t& expect_staple_report_id = + expect_staple_report_uri_it->second; + if (expect_staple_report_id > 15) { + return false; + } + + writer->WriteBits(expect_staple_report_id, 4); + } else { + writer->WriteBit(0); + } + return true; +} + } // namespace transport_security_state } // namespace net
diff --git a/net/tools/transport_security_state_generator/transport_security_state_entry.h b/net/tools/transport_security_state_generator/transport_security_state_entry.h index c3177dd..6c16c3f 100644 --- a/net/tools/transport_security_state_generator/transport_security_state_entry.h +++ b/net/tools/transport_security_state_generator/transport_security_state_entry.h
@@ -5,15 +5,23 @@ #ifndef NET_TOOLS_TRANSPORT_SECURITY_STATE_GENERATOR_TRANSPORT_SECURITY_STATE_ENTRY_H_ #define NET_TOOLS_TRANSPORT_SECURITY_STATE_GENERATOR_TRANSPORT_SECURITY_STATE_ENTRY_H_ +#include <map> #include <memory> #include <string> #include <vector> +#include "net/tools/huffman_trie/trie_entry.h" namespace net { namespace transport_security_state { -// TransportSecurityStateEntry represents a preloaded entry. +// Maps a name to an index. This is used to track the index of several values +// in the C++ code. The trie refers to the array index of the values. For +// example; the pinsets are outputted as a C++ array and the index for the +// pinset in that array is placed in the trie. +using NameIDMap = std::map<std::string, uint32_t>; +using NameIDPair = std::pair<std::string, uint32_t>; + struct TransportSecurityStateEntry { TransportSecurityStateEntry(); ~TransportSecurityStateEntry(); @@ -37,19 +45,25 @@ using TransportSecurityStateEntries = std::vector<std::unique_ptr<TransportSecurityStateEntry>>; -// ReversedEntry points to a TransportSecurityStateEntry and contains the -// reversed hostname for that entry. This is used to construct the trie. -struct ReversedEntry { - ReversedEntry(std::vector<uint8_t> reversed_name, - const TransportSecurityStateEntry* entry); - ~ReversedEntry(); +class TransportSecurityStateTrieEntry : public huffman_trie::TrieEntry { + public: + TransportSecurityStateTrieEntry(const NameIDMap& expect_ct_report_uri_map, + const NameIDMap& expect_staple_report_uri_map, + const NameIDMap& pinsets_map, + TransportSecurityStateEntry* entry); + ~TransportSecurityStateTrieEntry() override; - std::vector<uint8_t> reversed_name; - const TransportSecurityStateEntry* entry; + // huffman_trie::TrieEntry: + std::string name() const override; + bool WriteEntry(huffman_trie::TrieBitBuffer* writer) const override; + + private: + const NameIDMap& expect_ct_report_uri_map_; + const NameIDMap& expect_staple_report_uri_map_; + const NameIDMap& pinsets_map_; + TransportSecurityStateEntry* entry_; }; -using ReversedEntries = std::vector<std::unique_ptr<ReversedEntry>>; - } // namespace transport_security_state } // namespace net
diff --git a/net/tools/transport_security_state_generator/trie/trie_writer.cc b/net/tools/transport_security_state_generator/trie/trie_writer.cc deleted file mode 100644 index 2ae3f42..0000000 --- a/net/tools/transport_security_state_generator/trie/trie_writer.cc +++ /dev/null
@@ -1,297 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/tools/transport_security_state_generator/trie/trie_writer.h" - -#include <algorithm> - -#include "base/logging.h" -#include "net/tools/huffman_trie/trie/trie_bit_buffer.h" - -namespace net { - -namespace transport_security_state { - -namespace { - -bool CompareReversedEntries(const std::unique_ptr<ReversedEntry>& lhs, - const std::unique_ptr<ReversedEntry>& rhs) { - return lhs->reversed_name < rhs->reversed_name; -} - -// Returns true if the entry only configures HSTS with includeSubdomains. -// Such entries, when written, can be represented more compactly, and thus -// reduce the overall size of the trie. -bool IsSimpleEntry(const TransportSecurityStateEntry* entry) { - return entry->force_https && entry->include_subdomains && - entry->pinset.empty() && !entry->expect_ct && !entry->expect_staple; -} - -} // namespace - -ReversedEntry::ReversedEntry(std::vector<uint8_t> reversed_name, - const TransportSecurityStateEntry* entry) - : reversed_name(reversed_name), entry(entry) {} - -ReversedEntry::~ReversedEntry() = default; - -TrieWriter::TrieWriter( - const huffman_trie::HuffmanRepresentationTable& huffman_table, - const NameIDMap& expect_ct_report_uri_map, - const NameIDMap& expect_staple_report_uri_map, - const NameIDMap& pinsets_map, - huffman_trie::HuffmanBuilder* huffman_builder) - : huffman_table_(huffman_table), - expect_ct_report_uri_map_(expect_ct_report_uri_map), - expect_staple_report_uri_map_(expect_staple_report_uri_map), - pinsets_map_(pinsets_map), - huffman_builder_(huffman_builder) {} - -TrieWriter::~TrieWriter() = default; - -bool TrieWriter::WriteEntries(const TransportSecurityStateEntries& entries, - uint32_t* root_position) { - if (entries.empty()) - return false; - - ReversedEntries reversed_entries; - for (auto const& entry : entries) { - std::unique_ptr<ReversedEntry> reversed_entry( - new ReversedEntry(ReverseName(entry->hostname), entry.get())); - reversed_entries.push_back(std::move(reversed_entry)); - } - - std::stable_sort(reversed_entries.begin(), reversed_entries.end(), - CompareReversedEntries); - - return WriteDispatchTables(reversed_entries.begin(), reversed_entries.end(), - root_position); -} - -bool TrieWriter::WriteDispatchTables(ReversedEntries::iterator start, - ReversedEntries::iterator end, - uint32_t* position) { - DCHECK(start != end) << "No entries passed to WriteDispatchTables"; - - huffman_trie::TrieBitBuffer writer; - - std::vector<uint8_t> prefix = LongestCommonPrefix(start, end); - for (size_t i = 0; i < prefix.size(); ++i) { - writer.WriteBit(1); - } - writer.WriteBit(0); - - if (prefix.size()) { - for (size_t i = 0; i < prefix.size(); ++i) { - writer.WriteChar(prefix.at(i), huffman_table_, huffman_builder_); - } - } - - RemovePrefix(prefix.size(), start, end); - int32_t last_position = -1; - - while (start != end) { - uint8_t candidate = (*start)->reversed_name.at(0); - ReversedEntries::iterator sub_entries_end = start + 1; - - for (; sub_entries_end != end; sub_entries_end++) { - if ((*sub_entries_end)->reversed_name.at(0) != candidate) { - break; - } - } - - writer.WriteChar(candidate, huffman_table_, huffman_builder_); - - if (candidate == kTerminalValue) { - if (sub_entries_end - start != 1) { - return false; - } - if (!WriteEntry((*start)->entry, &writer)) { - return false; - } - } else { - RemovePrefix(1, start, sub_entries_end); - uint32_t table_position; - if (!WriteDispatchTables(start, sub_entries_end, &table_position)) { - return false; - } - - writer.WritePosition(table_position, &last_position); - } - - start = sub_entries_end; - } - - writer.WriteChar(kEndOfTableValue, huffman_table_, huffman_builder_); - - *position = buffer_.position(); - writer.Flush(); - writer.WriteToBitWriter(&buffer_); - return true; -} - -bool TrieWriter::WriteEntry(const TransportSecurityStateEntry* entry, - huffman_trie::TrieBitBuffer* writer) { - if (IsSimpleEntry(entry)) { - writer->WriteBit(1); - return true; - } else { - writer->WriteBit(0); - } - - uint8_t include_subdomains = 0; - if (entry->include_subdomains) { - include_subdomains = 1; - } - writer->WriteBit(include_subdomains); - - uint8_t force_https = 0; - if (entry->force_https) { - force_https = 1; - } - writer->WriteBit(force_https); - - if (entry->pinset.size()) { - writer->WriteBit(1); - - NameIDMap::const_iterator pin_id_it = pinsets_map_.find(entry->pinset); - if (pin_id_it == pinsets_map_.cend()) { - return false; - } - - const uint8_t& pin_id = pin_id_it->second; - if (pin_id > 15) { - return false; - } - - writer->WriteBits(pin_id, 4); - - if (!entry->include_subdomains) { - uint8_t include_subdomains_for_pinning = 0; - if (entry->hpkp_include_subdomains) { - include_subdomains_for_pinning = 1; - } - writer->WriteBit(include_subdomains_for_pinning); - } - } else { - writer->WriteBit(0); - } - - if (entry->expect_ct) { - writer->WriteBit(1); - NameIDMap::const_iterator expect_ct_report_uri_it = - expect_ct_report_uri_map_.find(entry->expect_ct_report_uri); - if (expect_ct_report_uri_it == expect_ct_report_uri_map_.cend()) { - return false; - } - - const uint8_t& expect_ct_report_id = expect_ct_report_uri_it->second; - if (expect_ct_report_id > 15) { - return false; - } - - writer->WriteBits(expect_ct_report_id, 4); - } else { - writer->WriteBit(0); - } - - if (entry->expect_staple) { - writer->WriteBit(1); - - if (entry->expect_staple_include_subdomains) { - writer->WriteBit(1); - } else { - writer->WriteBit(0); - } - - NameIDMap::const_iterator expect_staple_report_uri_it = - expect_staple_report_uri_map_.find(entry->expect_staple_report_uri); - if (expect_staple_report_uri_it == expect_staple_report_uri_map_.cend()) { - return false; - } - - const uint8_t& expect_staple_report_id = - expect_staple_report_uri_it->second; - if (expect_staple_report_id > 15) { - return false; - } - - writer->WriteBits(expect_staple_report_id, 4); - } else { - writer->WriteBit(0); - } - - return true; -} - -void TrieWriter::RemovePrefix(size_t length, - ReversedEntries::iterator start, - ReversedEntries::iterator end) { - for (ReversedEntries::iterator it = start; it != end; ++it) { - (*it)->reversed_name.erase((*it)->reversed_name.begin(), - (*it)->reversed_name.begin() + length); - } -} - -std::vector<uint8_t> TrieWriter::LongestCommonPrefix( - ReversedEntries::const_iterator start, - ReversedEntries::const_iterator end) const { - if (start == end) { - return std::vector<uint8_t>(); - } - - std::vector<uint8_t> prefix; - for (size_t i = 0;; ++i) { - if (i > (*start)->reversed_name.size()) { - break; - } - - uint8_t candidate = (*start)->reversed_name.at(i); - if (candidate == kTerminalValue) { - break; - } - - bool ok = true; - for (ReversedEntries::const_iterator it = start + 1; it != end; ++it) { - if (i > (*it)->reversed_name.size() || - (*it)->reversed_name.at(i) != candidate) { - ok = false; - break; - } - } - - if (!ok) { - break; - } - - prefix.push_back(candidate); - } - - return prefix; -} - -std::vector<uint8_t> TrieWriter::ReverseName( - const std::string& hostname) const { - size_t hostname_size = hostname.size(); - std::vector<uint8_t> reversed_name(hostname_size + 1); - - for (size_t i = 0; i < hostname_size; ++i) { - reversed_name[i] = hostname[hostname_size - i - 1]; - } - - reversed_name[reversed_name.size() - 1] = kTerminalValue; - return reversed_name; -} - -uint32_t TrieWriter::position() const { - return buffer_.position(); -} - -void TrieWriter::Flush() { - buffer_.Flush(); -} - -} // namespace transport_security_state - -} // namespace net
diff --git a/net/tools/transport_security_state_generator/trie/trie_writer.h b/net/tools/transport_security_state_generator/trie/trie_writer.h deleted file mode 100644 index ee82d0c..0000000 --- a/net/tools/transport_security_state_generator/trie/trie_writer.h +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_TOOLS_TRANSPORT_SECURITY_STATE_GENERATOR_TRIE_TRIE_WRITER_H_ -#define NET_TOOLS_TRANSPORT_SECURITY_STATE_GENERATOR_TRIE_TRIE_WRITER_H_ - -#include <string> -#include <vector> - -#include "net/tools/huffman_trie/bit_writer.h" -#include "net/tools/huffman_trie/huffman/huffman_builder.h" -#include "net/tools/transport_security_state_generator/transport_security_state_entry.h" - -namespace net { - -namespace huffman_trie { -class TrieBitBuffer; -} - -namespace transport_security_state { - -struct TransportSecurityStateEntry; - -// Maps a name to an index. This is used to track the index of several values -// in the C++ code. The trie refers to the array index of the values. For -// example; the pinsets are outputted as a C++ array and the index for the -// pinset in that array is placed in the trie. -using NameIDMap = std::map<std::string, uint32_t>; -using NameIDPair = std::pair<std::string, uint32_t>; - -class TrieWriter { - public: - enum : uint8_t { kTerminalValue = 0, kEndOfTableValue = 127 }; - - TrieWriter(const huffman_trie::HuffmanRepresentationTable& huffman_table, - const NameIDMap& expect_ct_report_uri_map, - const NameIDMap& expect_staple_report_uri_map, - const NameIDMap& pinsets_map, - huffman_trie::HuffmanBuilder* huffman_builder); - ~TrieWriter(); - - // Constructs a trie containing all |entries|. The output is written to - // |buffer_| and |*position| is set to the position of the trie root. Returns - // true on success and false on failure. - bool WriteEntries(const TransportSecurityStateEntries& entries, - uint32_t* position); - - // Returns the position |buffer_| is currently at. The returned value - // represents the number of bits. - uint32_t position() const; - - // Flushes |buffer_|. - void Flush(); - - // Returns the trie bytes. Call Flush() first to ensure the buffer is - // complete. - const std::vector<uint8_t>& bytes() const { return buffer_.bytes(); } - - private: - bool WriteDispatchTables(ReversedEntries::iterator start, - ReversedEntries::iterator end, - uint32_t* position); - - // Serializes |*entry| and writes it to |*writer|. - bool WriteEntry(const TransportSecurityStateEntry* entry, - huffman_trie::TrieBitBuffer* writer); - - // Removes the first |length| characters from all entries between |start| and - // |end|. - void RemovePrefix(size_t length, - ReversedEntries::iterator start, - ReversedEntries::iterator end); - - // Searches for the longest common prefix for all entries between |start| and - // |end|. - std::vector<uint8_t> LongestCommonPrefix( - ReversedEntries::const_iterator start, - ReversedEntries::const_iterator end) const; - - // Returns the reversed |hostname| as a vector of bytes. The reversed hostname - // will be terminated by |kTerminalValue|. - std::vector<uint8_t> ReverseName(const std::string& hostname) const; - - huffman_trie::BitWriter buffer_; - const huffman_trie::HuffmanRepresentationTable& huffman_table_; - const NameIDMap& expect_ct_report_uri_map_; - const NameIDMap& expect_staple_report_uri_map_; - const NameIDMap& pinsets_map_; - huffman_trie::HuffmanBuilder* huffman_builder_; -}; - -} // namespace transport_security_state - -} // namespace net - -#endif // NET_TOOLS_TRANSPORT_SECURITY_STATE_GENERATOR_TRIE_TRIE_WRITER_H_
diff --git a/remoting/protocol/webrtc_connection_to_client.cc b/remoting/protocol/webrtc_connection_to_client.cc index 7b951e0..b55fb96 100644 --- a/remoting/protocol/webrtc_connection_to_client.cc +++ b/remoting/protocol/webrtc_connection_to_client.cc
@@ -26,7 +26,6 @@ #include "remoting/protocol/webrtc_video_stream.h" #include "third_party/webrtc/api/mediastreaminterface.h" #include "third_party/webrtc/api/peerconnectioninterface.h" -#include "third_party/webrtc/api/test/fakeconstraints.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index 0674e55..64eddb69 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -34,7 +34,6 @@ #include "third_party/webrtc/api/audio_codecs/audio_encoder_factory_template.h" #include "third_party/webrtc/api/audio_codecs/opus/audio_decoder_opus.h" #include "third_party/webrtc/api/audio_codecs/opus/audio_encoder_opus.h" -#include "third_party/webrtc/api/test/fakeconstraints.h" using buzz::QName; using buzz::XmlElement; @@ -190,11 +189,8 @@ webrtc::CreateAudioDecoderFactory<webrtc::AudioDecoderOpus>(), encoder_factory.release(), nullptr); - webrtc::FakeConstraints constraints; - constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, - webrtc::MediaConstraintsInterface::kValueTrue); - webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; + rtc_config.enable_dtls_srtp = true; // Set bundle_policy and rtcp_mux_policy to ensure that all channels are // multiplexed over a single channel. @@ -206,7 +202,7 @@ rtc_config.media_config.video.periodic_alr_bandwidth_probing = true; peer_connection_ = peer_connection_factory_->CreatePeerConnection( - rtc_config, &constraints, std::move(port_allocator), nullptr, this); + rtc_config, std::move(port_allocator), nullptr, this); } ~PeerConnectionWrapper() override { @@ -691,25 +687,15 @@ DCHECK(negotiation_pending_); negotiation_pending_ = false; - webrtc::FakeConstraints offer_config; - offer_config.AddMandatory( - webrtc::MediaConstraintsInterface::kOfferToReceiveVideo, - webrtc::MediaConstraintsInterface::kValueTrue); - offer_config.AddMandatory( - webrtc::MediaConstraintsInterface::kOfferToReceiveAudio, - webrtc::MediaConstraintsInterface::kValueFalse); - offer_config.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, - webrtc::MediaConstraintsInterface::kValueTrue); - if (want_ice_restart_) { - offer_config.AddMandatory(webrtc::MediaConstraintsInterface::kIceRestart, - webrtc::MediaConstraintsInterface::kValueTrue); - want_ice_restart_ = false; - } + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; + options.offer_to_receive_video = true; + options.offer_to_receive_audio = false; + options.ice_restart = want_ice_restart_; peer_connection()->CreateOffer( CreateSessionDescriptionObserver::Create( base::Bind(&WebrtcTransport::OnLocalSessionDescriptionCreated, weak_factory_.GetWeakPtr())), - &offer_config); + options); } void WebrtcTransport::SendTransportInfo() {
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc index 03dfd0c..4b512a2 100644 --- a/remoting/protocol/webrtc_video_stream.cc +++ b/remoting/protocol/webrtc_video_stream.cc
@@ -20,7 +20,6 @@ #include "remoting/protocol/webrtc_transport.h" #include "third_party/webrtc/api/mediastreaminterface.h" #include "third_party/webrtc/api/peerconnectioninterface.h" -#include "third_party/webrtc/api/test/fakeconstraints.h" #include "third_party/webrtc/media/base/videocapturer.h" #if defined(USE_H264_ENCODER) @@ -118,14 +117,9 @@ capturer_->Start(this); - // Set video stream constraints. - webrtc::FakeConstraints video_constraints; - video_constraints.AddMandatory( - webrtc::MediaConstraintsInterface::kMinFrameRate, 5); - rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> src = - peer_connection_factory->CreateVideoSource(new WebrtcDummyVideoCapturer(), - &video_constraints); + peer_connection_factory->CreateVideoSource( + absl::make_unique<WebrtcDummyVideoCapturer>()); rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track = peer_connection_factory->CreateVideoTrack(kVideoLabel, src);
diff --git a/remoting/resources/remoting_strings_bn.xtb b/remoting/resources/remoting_strings_bn.xtb index 4b62288..e056ea14 100644 --- a/remoting/resources/remoting_strings_bn.xtb +++ b/remoting/resources/remoting_strings_bn.xtb
@@ -191,7 +191,7 @@ <translation id="5064360042339518108"><ph name="HOSTNAME" /> (অফলাইন)</translation> <translation id="5070121137485264635">একটি তৃতীয়-পক্ষ ওয়েবসাইট প্রমাণীকরণ করতে রিমোট হোস্টটির আপনাকে প্রয়োজন। অবিরত রাখতে, এই ওয়েবসাইট অ্যাক্সেস করতে আপনাকে অবশ্যই Chrome দূরবর্তী ডেস্কটপ অতিরিক্ত অনুমতির মঞ্জুরি দিতে হবে:</translation> <translation id="507204348399810022">আপনি কি নিশ্চিত যে আপনি <ph name="HOSTNAME" /> এর সাথে দূরবর্তী সংযোগ অক্ষম করতে চান?</translation> -<translation id="5081343395220691640">সার্ভারে যোগাযোগ করা যায়নি : <ph name="ERROR" /></translation> +<translation id="5081343395220691640">সার্ভারে যোগাযোগ করা যায়নি: <ph name="ERROR" /></translation> <translation id="5156271271724754543">উভয় বক্সে দয়া করে একই পিন লিখুন৷</translation> <translation id="5170982930780719864">অবৈধ হোস্ট আইডি।</translation> <translation id="518094545883702183">আপনার রিপোর্ট করা সমস্যার নির্ণয়ের জন্য এই তথ্য ব্যবহার করা হয়, যা কেবল আপনার রিপোর্ট সার্চ চালান এমন একজনের কাছে উপলব্ধ, এবং 30 দিনের বেশী রাখা হয় না।</translation>
diff --git a/remoting/resources/remoting_strings_hi.xtb b/remoting/resources/remoting_strings_hi.xtb index bbd2c22..8c2f0990 100644 --- a/remoting/resources/remoting_strings_hi.xtb +++ b/remoting/resources/remoting_strings_hi.xtb
@@ -54,7 +54,7 @@ <translation id="2208514473086078157">नीति सेटिंग इस कंप्यूटर को एक Chrome दूरस्थ डेस्कटॉप होस्ट के रूप में शेयर करने की अनुमति नहीं देतीं. सहायता के लिए अपने सिस्टम व्यवस्थापक से संपर्क करें.</translation> <translation id="2220529011494928058">किसी समस्या की रिपोर्ट करें</translation> <translation id="2221097377466213233">Win कुंजी के लिए राइट Ctrl का उपयोग करें (Mac पर ⌘)</translation> -<translation id="2235518894410572517">किसी अन्य उपयोगकर्ता द्वारा देखने और नियंत्रित करने के लिए यह कंप्यूटर शेयर करें.</translation> +<translation id="2235518894410572517">इस कंप्यूटर को किसी दूसरे उपयोगकर्ता से शेयर करें ताकि वह इसे देख सके और नियंत्रित कर सके.</translation> <translation id="2246783206985865117">यह सेटिंग आपकी डोमेन नीति द्वारा प्रबंधित है.</translation> <translation id="2256115617011615191">अभी पुनः प्रारंभ करें</translation> <translation id="225614027745146050">आपका स्वागत है</translation> @@ -88,7 +88,7 @@ • Chrome दूरस्थ डेस्कटॉप सॉफ़्टवेयर इंस्टॉल करें और सेटअप पूरा करने के निर्देशों का पालन करें. • अपने iOS डिवाइस पर, ऐप खोलें और कनेक्ट करने के लिए अपने किसी भी ऑनलाइन कंप्यूटर पर टैप करें.</translation> <translation id="2894654864775534701">यह कंप्यूटर वर्तमान में किसी भिन्न खाते के अंतर्गत शेयर किया गया है.</translation> -<translation id="2919669478609886916">आप वर्तमान में किसी अन्य उपयोगकर्ता के साथ इस मशीन को शेयर कर रहे हैं. क्या आप शेयरकरण जारी रखना चाहते हैं?</translation> +<translation id="2919669478609886916">आप फ़िलहाल में किसी अन्य उपयोगकर्ता के साथ यह मशीन शेयर कर रहे हैं. क्या आप शेयर करना जारी रखना चाहते हैं?</translation> <translation id="2921543551052660690">आपने पूर्व में <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) के रूप में प्रवेश किया था. उस खाते में अपने कंप्यूटर एक्सेस करने के लिए, उस खाते से <ph name="LINK_BEGIN" />क्रोमियम में प्रवेश करें<ph name="LINK_END" /> और Chromoting को पुन: इंस्टॉल करें.</translation> <translation id="2926340305933667314">इस कंप्यूटर के लिए दूर से एक्सेस की सुविधा बंद नहीं की जा सकी. कृपया बाद में फिर से कोशिश करें.</translation> <translation id="2930135165929238380">कुछ आवश्यक घटक अनुपलब्ध हैं. कृपया chrome://plugins पर जाएं और सुनिश्चित करें कि नेटिव क्लाइंट सक्षम है.</translation> @@ -210,7 +210,7 @@ <translation id="5593560073513909978">सेवा अस्थायी रूप से अनुपलब्ध है. कृपया बाद में पुन: प्रयास करें.</translation> <translation id="5601503069213153581">पिन</translation> <translation id="5619148062500147964">इस कंप्यूटर से</translation> -<translation id="5625493749705183369">सुरक्षित रूप से इंटरनेट पर अन्य कंप्यूटर तक पहुंचें या किसी अन्य उपयोगकर्ता को अपने कंप्यूटर तक पहुंचने दें.</translation> +<translation id="5625493749705183369">इंटरनेट के ज़रिए सुरक्षित तरीके से, दूसरे कंप्यूटर का एक्सेस करने या किसी अन्य उपयोगकर्ता को आपके कंप्यूटर का एक्सेस करने की सुविधा</translation> <translation id="5702987232842159181">कनेक्ट किया गया:</translation> <translation id="5708869785009007625">आपका डेस्कटॉप वर्तमान में <ph name="USER" /> के साथ शेयर किया गया है.</translation> <translation id="5750083143895808682"><ph name="EMAIL_ADDRESS" /> के रूप में साइन इन किया है.</translation> @@ -313,7 +313,7 @@ <translation id="809687642899217504">मेरे कंप्यूटर</translation> <translation id="811307782653349804">अपने कंप्यूटर पर कहीं से भी पहुंचें.</translation> <translation id="8116630183974937060">नेटवर्क गड़बड़ी हुई. कृपया जाँचें कि आपका डिवाइस ऑन-लाइन है और फिर पुन: प्रयास करें.</translation> -<translation id="8178433417677596899">उपयोगकर्ता-से-उपयोगकर्ता स्क्रीन साझाकरण, दूरस्थ तकनीकी सहायता के लिए उपयुक्त.</translation> +<translation id="8178433417677596899">एक उपयोगकर्ता की स्क्रीन दूसरे उपयोगकर्ता से शेयर करने की सुविधा, 'रिमोट तकनीकी सहायता' के लिए सबसे सही तरीका.</translation> <translation id="8187079423890319756">कॉपीराइट 2013 The Chromium Authors. सर्वाधिकार सुरक्षित.</translation> <translation id="8196755618196986400">हमें अतिरिक्त जानकारी हेतु आपसे संपर्क करने देने के लिए, आपके द्वारा सबमिट किए जाने वाले किसी भी फ़ीडबैक में आपका ईमेल पता शामिल किया जाएगा.</translation> <translation id="8244400547700556338">जानें कैसे.</translation>
diff --git a/services/audio/public/cpp/input_ipc.cc b/services/audio/public/cpp/input_ipc.cc index 3b465c4..e53a622 100644 --- a/services/audio/public/cpp/input_ipc.cc +++ b/services/audio/public/cpp/input_ipc.cc
@@ -17,7 +17,7 @@ media::mojom::AudioLogPtr log) : stream_(), stream_client_binding_(this), - device_id_(std::move(device_id)), + device_id_(device_id), stream_factory_(), stream_factory_info_(), log_(std::move(log)),
diff --git a/services/audio/public/cpp/input_ipc.h b/services/audio/public/cpp/input_ipc.h index 0ace69b..6971b2d9 100644 --- a/services/audio/public/cpp/input_ipc.h +++ b/services/audio/public/cpp/input_ipc.h
@@ -57,7 +57,7 @@ mojo::Binding<AudioInputStreamClient> stream_client_binding_; media::AudioInputIPCDelegate* delegate_ = nullptr; - const std::string& device_id_; + std::string device_id_; base::Optional<base::UnguessableToken> stream_id_; // stream_factory_info_ is bound in the constructor, and later used to
diff --git a/services/audio/public/cpp/input_ipc_unittest.cc b/services/audio/public/cpp/input_ipc_unittest.cc index 5bd1c091..60568bb 100644 --- a/services/audio/public/cpp/input_ipc_unittest.cc +++ b/services/audio/public/cpp/input_ipc_unittest.cc
@@ -4,6 +4,9 @@ #include "services/audio/public/cpp/input_ipc.h" +#include <string> +#include <utility> + #include "base/test/scoped_task_environment.h" #include "media/mojo/interfaces/audio_data_pipe.mojom.h" #include "mojo/public/cpp/system/buffer.h" @@ -20,7 +23,7 @@ namespace { -const std::string& kDeviceId = "1234"; +const char kDeviceId[] = "1234"; const size_t kShMemSize = 456; const double kNewVolume = 0.271828;
diff --git a/services/data_decoder/public/cpp/safe_json_parser.cc b/services/data_decoder/public/cpp/safe_json_parser.cc index 94070c4f..740b62e 100644 --- a/services/data_decoder/public/cpp/safe_json_parser.cc +++ b/services/data_decoder/public/cpp/safe_json_parser.cc
@@ -4,6 +4,7 @@ #include "services/data_decoder/public/cpp/safe_json_parser.h" +#include "base/optional.h" #include "build/build_config.h" #if defined(OS_ANDROID) @@ -21,7 +22,8 @@ SafeJsonParser* Create(service_manager::Connector* connector, const std::string& unsafe_json, const SafeJsonParser::SuccessCallback& success_callback, - const SafeJsonParser::ErrorCallback& error_callback) { + const SafeJsonParser::ErrorCallback& error_callback, + const base::Optional<std::string>& batch_id) { if (g_factory) return g_factory(unsafe_json, success_callback, error_callback); @@ -30,7 +32,7 @@ error_callback); #else return new SafeJsonParserImpl(connector, unsafe_json, success_callback, - error_callback); + error_callback, batch_id); #endif } @@ -46,8 +48,19 @@ const std::string& unsafe_json, const SuccessCallback& success_callback, const ErrorCallback& error_callback) { - SafeJsonParser* parser = - Create(connector, unsafe_json, success_callback, error_callback); + SafeJsonParser* parser = Create(connector, unsafe_json, success_callback, + error_callback, base::nullopt); + parser->Start(); +} + +// static +void SafeJsonParser::ParseBatch(service_manager::Connector* connector, + const std::string& unsafe_json, + const SuccessCallback& success_callback, + const ErrorCallback& error_callback, + const std::string& batch_id) { + SafeJsonParser* parser = Create(connector, unsafe_json, success_callback, + error_callback, batch_id); parser->Start(); }
diff --git a/services/data_decoder/public/cpp/safe_json_parser.h b/services/data_decoder/public/cpp/safe_json_parser.h index d033e76..61d2392 100644 --- a/services/data_decoder/public/cpp/safe_json_parser.h +++ b/services/data_decoder/public/cpp/safe_json_parser.h
@@ -36,9 +36,9 @@ // Starts parsing the passed in |unsafe_json| and calls either // |success_callback| or |error_callback| when finished. - // |connector| is the connector provided by the service manager and is used - // to retrieve the JSON decoder service. It's commonly retrieved from a - // service manager connection context object that the embedder provides. + // |connector| is the connector provided by the service manager and is used to + // retrieve the JSON decoder service. It's commonly retrieved from a service + // manager connection context object that the embedder provides. // Note that on Android, this runs in process, the sanitizing of |unsafe_json| // being performed in Java for safety. On other platforms the parsing happens // in an isolated sandboxed utility process. @@ -47,6 +47,17 @@ const SuccessCallback& success_callback, const ErrorCallback& error_callback); + // Same as Parse, but allows clients to provide a |batch_id|, which the system + // may use to batch this parse request with other parse requests using the + // same |batch_id| in an effort to amortize the overhead of a single request. + // The trade-off is that batch requests may not be well-isolated from each + // other, so this should be used with appropriate caution. + static void ParseBatch(service_manager::Connector* connector, + const std::string& unsafe_json, + const SuccessCallback& success_callback, + const ErrorCallback& error_callback, + const std::string& batch_id); + static void SetFactoryForTesting(Factory factory); protected:
diff --git a/services/data_decoder/public/cpp/safe_json_parser_impl.cc b/services/data_decoder/public/cpp/safe_json_parser_impl.cc index 3ffff9d..dbcee6a 100644 --- a/services/data_decoder/public/cpp/safe_json_parser_impl.cc +++ b/services/data_decoder/public/cpp/safe_json_parser_impl.cc
@@ -16,19 +16,20 @@ namespace data_decoder { -SafeJsonParserImpl::SafeJsonParserImpl(service_manager::Connector* connector, - const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) +SafeJsonParserImpl::SafeJsonParserImpl( + service_manager::Connector* connector, + const std::string& unsafe_json, + const SuccessCallback& success_callback, + const ErrorCallback& error_callback, + const base::Optional<std::string>& batch_id) : unsafe_json_(unsafe_json), success_callback_(success_callback), error_callback_(error_callback) { - // Use a random instance ID to guarantee the connection is to a new service - // (running in its own process). - base::UnguessableToken token = base::UnguessableToken::Create(); - service_manager::Identity identity(mojom::kServiceName, - service_manager::mojom::kInheritUserID, - token.ToString()); + // If no batch ID has been provided, use a random instance ID to guarantee the + // connection is to a new service running in its own process. + service_manager::Identity identity( + mojom::kServiceName, service_manager::mojom::kInheritUserID, + batch_id.value_or(base::UnguessableToken::Create().ToString())); connector->BindInterface(identity, &json_parser_ptr_); }
diff --git a/services/data_decoder/public/cpp/safe_json_parser_impl.h b/services/data_decoder/public/cpp/safe_json_parser_impl.h index 2ccc8e2..600e5ef0 100644 --- a/services/data_decoder/public/cpp/safe_json_parser_impl.h +++ b/services/data_decoder/public/cpp/safe_json_parser_impl.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/threading/thread_checker.h" #include "base/values.h" #include "services/data_decoder/public/cpp/safe_json_parser.h" @@ -27,7 +28,8 @@ SafeJsonParserImpl(service_manager::Connector* connector, const std::string& unsafe_json, const SuccessCallback& success_callback, - const ErrorCallback& error_callback); + const ErrorCallback& error_callback, + const base::Optional<std::string>& batch_id); private: ~SafeJsonParserImpl() override;
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index 847a7090..1d37ca7 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -74,6 +74,8 @@ "resource_scheduler_params_manager.h", "restricted_cookie_manager.cc", "restricted_cookie_manager.h", + "session_cleanup_channel_id_store.cc", + "session_cleanup_channel_id_store.h", "session_cleanup_cookie_store.cc", "session_cleanup_cookie_store.h", "socket_data_pump.cc", @@ -208,6 +210,7 @@ "resource_scheduler_params_manager_unittest.cc", "resource_scheduler_unittest.cc", "restricted_cookie_manager_unittest.cc", + "session_cleanup_channel_id_store_unittest.cc", "session_cleanup_cookie_store_unittest.cc", "socket_data_pump_unittest.cc", "ssl_config_service_mojo_unittest.cc",
diff --git a/services/network/cookie_manager.cc b/services/network/cookie_manager.cc index 98b5a3c..a127b81 100644 --- a/services/network/cookie_manager.cc +++ b/services/network/cookie_manager.cc
@@ -13,6 +13,7 @@ #include "net/cookies/cookie_options.h" #include "net/cookies/cookie_store.h" #include "net/cookies/cookie_util.h" +#include "services/network/session_cleanup_channel_id_store.h" #include "services/network/session_cleanup_cookie_store.h" #include "url/gurl.h" @@ -57,17 +58,26 @@ listener->OnCookieChange(cookie, ChangeCauseTranslation(cause)); } -CookieManager::CookieManager(net::CookieStore* cookie_store, - scoped_refptr<network::SessionCleanupCookieStore> - session_cleanup_cookie_store) +CookieManager::CookieManager( + net::CookieStore* cookie_store, + scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store, + scoped_refptr<SessionCleanupChannelIDStore> + session_cleanup_channel_id_store) : cookie_store_(cookie_store), - session_cleanup_cookie_store_(std::move(session_cleanup_cookie_store)) {} + session_cleanup_cookie_store_(std::move(session_cleanup_cookie_store)), + session_cleanup_channel_id_store_( + std::move(session_cleanup_channel_id_store)) {} CookieManager::~CookieManager() { if (session_cleanup_cookie_store_) { session_cleanup_cookie_store_->DeleteSessionCookies( cookie_settings_.CreateDeleteCookieOnExitPredicate()); } + if (session_cleanup_channel_id_store_) { + session_cleanup_channel_id_store_->DeleteSessionChannelIDs( + base::BindRepeating(&CookieSettings::IsCookieSessionOnly, + base::Unretained(&cookie_settings_))); + } } void CookieManager::AddRequest(mojom::CookieManagerRequest request) { @@ -205,6 +215,8 @@ void CookieManager::SetForceKeepSessionState() { cookie_store_->SetForceKeepSessionState(); + if (session_cleanup_channel_id_store_) + session_cleanup_channel_id_store_->SetForceKeepSessionState(); } void CookieManager::BlockThirdPartyCookies(bool block) {
diff --git a/services/network/cookie_manager.h b/services/network/cookie_manager.h index 2554aa45..fb5d93a 100644 --- a/services/network/cookie_manager.h +++ b/services/network/cookie_manager.h
@@ -26,6 +26,7 @@ namespace network { class SessionCleanupCookieStore; +class SessionCleanupChannelIDStore; // Wrap a cookie store in an implementation of the mojo cookie interface. @@ -37,9 +38,11 @@ public: // Construct a CookieService that can serve mojo requests for the underlying // cookie store. |*cookie_store| must outlive this object. - CookieManager(net::CookieStore* cookie_store, - scoped_refptr<network::SessionCleanupCookieStore> - session_cleanup_cookie_store); + CookieManager( + net::CookieStore* cookie_store, + scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store, + scoped_refptr<SessionCleanupChannelIDStore> + session_cleanup_channel_id_store); ~CookieManager() override; @@ -106,8 +109,8 @@ void RemoveChangeListener(ListenerRegistration* registration); net::CookieStore* const cookie_store_; - scoped_refptr<network::SessionCleanupCookieStore> - session_cleanup_cookie_store_; + scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store_; + scoped_refptr<SessionCleanupChannelIDStore> session_cleanup_channel_id_store_; mojo::BindingSet<mojom::CookieManager> bindings_; std::vector<std::unique_ptr<ListenerRegistration>> listener_registrations_; CookieSettings cookie_settings_;
diff --git a/services/network/cookie_manager_unittest.cc b/services/network/cookie_manager_unittest.cc index 74a820a..c5444f83c 100644 --- a/services/network/cookie_manager_unittest.cc +++ b/services/network/cookie_manager_unittest.cc
@@ -22,6 +22,7 @@ #include "net/cookies/cookie_store_test_callbacks.h" #include "net/cookies/cookie_store_test_helpers.h" #include "services/network/public/mojom/cookie_manager.mojom.h" +#include "services/network/session_cleanup_channel_id_store.h" #include "services/network/session_cleanup_cookie_store.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -170,7 +171,7 @@ class CookieManagerTest : public testing::Test { public: - CookieManagerTest() { InitializeCookieService(nullptr, nullptr); } + CookieManagerTest() { InitializeCookieService(nullptr, nullptr, nullptr); } ~CookieManagerTest() override {} @@ -203,6 +204,22 @@ return result; } + ContentSettingPatternSource CreateDefaultSetting(ContentSetting setting) { + return ContentSettingPatternSource( + ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), + base::Value(setting), std::string(), false); + } + + ContentSettingPatternSource CreateSetting(ContentSetting setting, + const std::string& url_str) { + const GURL url(url_str); + EXPECT_TRUE(url.is_valid()); + return ContentSettingPatternSource(ContentSettingsPattern::FromURL(url), + ContentSettingsPattern::Wildcard(), + base::Value(setting), std::string(), + false); + } + net::CookieStore* cookie_store() { return cookie_monster_.get(); } CookieManager* service() const { return cookie_service_.get(); } @@ -220,11 +237,13 @@ protected: void InitializeCookieService( scoped_refptr<net::CookieMonster::PersistentCookieStore> store, - scoped_refptr<SessionCleanupCookieStore> cleanup_store) { + scoped_refptr<SessionCleanupCookieStore> cleanup_store, + scoped_refptr<SessionCleanupChannelIDStore> channel_id_store) { connection_error_seen_ = false; cookie_monster_ = std::make_unique<net::CookieMonster>(std::move(store)); - cookie_service_ = std::make_unique<CookieManager>(cookie_monster_.get(), - std::move(cleanup_store)); + cookie_service_ = std::make_unique<CookieManager>( + cookie_monster_.get(), std::move(cleanup_store), + std::move(channel_id_store)); cookie_service_->AddRequest(mojo::MakeRequest(&cookie_service_ptr_)); service_wrapper_ = std::make_unique<SynchronousCookieManager>(cookie_service_ptr_.get()); @@ -1861,7 +1880,7 @@ public: FlushableCookieManagerTest() : store_(base::MakeRefCounted<net::FlushablePersistentStore>()) { - InitializeCookieService(store_, nullptr); + InitializeCookieService(store_, nullptr, nullptr); } ~FlushableCookieManagerTest() override {} @@ -1961,7 +1980,7 @@ void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); auto store = CreateCookieStore(); - InitializeCookieService(store, store); + InitializeCookieService(store, store, nullptr); } scoped_refptr<SessionCleanupCookieStore> CreateCookieStore() { @@ -1972,22 +1991,6 @@ return base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store.get()); } - ContentSettingPatternSource CreateDefaultSetting(ContentSetting setting) { - return ContentSettingPatternSource( - ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), - base::Value(setting), std::string(), false); - } - - ContentSettingPatternSource CreateSetting(ContentSetting setting, - const std::string& url_str) { - const GURL url(url_str); - EXPECT_TRUE(url.is_valid()); - return ContentSettingPatternSource(ContentSettingsPattern::FromURL(url), - ContentSettingsPattern::Wildcard(), - base::Value(setting), std::string(), - false); - } - net::CanonicalCookie CreateCookie() { return CreateCookie(kCookieDomain); } net::CanonicalCookie CreateCookie(const std::string& domain) { @@ -2012,7 +2015,7 @@ // Re-create the cookie store to make sure cookies are persisted. auto store = CreateCookieStore(); - InitializeCookieService(store, store); + InitializeCookieService(store, store, nullptr); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2027,7 +2030,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store); + InitializeCookieService(store, store, nullptr); EXPECT_EQ(0u, service_wrapper()->GetAllCookies().size()); } @@ -2042,7 +2045,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store); + InitializeCookieService(store, store, nullptr); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2060,7 +2063,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store); + InitializeCookieService(store, store, nullptr); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2076,7 +2079,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store); + InitializeCookieService(store, store, nullptr); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2094,10 +2097,114 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store); + InitializeCookieService(store, store, nullptr); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } +// A test class having a channel ID store with persistent backing. The channel +// ID store can be destroyed and recreated by calling InitializeCookieService +// again. +class SessionCleanupChannelIDCookieManagerTest : public CookieManagerTest { + protected: + using ChannelIDVector = + std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>; + + ~SessionCleanupChannelIDCookieManagerTest() override {} + + void SetUp() override { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + store_ = CreateChannelIDStore(); + ASSERT_EQ(0u, Load().size()); + InitializeCookieService(nullptr, nullptr, store_); + } + + void TearDown() override { + NukeService(); + store_ = nullptr; + base::RunLoop().RunUntilIdle(); + } + + scoped_refptr<SessionCleanupChannelIDStore> CreateChannelIDStore() { + return base::MakeRefCounted<SessionCleanupChannelIDStore>( + temp_dir_.GetPath().Append(kTestCookiesFilename), + scoped_task_environment_.GetMainThreadTaskRunner()); + } + + ChannelIDVector Load() { + ChannelIDVector channel_ids; + base::RunLoop run_loop; + store_->Load( + base::BindRepeating(&SessionCleanupChannelIDCookieManagerTest::OnLoaded, + base::Unretained(this), &run_loop, &channel_ids)); + run_loop.Run(); + return channel_ids; + } + + void OnLoaded(base::RunLoop* run_loop, + ChannelIDVector* channel_ids_out, + std::unique_ptr<ChannelIDVector> channel_ids) { + channel_ids_out->swap(*channel_ids); + run_loop->Quit(); + } + + scoped_refptr<SessionCleanupChannelIDStore> store_; + base::ScopedTempDir temp_dir_; +}; + +TEST_F(SessionCleanupChannelIDCookieManagerTest, PersistSessionChannelIDs) { + store_->AddChannelID(net::ChannelIDStore::ChannelID( + kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); + + // Re-create the channel ID store to make sure channel IDs are persisted. + store_ = CreateChannelIDStore(); + InitializeCookieService(nullptr, nullptr, store_); + + EXPECT_EQ(1u, Load().size()); +} + +TEST_F(SessionCleanupChannelIDCookieManagerTest, DeleteSessionChannelIDs) { + store_->AddChannelID(net::ChannelIDStore::ChannelID( + kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); + + cookie_service_client()->SetContentSettings( + {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)}); + base::RunLoop().RunUntilIdle(); + + store_ = CreateChannelIDStore(); + InitializeCookieService(nullptr, nullptr, store_); + + EXPECT_EQ(0u, Load().size()); +} + +TEST_F(SessionCleanupChannelIDCookieManagerTest, SettingMustMatchDomain) { + store_->AddChannelID(net::ChannelIDStore::ChannelID( + kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); + + cookie_service_client()->SetContentSettings( + {CreateSetting(CONTENT_SETTING_SESSION_ONLY, "http://other.com")}); + base::RunLoop().RunUntilIdle(); + + store_ = CreateChannelIDStore(); + InitializeCookieService(nullptr, nullptr, store_); + + EXPECT_EQ(1u, Load().size()); +} + +TEST_F(SessionCleanupChannelIDCookieManagerTest, ForceKeepSessionState) { + store_->AddChannelID(net::ChannelIDStore::ChannelID( + kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); + + cookie_service_client()->SetContentSettings( + {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)}); + cookie_service_client()->SetForceKeepSessionState(); + base::RunLoop().RunUntilIdle(); + + store_ = CreateChannelIDStore(); + InitializeCookieService(nullptr, nullptr, store_); + + EXPECT_EQ(1u, Load().size()); +} + } // namespace } // namespace network
diff --git a/services/network/network_change_manager.cc b/services/network/network_change_manager.cc index 00532f6..2732bf3 100644 --- a/services/network/network_change_manager.cc +++ b/services/network/network_change_manager.cc
@@ -18,9 +18,19 @@ net::NetworkChangeNotifier::AddNetworkChangeObserver(this); connection_type_ = mojom::ConnectionType(net::NetworkChangeNotifier::GetConnectionType()); + // Only initialize the NetworkChangeNotifier's HistogramWatcher if this class + // owns the NCN. Otherwise, can't ensure lifetime guarantees are met, so just + // rely on the embedder to set it up, if needed. + // TODO(mmenke): Once the network service ships, this class should always own + // the NCN, and then this can be done unconditionally. + if (network_change_notifier_) + net::NetworkChangeNotifier::InitHistogramWatcher(); } NetworkChangeManager::~NetworkChangeManager() { + // Shut down the HistogramWatcher, if it was started in the constructor. + if (network_change_notifier_) + net::NetworkChangeNotifier::ShutdownHistogramWatcher(); net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); }
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 9884ead5..a32d8d6 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -8,9 +8,11 @@ #include <utility> #include "base/command_line.h" +#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop_current.h" +#include "base/metrics/histogram_functions.h" #include "base/optional.h" #include "base/sequenced_task_runner.h" #include "base/strings/string_number_conversions.h" @@ -32,6 +34,8 @@ #include "components/prefs/pref_service_factory.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "net/base/layered_network_delegate.h" +#include "net/base/load_flags.h" +#include "net/base/net_errors.h" #include "net/base/network_delegate.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_log_verifier.h" @@ -70,6 +74,7 @@ #include "services/network/public/cpp/network_switches.h" #include "services/network/resource_scheduler_client.h" #include "services/network/restricted_cookie_manager.h" +#include "services/network/session_cleanup_channel_id_store.h" #include "services/network/session_cleanup_cookie_store.h" #include "services/network/ssl_config_service_mojo.h" #include "services/network/throttling/network_conditions.h" @@ -222,24 +227,73 @@ public: ContextNetworkDelegate( std::unique_ptr<net::NetworkDelegate> nested_network_delegate, - bool enable_referrers) + bool enable_referrers, + bool validate_referrer_policy_on_initial_request) : LayeredNetworkDelegate(std::move(nested_network_delegate)), - enable_referrers_(enable_referrers) {} + enable_referrers_(enable_referrers), + validate_referrer_policy_on_initial_request_( + validate_referrer_policy_on_initial_request) {} ~ContextNetworkDelegate() override {} + // net::NetworkDelegate implementation: + void OnBeforeURLRequestInternal(net::URLRequest* request, GURL* new_url) override { if (!enable_referrers_) request->SetReferrer(std::string()); } + void OnCompletedInternal(net::URLRequest* request, + bool started, + int net_error) override { + // TODO(mmenke): Once the network service ships on all platforms, can move + // this logic into URLLoader's completion method. + DCHECK_NE(net::ERR_IO_PENDING, net_error); + + // Record network errors that HTTP requests complete with, including OK and + // ABORTED. + // TODO(mmenke): Seems like this really should be looking at HTTPS requests, + // too. + // TODO(mmenke): We should remove the main frame case from here, and move it + // into the consumer - the network service shouldn't know what a main frame + // is. + if (request->url().SchemeIs("http")) { + base::UmaHistogramSparse("Net.HttpRequestCompletionErrorCodes", + -net_error); + + if (request->load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) { + base::UmaHistogramSparse( + "Net.HttpRequestCompletionErrorCodes.MainFrame", -net_error); + } + } + } + + bool OnCancelURLRequestWithPolicyViolatingReferrerHeaderInternal( + const net::URLRequest& request, + const GURL& target_url, + const GURL& referrer_url) const override { + // TODO(mmenke): Once the network service has shipped on all platforms, + // consider moving this logic into URLLoader, and removing this method from + // NetworkDelegate. Can just have a DCHECK in URLRequest instead. + if (!validate_referrer_policy_on_initial_request_) + return false; + + LOG(ERROR) << "Cancelling request to " << target_url + << " with invalid referrer " << referrer_url; + // Record information to help debug issues like http://crbug.com/422871. + if (target_url.SchemeIsHTTPOrHTTPS()) + base::debug::DumpWithoutCrashing(); + return true; + } + void set_enable_referrers(bool enable_referrers) { enable_referrers_ = enable_referrers; } private: bool enable_referrers_; + bool validate_referrer_policy_on_initial_request_; DISALLOW_COPY_AND_ASSIGN(ContextNetworkDelegate); }; @@ -254,8 +308,9 @@ on_connection_close_callback_(std::move(on_connection_close_callback)), binding_(this, std::move(request)) { SessionCleanupCookieStore* session_cleanup_cookie_store = nullptr; - url_request_context_owner_ = - MakeURLRequestContext(&session_cleanup_cookie_store); + SessionCleanupChannelIDStore* session_cleanup_channel_id_store = nullptr; + url_request_context_owner_ = MakeURLRequestContext( + &session_cleanup_cookie_store, &session_cleanup_channel_id_store); url_request_context_ = url_request_context_owner_.url_request_context.get(); network_service_->RegisterNetworkContext(this); @@ -268,7 +323,8 @@ &NetworkContext::OnConnectionError, base::Unretained(this))); cookie_manager_ = std::make_unique<CookieManager>( - url_request_context_->cookie_store(), session_cleanup_cookie_store); + url_request_context_->cookie_store(), session_cleanup_cookie_store, + session_cleanup_channel_id_store); socket_factory_ = std::make_unique<SocketFactory>(network_service_->net_log(), url_request_context_); resource_scheduler_ = @@ -291,7 +347,7 @@ network_service_->RegisterNetworkContext(this); cookie_manager_ = std::make_unique<CookieManager>( - url_request_context_->cookie_store(), nullptr); + url_request_context_->cookie_store(), nullptr, nullptr); socket_factory_ = std::make_unique<SocketFactory>(network_service_->net_log(), url_request_context_); resource_scheduler_ = @@ -306,6 +362,7 @@ binding_(this, std::move(request)), cookie_manager_( std::make_unique<CookieManager>(url_request_context->cookie_store(), + nullptr, nullptr)), socket_factory_(std::make_unique<SocketFactory>( network_service_ ? network_service_->net_log() : nullptr, @@ -854,7 +911,9 @@ std::unique_ptr<ContextNetworkDelegate> context_network_delegate = std::make_unique<ContextNetworkDelegate>( std::move(nested_network_delegate), - network_context_params->enable_referrers); + network_context_params->enable_referrers, + network_context_params + ->validate_referrer_policy_on_initial_request); if (out_context_network_delegate) *out_context_network_delegate = context_network_delegate.get(); return context_network_delegate; @@ -984,7 +1043,8 @@ } URLRequestContextOwner NetworkContext::MakeURLRequestContext( - SessionCleanupCookieStore** session_cleanup_cookie_store) { + SessionCleanupCookieStore** session_cleanup_cookie_store, + SessionCleanupChannelIDStore** session_cleanup_channel_id_store) { URLRequestContextBuilderMojo builder; const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -1007,9 +1067,9 @@ std::unique_ptr<net::ChannelIDService> channel_id_service; if (params_->channel_id_path) { - scoped_refptr<net::SQLiteChannelIDStore> channel_id_db = - new net::SQLiteChannelIDStore(params_->channel_id_path.value(), - background_task_runner); + auto channel_id_db = base::MakeRefCounted<SessionCleanupChannelIDStore>( + params_->channel_id_path.value(), background_task_runner); + *session_cleanup_channel_id_store = channel_id_db.get(); channel_id_service = std::make_unique<net::ChannelIDService>( new net::DefaultChannelIDStore(channel_id_db.get())); }
diff --git a/services/network/network_context.h b/services/network/network_context.h index 44d9ea1..be42ff6 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -220,7 +220,8 @@ void OnConnectionError(); URLRequestContextOwner MakeURLRequestContext( - SessionCleanupCookieStore** session_cleanup_cookie_store); + SessionCleanupCookieStore** session_cleanup_cookie_store, + SessionCleanupChannelIDStore** session_cleanup_channel_id_store); NetworkService* const network_service_;
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 8109cbf..9a41efc 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -23,6 +23,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/test/gtest_util.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/mock_entropy_provider.h" #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" @@ -35,6 +36,7 @@ #include "components/network_session_configurator/browser/network_session_configurator.h" #include "components/network_session_configurator/common/network_switches.h" #include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/system/data_pipe_utils.h" #include "net/base/cache_type.h" #include "net/base/hash_value.h" #include "net/base/ip_endpoint.h" @@ -815,6 +817,161 @@ } } +// Test that valid referrers are allowed, while invalid ones result in errors. +TEST_F(NetworkContextTest, Referrers) { + const GURL kReferrer = GURL("http://referrer/"); + net::test_server::EmbeddedTestServer test_server; + test_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("services/test/data"))); + ASSERT_TRUE(test_server.Start()); + + for (bool validate_referrer_policy_on_initial_request : {false, true}) { + for (net::URLRequest::ReferrerPolicy referrer_policy : + {net::URLRequest::NEVER_CLEAR_REFERRER, + net::URLRequest::NO_REFERRER}) { + mojom::NetworkContextParamsPtr context_params = CreateContextParams(); + context_params->validate_referrer_policy_on_initial_request = + validate_referrer_policy_on_initial_request; + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(std::move(context_params)); + + mojom::URLLoaderFactoryPtr loader_factory; + mojom::URLLoaderFactoryParamsPtr params = + mojom::URLLoaderFactoryParams::New(); + params->process_id = 0; + network_context->CreateURLLoaderFactory( + mojo::MakeRequest(&loader_factory), std::move(params)); + + ResourceRequest request; + request.url = test_server.GetURL("/echoheader?Referer"); + request.referrer = kReferrer; + request.referrer_policy = referrer_policy; + + mojom::URLLoaderPtr loader; + TestURLLoaderClient client; + loader_factory->CreateLoaderAndStart( + mojo::MakeRequest(&loader), 0 /* routing_id */, 0 /* request_id */, + 0 /* options */, request, client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag( + TRAFFIC_ANNOTATION_FOR_TESTS)); + + client.RunUntilComplete(); + EXPECT_TRUE(client.has_received_completion()); + + // If validating referrers, and the referrer policy is not to send + // referrers, the request should fail. + if (validate_referrer_policy_on_initial_request && + referrer_policy == net::URLRequest::NO_REFERRER) { + EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, + client.completion_status().error_code); + EXPECT_FALSE(client.response_body().is_valid()); + continue; + } + + // Otherwise, the request should succeed. + EXPECT_EQ(net::OK, client.completion_status().error_code); + std::string response_body; + ASSERT_TRUE(client.response_body().is_valid()); + EXPECT_TRUE(mojo::BlockingCopyToString(client.response_body_release(), + &response_body)); + if (referrer_policy == net::URLRequest::NO_REFERRER) { + // If not validating referrers, and the referrer policy is not to send + // referrers, the referrer should be cleared. + EXPECT_EQ("None", response_body); + } else { + // Otherwise, the referrer should be send. + EXPECT_EQ(kReferrer.spec(), response_body); + } + } + } +} + +TEST_F(NetworkContextTest, HttpRequestCompletionErrorCodes) { + net::EmbeddedTestServer test_server; + test_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("services/test/data"))); + ASSERT_TRUE(test_server.Start()); + + net::EmbeddedTestServer https_test_server( + net::test_server::EmbeddedTestServer::TYPE_HTTPS); + https_test_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("services/test/data"))); + ASSERT_TRUE(https_test_server.Start()); + + const struct { + const char* path; + bool use_https; + bool is_main_frame; + int expected_net_error; + int expected_request_completion_count; + int expected_request_completion_main_frame_count; + } kTests[] = { + {"/", false /* use_https */, true /* is_main_frame */, net::OK, + 1 /* expected_request_completion_count */, + 1 /* expected_request_completion_main_frame_count */}, + {"/close-socket", false /* use_https */, true /* is_main_frame */, + net::ERR_EMPTY_RESPONSE, 1 /* expected_request_completion_count */, + 1 /* expected_request_completion_main_frame_count */}, + {"/", false /* use_https */, false /* is_main_frame */, net::OK, + 1 /* expected_request_completion_count */, + 0 /* expected_request_completion_main_frame_count */}, + {"/", true /* use_https */, true /* is_main_frame */, net::OK, + 0 /* expected_request_completion_count */, + 0 /* expected_request_completion_main_frame_count */}, + }; + + const char kHttpRequestCompletionErrorCode[] = + "Net.HttpRequestCompletionErrorCodes"; + const char kHttpRequestCompletionErrorCodeMainFrame[] = + "Net.HttpRequestCompletionErrorCodes.MainFrame"; + + for (const auto& test : kTests) { + base::HistogramTester histograms; + + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + mojom::URLLoaderFactoryPtr loader_factory; + mojom::URLLoaderFactoryParamsPtr params = + mojom::URLLoaderFactoryParams::New(); + params->process_id = mojom::kBrowserProcessId; + network_context->CreateURLLoaderFactory(mojo::MakeRequest(&loader_factory), + std::move(params)); + + ResourceRequest request; + if (!test.use_https) { + request.url = test_server.GetURL(test.path); + } else { + request.url = https_test_server.GetURL(test.path); + } + if (test.is_main_frame) + request.load_flags = net::LOAD_MAIN_FRAME_DEPRECATED; + + mojom::URLLoaderPtr loader; + TestURLLoaderClient client; + loader_factory->CreateLoaderAndStart( + mojo::MakeRequest(&loader), 0 /* routing_id */, 0 /* request_id */, + 0 /* options */, request, client.CreateInterfacePtr(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); + + client.RunUntilComplete(); + EXPECT_TRUE(client.has_received_completion()); + EXPECT_EQ(test.expected_net_error, client.completion_status().error_code); + + histograms.ExpectTotalCount(kHttpRequestCompletionErrorCode, + test.expected_request_completion_count); + histograms.ExpectUniqueSample(kHttpRequestCompletionErrorCode, + -test.expected_net_error, + test.expected_request_completion_count); + histograms.ExpectTotalCount( + kHttpRequestCompletionErrorCodeMainFrame, + test.expected_request_completion_main_frame_count); + histograms.ExpectUniqueSample( + kHttpRequestCompletionErrorCodeMainFrame, -test.expected_net_error, + test.expected_request_completion_main_frame_count); + } +} + // Validates that clearing the HTTP cache when no cache exists does complete. TEST_F(NetworkContextTest, ClearHttpCacheWithNoCache) { mojom::NetworkContextParamsPtr context_params = CreateContextParams();
diff --git a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc index cfb2a19..704b2dd0 100644 --- a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc +++ b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc
@@ -177,7 +177,10 @@ void CrossThreadSharedURLLoaderFactoryInfo::State::DeleteOnCorrectThread() const { - task_runner_->DeleteSoon(FROM_HERE, this); + if (task_runner_->RunsTasksInCurrentSequence()) + delete this; + else + task_runner_->DeleteSoon(FROM_HERE, this); } void CrossThreadSharedURLLoaderFactoryInfo::State::CreateLoaderAndStart(
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index b44618b..ef2c01d 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -50,6 +50,10 @@ // If false, the referrer of requests is never populated. bool enable_referrers = true; + // If true, requests initiated with referrers that don't match their referrer + // policy will fail. + bool validate_referrer_policy_on_initial_request = true; + // Handles PAC script execution. If not populated, will attempt to use // platform implementation to execute PAC scripts, if available (Only // available on Windows and Mac).
diff --git a/services/network/session_cleanup_channel_id_store.cc b/services/network/session_cleanup_channel_id_store.cc new file mode 100644 index 0000000..e3de7d9 --- /dev/null +++ b/services/network/session_cleanup_channel_id_store.cc
@@ -0,0 +1,80 @@ +// 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 "services/network/session_cleanup_channel_id_store.h" + +#include <list> + +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/strings/string_util.h" +#include "base/threading/thread.h" +#include "base/threading/thread_restrictions.h" +#include "net/cookies/cookie_util.h" +#include "net/extras/sqlite/sqlite_channel_id_store.h" +#include "url/gurl.h" + +namespace network { + +SessionCleanupChannelIDStore::SessionCleanupChannelIDStore( + const base::FilePath& path, + const scoped_refptr<base::SequencedTaskRunner>& background_task_runner) + : persistent_store_( + new net::SQLiteChannelIDStore(path, background_task_runner)) { + DCHECK(background_task_runner.get()); +} + +SessionCleanupChannelIDStore::~SessionCleanupChannelIDStore() {} + +void SessionCleanupChannelIDStore::DeleteSessionChannelIDs( + DeleteChannelIDPredicate delete_channel_id_predicate) { + if (force_keep_session_state_ || !delete_channel_id_predicate) + return; + + std::list<std::string> session_only_server_identifiers; + for (const std::string& server_identifier : server_identifiers_) { + GURL url(net::cookie_util::CookieOriginToURL(server_identifier, true)); + if (delete_channel_id_predicate.Run(url)) + session_only_server_identifiers.push_back(server_identifier); + } + persistent_store_->DeleteAllInList(session_only_server_identifiers); +} + +void SessionCleanupChannelIDStore::Load(const LoadedCallback& loaded_callback) { + persistent_store_->Load(base::BindRepeating( + &SessionCleanupChannelIDStore::OnLoad, this, loaded_callback)); +} + +void SessionCleanupChannelIDStore::AddChannelID( + const net::DefaultChannelIDStore::ChannelID& channel_id) { + server_identifiers_.insert(channel_id.server_identifier()); + persistent_store_->AddChannelID(channel_id); +} + +void SessionCleanupChannelIDStore::DeleteChannelID( + const net::DefaultChannelIDStore::ChannelID& channel_id) { + server_identifiers_.erase(channel_id.server_identifier()); + persistent_store_->DeleteChannelID(channel_id); +} + +void SessionCleanupChannelIDStore::Flush() { + persistent_store_->Flush(); +} + +void SessionCleanupChannelIDStore::SetForceKeepSessionState() { + force_keep_session_state_ = true; +} + +void SessionCleanupChannelIDStore::OnLoad( + const LoadedCallback& loaded_callback, + std::unique_ptr<ChannelIDVector> channel_ids) { + for (const auto& channel_id : *channel_ids) + server_identifiers_.insert(channel_id->server_identifier()); + loaded_callback.Run(std::move(channel_ids)); +} + +} // namespace network
diff --git a/services/network/session_cleanup_channel_id_store.h b/services/network/session_cleanup_channel_id_store.h new file mode 100644 index 0000000..e32a493 --- /dev/null +++ b/services/network/session_cleanup_channel_id_store.h
@@ -0,0 +1,80 @@ +// 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 SERVICES_NETWORK_SESSION_CLEANUP_CHANNEL_ID_STORE_H_ +#define SERVICES_NETWORK_SESSION_CLEANUP_CHANNEL_ID_STORE_H_ + +#include <set> +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/compiler_specific.h" +#include "base/component_export.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "net/extras/sqlite/sqlite_channel_id_store.h" +#include "net/ssl/default_channel_id_store.h" + +class GURL; + +namespace base { +class FilePath; +class SequencedTaskRunner; +} // namespace base + +namespace network { + +// Implements a PersistentStore that keeps an in-memory map of channel IDs, and +// allows deletion of channel IDs using the DeleteChannelIDPredicate. This is +// used to clear channel IDs with session-only policy at the end of a session. +class COMPONENT_EXPORT(NETWORK_SERVICE) SessionCleanupChannelIDStore + : public net::DefaultChannelIDStore::PersistentStore { + public: + // Returns true if the channel ID for the URL should be deleted. + using DeleteChannelIDPredicate = base::RepeatingCallback<bool(const GURL&)>; + + // Create or open persistent store in file |path|. All I/O tasks are performed + // in background using |background_task_runner|. + SessionCleanupChannelIDStore( + const base::FilePath& path, + const scoped_refptr<base::SequencedTaskRunner>& background_task_runner); + + // net::DefaultChannelIDStore::PersistentStore: + void Load(const LoadedCallback& loaded_callback) override; + void AddChannelID( + const net::DefaultChannelIDStore::ChannelID& channel_id) override; + void DeleteChannelID( + const net::DefaultChannelIDStore::ChannelID& channel_id) override; + void Flush() override; + void SetForceKeepSessionState() override; + + // Should be called at the end of a session. Deletes all channel IDs that + // |delete_channel_id_predicate| returns true for. + void DeleteSessionChannelIDs( + DeleteChannelIDPredicate delete_channel_id_predicate); + + protected: + ~SessionCleanupChannelIDStore() override; + + private: + using ChannelIDVector = + std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>; + + void OnLoad(const LoadedCallback& loaded_callback, + std::unique_ptr<ChannelIDVector> channel_ids); + + scoped_refptr<net::SQLiteChannelIDStore> persistent_store_; + // Cache of server identifiers we have channel IDs stored for. + std::set<std::string> server_identifiers_; + // When set to true, DeleteSessionChannelIDs will be a no-op, and all channel + // IDs will be kept. + bool force_keep_session_state_ = false; + + DISALLOW_COPY_AND_ASSIGN(SessionCleanupChannelIDStore); +}; + +} // namespace network + +#endif // SERVICES_NETWORK_SESSION_CLEANUP_CHANNEL_ID_STORE_H_
diff --git a/services/network/session_cleanup_channel_id_store_unittest.cc b/services/network/session_cleanup_channel_id_store_unittest.cc new file mode 100644 index 0000000..512be9f2 --- /dev/null +++ b/services/network/session_cleanup_channel_id_store_unittest.cc
@@ -0,0 +1,186 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/session_cleanup_channel_id_store.h" + +#include <vector> + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/memory/ref_counted.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "net/test/channel_id_test_util.h" +#include "net/test/test_data_directory.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace network { +namespace { + +using ChannelIDVector = + std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>; + +const base::FilePath::CharType kTestChannelIDFilename[] = + FILE_PATH_LITERAL("ChannelID"); + +class SessionCleanupChannelIDStoreTest : public testing::Test { + public: + ChannelIDVector Load() { + ChannelIDVector channel_ids; + base::RunLoop run_loop; + store_->Load( + base::BindRepeating(&SessionCleanupChannelIDStoreTest::OnLoaded, + base::Unretained(this), &run_loop, &channel_ids)); + run_loop.Run(); + return channel_ids; + } + + void OnLoaded(base::RunLoop* run_loop, + ChannelIDVector* channel_ids_out, + std::unique_ptr<ChannelIDVector> channel_ids) { + channel_ids_out->swap(*channel_ids); + run_loop->Quit(); + } + + ChannelIDVector CreateAndLoad() { + store_ = base::MakeRefCounted<SessionCleanupChannelIDStore>( + temp_dir_.GetPath().Append(kTestChannelIDFilename), + scoped_task_environment_.GetMainThreadTaskRunner()); + return Load(); + } + + protected: + void SetUp() override { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + ChannelIDVector channel_ids = CreateAndLoad(); + ASSERT_EQ(0u, channel_ids.size()); + } + + void TearDown() override { + store_ = nullptr; + scoped_task_environment_.RunUntilIdle(); + } + + base::ScopedTempDir temp_dir_; + scoped_refptr<SessionCleanupChannelIDStore> store_; + base::test::ScopedTaskEnvironment scoped_task_environment_; +}; + +TEST_F(SessionCleanupChannelIDStoreTest, TestPersistence) { + std::unique_ptr<crypto::ECPrivateKey> goog_key( + crypto::ECPrivateKey::Create()); + std::unique_ptr<crypto::ECPrivateKey> foo_key(crypto::ECPrivateKey::Create()); + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "google.com", base::Time::FromDoubleT(1), goog_key->Copy())); + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "foo.com", base::Time::FromDoubleT(3), foo_key->Copy())); + + // Replace the store effectively destroying the current one and forcing it + // to write its data to disk. Then we can see if after loading it again it + // is still there. + store_ = nullptr; + // Make sure we wait until the destructor has run. + scoped_task_environment_.RunUntilIdle(); + + // Reload and test for persistence + ChannelIDVector channel_ids = CreateAndLoad(); + ASSERT_EQ(2u, channel_ids.size()); + net::DefaultChannelIDStore::ChannelID* goog_channel_id; + net::DefaultChannelIDStore::ChannelID* foo_channel_id; + if (channel_ids[0]->server_identifier() == "google.com") { + goog_channel_id = channel_ids[0].get(); + foo_channel_id = channel_ids[1].get(); + } else { + goog_channel_id = channel_ids[1].get(); + foo_channel_id = channel_ids[0].get(); + } + EXPECT_EQ("google.com", goog_channel_id->server_identifier()); + EXPECT_TRUE(net::KeysEqual(goog_key.get(), goog_channel_id->key())); + EXPECT_EQ(1, goog_channel_id->creation_time().ToDoubleT()); + EXPECT_EQ("foo.com", foo_channel_id->server_identifier()); + EXPECT_TRUE(net::KeysEqual(foo_key.get(), foo_channel_id->key())); + EXPECT_EQ(3, foo_channel_id->creation_time().ToDoubleT()); + + // Now delete the channel ID and check persistence again. + store_->DeleteChannelID(*channel_ids[0]); + store_->DeleteChannelID(*channel_ids[1]); + store_ = nullptr; + // Make sure we wait until the destructor has run. + scoped_task_environment_.RunUntilIdle(); + + // Reload and check if the channel ID has been removed. + channel_ids = CreateAndLoad(); + EXPECT_EQ(0u, channel_ids.size()); +} + +TEST_F(SessionCleanupChannelIDStoreTest, TestDeleteSessionChannelIDs) { + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "google.com", base::Time::FromDoubleT(1), + crypto::ECPrivateKey::Create())); + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "nonpersistent.com", base::Time::FromDoubleT(3), + crypto::ECPrivateKey::Create())); + + // Replace the store and force it to write to disk. + store_ = nullptr; + scoped_task_environment_.RunUntilIdle(); + ChannelIDVector channel_ids = CreateAndLoad(); + EXPECT_EQ(2u, channel_ids.size()); + + // Add another two channel IDs before closing the store. Because additions are + // delayed and committed to disk in batches, these will not be committed until + // the store is destroyed, which is after the policy is applied. The pending + // operation pruning logic should prevent the "nonpersistent.com" ID from + // being committed to disk. + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "nonpersistent.com", base::Time::FromDoubleT(5), + crypto::ECPrivateKey::Create())); + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "persistent.com", base::Time::FromDoubleT(7), + crypto::ECPrivateKey::Create())); + + store_->DeleteSessionChannelIDs(base::BindRepeating( + [](const GURL& url) { return url.host() == "nonpersistent.com"; })); + scoped_task_environment_.RunUntilIdle(); + // Now close the store, and the nonpersistent.com channel IDs should have been + // deleted. + store_ = nullptr; + scoped_task_environment_.RunUntilIdle(); + + // Reload and check that the nonpersistent.com channel IDs have been removed. + channel_ids = CreateAndLoad(); + EXPECT_EQ(2u, channel_ids.size()); + for (const auto& id : channel_ids) { + EXPECT_NE("nonpersistent.com", id->server_identifier()); + } +} + +TEST_F(SessionCleanupChannelIDStoreTest, TestForceKeepSessionState) { + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "google.com", base::Time::FromDoubleT(1), + crypto::ECPrivateKey::Create())); + store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( + "nonpersistent.com", base::Time::FromDoubleT(3), + crypto::ECPrivateKey::Create())); + + store_->SetForceKeepSessionState(); + store_->DeleteSessionChannelIDs(base::BindRepeating( + [](const GURL& url) { return url.host() == "nonpersistent.com"; })); + scoped_task_environment_.RunUntilIdle(); + + store_ = nullptr; + scoped_task_environment_.RunUntilIdle(); + + // Reload and check that the all channel IDs are still present. + ChannelIDVector channel_ids = CreateAndLoad(); + EXPECT_EQ(2u, channel_ids.size()); +} + +} // namespace +} // namespace network
diff --git a/services/network/test/test_url_loader_factory.cc b/services/network/test/test_url_loader_factory.cc index 719f13cb..679c0bf 100644 --- a/services/network/test/test_url_loader_factory.cc +++ b/services/network/test/test_url_loader_factory.cc
@@ -121,7 +121,7 @@ } void TestURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) { - NOTIMPLEMENTED(); + bindings_.AddBinding(this, std::move(request)); } bool TestURLLoaderFactory::CreateLoaderAndStartInternal(
diff --git a/services/network/test/test_url_loader_factory.h b/services/network/test/test_url_loader_factory.h index 5d23df8..f36a6ce 100644 --- a/services/network/test/test_url_loader_factory.h +++ b/services/network/test/test_url_loader_factory.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/macros.h" +#include "mojo/public/cpp/bindings/binding_set.h" #include "net/http/http_status_code.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" @@ -106,6 +107,7 @@ std::vector<PendingRequest> pending_requests_; Interceptor interceptor_; + mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_; DISALLOW_COPY_AND_ASSIGN(TestURLLoaderFactory); };
diff --git a/services/tracing/perfetto/json_trace_exporter.cc b/services/tracing/perfetto/json_trace_exporter.cc index b908fda..6599c9cf 100644 --- a/services/tracing/perfetto/json_trace_exporter.cc +++ b/services/tracing/perfetto/json_trace_exporter.cc
@@ -177,7 +177,7 @@ namespace tracing { JSONTraceExporter::JSONTraceExporter(const std::string& config, - perfetto::Service* service) + perfetto::TracingService* service) : config_(config) { consumer_endpoint_ = service->ConnectConsumer(this); }
diff --git a/services/tracing/perfetto/json_trace_exporter.h b/services/tracing/perfetto/json_trace_exporter.h index 2efdc61..782396a 100644 --- a/services/tracing/perfetto/json_trace_exporter.h +++ b/services/tracing/perfetto/json_trace_exporter.h
@@ -13,7 +13,7 @@ #include "base/macros.h" #include "third_party/perfetto/include/perfetto/tracing/core/consumer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/service.h" +#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" namespace tracing { @@ -25,7 +25,8 @@ public: // The owner of JSONTraceExporter should make sure to destroy // |service| before destroying this. - JSONTraceExporter(const std::string& config, perfetto::Service* service); + JSONTraceExporter(const std::string& config, + perfetto::TracingService* service); ~JSONTraceExporter() override; @@ -49,7 +50,8 @@ std::string config_; // Keep last to avoid edge-cases where its callbacks come in mid-destruction. - std::unique_ptr<perfetto::Service::ConsumerEndpoint> consumer_endpoint_; + std::unique_ptr<perfetto::TracingService::ConsumerEndpoint> + consumer_endpoint_; DISALLOW_COPY_AND_ASSIGN(JSONTraceExporter); };
diff --git a/services/tracing/perfetto/json_trace_exporter_unittest.cc b/services/tracing/perfetto/json_trace_exporter_unittest.cc index 1992bec..3af401d 100644 --- a/services/tracing/perfetto/json_trace_exporter_unittest.cc +++ b/services/tracing/perfetto/json_trace_exporter_unittest.cc
@@ -22,7 +22,7 @@ namespace tracing { -class MockService : public perfetto::Service { +class MockService : public perfetto::TracingService { public: explicit MockService(base::MessageLoop* message_loop); @@ -36,7 +36,7 @@ return tracing_enabled_with_config_; } - // perfetto::Service implementation. + // perfetto::TracingService implementation. std::unique_ptr<ProducerEndpoint> ConnectProducer( perfetto::Producer*, uid_t uid, @@ -54,7 +54,7 @@ std::string tracing_enabled_with_config_; }; -class MockConsumerEndpoint : public perfetto::Service::ConsumerEndpoint { +class MockConsumerEndpoint : public perfetto::TracingService::ConsumerEndpoint { public: explicit MockConsumerEndpoint(MockService* mock_service) : mock_service_(mock_service) { @@ -100,8 +100,8 @@ wait_for_tracing_disabled_.Run(); } -// perfetto::Service implementation. -std::unique_ptr<perfetto::Service::ProducerEndpoint> +// perfetto::TracingService implementation. +std::unique_ptr<perfetto::TracingService::ProducerEndpoint> MockService::ConnectProducer(perfetto::Producer*, uid_t uid, const std::string& name, @@ -110,7 +110,7 @@ return nullptr; } -std::unique_ptr<perfetto::Service::ConsumerEndpoint> +std::unique_ptr<perfetto::TracingService::ConsumerEndpoint> MockService::ConnectConsumer(perfetto::Consumer* consumer) { message_loop_->task_runner()->PostTask( FROM_HERE, base::BindOnce(&perfetto::Consumer::OnConnect,
diff --git a/services/tracing/perfetto/perfetto_integration_unittest.cc b/services/tracing/perfetto/perfetto_integration_unittest.cc index 634a1aa..c44c9ca 100644 --- a/services/tracing/perfetto/perfetto_integration_unittest.cc +++ b/services/tracing/perfetto/perfetto_integration_unittest.cc
@@ -16,10 +16,10 @@ #include "third_party/perfetto/include/perfetto/tracing/core/commit_data_request.h" #include "third_party/perfetto/include/perfetto/tracing/core/consumer.h" #include "third_party/perfetto/include/perfetto/tracing/core/data_source_descriptor.h" -#include "third_party/perfetto/include/perfetto/tracing/core/service.h" #include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" #include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" #include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" #include "third_party/perfetto/protos/perfetto/common/commit_data_request.pb.h" #include "third_party/perfetto/protos/perfetto/trace/test_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h" @@ -170,7 +170,7 @@ class MockConsumer : public perfetto::Consumer { public: using PacketReceivedCallback = std::function<void(bool)>; - MockConsumer(perfetto::Service* service, + MockConsumer(perfetto::TracingService* service, std::string data_source_name, PacketReceivedCallback packet_received_callback) : packet_received_callback_(packet_received_callback), @@ -218,7 +218,8 @@ } private: - std::unique_ptr<perfetto::Service::ConsumerEndpoint> consumer_endpoint_; + std::unique_ptr<perfetto::TracingService::ConsumerEndpoint> + consumer_endpoint_; size_t received_packets_ = 0; PacketReceivedCallback packet_received_callback_; std::string data_source_name_; @@ -260,7 +261,7 @@ } void OnMessagepipesReadyCallback( - perfetto::Service* perfetto_service, + perfetto::TracingService* perfetto_service, mojom::ProducerClientPtr producer_client_pipe, mojom::ProducerHostRequest producer_host_pipe) { Initialize(std::move(producer_client_pipe), std::move(producer_host_pipe),
diff --git a/services/tracing/perfetto/perfetto_service.cc b/services/tracing/perfetto/perfetto_service.cc index 45869a3..22935f6e6 100644 --- a/services/tracing/perfetto/perfetto_service.cc +++ b/services/tracing/perfetto/perfetto_service.cc
@@ -11,7 +11,7 @@ #include "services/tracing/perfetto/producer_host.h" #include "services/tracing/public/cpp/perfetto/shared_memory.h" -#include "third_party/perfetto/include/perfetto/tracing/core/service.h" +#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" namespace tracing { @@ -82,12 +82,12 @@ void PerfettoService::CreateServiceOnSequence() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - service_ = perfetto::Service::CreateInstance( + service_ = perfetto::TracingService::CreateInstance( std::make_unique<MojoSharedMemory::Factory>(), &perfetto_task_runner_); DCHECK(service_); } -perfetto::Service* PerfettoService::GetService() const { +perfetto::TracingService* PerfettoService::GetService() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return service_.get(); }
diff --git a/services/tracing/perfetto/perfetto_service.h b/services/tracing/perfetto/perfetto_service.h index fcf575aa..3653dc9 100644 --- a/services/tracing/perfetto/perfetto_service.h +++ b/services/tracing/perfetto/perfetto_service.h
@@ -21,13 +21,13 @@ } // namespace service_manager namespace perfetto { -class Service; +class TracingService; } // namespace perfetto namespace tracing { // This class serves two purposes: It wraps the use of the system-wide -// perfetto::Service instance, and serves as the main Mojo interface for +// perfetto::TracingService instance, and serves as the main Mojo interface for // connecting per-process ProducerClient with corresponding service-side // ProducerHost. class PerfettoService : public mojom::PerfettoService { @@ -46,7 +46,7 @@ void ConnectToProducerHost(mojom::ProducerClientPtr producer_client, mojom::ProducerHostRequest producer_host) override; - perfetto::Service* GetService() const; + perfetto::TracingService* GetService() const; scoped_refptr<base::SequencedTaskRunner> task_runner() { return perfetto_task_runner_.task_runner(); } @@ -57,7 +57,7 @@ void CreateServiceOnSequence(); PerfettoTaskRunner perfetto_task_runner_; - std::unique_ptr<perfetto::Service> service_; + std::unique_ptr<perfetto::TracingService> service_; mojo::BindingSet<mojom::PerfettoService, service_manager::Identity> bindings_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/services/tracing/perfetto/producer_host.cc b/services/tracing/perfetto/producer_host.cc index 0dfd594f..2349fe70 100644 --- a/services/tracing/perfetto/producer_host.cc +++ b/services/tracing/perfetto/producer_host.cc
@@ -18,7 +18,7 @@ void ProducerHost::Initialize(mojom::ProducerClientPtr producer_client, mojom::ProducerHostRequest producer_host, - perfetto::Service* service, + perfetto::TracingService* service, const std::string& name) { DCHECK(service); DCHECK(!producer_endpoint_);
diff --git a/services/tracing/perfetto/producer_host.h b/services/tracing/perfetto/producer_host.h index f4677e6..ae4228ce 100644 --- a/services/tracing/perfetto/producer_host.h +++ b/services/tracing/perfetto/producer_host.h
@@ -18,7 +18,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "third_party/perfetto/include/perfetto/tracing/core/producer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/service.h" +#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" namespace perfetto { class CommitDataRequest; @@ -51,11 +51,11 @@ // corresponding remote ProducerClient. void Initialize(mojom::ProducerClientPtr producer_client, mojom::ProducerHostRequest producer_host, - perfetto::Service* service, + perfetto::TracingService* service, const std::string& name); // perfetto::Producer implementation. - // Gets called by perfetto::Service to toggle specific data sources + // Gets called by perfetto::TracingService to toggle specific data sources // when requested by a Perfetto Consumer. void OnConnect() override; void OnDisconnect() override; @@ -89,7 +89,8 @@ protected: // Perfetto guarantees that no OnXX callbacks are invoked on |this| // immediately after |producer_endpoint_| is destroyed. - std::unique_ptr<perfetto::Service::ProducerEndpoint> producer_endpoint_; + std::unique_ptr<perfetto::TracingService::ProducerEndpoint> + producer_endpoint_; DISALLOW_COPY_AND_ASSIGN(ProducerHost); };
diff --git a/services/tracing/public/cpp/perfetto/producer_client.h b/services/tracing/public/cpp/perfetto/producer_client.h index 2a9dea2..b3d7daf 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.h +++ b/services/tracing/public/cpp/perfetto/producer_client.h
@@ -16,7 +16,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "services/tracing/public/cpp/perfetto/task_runner.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/service.h" +#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" namespace perfetto { class SharedMemoryArbiter; @@ -39,7 +39,7 @@ // in ProducerClient::CreateDataSourceInstance. class COMPONENT_EXPORT(TRACING_CPP) ProducerClient : public mojom::ProducerClient, - public perfetto::Service::ProducerEndpoint { + public perfetto::TracingService::ProducerEndpoint { public: ProducerClient(); ~ProducerClient() override; @@ -70,7 +70,7 @@ void Flush(uint64_t flush_request_id, const std::vector<uint64_t>& data_source_ids) override; - // perfetto::Service::ProducerEndpoint implementation. + // perfetto::TracingService::ProducerEndpoint implementation. // Used by the TraceWriters // to signal Perfetto that shared memory chunks are ready // for consumption.
diff --git a/services/ui/ws2/BUILD.gn b/services/ui/ws2/BUILD.gn index fdaea45..558b837 100644 --- a/services/ui/ws2/BUILD.gn +++ b/services/ui/ws2/BUILD.gn
@@ -71,6 +71,29 @@ defines = [ "IS_WINDOW_SERVICE_IMPL" ] } +source_set("host") { + public = [ + "host_context_factory.h", + ] + sources = [ + "host_context_factory.cc", + ] + + deps = [ + ":lib", + "//cc/mojo_embedder", + "//components/viz/client", + "//components/viz/common", + "//components/viz/host", + "//services/ui/public/cpp", + "//services/ui/public/cpp/gpu", + "//services/viz/privileged/interfaces/compositing", + "//services/viz/public/interfaces", + "//ui/compositor", + "//ui/compositor/host", + ] +} + static_library("test_support") { testonly = true @@ -140,6 +163,7 @@ "embedding_unittest.cc", "focus_handler_unittest.cc", "screen_provider_unittest.cc", + "window_service_unittest.cc", "window_tree_client_unittest.cc", "window_tree_unittest.cc", ] @@ -151,6 +175,7 @@ "//components/viz/common", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", "//services/service_manager/public/mojom", "//services/ui/common:task_runner_test_base", "//services/ui/public/cpp",
diff --git a/services/ui/ws2/host_context_factory.cc b/services/ui/ws2/host_context_factory.cc new file mode 100644 index 0000000..4761aa8 --- /dev/null +++ b/services/ui/ws2/host_context_factory.cc
@@ -0,0 +1,97 @@ +// 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 "services/ui/ws2/host_context_factory.h" + +#include "base/bind.h" +#include "components/viz/common/gpu/context_provider.h" +#include "components/viz/common/gpu/raster_context_provider.h" +#include "components/viz/host/host_frame_sink_manager.h" +#include "services/ui/public/cpp/gpu/gpu.h" +#include "services/ui/ws2/ids.h" +#include "ui/compositor/host/host_context_factory_private.h" + +namespace ui { +namespace ws2 { + +// NOTE: resize_task_runner needs to be specialized on mac. +HostContextFactory::HostContextFactory( + ui::Gpu* gpu, + viz::HostFrameSinkManager* host_frame_sink_manager) + : gpu_(gpu), + context_factory_private_(std::make_unique<HostContextFactoryPrivate>( + kWindowServerClientId, + host_frame_sink_manager, + base::ThreadTaskRunnerHandle::Get())), + weak_ptr_factory_(this) {} + +HostContextFactory::~HostContextFactory() = default; + +ui::ContextFactoryPrivate* HostContextFactory::GetContextFactoryPrivate() { + return context_factory_private_.get(); +} + +void HostContextFactory::OnEstablishedGpuChannel( + base::WeakPtr<ui::Compositor> compositor, + scoped_refptr<gpu::GpuChannelHost> gpu_channel) { + if (!compositor) + return; + + scoped_refptr<viz::ContextProvider> context_provider = + gpu_->CreateContextProvider(std::move(gpu_channel)); + // If the binding fails, then we need to return early since the compositor + // expects a successfully initialized/bound provider. + if (context_provider->BindToCurrentThread() != gpu::ContextResult::kSuccess) { + // TODO(danakj): We should retry if the result was not kFatalFailure. + return; + } + context_factory_private_->ConfigureCompositor( + compositor, std::move(context_provider), nullptr); +} + +void HostContextFactory::CreateLayerTreeFrameSink( + base::WeakPtr<ui::Compositor> compositor) { + gpu_->EstablishGpuChannel( + base::BindOnce(&HostContextFactory::OnEstablishedGpuChannel, + weak_ptr_factory_.GetWeakPtr(), compositor)); +} + +scoped_refptr<viz::ContextProvider> +HostContextFactory::SharedMainThreadContextProvider() { + if (!shared_main_thread_context_provider_) { + scoped_refptr<gpu::GpuChannelHost> gpu_channel = + gpu_->EstablishGpuChannelSync(); + shared_main_thread_context_provider_ = + gpu_->CreateContextProvider(std::move(gpu_channel)); + if (shared_main_thread_context_provider_->BindToCurrentThread() != + gpu::ContextResult::kSuccess) + shared_main_thread_context_provider_ = nullptr; + } + return shared_main_thread_context_provider_; +} + +void HostContextFactory::RemoveCompositor(ui::Compositor* compositor) { + context_factory_private_->UnconfigureCompositor(compositor); +} + +double HostContextFactory::GetRefreshRate() const { + return 60.0; +} + +gpu::GpuMemoryBufferManager* HostContextFactory::GetGpuMemoryBufferManager() { + return gpu_->gpu_memory_buffer_manager(); +} + +cc::TaskGraphRunner* HostContextFactory::GetTaskGraphRunner() { + return raster_thread_helper_.task_graph_runner(); +} + +bool HostContextFactory::SyncTokensRequiredForDisplayCompositor() { + // This runs out-of-process, so must be using a different context from the + // UI compositor, and requires synchronization between them. + return true; +} + +} // namespace ws2 +} // namespace ui
diff --git a/services/ui/ws2/host_context_factory.h b/services/ui/ws2/host_context_factory.h new file mode 100644 index 0000000..e9f0bd89e --- /dev/null +++ b/services/ui/ws2/host_context_factory.h
@@ -0,0 +1,74 @@ +// 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 SERVICES_UI_WS2_HOST_CONTEXT_FACTORY_H_ +#define SERVICES_UI_WS2_HOST_CONTEXT_FACTORY_H_ + +#include <stdint.h> + +#include <memory> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "components/viz/common/display/renderer_settings.h" +#include "components/viz/common/gpu/context_provider.h" +#include "services/ui/public/cpp/raster_thread_helper.h" +#include "ui/compositor/compositor.h" + +namespace gpu { +class GpuChannelHost; +} + +namespace ui { + +class Gpu; +class HostContextFactoryPrivate; + +namespace ws2 { + +// ui::ContextFactory used when the WindowService is acting as the viz host. +// Internally this creates a ui::HostContextFactoryPrivate for the +// ui::ContextFactoryPrivate implementation. +class HostContextFactory : public ui::ContextFactory { + public: + HostContextFactory(ui::Gpu* gpu, + viz::HostFrameSinkManager* host_frame_sink_manager); + ~HostContextFactory() override; + + ui::ContextFactoryPrivate* GetContextFactoryPrivate(); + + private: + // Callback function for Gpu::EstablishGpuChannel(). + void OnEstablishedGpuChannel(base::WeakPtr<ui::Compositor> compositor, + scoped_refptr<gpu::GpuChannelHost> gpu_channel); + + // ContextFactory: + void CreateLayerTreeFrameSink( + base::WeakPtr<ui::Compositor> compositor) override; + scoped_refptr<viz::ContextProvider> SharedMainThreadContextProvider() + override; + void RemoveCompositor(ui::Compositor* compositor) override; + double GetRefreshRate() const override; + gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override; + cc::TaskGraphRunner* GetTaskGraphRunner() override; + void AddObserver(ui::ContextFactoryObserver* observer) override {} + void RemoveObserver(ui::ContextFactoryObserver* observer) override {} + bool SyncTokensRequiredForDisplayCompositor() override; + + ui::RasterThreadHelper raster_thread_helper_; + ui::Gpu* gpu_; + scoped_refptr<viz::ContextProvider> shared_main_thread_context_provider_; + + std::unique_ptr<HostContextFactoryPrivate> context_factory_private_; + + base::WeakPtrFactory<HostContextFactory> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(HostContextFactory); +}; + +} // namespace ws2 +} // namespace ui + +#endif // SERVICES_UI_WS2_HOST_CONTEXT_FACTORY_H_
diff --git a/services/ui/ws2/window_service.cc b/services/ui/ws2/window_service.cc index 6216107..befc350 100644 --- a/services/ui/ws2/window_service.cc +++ b/services/ui/ws2/window_service.cc
@@ -36,6 +36,9 @@ } WindowService::~WindowService() { + // WindowTreeFactory owns WindowTrees created by way of WindowTreeFactory. + // Deleting it should ensure there are no WindowTrees left. + window_tree_factory_.reset(); DCHECK(window_trees_.empty()); }
diff --git a/services/ui/ws2/window_service_unittest.cc b/services/ui/ws2/window_service_unittest.cc new file mode 100644 index 0000000..412a6a0 --- /dev/null +++ b/services/ui/ws2/window_service_unittest.cc
@@ -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. + +#include "services/ui/ws2/window_service.h" + +#include <memory> + +#include "base/run_loop.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/test/test_connector_factory.h" +#include "services/ui/public/interfaces/constants.mojom.h" +#include "services/ui/public/interfaces/window_tree.mojom.h" +#include "services/ui/ws2/gpu_interface_provider.h" +#include "services/ui/ws2/window_service_test_setup.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ui { +namespace ws2 { + +TEST(WindowServiceTest, DeleteWithClients) { + // Use |test_setup| to configure aura and other state. + WindowServiceTestSetup test_setup; + + // Create another WindowService. + TestWindowServiceDelegate test_window_service_delegate; + std::unique_ptr<WindowService> window_service_ptr = + std::make_unique<WindowService>(&test_window_service_delegate, nullptr, + test_setup.focus_controller()); + WindowService* window_service = window_service_ptr.get(); + std::unique_ptr<service_manager::TestConnectorFactory> factory = + service_manager::TestConnectorFactory::CreateForUniqueService( + std::move(window_service_ptr)); + std::unique_ptr<service_manager::Connector> connector = + factory->CreateConnector(); + + // Connect to |window_service| and ask for a new WindowTree. + ui::mojom::WindowTreeFactoryPtr window_tree_factory; + connector->BindInterface(ui::mojom::kServiceName, &window_tree_factory); + ui::mojom::WindowTreePtr window_tree; + ui::mojom::WindowTreeClientPtr client; + mojom::WindowTreeClientRequest client_request = MakeRequest(&client); + window_tree_factory->CreateWindowTree(MakeRequest(&window_tree), + std::move(client)); + + // Use FlushForTesting() to ensure WindowService processes the request. + window_tree_factory.FlushForTesting(); + + // There should be at least one WindowTree. + EXPECT_FALSE(window_service->window_trees().empty()); + + // Destroying the |window_service| should remove all the WindowTrees and + // ensure a DCHECK isn't hit in ~WindowTree. +} + +} // namespace ws2 +} // namespace ui
diff --git a/services/video_capture/device_factory_media_to_mojo_adapter.cc b/services/video_capture/device_factory_media_to_mojo_adapter.cc index e95d3ea..8fcf427 100644 --- a/services/video_capture/device_factory_media_to_mojo_adapter.cc +++ b/services/video_capture/device_factory_media_to_mojo_adapter.cc
@@ -79,10 +79,12 @@ DeviceFactoryMediaToMojoAdapter::DeviceFactoryMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureSystem> capture_system, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback) + media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback, + scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner) : service_ref_(std::move(service_ref)), capture_system_(std::move(capture_system)), jpeg_decoder_factory_callback_(std::move(jpeg_decoder_factory_callback)), + jpeg_decoder_task_runner_(std::move(jpeg_decoder_task_runner)), has_called_get_device_infos_(false), weak_factory_(this) {} @@ -158,7 +160,7 @@ ActiveDeviceEntry device_entry; device_entry.device = std::make_unique<DeviceMediaToMojoAdapter>( service_ref_->Clone(), std::move(media_device), - jpeg_decoder_factory_callback_); + jpeg_decoder_factory_callback_, jpeg_decoder_task_runner_); device_entry.binding = std::make_unique<mojo::Binding<mojom::Device>>( device_entry.device.get(), std::move(device_request)); device_entry.binding->set_connection_error_handler(base::Bind(
diff --git a/services/video_capture/device_factory_media_to_mojo_adapter.h b/services/video_capture/device_factory_media_to_mojo_adapter.h index 1104838..aaff946c 100644 --- a/services/video_capture/device_factory_media_to_mojo_adapter.h +++ b/services/video_capture/device_factory_media_to_mojo_adapter.h
@@ -26,7 +26,8 @@ DeviceFactoryMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureSystem> capture_system, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback); + media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback, + scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner); ~DeviceFactoryMediaToMojoAdapter() override; // mojom::DeviceFactory implementation. @@ -65,6 +66,7 @@ const std::unique_ptr<media::VideoCaptureSystem> capture_system_; const media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback_; + scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner_; std::map<std::string, ActiveDeviceEntry> active_devices_by_id_; bool has_called_get_device_infos_;
diff --git a/services/video_capture/device_factory_provider_impl.cc b/services/video_capture/device_factory_provider_impl.cc index 930f237..f290f7c 100644 --- a/services/video_capture/device_factory_provider_impl.cc +++ b/services/video_capture/device_factory_provider_impl.cc
@@ -4,6 +4,8 @@ #include "services/video_capture/device_factory_provider_impl.h" +#include "base/task_scheduler/post_task.h" +#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "media/capture/video/fake_video_capture_device_factory.h" #include "media/capture/video/video_capture_buffer_pool.h" #include "media/capture/video/video_capture_buffer_tracker.h" @@ -15,26 +17,102 @@ namespace video_capture { +// Intended usage of this class is to instantiate on any sequence, and then +// operate and release the instance on the task runner exposed via +// GetTaskRunner() via WeakPtrs provided via GetWeakPtr(). To this end, +// GetTaskRunner() and GetWeakPtr() can be called from any sequence, typically +// the same as the one calling the constructor. +class DeviceFactoryProviderImpl::GpuDependenciesContext { + public: + GpuDependenciesContext() : weak_factory_for_gpu_io_thread_(this) { + gpu_io_task_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::TaskPriority::BACKGROUND, base::MayBlock()}); + } + + ~GpuDependenciesContext() { + DCHECK(gpu_io_task_runner_->RunsTasksInCurrentSequence()); + } + + base::WeakPtr<GpuDependenciesContext> GetWeakPtr() { + return weak_factory_for_gpu_io_thread_.GetWeakPtr(); + } + + scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() { + return gpu_io_task_runner_; + } + + gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() { + return gpu_memory_buffer_manager_.get(); + } + + void InjectGpuDependencies( + ui::mojom::GpuMemoryBufferFactoryPtrInfo memory_buffer_factory_info, + mojom::AcceleratorFactoryPtrInfo accelerator_factory_info) { + DCHECK(gpu_io_task_runner_->RunsTasksInCurrentSequence()); + accelerator_factory_.Bind(std::move(accelerator_factory_info)); + +// Since the instance of ui::ClientGpuMemoryBufferManager seems kind of +// expensive, we only create it on platforms where it gets actually used. +#if defined(OS_CHROMEOS) + ui::mojom::GpuMemoryBufferFactoryPtr memory_buffer_factory; + memory_buffer_factory.Bind(std::move(memory_buffer_factory_info)); + gpu_memory_buffer_manager_ = + std::make_unique<ui::ClientGpuMemoryBufferManager>( + std::move(memory_buffer_factory)); +#endif + } + + void CreateJpegDecodeAccelerator( + media::mojom::JpegDecodeAcceleratorRequest request) { + DCHECK(gpu_io_task_runner_->RunsTasksInCurrentSequence()); + if (!accelerator_factory_) + return; + accelerator_factory_->CreateJpegDecodeAccelerator(std::move(request)); + } + + void CreateJpegEncodeAccelerator( + media::mojom::JpegEncodeAcceleratorRequest request) { + DCHECK(gpu_io_task_runner_->RunsTasksInCurrentSequence()); + if (!accelerator_factory_) + return; + accelerator_factory_->CreateJpegEncodeAccelerator(std::move(request)); + } + + private: + // Task runner for operating |accelerator_factory_| and + // |gpu_memory_buffer_manager_| on. This must be a different thread from the + // main service thread in order to avoid a deadlock during shutdown where + // the main service thread joins a video capture device thread that, in turn, + // will try to post the release of the jpeg decoder to the thread it is + // operated on. + scoped_refptr<base::SequencedTaskRunner> gpu_io_task_runner_; + mojom::AcceleratorFactoryPtr accelerator_factory_; + std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_; + base::WeakPtrFactory<GpuDependenciesContext> weak_factory_for_gpu_io_thread_; +}; + DeviceFactoryProviderImpl::DeviceFactoryProviderImpl( std::unique_ptr<service_manager::ServiceContextRef> service_ref, base::Callback<void(float)> set_shutdown_delay_cb) : service_ref_(std::move(service_ref)), - set_shutdown_delay_cb_(std::move(set_shutdown_delay_cb)), - weak_factory_(this) {} + set_shutdown_delay_cb_(std::move(set_shutdown_delay_cb)) {} -DeviceFactoryProviderImpl::~DeviceFactoryProviderImpl() {} +DeviceFactoryProviderImpl::~DeviceFactoryProviderImpl() { + factory_bindings_.CloseAllBindings(); + device_factory_.reset(); + gpu_dependencies_context_->GetTaskRunner()->DeleteSoon( + FROM_HERE, std::move(gpu_dependencies_context_)); +} void DeviceFactoryProviderImpl::InjectGpuDependencies( ui::mojom::GpuMemoryBufferFactoryPtr memory_buffer_factory, mojom::AcceleratorFactoryPtr accelerator_factory) { - accelerator_factory_ = std::move(accelerator_factory); -// Since the instance of ui::ClientGpuMemoryBufferManager seems kind of -// expensive, we only create it on platforms where it gets actually used. -#if defined(OS_CHROMEOS) - gpu_memory_buffer_manager_ = - std::make_unique<ui::ClientGpuMemoryBufferManager>( - std::move(memory_buffer_factory)); -#endif + LazyInitializeGpuDependenciesContext(); + gpu_dependencies_context_->GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&GpuDependenciesContext::InjectGpuDependencies, + gpu_dependencies_context_->GetWeakPtr(), + memory_buffer_factory.PassInterface(), + accelerator_factory.PassInterface())); } void DeviceFactoryProviderImpl::ConnectToDeviceFactory( @@ -47,23 +125,31 @@ set_shutdown_delay_cb_.Run(seconds); } +void DeviceFactoryProviderImpl::LazyInitializeGpuDependenciesContext() { + if (!gpu_dependencies_context_) + gpu_dependencies_context_ = std::make_unique<GpuDependenciesContext>(); +} + void DeviceFactoryProviderImpl::LazyInitializeDeviceFactory() { if (device_factory_) return; + LazyInitializeGpuDependenciesContext(); + // Create the platform-specific device factory. // The task runner passed to CreateFactory is used for things that need to // happen on a "UI thread equivalent", e.g. obtaining screen rotation on // Chrome OS. std::unique_ptr<media::VideoCaptureDeviceFactory> media_device_factory = media::VideoCaptureDeviceFactory::CreateFactory( - base::ThreadTaskRunnerHandle::Get(), gpu_memory_buffer_manager_.get(), + base::ThreadTaskRunnerHandle::Get(), + gpu_dependencies_context_->GetGpuMemoryBufferManager(), base::BindRepeating( - &DeviceFactoryProviderImpl::CreateJpegDecodeAccelerator, - weak_factory_.GetWeakPtr()), + &GpuDependenciesContext::CreateJpegDecodeAccelerator, + gpu_dependencies_context_->GetWeakPtr()), base::BindRepeating( - &DeviceFactoryProviderImpl::CreateJpegEncodeAccelerator, - weak_factory_.GetWeakPtr())); + &GpuDependenciesContext::CreateJpegEncodeAccelerator, + gpu_dependencies_context_->GetWeakPtr())); auto video_capture_system = std::make_unique<media::VideoCaptureSystemImpl>( std::move(media_device_factory)); @@ -72,22 +158,9 @@ std::make_unique<DeviceFactoryMediaToMojoAdapter>( service_ref_->Clone(), std::move(video_capture_system), base::BindRepeating( - &DeviceFactoryProviderImpl::CreateJpegDecodeAccelerator, - weak_factory_.GetWeakPtr()))); -} - -void DeviceFactoryProviderImpl::CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest request) { - if (!accelerator_factory_) - return; - accelerator_factory_->CreateJpegDecodeAccelerator(std::move(request)); -} - -void DeviceFactoryProviderImpl::CreateJpegEncodeAccelerator( - media::mojom::JpegEncodeAcceleratorRequest request) { - if (!accelerator_factory_) - return; - accelerator_factory_->CreateJpegEncodeAccelerator(std::move(request)); + &GpuDependenciesContext::CreateJpegDecodeAccelerator, + gpu_dependencies_context_->GetWeakPtr()), + gpu_dependencies_context_->GetTaskRunner())); } } // namespace video_capture
diff --git a/services/video_capture/device_factory_provider_impl.h b/services/video_capture/device_factory_provider_impl.h index de633d4..33be171 100644 --- a/services/video_capture/device_factory_provider_impl.h +++ b/services/video_capture/device_factory_provider_impl.h
@@ -7,7 +7,7 @@ #include <memory> -#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" +#include "base/threading/thread.h" #include "media/capture/video/video_capture_jpeg_decoder.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/connector.h" @@ -32,20 +32,16 @@ void SetShutdownDelayInSeconds(float seconds) override; private: + class GpuDependenciesContext; + + void LazyInitializeGpuDependenciesContext(); void LazyInitializeDeviceFactory(); - void CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest request); - void CreateJpegEncodeAccelerator( - media::mojom::JpegEncodeAcceleratorRequest request); mojo::BindingSet<mojom::DeviceFactory> factory_bindings_; std::unique_ptr<mojom::DeviceFactory> device_factory_; - const std::unique_ptr<service_manager::ServiceContextRef> service_ref_; - mojom::AcceleratorFactoryPtr accelerator_factory_; - std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_; + std::unique_ptr<GpuDependenciesContext> gpu_dependencies_context_; base::Callback<void(float)> set_shutdown_delay_cb_; - base::WeakPtrFactory<DeviceFactoryProviderImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(DeviceFactoryProviderImpl); };
diff --git a/services/video_capture/device_media_to_mojo_adapter.cc b/services/video_capture/device_media_to_mojo_adapter.cc index 49804b0b..8b5b60d 100644 --- a/services/video_capture/device_media_to_mojo_adapter.cc +++ b/services/video_capture/device_media_to_mojo_adapter.cc
@@ -16,7 +16,7 @@ namespace { std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( - scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner, + scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback, media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb, base::RepeatingCallback<void(const std::string&)> send_log_message_cb) { @@ -32,10 +32,12 @@ DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureDevice> device, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback) + media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback, + scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner) : service_ref_(std::move(service_ref)), device_(std::move(device)), jpeg_decoder_factory_callback_(std::move(jpeg_decoder_factory_callback)), + jpeg_decoder_task_runner_(std::move(jpeg_decoder_task_runner)), device_started_(false), weak_factory_(this) {} @@ -67,12 +69,13 @@ auto device_client = std::make_unique<media::VideoCaptureDeviceClient>( std::move(media_receiver), buffer_pool, base::BindRepeating( - &CreateGpuJpegDecoder, base::ThreadTaskRunnerHandle::Get(), + &CreateGpuJpegDecoder, jpeg_decoder_task_runner_, jpeg_decoder_factory_callback_, - base::BindRepeating(&media::VideoFrameReceiver::OnFrameReadyInBuffer, - receiver_->GetWeakPtr()), - base::BindRepeating(&media::VideoFrameReceiver::OnLog, - receiver_->GetWeakPtr()))); + media::BindToCurrentLoop(base::BindRepeating( + &media::VideoFrameReceiver::OnFrameReadyInBuffer, + receiver_->GetWeakPtr())), + media::BindToCurrentLoop(base::BindRepeating( + &media::VideoFrameReceiver::OnLog, receiver_->GetWeakPtr())))); device_->AllocateAndStart(requested_settings, std::move(device_client)); device_started_ = true;
diff --git a/services/video_capture/device_media_to_mojo_adapter.h b/services/video_capture/device_media_to_mojo_adapter.h index fb218bf..c238258 100644 --- a/services/video_capture/device_media_to_mojo_adapter.h +++ b/services/video_capture/device_media_to_mojo_adapter.h
@@ -25,7 +25,8 @@ DeviceMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureDevice> device, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback); + media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback, + scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner); ~DeviceMediaToMojoAdapter() override; // mojom::Device implementation. @@ -53,6 +54,7 @@ const std::unique_ptr<media::VideoCaptureDevice> device_; const media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback_; + scoped_refptr<base::SequencedTaskRunner> jpeg_decoder_task_runner_; std::unique_ptr<ReceiverMojoToMediaAdapter> receiver_; bool device_started_; base::ThreadChecker thread_checker_;
diff --git a/services/video_capture/device_media_to_mojo_adapter_unittest.cc b/services/video_capture/device_media_to_mojo_adapter_unittest.cc index 5c24915a6..939fadb 100644 --- a/services/video_capture/device_media_to_mojo_adapter_unittest.cc +++ b/services/video_capture/device_media_to_mojo_adapter_unittest.cc
@@ -28,7 +28,8 @@ mock_device_ptr_ = mock_device.get(); adapter_ = std::make_unique<DeviceMediaToMojoAdapter>( std::unique_ptr<service_manager::ServiceContextRef>(), - std::move(mock_device), base::DoNothing()); + std::move(mock_device), base::DoNothing(), + base::ThreadTaskRunnerHandle::Get()); } void TearDown() override {
diff --git a/services/video_capture/test/mock_device_test.cc b/services/video_capture/test/mock_device_test.cc index 24c26466..1d1cca2 100644 --- a/services/video_capture/test/mock_device_test.cc +++ b/services/video_capture/test/mock_device_test.cc
@@ -32,7 +32,7 @@ mock_device_factory_adapter_ = std::make_unique<DeviceFactoryMediaToMojoAdapter>( ref_factory_.CreateRef(), std::move(video_capture_system), - base::DoNothing()); + base::DoNothing(), base::ThreadTaskRunnerHandle::Get()); mock_factory_binding_ = std::make_unique<mojo::Binding<mojom::DeviceFactory>>( mock_device_factory_adapter_.get(), mojo::MakeRequest(&factory_));
diff --git a/skia/ext/fontmgr_default_android.cc b/skia/ext/fontmgr_default_android.cc index 7a6ad44..1b563374 100644 --- a/skia/ext/fontmgr_default_android.cc +++ b/skia/ext/fontmgr_default_android.cc
@@ -4,7 +4,7 @@ #include "skia/ext/fontmgr_default_android.h" -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontMgr_android.h" namespace {
diff --git a/skia/ext/fontmgr_default_fuchsia.cc b/skia/ext/fontmgr_default_fuchsia.cc index ba73954..582e5a2c 100644 --- a/skia/ext/fontmgr_default_fuchsia.cc +++ b/skia/ext/fontmgr_default_fuchsia.cc
@@ -4,8 +4,8 @@ #include "skia/ext/fontmgr_default_fuchsia.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontConfigInterface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontMgr_empty.h" namespace {
diff --git a/skia/ext/fontmgr_default_linux.cc b/skia/ext/fontmgr_default_linux.cc index 22430e4..1885ba6 100644 --- a/skia/ext/fontmgr_default_linux.cc +++ b/skia/ext/fontmgr_default_linux.cc
@@ -4,8 +4,8 @@ #include "skia/ext/fontmgr_default_linux.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontConfigInterface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontMgr_FontConfigInterface.h" namespace {
diff --git a/skia/ext/fontmgr_default_win.cc b/skia/ext/fontmgr_default_win.cc index 5e480d3..9d3b870f 100644 --- a/skia/ext/fontmgr_default_win.cc +++ b/skia/ext/fontmgr_default_win.cc
@@ -4,7 +4,7 @@ #include "skia/ext/fontmgr_default_win.h" -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkTypeface_win.h" namespace {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 78d9f18..e1836e4 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -820,9 +820,6 @@ ], "gtest_tests": [ { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter" - ], "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -989,9 +986,6 @@ ], "gtest_tests": [ { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter" - ], "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [ @@ -1129,9 +1123,6 @@ ], "gtest_tests": [ { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter" - ], "swarming": { "can_use_on_swarming_builders": true }, @@ -1852,43 +1843,6 @@ }, "test": "wm_unittests" } - ], - "isolated_scripts": [ - { - "args": [ - "--browser=exact", - "--browser-executable=./test_chrome", - "--xvfb", - "--skip=scripts_smoke_unittest.ScriptsSmokeTest.testRunTelemetryBenchmarkAsGoogletest", - "--skip=benchmarks.benchmark_smoke_unittest.BenchmarkSmokeTest.v8.runtime_stats.top_25" - ], - "isolate_name": "telemetry_perf_unittests", - "name": "telemetry_perf_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "hard_timeout": 960, - "shards": 12 - } - }, - { - "args": [ - "--browser=exact", - "--browser-executable=./test_chrome", - "--jobs=1", - "--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForElement", - "--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForElementWithWrongText", - "--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForJavaScriptCondition", - "--skip=telemetry.internal.actions.key_event_unittest.KeyPressActionTest.testPressEndAndHome", - "--skip=telemetry.internal.actions.repeatable_scroll_unittest.RepeatableScrollActionTest.testRepeatableScrollActionNoRepeats", - "--skip=telemetry.page.page_run_end_to_end_unittest.ActualPageRunEndToEndTests.testTrafficSettings" - ], - "isolate_name": "telemetry_unittests", - "name": "telemetry_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 4 - } - } ] }, "Mojo Linux": { @@ -5692,6 +5646,31 @@ "io_timeout": 3600, "shards": 12 } + }, + { + "args": [ + "--jobs=1", + "--browser=cros-chrome", + "--remote=127.0.0.1", + "--remote-ssh-port=9222", + "--skip=telemetry.core.cros_interface_unittest.CrOSInterfaceTest.testGetFileNonExistent", + "--skip=telemetry.internal.app.android_app_unittest.AndroidAppTest.testWebView" + ], + "isolate_name": "telemetry_unittests", + "name": "telemetry_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ], + "hard_timeout": 3600, + "io_timeout": 3600, + "shards": 6 + } } ] },
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 28a9efde..b746325 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -538,9 +538,6 @@ ], "gtest_tests": [ { - "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter" - ], "swarming": { "can_use_on_swarming_builders": true, "dimension_sets": [
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index d65b30d..089c4de 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -57,7 +57,6 @@ source_set("fuchsia_filters") { data = [ - "//testing/buildbot/filters/fuchsia.base_unittests.filter", "//testing/buildbot/filters/fuchsia.content_unittests.filter", "//testing/buildbot/filters/fuchsia.ipc_tests.filter", "//testing/buildbot/filters/fuchsia.mojo_unittests.filter",
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter deleted file mode 100644 index 8709b33..0000000 --- a/testing/buildbot/filters/fuchsia.base_unittests.filter +++ /dev/null
@@ -1 +0,0 @@ -# TODO(fuchsia): Being ported, see https://crbug.com/706592.
diff --git a/testing/buildbot/filters/mash.browser_tests.filter b/testing/buildbot/filters/mash.browser_tests.filter index fedf0620..7c471c5 100644 --- a/testing/buildbot/filters/mash.browser_tests.filter +++ b/testing/buildbot/filters/mash.browser_tests.filter
@@ -275,4 +275,9 @@ # supported in mash. crbug/834775 -DisplayPrefsBrowserTest.* +# Picture-in-Picture does not work with mash because VideoSurfaceLayer is +# disabled. +# https://crbug.com/827327 +-PictureInPictureWindowControllerBrowserTest.* + # See comment at top of file regarding adding test exclusions.
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index c93ced4..7ce5a21 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -85,11 +85,6 @@ -ExtensionManagementTest.ExternalUrlUpdate -ExtensionManagementTest.PolicyOverridesUserInstall -# components/image_fetcher/core/image_fetcher_impl.cc still uses URLFetcher. -# https://crbug.com/843205 --ImageFetcherImplBrowserTest.MultipleFetch --ImageFetcherImplBrowserTest.NormalFetch - # components/payments/core/payment_manifest_downloader.cc still uses # URLFetcher. # https://crbug.com/853778 @@ -116,6 +111,10 @@ -PPAPINaClPNaClNonSfiTest.TCPServerSocketPrivate -PPAPINaClPNaClNonSfiTest.TCPSocket -PPAPINaClPNaClNonSfiTest.TCPSocketPrivate +# This test fails flakily. Only enable it once +# SocketExtensionWithDnsLookupFunction::StartDnsLookup uses the Mojo +# HostResolver API. +-SocketApiTest.SocketUDPExtension # Uncategorized PPAPI timeouts or test failures. -OutOfProcessPPAPITest.HostResolver
diff --git a/testing/buildbot/filters/surface_sync.content_browsertests.filter b/testing/buildbot/filters/surface_sync.content_browsertests.filter index 09bd07d..73c94b1 100644 --- a/testing/buildbot/filters/surface_sync.content_browsertests.filter +++ b/testing/buildbot/filters/surface_sync.content_browsertests.filter
@@ -6,4 +6,5 @@ -SitePerProcess* -ScrollLatencyBrowserTest.SmoothWheelScroll -TouchInputBrowserTest.TouchHandlerConsume +-TouchInputBrowserTest.TouchHandlerNoConsume -TouchSelectionControllerClientAndroidSiteIsolationTest.BasicSelectionIsolatedIframe
diff --git a/testing/buildbot/filters/viz.android.content_browsertests.filter b/testing/buildbot/filters/viz.android.content_browsertests.filter index 07e5d89e..12165f3 100644 --- a/testing/buildbot/filters/viz.android.content_browsertests.filter +++ b/testing/buildbot/filters/viz.android.content_browsertests.filter
@@ -38,6 +38,7 @@ -TouchInputBrowserTest.TouchHandlerConsume -TouchInputBrowserTest.TouchHandlerNoConsume -TouchSelectionControllerClientAndroidSiteIsolationTest.BasicSelectionIsolatedIframe +-WebContentsImplBrowserTest.NotifyFullscreenAcquired_Navigate ## Base viz.content_browsertests.filter since we cannot chain filter files # SynchronizeVisualPropertiesMessageFilter::WaitForRect() times out.
diff --git a/testing/buildbot/filters/viz.browser_tests.filter b/testing/buildbot/filters/viz.browser_tests.filter index fc3a153..8f3d06f 100644 --- a/testing/buildbot/filters/viz.browser_tests.filter +++ b/testing/buildbot/filters/viz.browser_tests.filter
@@ -2,14 +2,7 @@ # http://crbug.com/807465 -ArcAccessibilityHelperBridgeBrowserTest.PreferenceChange -# Tab Capture on Viz fails at CopyOutputRequest: crbug.com/810389 --FeedbackTest.* --LoginFeedbackTest.Basic +# Timing out in extensions::ResultCatcher::GetNextResult(). +# https://crbug.com/854798 -TabCaptureApiPixelTest.OffscreenTabEndToEnd -TabCaptureApiPixelTest.OffscreenTabEvilTests - -# Mac Flaking with missing browser. https://crbug.com/842664 --IndependentOTRProfileManagerTest.DeleteImmediatelyWhenBrowsersAlreadyClosed - -# Mac Frequent WindowServer crashes. Not just Viz. https://crbug.com/828031 --ConstrainedWebDialogBrowserTest.*
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 51f18fe..4ba67f2b 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -401,6 +401,21 @@ 'shards': 12, }, }, + 'telemetry_unittests': { + 'args': [ + '--jobs=1', + '--browser=cros-chrome', + # By default, CrOS VMs' ssh servers listen on local port 9222. + '--remote=127.0.0.1', + '--remote-ssh-port=9222', + '--skip=telemetry.core.cros_interface_unittest.CrOSInterfaceTest.testGetFileNonExistent', + '--skip=telemetry.internal.app.android_app_unittest.AndroidAppTest.testWebView', + ], + 'swarming': { + 'hard_timeout': 1200, + 'shards': 6, + }, + }, }, 'chromeos_remote_device_isolated_tests': { @@ -903,11 +918,7 @@ }, 'fuchsia_gtests': { - 'base_unittests': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter', - ], - }, + 'base_unittests': {}, 'content_unittests': { 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter', @@ -921,8 +932,7 @@ '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ipc_tests.filter', ], }, - 'media_unittests': { - }, + 'media_unittests': {}, 'mojo_unittests': { 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter', @@ -1862,38 +1872,6 @@ 'wayland_client_perftests': {}, }, - 'mojo_chromiumos_isolated_scripts': { - 'telemetry_perf_unittests': { - 'args': [ - '--browser=exact', - '--browser-executable=./test_chrome', - '--xvfb', - '--skip=scripts_smoke_unittest.ScriptsSmokeTest.testRunTelemetryBenchmarkAsGoogletest', - '--skip=benchmarks.benchmark_smoke_unittest.BenchmarkSmokeTest.v8.runtime_stats.top_25', - ], - 'swarming': { - 'hard_timeout': 960, - 'shards': 12, - }, - }, - 'telemetry_unittests': { - 'args': [ - '--browser=exact', - '--browser-executable=./test_chrome', - '--jobs=1', - '--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForElement', - '--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForElementWithWrongText', - '--skip=telemetry.internal.actions.action_runner_unittest.ActionRunnerTest.testWaitForJavaScriptCondition', - '--skip=telemetry.internal.actions.key_event_unittest.KeyPressActionTest.testPressEndAndHome', - '--skip=telemetry.internal.actions.repeatable_scroll_unittest.RepeatableScrollActionTest.testRepeatableScrollActionNoRepeats', - '--skip=telemetry.page.page_run_end_to_end_unittest.ActualPageRunEndToEndTests.testTrafficSettings', - ], - 'swarming': { - 'shards': 4, - }, - }, - }, - 'non_android_chromium_gtests': { 'accessibility_unittests': {}, 'app_shell_unittests': {},
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 7292463..2c469e1 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -2397,7 +2397,6 @@ ], 'test_suites': { 'gtest_tests': 'mojo_chromiumos_fyi_gtests', - 'isolated_scripts': 'mojo_chromiumos_isolated_scripts', }, }, 'Mojo Linux': {
diff --git a/testing/test_env.py b/testing/test_env.py index 51de8fa..1b70351 100755 --- a/testing/test_env.py +++ b/testing/test_env.py
@@ -7,6 +7,7 @@ import io import os +import signal import stat import subprocess import sys @@ -181,6 +182,7 @@ reader: process = subprocess.Popen(argv, env=env, cwd=cwd, stdout=writer, stderr=subprocess.STDOUT) + forward_signals([process]) while process.poll() is None: sys.stdout.write(reader.read()) time.sleep(0.1) @@ -190,6 +192,28 @@ return process.returncode +def forward_signals(procs): + """Forwards unix's SIGTERM or win's CTRL_BREAK_EVENT to the given processes. + + This plays nicely with swarming's timeout handling. See also + https://chromium.googlesource.com/infra/luci/luci-py/+/master/appengine/swarming/doc/Bot.md#graceful-termination_aka-the-sigterm-and-sigkill-dance + + Args: + procs: A list of subprocess.Popen objects representing child processes. + """ + assert all(isinstance(p, subprocess.Popen) for p in procs) + def _sig_handler(sig, _): + for p in procs: + if sig == signal.SIGBREAK: + p.send_signal(signal.CTRL_BREAK_EVENT) + else: + p.send_signal(sig) + if sys.platform == 'win32': + signal.signal(signal.SIGBREAK, _sig_handler) + else: + signal.signal(signal.SIGTERM, _sig_handler) + + def run_executable(cmd, env, stdoutfile=None): """Runs an executable with: - CHROME_HEADLESS set to indicate that the test is running on a @@ -260,13 +284,16 @@ get_sanitizer_symbolize_command(executable_path=cmd[0]), env=env, stdin=p1.stdout) p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. + forward_signals([p1, p2]) p1.wait() p2.wait() # Also feed the out-of-band JSON output to the symbolizer script. symbolize_snippets_in_json(cmd, env) return p1.returncode else: - return subprocess.call(cmd, env=env) + p = subprocess.Popen(cmd, env=env) + forward_signals([p]) + return p.wait() except OSError: print >> sys.stderr, 'Failed to start %s' % cmd raise
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 75a476a..ea80c06 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -350,6 +350,21 @@ ] } ], + "AsyncNavigationIntercept": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AsyncNavigationIntercept" + ] + } + ] + } + ], "AudioService": [ { "platforms": [ @@ -359,13 +374,12 @@ ], "experiments": [ { - "name": "AudioProcess_LaunchOnStartup_v2", + "name": "AudioProcess", "params": { - "teardown_timeout_s": "0" + "teardown_timeout_s": "300" }, "enable_features": [ "AudioServiceAudioStreams", - "AudioServiceLaunchOnStartup", "AudioServiceOutOfProcess" ] }
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 0aa0fa32..fa59ae6e 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -1,7 +1,6 @@ # These tests currently fail when they run with --enable-blink-features=LayoutNG # See https://crbug.com/591099. - # Need support for Range.getClientRects() and Range.getBoundingClientRect() crbug.com/755750 accessibility/selection-affinity.html [ Failure ] @@ -110,11 +109,7 @@ crbug.com/591099 compositing/squashing/add-remove-squashed-layers.html [ Failure ] crbug.com/591099 css1/box_properties/float_on_text_elements.html [ Failure ] crbug.com/591099 css1/classification/list_style_image.html [ Failure ] -crbug.com/591099 css2.1/20110323/margin-applies-to-008.htm [ Failure ] crbug.com/591099 css2.1/t0510-c25-pseudo-elmnt-00-c.html [ Failure ] -crbug.com/591099 css2.1/t0905-c414-flt-wrap-01-d-g.html [ Failure ] -crbug.com/591099 css2.1/t100801-c544-valgn-00-a-ag.html [ Failure ] -crbug.com/591099 css2.1/t100801-c544-valgn-03-d-agi.html [ Failure ] crbug.com/591099 css2.1/t1202-counter-04-b.html [ Failure ] crbug.com/591099 css2.1/t1202-counters-04-b.html [ Failure ] crbug.com/591099 css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change.html [ Failure ] @@ -308,6 +303,7 @@ crbug.com/591099 external/wpt/css/css-writing-modes/text-orientation-script-001c.html [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/vertical-alignment-003.xht [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/vertical-alignment-009.xht [ Pass ] +crbug.com/851075 external/wpt/css/cssom-view/elementFromPoint-mixed-font-sizes.html [ Failure ] crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Pass ] crbug.com/591099 external/wpt/css/selectors/focus-within-004.html [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html [ Pass ] @@ -340,7 +336,6 @@ crbug.com/591099 external/wpt/editing/run/justifyfull.html [ Pass ] crbug.com/591099 external/wpt/editing/run/justifyright.html [ Pass ] crbug.com/591099 external/wpt/editing/run/multitest.html [ Pass ] -crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Pass ] crbug.com/591099 external/wpt/html-media-capture/capture_audio_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_image_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_video_cancel-manual.html [ Failure ] @@ -460,7 +455,6 @@ crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-margin-auto.html [ Failure ] crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-margin-percentage.html [ Failure ] crbug.com/591099 fast/css/import_with_baseurl.html [ Failure Pass ] -crbug.com/591099 fast/css/margin-top-bottom-dynamic.html [ Failure ] crbug.com/591099 fast/css/negative-text-indent-in-inline-block.html [ Failure ] crbug.com/591099 fast/css/opacity-float.html [ Pass ] crbug.com/591099 fast/css/outline-narrowLine.html [ Failure ] @@ -494,9 +488,6 @@ crbug.com/591099 fast/dynamic/text-combine.html [ Failure ] crbug.com/591099 fast/encoding/utf-16-big-endian.html [ Failure ] crbug.com/591099 fast/encoding/utf-16-little-endian.html [ Failure ] -crbug.com/591099 fast/events/background-tab-on-submit-ctrl-click.html [ Failure ] -crbug.com/591099 fast/events/background-tab-on-submit-synthesized-ctrl-click.html [ Failure ] -crbug.com/714962 fast/events/event-on-culled_inline.html [ Failure ] crbug.com/591099 fast/events/mouse-relative-position.html [ Failure ] crbug.com/591099 fast/events/onclick-list-marker.html [ Failure ] crbug.com/591099 fast/events/select-element.html [ Failure ] @@ -508,7 +499,7 @@ crbug.com/591099 fast/forms/form-hides-table.html [ Failure ] crbug.com/591099 fast/forms/select/select-initial-position.html [ Failure ] crbug.com/591099 fast/forms/select/select-style.html [ Failure ] -crbug.com/591099 fast/forms/text-control-intrinsic-widths.html [ Timeout ] +crbug.com/591099 fast/forms/text-control-intrinsic-widths.html [ Pass Timeout ] crbug.com/591099 fast/frames/iframe-with-frameborder.html [ Failure ] crbug.com/591099 fast/gradients/list-item-gradient.html [ Failure ] crbug.com/591099 fast/gradients/unprefixed-list-item-gradient.html [ Failure ] @@ -524,7 +515,6 @@ crbug.com/591099 fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ] crbug.com/591099 fast/inline/inline-offsetLeft-relpos.html [ Failure ] crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ] -crbug.com/591099 fast/inline/justify-emphasis-inline-box.html [ Failure ] crbug.com/591099 fast/inline/nested-text-descendants.html [ Failure ] crbug.com/591099 fast/inline/outline-continuations.html [ Failure ] crbug.com/714962 fast/inline/outline-offset.html [ Failure ] @@ -574,7 +564,7 @@ crbug.com/591099 fast/sub-pixel/inline-block-with-padding.html [ Failure ] crbug.com/591099 fast/sub-pixel/sub-pixel-border-2.html [ Failure ] crbug.com/591099 fast/table/032.html [ Failure ] -crbug.com/591099 fast/table/background-gradient-border-collapsed.html [ Failure ] +crbug.com/591099 fast/table/background-gradient-border-collapsed.html [ Failure Pass ] crbug.com/591099 fast/table/border-collapsing/004-vertical.html [ Failure ] crbug.com/591099 fast/table/border-collapsing/composited-cell-collapsed-border.html [ Failure ] crbug.com/591099 fast/table/column-in-inline.html [ Failure ] @@ -584,7 +574,7 @@ crbug.com/591099 fast/table/height-percent-test-vertical.html [ Failure ] crbug.com/591099 fast/table/large-shrink-wrapped-width.html [ Failure ] crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure Pass ] -crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure Pass ] +crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure ] crbug.com/591099 fast/table/percent-height-replaced-content-in-cell.html [ Failure ] crbug.com/591099 fast/table/table-display-types-vertical.html [ Failure ] crbug.com/591099 fast/table/unbreakable-images-quirk.html [ Failure ] @@ -599,8 +589,6 @@ crbug.com/796943 fast/text/international/shape-across-elements-simple.html [ Pass ] crbug.com/591099 fast/text/international/text-combine-image-test.html [ Failure ] crbug.com/591099 fast/text/orientation-sideways.html [ Failure ] -crbug.com/591099 fast/text/place-ellipsis-in-inline-block-adjacent-float-2.html [ Failure ] -crbug.com/591099 fast/text/place-ellipsis-in-inline-block-adjacent-float.html [ Failure ] crbug.com/591099 fast/text/text-combine-first-line-crash.html [ Crash ] crbug.com/591099 fast/text/unicode-fallback-font.html [ Failure ] crbug.com/591099 fast/text/whitespace/018.html [ Failure ] @@ -627,10 +615,9 @@ crbug.com/591099 fast/writing-mode/text-combine-justify.html [ Failure ] crbug.com/591099 fast/writing-mode/text-combine-line-break.html [ Failure ] crbug.com/591099 fast/writing-mode/text-combine-various-fonts.html [ Failure ] -crbug.com/591099 fast/writing-mode/vertical-lr-replaced-selection.html [ Failure ] +crbug.com/591099 fast/writing-mode/vertical-lr-replaced-selection.html [ Failure Pass ] crbug.com/591099 fullscreen/full-screen-with-flex-item.html [ Failure ] crbug.com/591099 hittesting/border-hittest-inlineFlowBox.html [ Failure ] -crbug.com/714962 hittesting/culled-inline.html [ Failure ] crbug.com/591099 hittesting/inline-with-clip-path.html [ Failure ] crbug.com/591099 html/details_summary/details-writing-mode-align-center.html [ Failure ] crbug.com/591099 html/details_summary/details-writing-mode-align-left.html [ Failure ] @@ -651,7 +638,7 @@ crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations.js [ Failure ] crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.js [ Failure ] crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure ] -crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Pass Timeout ] +crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Timeout ] crbug.com/591099 http/tests/incremental/slow-utf8-text.pl [ Pass Timeout ] crbug.com/591099 http/tests/loading/nested_bad_objects.php [ Failure ] crbug.com/591099 http/tests/loading/preload-picture-nested.html [ Failure ] @@ -759,7 +746,6 @@ crbug.com/591099 paint/invalidation/invisible-objects.html [ Failure ] crbug.com/591099 paint/invalidation/lines-with-layout-delta.html [ Failure ] crbug.com/591099 paint/invalidation/list-marker-2.html [ Failure ] -crbug.com/591099 paint/invalidation/list-marker.html [ Failure ] crbug.com/591099 paint/invalidation/make-children-non-inline.html [ Failure ] crbug.com/591099 paint/invalidation/mix-blend-mode-separate-stacking-context.html [ Failure ] crbug.com/824918 paint/invalidation/multicol/multicol-repaint.html [ Failure ] @@ -876,8 +862,6 @@ crbug.com/591099 paint/invalidation/vertical-rl-as-paint-container.html [ Failure ] crbug.com/591099 paint/invalidation/window-resize/window-resize-centered-inline-under-fixed-pos.html [ Failure ] crbug.com/591099 paint/invalidation/window-resize/window-resize-vertical-writing-mode.html [ Failure ] -crbug.com/591099 paint/markers/active-suggestion-marker-split.html [ Failure ] -crbug.com/591099 paint/markers/composition-marker-split.html [ Failure ] crbug.com/591099 paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers.html [ Failure ] crbug.com/591099 paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers.html [ Failure ] crbug.com/591099 paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers.html [ Failure ] @@ -904,7 +888,6 @@ crbug.com/591099 svg/custom/inline-svg-use-available-width-in-stf.html [ Failure ] crbug.com/591099 svg/custom/object-sizing-no-width-height.xhtml [ Failure ] crbug.com/591099 svg/custom/stf-container-with-intrinsic-ratio-svg.html [ Failure ] -crbug.com/591099 svg/custom/text-match-highlight.html [ Failure ] crbug.com/591099 svg/filters/feTurbulence-bad-seeds.html [ Failure ] crbug.com/591099 svg/in-html/sizing/svg-inline.html [ Failure ] crbug.com/714962 svg/text/tspan-multiple-outline.svg [ Failure ] @@ -939,13 +922,11 @@ crbug.com/591099 virtual/android/ [ Skip ] crbug.com/591099 virtual/exotic-color-space/ [ Skip ] crbug.com/591099 virtual/feature-policy-vibrate/ [ Skip ] +crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/shadow-huge-blur.html [ Pass ] crbug.com/591099 virtual/layout_ng/ [ Skip ] crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ] crbug.com/591099 virtual/mojo-blob-urls/external/wpt/FileAPI/url/sandboxed-iframe.html [ Pass ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/background-tab-on-submit-ctrl-click.html [ Failure ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/background-tab-on-submit-synthesized-ctrl-click.html [ Failure ] -crbug.com/714962 virtual/mouseevent_fractional/fast/events/event-on-culled_inline.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-relative-position.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/select-element.html [ Failure ] @@ -966,9 +947,7 @@ crbug.com/591099 virtual/stable/ [ Skip ] crbug.com/591099 virtual/threaded/ [ Skip ] crbug.com/591099 virtual/user-activation-v2/fast/dom/Window/window-lookup-precedence.html [ Failure ] -crbug.com/591099 virtual/user-activation-v2/fast/events/background-tab-on-submit-ctrl-click.html [ Failure ] -crbug.com/591099 virtual/user-activation-v2/fast/events/background-tab-on-submit-synthesized-ctrl-click.html [ Failure ] -crbug.com/591099 virtual/user-activation-v2/fast/events/event-on-culled_inline.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/event-on-culled_inline.html [ Failure Pass ] crbug.com/591099 virtual/user-activation-v2/fast/events/mouse-cursor.html [ Failure ] crbug.com/591099 virtual/user-activation-v2/fast/events/mouse-relative-position.html [ Failure ] crbug.com/591099 virtual/user-activation-v2/fast/events/onclick-list-marker.html [ Failure ] @@ -980,11 +959,6 @@ crbug.com/591099 virtual/video-surface-layer/media/media-document-audio-repaint.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/picture-in-picture/picture-in-picture-enabled.html [ Pass ] crbug.com/591099 virtual/video-surface-layer/media/video-aspect-ratio.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/video-colorspace-yuv420.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/video-colorspace-yuv422.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/video-display-toggle.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/video-layer-crash.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/video-poster-scale.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/video-replaces-poster.html [ Failure ] -crbug.com/591099 virtual/video-surface-layer/media/video-zoom.html [ Failure ] crbug.com/591099 virtual/wheelscrolllatching/ [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees index 5b9bf04..026c350 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
@@ -632,9 +632,6 @@ crbug.com/854192 fast/multicol/vertical-rl/composited-relpos-overlapping-will-change.html [ Failure ] crbug.com/854192 paint/pagination/composited-paginated-outlined-box.html [ Failure ] -# Crash due to layer bounds DCHECK. -crbug.com/854194 fast/multicol/short-columns-insane-unbreakable-content-height-crash.html [ Crash ] - # Image layers are not scaled. crbug.com/854195 images/color-profile-layer.html [ Failure ] crbug.com/854195 images/pixelated-composited.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService index 4d3917fe..72df7a7 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -6,7 +6,6 @@ Bug(none) external/wpt/html/browsers/offline/appcache/workers/appcache-worker.html [ Timeout ] crbug.com/829417 external/wpt/html/browsers/offline/appcache/workers/appcache-worker.https.html [ Timeout ] crbug.com/771118 external/wpt/service-workers/service-worker/mime-sniffing.https.html [ Failure ] -crbug.com/850839 external/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html [ Failure Crash ] # Passes on NetworkService and fails on non-NetworkService because # NetworkService isn't affected by https://crbug.com/595993.
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index 28a24f73..de2ed218 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -220,3 +220,7 @@ crbug.com/794631 http/tests/media/autoplay/document-user-activation-feature-policy-iframe-no-gesture.html [ Failure Pass Timeout ] crbug.com/794631 http/tests/media/autoplay/document-user-activation-feature-policy-same-origin.html [ Failure Pass Timeout ] crbug.com/794631 http/tests/media/autoplay/document-user-activation-iframe-delegation.html [ Failure Pass Timeout ] +crbug.com/794631 virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-delegation.html [ Failure Pass Timeout ] +crbug.com/794631 virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-disabled.html [ Failure Pass Timeout ] +crbug.com/794631 virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-gesture.html [ Failure Pass Timeout ] +crbug.com/794631 virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-iframe-delegation.html [ Failure Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 21bb728..40104ba 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -107,7 +107,6 @@ crbug.com/726075 [ Mac ] css3/filters/effect-combined-hw.html [ Pass Timeout ] crbug.com/726075 [ Mac ] virtual/gpu/fast/canvas/canvas-composite-video.html [ Pass Timeout ] crbug.com/726075 [ Mac ] virtual/gpu/fast/canvas/OffscreenCanvas-filter-in-worker.html [ Pass Timeout ] -crbug.com/845266 [ Mac ] virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Pass Timeout ] crbug.com/693568 [ Mac ] virtual/gpu/fast/canvas/canvas-imageSmoothingQuality.html [ Failure Pass Timeout ] @@ -1748,13 +1747,26 @@ crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html [ Timeout ] crbug.com/626703 virtual/outofblink-cors/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html [ Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/access-control-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/auth-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/auth-nocors-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/cookie-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/cookie-nocors-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/cors-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/cors-preflight-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/cors-preflight2-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/nocors-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/redirect-nocors-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/redirect-password-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/scheme-blob-base-https-other-https.html [ Pass Timeout ] +crbug.com/854630 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/scheme-data-base-https-other-https.html [ Pass Timeout ] crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/cross-origin-unsupported-url.html [ Timeout ] crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post.html [ Timeout ] crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url.html [ Timeout ] # Failing tests in dictionary order. crbug.com/802835 virtual/outofblink-cors/external/wpt/fetch/corb/img-mime-types-coverage.tentative.sub.html [ Failure ] -crbug.com/850839 virtual/outofblink-cors/external/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html [ Failure ] +crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html [ Failure ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html [ Failure ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-image.https.html [ Failure ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html [ Failure ] @@ -2279,8 +2291,6 @@ crbug.com/630342 virtual/mse-1mb-buffers/http/tests/media/media-source/stream_memory_tests/mediasource-appendbuffer-quota-exceeded-default-buffers.html [ Skip ] crbug.com/630342 http/tests/media/media-source/stream_memory_tests/mediasource-appendbuffer-quota-exceeded-1mb-buffers.html [ Skip ] -crbug.com/850839 virtual/service-worker-servicification/external/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html [ Failure Crash ] - # On these platforms (all but Android) media tests don't currently use gpu-accelerated (proprietary) codecs, so no # benefit to running them again with gpu acceleration enabled. crbug.com/555703 [ Linux Mac Win Fuchsia ] virtual/media-gpu-accelerated [ Skip ] @@ -2332,9 +2342,8 @@ crbug.com/574283 [ Mac ] virtual/threaded/fast/scroll-behavior/smooth-scroll/mousewheel-scroll-interrupted.html [ Skip ] crbug.com/665577 virtual/threaded/fast/scroll-behavior/overflow-scroll-root-frame-animates.html [ Pass Timeout ] -crbug.com/665577 virtual/threaded/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html [ Pass Failure ] crbug.com/665577 [ Linux Win ] virtual/threaded/fast/scroll-behavior/smooth-scroll/mousewheel-scroll-interrupted.html [ Pass Failure Timeout ] -crbug.com/665577 [ Linux Win Mac ] virtual/threaded/fast/scroll-behavior/smooth-scroll/track-scroll.html [ Pass Failure Crash ] +crbug.com/665577 [ Mac ] virtual/threaded/fast/scroll-behavior/smooth-scroll/track-scroll.html [ Pass Failure ] crbug.com/599670 [ Win ] http/tests/devtools/resource-parameters-ipv6.js [ Pass Failure ] crbug.com/472330 fast/borders/border-image-outset-split-inline-vertical-lr.html [ Failure ] @@ -2825,7 +2834,6 @@ crbug.com/626703 external/wpt/payment-request/PaymentMethodChangeEvent/methodName-attribute.https.html [ Timeout ] crbug.com/626703 external/wpt/payment-request/PaymentMethodChangeEvent/methodDetails-attribute.https.html [ Timeout ] crbug.com/626703 external/wpt/screen-orientation/orientation-reading.html [ Timeout ] -crbug.com/626703 [ Mac10.12 ] external/wpt/webaudio/idlharness.https.html [ Timeout ] crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-image.html [ Failure ] crbug.com/626703 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_parent [ Timeout ] crbug.com/626703 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_top [ Timeout ] @@ -3808,7 +3816,6 @@ crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/main-thread-scrolling-reason-added.html [ Skip ] crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html [ Skip ] crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-vertical-rl-anchors.html [ Skip ] -crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/scroll-during-selection.html [ Skip ] crbug.com/766357 virtual/threaded/fast/scroll-behavior/wheel-and-touch-scroll-use-count.html [ Pass Failure ] @@ -4731,3 +4738,5 @@ # Sheriff 2018-06-18 crbug.com/853852 [ Linux ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-wheel-block-manual.tentative.html [ Pass Timeout ] crbug.com/854053 [ Mac10.13 Debug ] virtual/threaded/fast/animationworklet/animation-worklet-scroll-timeline.html [ Pass Crash ] + +crbug.com/854599 [ Linux ] external/wpt/dom/interfaces.html?exclude=Node [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index e564cf22..48ab208 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -696,6 +696,11 @@ "args": ["--enable-features=UserActivationV2"] }, { + "prefix": "user-activation-v2", + "base": "http/tests/media/autoplay", + "args": ["--enable-features=UserActivationV2"] + }, + { "prefix": "display-compositor-pixel-dump", "base": "fast/canvas/display-compositor-pixel-dump", "args": ["--enable-display-compositor-pixel-dump",
diff --git a/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border-expected.txt b/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border-expected.txt deleted file mode 100644 index bfd9a33..0000000 --- a/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x56 - LayoutBlockFlow {HTML} at (0,0) size 800x55.52 - LayoutBlockFlow {BODY} at (10,12.63) size 780x32.89 - LayoutBlockFlow {DIV} at (0,0) size 502.50x32.89 [color=#FFFFFF] [bgcolor=#FF0000] [border: (1.25px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border.html b/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border.html deleted file mode 100644 index 2f3ce46..0000000 --- a/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border.html +++ /dev/null
@@ -1,5 +0,0 @@ -<!DOCTYPE html> -<body style="zoom: 125%"> -<div class="heightchange" style="margin-top: 10.1px; width:400px; height: 24.3125px; border-radius:10px; border:1px solid black; background-color:red; background-image:linear-gradient(to bottom, rgb(0,255,0), rgb(0,0,255)); color:white"> -</div> -</body>
diff --git a/third_party/WebKit/LayoutTests/css3/background/resources/tall-narrow-spritemap.png b/third_party/WebKit/LayoutTests/css3/background/resources/tall-narrow-spritemap.png new file mode 100644 index 0000000..f46b542 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/background/resources/tall-narrow-spritemap.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border-expected.png b/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2-expected.png similarity index 62% rename from third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border-expected.png rename to third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2-expected.png index 020d643..141132c 100644 --- a/third_party/WebKit/LayoutTests/css3/background/background-subpixel-gradient-fills-border-expected.png +++ b/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2-expected.txt b/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2-expected.txt new file mode 100644 index 0000000..100bb81 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2-expected.txt
@@ -0,0 +1,6 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x48 + LayoutBlockFlow {HTML} at (0,0) size 800x47.50 + LayoutBlockFlow {BODY} at (10,10) size 780x27.50 + LayoutBlockFlow {DIV} at (0,0) size 27.50x27.50
diff --git a/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2.html b/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2.html new file mode 100644 index 0000000..ed8626e8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/background/zoomed-background-position-accuracy-2.html
@@ -0,0 +1,16 @@ +<!doctype html> +<html> +<head> + <style type="text/css"> + .green { + background: url('resources/tall-narrow-spritemap.png') no-repeat 0px -176px; + background-size: 100%; + height: 22px; + width: 22px; + } + </style> +</head> +<body style="zoom: 125%;"> + <div class="green"></div> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/6026335.html b/third_party/WebKit/LayoutTests/editing/deleting/6026335.html index 8312d7a4..abceb676 100644 --- a/third_party/WebKit/LayoutTests/editing/deleting/6026335.html +++ b/third_party/WebKit/LayoutTests/editing/deleting/6026335.html
@@ -7,9 +7,9 @@ [ '<div contenteditable>', '<div contenteditable="false">', '<span> </span>', - '<span contenteditable>|Hello</span>', + '<span contenteditable>^Hello</span>', '</div>', - '<div>^<br></div>', + '<div>|<br></div>', '</div>', ], 'delete',
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/delete-across-editable-content-boundaries-2.html b/third_party/WebKit/LayoutTests/editing/deleting/delete-across-editable-content-boundaries-2.html index 8d20b89b..78ddec1c 100644 --- a/third_party/WebKit/LayoutTests/editing/deleting/delete-across-editable-content-boundaries-2.html +++ b/third_party/WebKit/LayoutTests/editing/deleting/delete-across-editable-content-boundaries-2.html
@@ -8,11 +8,11 @@ '<table contenteditable="false">', '<tr>', '<td>foo</td>', - '<td contenteditable>bar <span>|baz</span></td>', + '<td contenteditable>bar <span>^baz</span></td>', '<td>qux</td>', '</tr>', '</table>', - 'Editable <span>^content</span>', + 'Editable <span>|content</span>', '</div>', ], 'delete',
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 4dd8138..411eca95 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -102611,6 +102611,16 @@ {} ] ], + "background-fetch/interfaces.https.any-expected.txt": [ + [ + {} + ] + ], + "background-fetch/interfaces.https.any.worker-expected.txt": [ + [ + {} + ] + ], "background-fetch/interfaces.https.worker-expected.txt": [ [ {} @@ -102741,6 +102751,11 @@ {} ] ], + "bluetooth/idl/idlharness.tentative.window-expected.txt": [ + [ + {} + ] + ], "bluetooth/resources/bluetooth-helpers.js": [ [ {} @@ -153651,17 +153666,42 @@ {} ] ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none-expected.txt": [ + [ + {} + ] + ], "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-expected.txt": [ [ {} ] ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode-expected.txt": [ + [ + {} + ] + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode-expected.txt": [ + [ + {} + ] + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px-expected.txt": [ + [ + {} + ] + ], "html/semantics/embedded-content/the-img-element/sizes/sizes-dynamic-001-ref.html": [ [ {} ] ], - "html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html": [ + "html/semantics/embedded-content/the-img-element/sizes/support/parse-a-sizes-attribute.js": [ + [ + {} + ] + ], + "html/semantics/embedded-content/the-img-element/sizes/support/sizes-iframed.sub.html": [ [ {} ] @@ -157561,6 +157601,11 @@ {} ] ], + "interfaces/referrer-policy.idl": [ + [ + {} + ] + ], "interfaces/remote-playback.idl": [ [ {} @@ -157576,6 +157621,16 @@ {} ] ], + "interfaces/scroll-animations.idl": [ + [ + {} + ] + ], + "interfaces/secure-contexts.idl": [ + [ + {} + ] + ], "interfaces/selection-api.idl": [ [ {} @@ -157596,6 +157651,11 @@ {} ] ], + "interfaces/touch-events.idl": [ + [ + {} + ] + ], "interfaces/touchevents.idl": [ [ {} @@ -157631,7 +157691,7 @@ {} ] ], - "interfaces/web-audio-api.idl": [ + "interfaces/web-bluetooth.idl": [ [ {} ] @@ -157646,7 +157706,7 @@ {} ] ], - "interfaces/webappsec-referrer-policy.idl": [ + "interfaces/webaudio.idl": [ [ {} ] @@ -159751,11 +159811,6 @@ {} ] ], - "payment-request/historical.https-expected.txt": [ - [ - {} - ] - ], "payment-request/interfaces.https-expected.txt": [ [ {} @@ -159776,11 +159831,6 @@ {} ] ], - "payment-request/payment-request-ctor-pmi-handling.https-expected.txt": [ - [ - {} - ] - ], "payment-request/payment-response/helpers.js": [ [ {} @@ -163496,6 +163546,16 @@ {} ] ], + "scroll-animations/META.yml": [ + [ + {} + ] + ], + "scroll-animations/idlharness-expected.txt": [ + [ + {} + ] + ], "secure-contexts/META.yml": [ [ {} @@ -163531,6 +163591,11 @@ {} ] ], + "secure-contexts/idlharness.any-expected.txt": [ + [ + {} + ] + ], "secure-contexts/postMessage-helper.html": [ [ {} @@ -167611,6 +167676,11 @@ {} ] ], + "touch-events/idlharness.window-expected.txt": [ + [ + {} + ] + ], "touch-events/multi-touch-interactions.js": [ [ {} @@ -182195,21 +182265,13 @@ {} ] ], - "background-fetch/interfaces-worker.https.html": [ + "background-fetch/interfaces.https.any.js": [ [ - "/background-fetch/interfaces-worker.https.html", + "/background-fetch/interfaces.https.any.html", {} - ] - ], - "background-fetch/interfaces.https.html": [ + ], [ - "/background-fetch/interfaces.https.html", - {} - ] - ], - "background-fetch/interfaces.https.worker.js": [ - [ - "/background-fetch/interfaces.https.worker.html", + "/background-fetch/interfaces.https.any.worker.html", {} ] ], @@ -182681,6 +182743,12 @@ {} ] ], + "bluetooth/idl/idlharness.tentative.window.js": [ + [ + "/bluetooth/idl/idlharness.tentative.window.html", + {} + ] + ], "bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.https.html": [ [ "/bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.https.html", @@ -186157,6 +186225,12 @@ {} ] ], + "cookie-store/cookieListItem_attributes.tentative.window.js": [ + [ + "/cookie-store/cookieListItem_attributes.tentative.window.html", + {} + ] + ], "cookie-store/cookieStore_delete_arguments.tentative.window.js": [ [ "/cookie-store/cookieStore_delete_arguments.tentative.window.html", @@ -195979,6 +196053,12 @@ {} ] ], + "css/cssom-view/elementFromPoint-mixed-font-sizes.html": [ + [ + "/css/cssom-view/elementFromPoint-mixed-font-sizes.html", + {} + ] + ], "css/cssom-view/elementFromPoint-parameters.html": [ [ "/css/cssom-view/elementFromPoint-parameters.html", @@ -217055,12 +217135,28 @@ {} ] ], - "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html": [ + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none.html": [ [ - "/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html", - { - "timeout": "long" - } + "/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none.html", + {} + ] + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode.html": [ + [ + "/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode.html", + {} + ] + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode.html": [ + [ + "/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode.html", + {} + ] + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html": [ + [ + "/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html", + {} ] ], "html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html": [ @@ -245077,6 +245173,12 @@ {} ] ], + "scroll-animations/idlharness.html": [ + [ + "/scroll-animations/idlharness.html", + {} + ] + ], "secure-contexts/basic-dedicated-worker.html": [ [ "/secure-contexts/basic-dedicated-worker.html", @@ -245113,6 +245215,24 @@ {} ] ], + "secure-contexts/idlharness.any.js": [ + [ + "/secure-contexts/idlharness.any.html", + {} + ], + [ + "/secure-contexts/idlharness.any.sharedworker.html", + {} + ], + [ + "/secure-contexts/idlharness.any.worker.html", + {} + ], + [ + "/secure-contexts/idlharness.https.any.serviceworker.html", + {} + ] + ], "secure-contexts/shared-worker-insecure-first.https.html": [ [ "/secure-contexts/shared-worker-insecure-first.https.html", @@ -249265,6 +249385,12 @@ {} ] ], + "touch-events/idlharness.window.js": [ + [ + "/touch-events/idlharness.window.html", + {} + ] + ], "touch-events/touch-globaleventhandler-interface.html": [ [ "/touch-events/touch-globaleventhandler-interface.html", @@ -271822,26 +271948,26 @@ "88211a0d44012d229af146366440ced5d12b0988", "support" ], - "background-fetch/interfaces-worker.https.html": [ - "ddb477404c7f985dfa2ed61c820d68848ea3acb5", - "testharness" - ], "background-fetch/interfaces.https-expected.txt": [ "145c69b2dffb9739c14693f8aa2ab2226a16a565", "support" ], - "background-fetch/interfaces.https.html": [ - "dc48b3e0bff00fed4a0e846e35f2499d6579dcd8", + "background-fetch/interfaces.https.any-expected.txt": [ + "8a5cf2119205440349c364ccdeaa65ce3cf42791", + "support" + ], + "background-fetch/interfaces.https.any.js": [ + "af1d0da2759a9c1c5b993eb9ea0905601f531301", "testharness" ], + "background-fetch/interfaces.https.any.worker-expected.txt": [ + "66d01d6b1e71e7381f1a1b87b56372ffe850b27f", + "support" + ], "background-fetch/interfaces.https.worker-expected.txt": [ "be45725c15e69f8bd48e3f84a965b0347f399c5e", "support" ], - "background-fetch/interfaces.https.worker.js": [ - "f1013d140f361226c81c24926548860d975ec3b2", - "testharness" - ], "background-fetch/mixed-content-and-allowed-schemes.https.window.js": [ "a285388a7d275f50444079b9549797ed29b27fd3", "testharness" @@ -272218,6 +272344,14 @@ "fa121bcbea3d19898a71f7dda79708ee941e4b6c", "testharness" ], + "bluetooth/idl/idlharness.tentative.window-expected.txt": [ + "bacd630d5e78ce66ff067cbe3d87d5ea55592e4b", + "support" + ], + "bluetooth/idl/idlharness.tentative.window.js": [ + "02a6bf3346f34196fab9b5788131641d44bf9b77", + "testharness" + ], "bluetooth/requestDevice/acceptAllDevices/device-with-empty-name.https.html": [ "850418b4a67df894ac4b21d2e5a18c5c266d03fd", "testharness" @@ -275827,7 +275961,7 @@ "testharness" ], "cookie-store/META.yml": [ - "c04035be35660a958882953b9fc701a0b8d38322", + "b0d8c58c78cfd2dcc8a81b83fb17afadeabfb375", "support" ], "cookie-store/OWNERS": [ @@ -275838,8 +275972,12 @@ "40595162d15dec7e315ef16f94646045596d7b1c", "support" ], + "cookie-store/cookieListItem_attributes.tentative.window.js": [ + "7d89e9ee77bad065c75bdb4f3467852dbf256b09", + "testharness" + ], "cookie-store/cookieStore_delete_arguments.tentative.window.js": [ - "a2a3b036e62ed11e8013f7e255bbc418576dd451", + "740fccd53713d8ffdd84aa388580630025fc016c", "testharness" ], "cookie-store/cookieStore_delete_basic.tentative.window.js": [ @@ -275895,7 +276033,7 @@ "testharness" ], "cookie-store/cookieStore_set_arguments.tentative.window.js": [ - "33e7ed082d0e461147eb01dfabf305022952401f", + "86cdff2d6d564eef090342adb3d41c0b1e1c4513", "testharness" ], "cookie-store/cookieStore_set_expires_option.tentative.window-expected.txt": [ @@ -338026,6 +338164,10 @@ "6ee9a47112c9a5fe4f0c85f85ea577575790c5be", "testharness" ], + "css/cssom-view/elementFromPoint-mixed-font-sizes.html": [ + "d73025913e0ff9d0ba490b8a54f543e876808450", + "testharness" + ], "css/cssom-view/elementFromPoint-parameters.html": [ "0c31602268a831eae1bcd44b4a5e7b678a7ed7cb", "testharness" @@ -349619,7 +349761,7 @@ "testharness" ], "encrypted-media/idlharness.https.html": [ - "29f3c9774b623413c4127ea0e5a915e67f24cd24", + "ab08c64408ed83c880f9a6ae9624d6f097929514", "testharness" ], "encrypted-media/polyfill/cast-polyfill.js": [ @@ -350947,7 +351089,7 @@ "support" ], "fetch/api/idl.any.js": [ - "e5aad955f348ef56288fa0d50b9396a3b5f02571", + "807763b90c8b6d237371b1ab574b0a2283e28f15", "testharness" ], "fetch/api/idl.any.sharedworker-expected.txt": [ @@ -366966,12 +367108,40 @@ "d8bdb2208a32d2200afb173368c38826fede8476", "support" ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none-expected.txt": [ + "f6bf278195082060d67dbb12fc6d1a76412b8b16", + "support" + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none.html": [ + "0640911a07b6d8d52a99657bab9cfd60f12ca039", + "testharness" + ], "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-expected.txt": [ "8bbd28341e2176d160835e3a5b6d8490a0d5d6bd", "support" ], - "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html": [ - "22040d8543a29c1e4f1708017096a5f9de478549", + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode-expected.txt": [ + "2e3c0ee962f667aa1a175b1b1f4ac9e7ad4f38f4", + "support" + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode.html": [ + "5654a57151b4f3d4cbea49dce643aa67921faef3", + "testharness" + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode-expected.txt": [ + "57fda2925502276a94bf0ce0a3ad9df4aa51201e", + "support" + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode.html": [ + "2fe5520523418bf16c57108dc2f3eda06cf7084e", + "testharness" + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px-expected.txt": [ + "ec8e6fcde175198b2da6170a157651c9bd1c6f80", + "support" + ], + "html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html": [ + "043e76618e8ddbdf7c62a28150e467840f3a2193", "testharness" ], "html/semantics/embedded-content/the-img-element/sizes/sizes-dynamic-001-ref.html": [ @@ -366982,7 +367152,11 @@ "c25df42c0fa9b20cfac886da13c74801c63d8d40", "reftest" ], - "html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html": [ + "html/semantics/embedded-content/the-img-element/sizes/support/parse-a-sizes-attribute.js": [ + "4ddd034873cb0340ef07eebe6579c12f1c78b767", + "support" + ], + "html/semantics/embedded-content/the-img-element/sizes/support/sizes-iframed.sub.html": [ "47e56d828d8c366a95d0ea77571a1dbcaaca3164", "support" ], @@ -373607,7 +373781,7 @@ "support" ], "interfaces/background-fetch.idl": [ - "f2c8fc84af7bf785ba42f1398181e2ab08c3826a", + "272d5ef66a2df3a6c3fefaf9688802ed93a9ad5f", "support" ], "interfaces/battery.idl": [ @@ -373691,7 +373865,7 @@ "support" ], "interfaces/encrypted-media.idl": [ - "ef1f1432c42fc6d01f3bfbd576fa5c7de349de96", + "9965e27558616e512abdfacb451a4798035cf1df", "support" ], "interfaces/entries-api.idl": [ @@ -373814,6 +373988,10 @@ "5416752c31de2d0f7a3b72941e24a0030d98599c", "support" ], + "interfaces/referrer-policy.idl": [ + "04193aef279c9c8e0cb060d715d91c66045aaf17", + "support" + ], "interfaces/remote-playback.idl": [ "9ddb3a7bfce2454a3f7d835785db912f70521449", "support" @@ -373826,6 +374004,14 @@ "ace5a4ae79933cdfd7ecf5c3801e93f0636fe57b", "support" ], + "interfaces/scroll-animations.idl": [ + "b8a8781f130345d09ceb3cf064ce02ef1cd1c96a", + "support" + ], + "interfaces/secure-contexts.idl": [ + "27034035747147b5b460d6ee782e060cfa58b2f5", + "support" + ], "interfaces/selection-api.idl": [ "c8c9e45b541e511673dbe8ddd1321dceef2856b4", "support" @@ -373842,6 +374028,10 @@ "a1ad440d60e04902f494ecaced1fceb8560adc5c", "support" ], + "interfaces/touch-events.idl": [ + "00811ff421c7ecafb8070d1a3d17310e1228c725", + "support" + ], "interfaces/touchevents.idl": [ "6ce4f601cda6cd3b99a300e0b28d2886647f06d3", "support" @@ -373870,8 +374060,8 @@ "a68224b17684bd43309bef57e7ad835f5f324a3a", "support" ], - "interfaces/web-audio-api.idl": [ - "6e6a41a2b1dfde69171a8d28252cc3354c86b83e", + "interfaces/web-bluetooth.idl": [ + "48e51b15f2338d6b3b0a8c0a013b4f1bfdf6ca1f", "support" ], "interfaces/web-nfc.idl": [ @@ -373882,8 +374072,8 @@ "21b54128664c5962c29fd708ebba3d8d90987f26", "support" ], - "interfaces/webappsec-referrer-policy.idl": [ - "d19ab092de767fd06ede1b77236b35d9cbe45c4c", + "interfaces/webaudio.idl": [ + "a2adb319de88d1d33080a837972caefa5c5c1946", "support" ], "interfaces/webauthn.idl": [ @@ -374423,11 +374613,11 @@ "testharness" ], "media-source/mediasource-append-buffer-expected.txt": [ - "505ef24c1f9cde1e49ecee8db9ecb3a4778f8f54", + "234a1e0d6274588bfb61b8cd2869dcf44bf56d9a", "support" ], "media-source/mediasource-append-buffer.html": [ - "a29b47e56f3f3b963063ff2a8e9d41c05299e024", + "44a899df039dcda1082df46ff47345acf043fac7", "testharness" ], "media-source/mediasource-appendbuffer-quota-exceeded.html": [ @@ -384134,10 +384324,6 @@ "ea205c844bf3932b5bdd85201b05174fc7ab0836", "manual" ], - "payment-request/historical.https-expected.txt": [ - "a98767fbf7d24f102e1546aafe4ed6276c2e79eb", - "support" - ], "payment-request/historical.https.html": [ "6695acdcd1647fdd37702a7f63658dcd50f25596", "testharness" @@ -384186,10 +384372,6 @@ "cee3a8a8b9d25b5a44445a416b1bc9be2b341a04", "testharness" ], - "payment-request/payment-request-ctor-pmi-handling.https-expected.txt": [ - "7ce23837915999ca0934c22d51fd20fdd11a8eef", - "support" - ], "payment-request/payment-request-ctor-pmi-handling.https.html": [ "f2372d7eea1cc49cd739ed4818c74cf9e5a39151", "testharness" @@ -394058,6 +394240,18 @@ "9984a22d62b08da1aa2102936b0c5375fe237548", "support" ], + "scroll-animations/META.yml": [ + "fab0b68ec248d2d69cdcec6085c07c6c6004b0a4", + "support" + ], + "scroll-animations/idlharness-expected.txt": [ + "849492170e58082789fc91b5c05088013ef023fe", + "support" + ], + "scroll-animations/idlharness.html": [ + "343f75a4f8c405542f2fbe8ec5bdb6e757d17d0a", + "testharness" + ], "secure-contexts/META.yml": [ "4966e7a03e815dac333218faf57875b57b9dd535", "support" @@ -394110,6 +394304,14 @@ "7241035c47bc2a0251826d2c9ad3bc5f9acd61d2", "testharness" ], + "secure-contexts/idlharness.any-expected.txt": [ + "90ab254b25f5a7bd8afaa3355cb3f140f0c38619", + "support" + ], + "secure-contexts/idlharness.any.js": [ + "aadb6cb566dfa52c34e7c9f261874ecbcb55d13a", + "testharness" + ], "secure-contexts/postMessage-helper.html": [ "8b5438e8ff88bd322c5231b5116128f50652f43b", "support" @@ -400438,6 +400640,14 @@ "2a748b6f1b66874fa613f3188125a04c95587976", "testharness" ], + "touch-events/idlharness.window-expected.txt": [ + "2935239d46556213a272d757c07b8b3b9866fec5", + "support" + ], + "touch-events/idlharness.window.js": [ + "c5bcdd44381f6f49f0e653c48d05cc14c93f424a", + "testharness" + ], "touch-events/multi-touch-interactions.js": [ "ebd23ef9b71a949ba6f45a08b342ec569626fd82", "support" @@ -402375,11 +402585,11 @@ "testharness" ], "webaudio/idlharness.https-expected.txt": [ - "d4595c10a6dee34fe2c84039b41f3117640ffa0b", + "451ba6e7843b5bc4e64983f0ac2aac11467f91e4", "support" ], "webaudio/idlharness.https.html": [ - "af74995e367b63d17b5dea6bd2bfa9646ab08798", + "ce6a8abcc0eb9863b0515d6ec2f16e7b42b4151c", "testharness" ], "webaudio/js/buffer-loader.js": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces-worker.https.html b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces-worker.https.html deleted file mode 100644 index f417848..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces-worker.https.html +++ /dev/null
@@ -1,15 +0,0 @@ -<!doctype html> -<meta charset="utf-8"> -<title>Background Fetch API IDL tests</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> - -<h1>idlharness test</h1> -<p>This test validates the WebIDL included in the Background Fetch API (Service Workers).</p> - -<script> -'use strict'; - -service_worker_test('interfaces.https.worker.js', 'Service Worker-scoped tests.'); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any-expected.txt new file mode 100644 index 0000000..0ef24b5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any-expected.txt
@@ -0,0 +1,77 @@ +This is a testharness.js-based test. +PASS background-fetch interfaces +PASS Partial interface ServiceWorkerGlobalScope: original interface defined +PASS Partial interface ServiceWorkerRegistration: original interface defined +PASS BackgroundFetchManager interface: existence and properties of interface object +PASS BackgroundFetchManager interface object length +PASS BackgroundFetchManager interface object name +PASS BackgroundFetchManager interface: existence and properties of interface prototype object +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) +PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation get(DOMString) +PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation getIds() +PASS Unscopable handled correctly for getIds() on BackgroundFetchManager +PASS BackgroundFetchRegistration interface: existence and properties of interface object +PASS BackgroundFetchRegistration interface object length +PASS BackgroundFetchRegistration interface object name +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchRegistration interface: attribute id +PASS Unscopable handled correctly for id property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploadTotal +PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploaded +PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloadTotal +PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloaded +PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration +FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false +PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute onprogress +PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: operation abort() +PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration +PASS BackgroundFetchFetch interface: existence and properties of interface object +PASS BackgroundFetchFetch interface object length +PASS BackgroundFetchFetch interface object name +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchFetch interface: attribute request +PASS Unscopable handled correctly for request property on BackgroundFetchFetch +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for match(RequestInfo) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch +PASS BackgroundFetchEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledFetches interface: existence and properties of interface object +PASS BackgroundFetchSettledFetch interface: existence and properties of interface object +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object +PASS BackgroundFetchClickEvent interface: existence and properties of interface object +PASS ServiceWorkerRegistration interface: attribute backgroundFetch +PASS Unscopable handled correctly for backgroundFetch property on ServiceWorkerRegistration +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +PASS WorkerGlobalScope interface: existence and properties of interface object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.js new file mode 100644 index 0000000..668a679 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.js
@@ -0,0 +1,19 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://wicg.github.io/background-fetch/ + +promise_test(async () => { + const srcs = ['background-fetch', 'dedicated-workers', 'ServiceWorker', 'dom']; + const [idls, worker, serviceWorker, dom] = await Promise.all( + srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); + + var idlArray = new IdlArray(); + idlArray.add_idls(idls); + idlArray.add_dependency_idls(serviceWorker); + idlArray.add_dependency_idls(worker); + idlArray.add_dependency_idls(dom); + idlArray.test(); +}, 'background-fetch interfaces');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.worker-expected.txt new file mode 100644 index 0000000..7c6819c2f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.any.worker-expected.txt
@@ -0,0 +1,76 @@ +This is a testharness.js-based test. +PASS background-fetch interfaces +PASS Partial interface ServiceWorkerGlobalScope: original interface defined +PASS Partial interface ServiceWorkerRegistration: original interface defined +PASS BackgroundFetchManager interface: existence and properties of interface object +PASS BackgroundFetchManager interface object length +PASS BackgroundFetchManager interface object name +PASS BackgroundFetchManager interface: existence and properties of interface prototype object +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchManager interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchManager interface: operation fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) +PASS Unscopable handled correctly for fetch(DOMString, [object Object],[object Object], BackgroundFetchOptions) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation get(DOMString) +PASS Unscopable handled correctly for get(DOMString) on BackgroundFetchManager +PASS BackgroundFetchManager interface: operation getIds() +PASS Unscopable handled correctly for getIds() on BackgroundFetchManager +PASS BackgroundFetchRegistration interface: existence and properties of interface object +PASS BackgroundFetchRegistration interface object length +PASS BackgroundFetchRegistration interface object name +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchRegistration interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchRegistration interface: attribute id +PASS Unscopable handled correctly for id property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploadTotal +PASS Unscopable handled correctly for uploadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute uploaded +PASS Unscopable handled correctly for uploaded property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloadTotal +PASS Unscopable handled correctly for downloadTotal property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute downloaded +PASS Unscopable handled correctly for downloaded property on BackgroundFetchRegistration +FAIL BackgroundFetchRegistration interface: attribute activeFetches assert_true: The prototype object must have a property "activeFetches" expected true got false +PASS Unscopable handled correctly for activeFetches property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: attribute onprogress +PASS Unscopable handled correctly for onprogress property on BackgroundFetchRegistration +PASS BackgroundFetchRegistration interface: operation abort() +PASS Unscopable handled correctly for abort() on BackgroundFetchRegistration +PASS BackgroundFetchFetch interface: existence and properties of interface object +PASS BackgroundFetchFetch interface object length +PASS BackgroundFetchFetch interface object name +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's "constructor" property +PASS BackgroundFetchFetch interface: existence and properties of interface prototype object's @@unscopables property +PASS BackgroundFetchFetch interface: attribute request +PASS Unscopable handled correctly for request property on BackgroundFetchFetch +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +FAIL BackgroundFetchActiveFetches interface: operation match(RequestInfo) assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for match(RequestInfo) on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetches interface: operation values() assert_own_property: self does not have own property "BackgroundFetchActiveFetches" expected property "BackgroundFetchActiveFetches" missing +PASS Unscopable handled correctly for values() on BackgroundFetchActiveFetches +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object length assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface object name assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +FAIL BackgroundFetchActiveFetch interface: attribute responseReady assert_own_property: self does not have own property "BackgroundFetchActiveFetch" expected property "BackgroundFetchActiveFetch" missing +PASS Unscopable handled correctly for responseReady property on BackgroundFetchActiveFetch +PASS BackgroundFetchEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledEvent interface: existence and properties of interface object +PASS BackgroundFetchSettledFetches interface: existence and properties of interface object +PASS BackgroundFetchSettledFetch interface: existence and properties of interface object +PASS BackgroundFetchUpdateEvent interface: existence and properties of interface object +PASS BackgroundFetchClickEvent interface: existence and properties of interface object +PASS ServiceWorkerRegistration interface: attribute backgroundFetch +PASS Unscopable handled correctly for backgroundFetch property on ServiceWorkerRegistration +PASS ServiceWorkerGlobalScope interface: existence and properties of interface object +PASS ExtendableEvent interface: existence and properties of interface object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.html b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.html deleted file mode 100644 index 51e320e..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.html +++ /dev/null
@@ -1,28 +0,0 @@ -<!doctype html> -<meta charset="utf-8"> -<title>Background Fetch API IDL tests</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/resources/WebIDLParser.js"></script> -<script src="/resources/idlharness.js"></script> - -<h1>idlharness test</h1> -<p>This test validates the WebIDL included in the Background Fetch API (Documents).</p> - -<script> -'use strict'; - -promise_test(async function () { - const idls = await fetch('/interfaces/background-fetch.idl').then(r => r.text()); - const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); - - var idlArray = new IdlArray(); - idlArray.add_untested_idls('interface ServiceWorkerRegistration {};'); - idlArray.add_untested_idls('[Exposed=ServiceWorker] interface ServiceWorkerGlobalScope {};'); - idlArray.add_untested_idls('interface ExtendableEvent{};'); - idlArray.add_untested_idls('dictionary ExtendableEventInit{};'); - idlArray.add_untested_idls(dom, { only: ['EventTarget'] }); - idlArray.add_idls(idls); - idlArray.test(); -}, 'Exposed interfaces in a Document.'); -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.worker.js b/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.worker.js deleted file mode 100644 index 0760ffd..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/background-fetch/interfaces.https.worker.js +++ /dev/null
@@ -1,20 +0,0 @@ -'use strict'; - -importScripts('/resources/testharness.js'); -importScripts('/resources/WebIDLParser.js', '/resources/idlharness.js'); - -promise_test(async function() { - const idls = await fetch('/interfaces/background-fetch.idl').then(r => r.text()); - const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); - - var idlArray = new IdlArray(); - idlArray.add_untested_idls('interface ServiceWorkerRegistration {};'); - idlArray.add_untested_idls('[SecureContext, Exposed = (Window, Worker)] interface ServiceWorkerGlobalScope {};'); - idlArray.add_untested_idls('interface ExtendableEvent{};'); - idlArray.add_untested_idls('dictionary ExtendableEventInit{};'); - idlArray.add_untested_idls(dom, { only: ['EventTarget'] }); - idlArray.add_idls(idls); - idlArray.test(); -}, 'Exposed interfaces in a Service Worker.'); - -done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idlharness.tentative.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idlharness.tentative.window-expected.txt new file mode 100644 index 0000000..67033a5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idlharness.tentative.window-expected.txt
@@ -0,0 +1,238 @@ +This is a testharness.js-based test. +Found 234 tests; 166 PASS, 68 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS web-bluetooth interfaces. +PASS Partial interface Navigator: original interface defined +FAIL Bluetooth interface: existence and properties of interface object assert_equals: prototype of Bluetooth is not EventTarget expected function "function EventTarget() { [native code] }" but got function "function () { [native code] }" +PASS Bluetooth interface object length +PASS Bluetooth interface object name +FAIL Bluetooth interface: existence and properties of interface prototype object assert_equals: prototype of Bluetooth.prototype is not EventTarget.prototype expected object "[object EventTarget]" but got object "[object Object]" +PASS Bluetooth interface: existence and properties of interface prototype object's "constructor" property +PASS Bluetooth interface: existence and properties of interface prototype object's @@unscopables property +FAIL Bluetooth interface: operation getAvailability() assert_own_property: interface prototype object missing non-static operation expected property "getAvailability" missing +PASS Unscopable handled correctly for getAvailability() on Bluetooth +FAIL Bluetooth interface: attribute onavailabilitychanged assert_true: The prototype object must have a property "onavailabilitychanged" expected true got false +PASS Unscopable handled correctly for onavailabilitychanged property on Bluetooth +FAIL Bluetooth interface: attribute referringDevice assert_true: The prototype object must have a property "referringDevice" expected true got false +PASS Unscopable handled correctly for referringDevice property on Bluetooth +FAIL Bluetooth interface: operation requestDevice(RequestDeviceOptions) assert_own_property: interface prototype object missing non-static operation expected property "requestDevice" missing +PASS Unscopable handled correctly for requestDevice(RequestDeviceOptions) on Bluetooth +FAIL Bluetooth interface: attribute ongattserverdisconnected assert_true: The prototype object must have a property "ongattserverdisconnected" expected true got false +PASS Unscopable handled correctly for ongattserverdisconnected property on Bluetooth +FAIL Bluetooth interface: attribute oncharacteristicvaluechanged assert_true: The prototype object must have a property "oncharacteristicvaluechanged" expected true got false +PASS Unscopable handled correctly for oncharacteristicvaluechanged property on Bluetooth +FAIL Bluetooth interface: attribute onserviceadded assert_true: The prototype object must have a property "onserviceadded" expected true got false +PASS Unscopable handled correctly for onserviceadded property on Bluetooth +FAIL Bluetooth interface: attribute onservicechanged assert_true: The prototype object must have a property "onservicechanged" expected true got false +PASS Unscopable handled correctly for onservicechanged property on Bluetooth +FAIL Bluetooth interface: attribute onserviceremoved assert_true: The prototype object must have a property "onserviceremoved" expected true got false +PASS Unscopable handled correctly for onserviceremoved property on Bluetooth +FAIL BluetoothPermissionResult interface: existence and properties of interface object assert_own_property: self does not have own property "BluetoothPermissionResult" expected property "BluetoothPermissionResult" missing +FAIL BluetoothPermissionResult interface object length assert_own_property: self does not have own property "BluetoothPermissionResult" expected property "BluetoothPermissionResult" missing +FAIL BluetoothPermissionResult interface object name assert_own_property: self does not have own property "BluetoothPermissionResult" expected property "BluetoothPermissionResult" missing +FAIL BluetoothPermissionResult interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BluetoothPermissionResult" expected property "BluetoothPermissionResult" missing +FAIL BluetoothPermissionResult interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BluetoothPermissionResult" expected property "BluetoothPermissionResult" missing +FAIL BluetoothPermissionResult interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BluetoothPermissionResult" expected property "BluetoothPermissionResult" missing +FAIL BluetoothPermissionResult interface: attribute devices assert_own_property: self does not have own property "BluetoothPermissionResult" expected property "BluetoothPermissionResult" missing +PASS Unscopable handled correctly for devices property on BluetoothPermissionResult +FAIL ValueEvent interface: existence and properties of interface object assert_own_property: self does not have own property "ValueEvent" expected property "ValueEvent" missing +FAIL ValueEvent interface object length assert_own_property: self does not have own property "ValueEvent" expected property "ValueEvent" missing +FAIL ValueEvent interface object name assert_own_property: self does not have own property "ValueEvent" expected property "ValueEvent" missing +FAIL ValueEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ValueEvent" expected property "ValueEvent" missing +FAIL ValueEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ValueEvent" expected property "ValueEvent" missing +FAIL ValueEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ValueEvent" expected property "ValueEvent" missing +FAIL ValueEvent interface: attribute value assert_own_property: self does not have own property "ValueEvent" expected property "ValueEvent" missing +PASS Unscopable handled correctly for value property on ValueEvent +FAIL BluetoothDevice interface: existence and properties of interface object assert_equals: prototype of self's property "BluetoothDevice" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }" +PASS BluetoothDevice interface object length +PASS BluetoothDevice interface object name +FAIL BluetoothDevice interface: existence and properties of interface prototype object assert_equals: prototype of BluetoothDevice.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]" +PASS BluetoothDevice interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothDevice interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothDevice interface: attribute id +PASS Unscopable handled correctly for id property on BluetoothDevice +PASS BluetoothDevice interface: attribute name +PASS Unscopable handled correctly for name property on BluetoothDevice +PASS BluetoothDevice interface: attribute gatt +PASS Unscopable handled correctly for gatt property on BluetoothDevice +FAIL BluetoothDevice interface: operation watchAdvertisements() assert_own_property: interface prototype object missing non-static operation expected property "watchAdvertisements" missing +PASS Unscopable handled correctly for watchAdvertisements() on BluetoothDevice +FAIL BluetoothDevice interface: operation unwatchAdvertisements() assert_own_property: interface prototype object missing non-static operation expected property "unwatchAdvertisements" missing +PASS Unscopable handled correctly for unwatchAdvertisements() on BluetoothDevice +FAIL BluetoothDevice interface: attribute watchingAdvertisements assert_true: The prototype object must have a property "watchingAdvertisements" expected true got false +PASS Unscopable handled correctly for watchingAdvertisements property on BluetoothDevice +PASS BluetoothDevice interface: attribute ongattserverdisconnected +PASS Unscopable handled correctly for ongattserverdisconnected property on BluetoothDevice +FAIL BluetoothDevice interface: attribute oncharacteristicvaluechanged assert_true: The prototype object must have a property "oncharacteristicvaluechanged" expected true got false +PASS Unscopable handled correctly for oncharacteristicvaluechanged property on BluetoothDevice +FAIL BluetoothDevice interface: attribute onserviceadded assert_true: The prototype object must have a property "onserviceadded" expected true got false +PASS Unscopable handled correctly for onserviceadded property on BluetoothDevice +FAIL BluetoothDevice interface: attribute onservicechanged assert_true: The prototype object must have a property "onservicechanged" expected true got false +PASS Unscopable handled correctly for onservicechanged property on BluetoothDevice +FAIL BluetoothDevice interface: attribute onserviceremoved assert_true: The prototype object must have a property "onserviceremoved" expected true got false +PASS Unscopable handled correctly for onserviceremoved property on BluetoothDevice +FAIL BluetoothManufacturerDataMap interface: existence and properties of interface object assert_own_property: self does not have own property "BluetoothManufacturerDataMap" expected property "BluetoothManufacturerDataMap" missing +FAIL BluetoothManufacturerDataMap interface object length assert_own_property: self does not have own property "BluetoothManufacturerDataMap" expected property "BluetoothManufacturerDataMap" missing +FAIL BluetoothManufacturerDataMap interface object name assert_own_property: self does not have own property "BluetoothManufacturerDataMap" expected property "BluetoothManufacturerDataMap" missing +FAIL BluetoothManufacturerDataMap interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BluetoothManufacturerDataMap" expected property "BluetoothManufacturerDataMap" missing +FAIL BluetoothManufacturerDataMap interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BluetoothManufacturerDataMap" expected property "BluetoothManufacturerDataMap" missing +FAIL BluetoothManufacturerDataMap interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BluetoothManufacturerDataMap" expected property "BluetoothManufacturerDataMap" missing +FAIL BluetoothServiceDataMap interface: existence and properties of interface object assert_own_property: self does not have own property "BluetoothServiceDataMap" expected property "BluetoothServiceDataMap" missing +FAIL BluetoothServiceDataMap interface object length assert_own_property: self does not have own property "BluetoothServiceDataMap" expected property "BluetoothServiceDataMap" missing +FAIL BluetoothServiceDataMap interface object name assert_own_property: self does not have own property "BluetoothServiceDataMap" expected property "BluetoothServiceDataMap" missing +FAIL BluetoothServiceDataMap interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BluetoothServiceDataMap" expected property "BluetoothServiceDataMap" missing +FAIL BluetoothServiceDataMap interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BluetoothServiceDataMap" expected property "BluetoothServiceDataMap" missing +FAIL BluetoothServiceDataMap interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BluetoothServiceDataMap" expected property "BluetoothServiceDataMap" missing +FAIL BluetoothAdvertisingEvent interface: existence and properties of interface object assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +FAIL BluetoothAdvertisingEvent interface object length assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +FAIL BluetoothAdvertisingEvent interface object name assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +FAIL BluetoothAdvertisingEvent interface: existence and properties of interface prototype object assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +FAIL BluetoothAdvertisingEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +FAIL BluetoothAdvertisingEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +FAIL BluetoothAdvertisingEvent interface: attribute device assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for device property on BluetoothAdvertisingEvent +FAIL BluetoothAdvertisingEvent interface: attribute uuids assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for uuids property on BluetoothAdvertisingEvent +FAIL BluetoothAdvertisingEvent interface: attribute name assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for name property on BluetoothAdvertisingEvent +FAIL BluetoothAdvertisingEvent interface: attribute appearance assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for appearance property on BluetoothAdvertisingEvent +FAIL BluetoothAdvertisingEvent interface: attribute txPower assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for txPower property on BluetoothAdvertisingEvent +FAIL BluetoothAdvertisingEvent interface: attribute rssi assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for rssi property on BluetoothAdvertisingEvent +FAIL BluetoothAdvertisingEvent interface: attribute manufacturerData assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for manufacturerData property on BluetoothAdvertisingEvent +FAIL BluetoothAdvertisingEvent interface: attribute serviceData assert_own_property: self does not have own property "BluetoothAdvertisingEvent" expected property "BluetoothAdvertisingEvent" missing +PASS Unscopable handled correctly for serviceData property on BluetoothAdvertisingEvent +PASS BluetoothRemoteGATTServer interface: existence and properties of interface object +PASS BluetoothRemoteGATTServer interface object length +PASS BluetoothRemoteGATTServer interface object name +PASS BluetoothRemoteGATTServer interface: existence and properties of interface prototype object +PASS BluetoothRemoteGATTServer interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothRemoteGATTServer interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothRemoteGATTServer interface: attribute device +PASS Unscopable handled correctly for device property on BluetoothRemoteGATTServer +PASS BluetoothRemoteGATTServer interface: attribute connected +PASS Unscopable handled correctly for connected property on BluetoothRemoteGATTServer +PASS BluetoothRemoteGATTServer interface: operation connect() +PASS Unscopable handled correctly for connect() on BluetoothRemoteGATTServer +PASS BluetoothRemoteGATTServer interface: operation disconnect() +PASS Unscopable handled correctly for disconnect() on BluetoothRemoteGATTServer +PASS BluetoothRemoteGATTServer interface: operation getPrimaryService(BluetoothServiceUUID) +PASS Unscopable handled correctly for getPrimaryService(BluetoothServiceUUID) on BluetoothRemoteGATTServer +PASS BluetoothRemoteGATTServer interface: operation getPrimaryServices(BluetoothServiceUUID) +PASS Unscopable handled correctly for getPrimaryServices(BluetoothServiceUUID) on BluetoothRemoteGATTServer +PASS BluetoothRemoteGATTService interface: existence and properties of interface object +PASS BluetoothRemoteGATTService interface object length +PASS BluetoothRemoteGATTService interface object name +PASS BluetoothRemoteGATTService interface: existence and properties of interface prototype object +PASS BluetoothRemoteGATTService interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothRemoteGATTService interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothRemoteGATTService interface: attribute device +PASS Unscopable handled correctly for device property on BluetoothRemoteGATTService +PASS BluetoothRemoteGATTService interface: attribute uuid +PASS Unscopable handled correctly for uuid property on BluetoothRemoteGATTService +PASS BluetoothRemoteGATTService interface: attribute isPrimary +PASS Unscopable handled correctly for isPrimary property on BluetoothRemoteGATTService +PASS BluetoothRemoteGATTService interface: operation getCharacteristic(BluetoothCharacteristicUUID) +PASS Unscopable handled correctly for getCharacteristic(BluetoothCharacteristicUUID) on BluetoothRemoteGATTService +PASS BluetoothRemoteGATTService interface: operation getCharacteristics(BluetoothCharacteristicUUID) +PASS Unscopable handled correctly for getCharacteristics(BluetoothCharacteristicUUID) on BluetoothRemoteGATTService +FAIL BluetoothRemoteGATTService interface: operation getIncludedService(BluetoothServiceUUID) assert_own_property: interface prototype object missing non-static operation expected property "getIncludedService" missing +PASS Unscopable handled correctly for getIncludedService(BluetoothServiceUUID) on BluetoothRemoteGATTService +FAIL BluetoothRemoteGATTService interface: operation getIncludedServices(BluetoothServiceUUID) assert_own_property: interface prototype object missing non-static operation expected property "getIncludedServices" missing +PASS Unscopable handled correctly for getIncludedServices(BluetoothServiceUUID) on BluetoothRemoteGATTService +FAIL BluetoothRemoteGATTService interface: attribute oncharacteristicvaluechanged assert_true: The prototype object must have a property "oncharacteristicvaluechanged" expected true got false +PASS Unscopable handled correctly for oncharacteristicvaluechanged property on BluetoothRemoteGATTService +FAIL BluetoothRemoteGATTService interface: attribute onserviceadded assert_true: The prototype object must have a property "onserviceadded" expected true got false +PASS Unscopable handled correctly for onserviceadded property on BluetoothRemoteGATTService +FAIL BluetoothRemoteGATTService interface: attribute onservicechanged assert_true: The prototype object must have a property "onservicechanged" expected true got false +PASS Unscopable handled correctly for onservicechanged property on BluetoothRemoteGATTService +FAIL BluetoothRemoteGATTService interface: attribute onserviceremoved assert_true: The prototype object must have a property "onserviceremoved" expected true got false +PASS Unscopable handled correctly for onserviceremoved property on BluetoothRemoteGATTService +FAIL BluetoothRemoteGATTCharacteristic interface: existence and properties of interface object assert_equals: prototype of self's property "BluetoothRemoteGATTCharacteristic" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }" +PASS BluetoothRemoteGATTCharacteristic interface object length +PASS BluetoothRemoteGATTCharacteristic interface object name +FAIL BluetoothRemoteGATTCharacteristic interface: existence and properties of interface prototype object assert_equals: prototype of BluetoothRemoteGATTCharacteristic.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]" +PASS BluetoothRemoteGATTCharacteristic interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothRemoteGATTCharacteristic interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothRemoteGATTCharacteristic interface: attribute service +PASS Unscopable handled correctly for service property on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: attribute uuid +PASS Unscopable handled correctly for uuid property on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: attribute properties +PASS Unscopable handled correctly for properties property on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: attribute value +PASS Unscopable handled correctly for value property on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: operation getDescriptor(BluetoothDescriptorUUID) +PASS Unscopable handled correctly for getDescriptor(BluetoothDescriptorUUID) on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: operation getDescriptors(BluetoothDescriptorUUID) +PASS Unscopable handled correctly for getDescriptors(BluetoothDescriptorUUID) on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: operation readValue() +PASS Unscopable handled correctly for readValue() on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: operation writeValue(BufferSource) +PASS Unscopable handled correctly for writeValue(BufferSource) on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: operation startNotifications() +PASS Unscopable handled correctly for startNotifications() on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: operation stopNotifications() +PASS Unscopable handled correctly for stopNotifications() on BluetoothRemoteGATTCharacteristic +PASS BluetoothRemoteGATTCharacteristic interface: attribute oncharacteristicvaluechanged +PASS Unscopable handled correctly for oncharacteristicvaluechanged property on BluetoothRemoteGATTCharacteristic +PASS BluetoothCharacteristicProperties interface: existence and properties of interface object +PASS BluetoothCharacteristicProperties interface object length +PASS BluetoothCharacteristicProperties interface object name +PASS BluetoothCharacteristicProperties interface: existence and properties of interface prototype object +PASS BluetoothCharacteristicProperties interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothCharacteristicProperties interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothCharacteristicProperties interface: attribute broadcast +PASS Unscopable handled correctly for broadcast property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute read +PASS Unscopable handled correctly for read property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute writeWithoutResponse +PASS Unscopable handled correctly for writeWithoutResponse property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute write +PASS Unscopable handled correctly for write property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute notify +PASS Unscopable handled correctly for notify property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute indicate +PASS Unscopable handled correctly for indicate property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute authenticatedSignedWrites +PASS Unscopable handled correctly for authenticatedSignedWrites property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute reliableWrite +PASS Unscopable handled correctly for reliableWrite property on BluetoothCharacteristicProperties +PASS BluetoothCharacteristicProperties interface: attribute writableAuxiliaries +PASS Unscopable handled correctly for writableAuxiliaries property on BluetoothCharacteristicProperties +PASS BluetoothRemoteGATTDescriptor interface: existence and properties of interface object +PASS BluetoothRemoteGATTDescriptor interface object length +PASS BluetoothRemoteGATTDescriptor interface object name +PASS BluetoothRemoteGATTDescriptor interface: existence and properties of interface prototype object +PASS BluetoothRemoteGATTDescriptor interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothRemoteGATTDescriptor interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothRemoteGATTDescriptor interface: attribute characteristic +PASS Unscopable handled correctly for characteristic property on BluetoothRemoteGATTDescriptor +PASS BluetoothRemoteGATTDescriptor interface: attribute uuid +PASS Unscopable handled correctly for uuid property on BluetoothRemoteGATTDescriptor +PASS BluetoothRemoteGATTDescriptor interface: attribute value +PASS Unscopable handled correctly for value property on BluetoothRemoteGATTDescriptor +PASS BluetoothRemoteGATTDescriptor interface: operation readValue() +PASS Unscopable handled correctly for readValue() on BluetoothRemoteGATTDescriptor +PASS BluetoothRemoteGATTDescriptor interface: operation writeValue(BufferSource) +PASS Unscopable handled correctly for writeValue(BufferSource) on BluetoothRemoteGATTDescriptor +PASS BluetoothUUID interface: existence and properties of interface object +PASS BluetoothUUID interface object length +PASS BluetoothUUID interface object name +PASS BluetoothUUID interface: existence and properties of interface prototype object +PASS BluetoothUUID interface: existence and properties of interface prototype object's "constructor" property +PASS BluetoothUUID interface: existence and properties of interface prototype object's @@unscopables property +PASS BluetoothUUID interface: operation getService([object Object],[object Object]) +PASS Unscopable handled correctly for getService([object Object],[object Object]) on BluetoothUUID +PASS BluetoothUUID interface: operation getCharacteristic([object Object],[object Object]) +PASS Unscopable handled correctly for getCharacteristic([object Object],[object Object]) on BluetoothUUID +PASS BluetoothUUID interface: operation getDescriptor([object Object],[object Object]) +PASS Unscopable handled correctly for getDescriptor([object Object],[object Object]) on BluetoothUUID +PASS BluetoothUUID interface: operation canonicalUUID(unsigned long) +PASS Unscopable handled correctly for canonicalUUID(unsigned long) on BluetoothUUID +PASS Navigator interface: attribute bluetooth +PASS Unscopable handled correctly for bluetooth property on Navigator +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idlharness.tentative.window.js b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idlharness.tentative.window.js new file mode 100644 index 0000000..6214f13 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idlharness.tentative.window.js
@@ -0,0 +1,19 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://webbluetoothcg.github.io/web-bluetooth/ + +promise_test(async () => { + const srcs = ['web-bluetooth', 'dom', 'html', 'permissions']; + const [idl, dom, html, permissions] = await Promise.all( + srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); + + const idl_array = new IdlArray(); + idl_array.add_idls(idl); + idl_array.add_dependency_idls(dom); + idl_array.add_dependency_idls(html); + idl_array.add_dependency_idls(permissions); + idl_array.test(); +}, 'web-bluetooth interfaces.');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/META.yml b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/META.yml index f6fab6f..eeb57de 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/META.yml +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/META.yml
@@ -1,3 +1,3 @@ suggested_reviewers: - - bsittler + - inexorabletash - pwnall
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieListItem_attributes.tentative.window.js b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieListItem_attributes.tentative.window.js new file mode 100644 index 0000000..4b4b211b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieListItem_attributes.tentative.window.js
@@ -0,0 +1,121 @@ +'use strict'; + +// Workaround because add_cleanup doesn't support async functions yet. +// See https://github.com/web-platform-tests/wpt/issues/6075 +async function async_cleanup(cleanup_function) { + try { + await cleanup_function(); + } catch (e) { + // Errors in cleanup functions shouldn't result in test failures. + } +} + +const kCurrentHostname = (new URL(self.location.href)).hostname; +const kIsSecureTransport = (new URL(self.location.href)).protocol === 'https:'; + +const kOneDay = 24 * 60 * 60 * 1000; +const kTenYears = 10 * 365 * kOneDay; +const kTenYearsFromNow = Date.now() + kTenYears; + +promise_test(async testCase => { + await cookieStore.delete('cookie-name'); + + await cookieStore.set('cookie-name', 'cookie-value'); + + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + assert_equals(cookie.domain, null); + assert_equals(cookie.path, '/'); + assert_equals(cookie.expires, null); + assert_equals(cookie.secure, kIsSecureTransport); + + await async_cleanup(() => cookieStore.delete('cookie-name')); +}, 'cookieStore.set defaults with positional name and value'); + +promise_test(async testCase => { + await cookieStore.delete('cookie-name'); + + await cookieStore.set({ name: 'cookie-name', value: 'cookie-value' }); + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + assert_equals(cookie.domain, null); + assert_equals(cookie.path, '/'); + assert_equals(cookie.expires, null); + assert_equals(cookie.secure, kIsSecureTransport); + + await async_cleanup(() => cookieStore.delete('cookie-name')); +}, 'cookieStore.set defaults with name and value in options'); + +promise_test(async testCase => { + await cookieStore.delete('cookie-name'); + + await cookieStore.set('cookie-name', 'cookie-value', + { expires: kTenYearsFromNow }); + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + assert_equals(cookie.domain, null); + assert_equals(cookie.path, '/'); + assert_approx_equals(cookie.expires, kTenYearsFromNow, kOneDay); + assert_equals(cookie.secure, kIsSecureTransport); + + await async_cleanup(() => cookieStore.delete('cookie-name')); +}, 'cookieStore.set with expires set to 10 years in the future'); + +promise_test(async testCase => { + await cookieStore.delete('cookie-name'); + + await cookieStore.set({ name: 'cookie-name', value: 'cookie-value', + expires: kTenYearsFromNow }); + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + assert_equals(cookie.domain, null); + assert_equals(cookie.path, '/'); + assert_approx_equals(cookie.expires, kTenYearsFromNow, kOneDay); + assert_equals(cookie.secure, kIsSecureTransport); + + await async_cleanup(() => cookieStore.delete('cookie-name')); +}, 'cookieStore.set with name and value in options and expires in the future'); + +promise_test(async testCase => { + await cookieStore.delete('cookie-name', { domain: kCurrentHostname }); + + await cookieStore.set('cookie-name', 'cookie-value', + { domain: kCurrentHostname }); + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + assert_equals(cookie.domain, kCurrentHostname); + assert_equals(cookie.path, '/'); + assert_equals(cookie.expires, null); + assert_equals(cookie.secure, kIsSecureTransport); + + await async_cleanup(async () => { + await cookieStore.delete('cookie-name', { domain: kCurrentHostname }); + }); +}, 'cookieStore.set with domain set to the current hostname'); + +promise_test(async testCase => { + const currentUrl = new URL(self.location.href); + const currentPath = currentUrl.pathname; + const currentDirectory = + currentPath.substr(0, currentPath.lastIndexOf('/') + 1); + await cookieStore.delete('cookie-name', { path: currentDirectory }); + + await cookieStore.set('cookie-name', 'cookie-value', + { path: currentDirectory }); + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie.name, 'cookie-name'); + assert_equals(cookie.value, 'cookie-value'); + assert_equals(cookie.domain, null); + assert_equals(cookie.path, currentDirectory); + assert_equals(cookie.expires, null); + assert_equals(cookie.secure, kIsSecureTransport); + + await async_cleanup(async () => { + await cookieStore.delete('cookie-name', { path: currentDirectory }); + }); +}, 'cookieStore.set with path set to the current directory');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_delete_arguments.tentative.window.js b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_delete_arguments.tentative.window.js index 974d16b..9b10204 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_delete_arguments.tentative.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_delete_arguments.tentative.window.js
@@ -86,22 +86,26 @@ const currentUrl = new URL(self.location.href); const currentDomain = currentUrl.hostname; const subDomain = `sub.${currentDomain}`; - await cookieStore.set( - 'cookie-name', 'cookie-value', { domain: currentDomain }); - await cookieStore.delete('cookie-name', { domain: subDomain }); - const cookie = await cookieStore.get('cookie-name'); - assert_equals(cookie.name, 'cookie-name'); - assert_equals(cookie.value, 'cookie-value'); - - await async_cleanup(async () => { - await cookieStore.delete('cookie-name', { domain: currentDomain }) - }); + await promise_rejects(testCase, new TypeError(), cookieStore.delete( + 'cookie-name', 'cookie-value', { domain: subDomain })); }, 'cookieStore.delete with domain set to a subdomain of the current hostname'); promise_test(async testCase => { const currentUrl = new URL(self.location.href); const currentDomain = currentUrl.hostname; + assert_not_equals(currentDomain[0] === '.', + 'this test assumes that the current hostname does not start with .'); + const domainSuffix = currentDomain.substr(1); + + await promise_rejects(testCase, new TypeError(), cookieStore.delete( + 'cookie-name', { domain: domainSuffix })); +}, 'cookieStore.delete with domain set to a non-domain-matching suffix of ' + + 'the current hostname'); + +promise_test(async testCase => { + const currentUrl = new URL(self.location.href); + const currentDomain = currentUrl.hostname; await cookieStore.set( 'cookie-name', 'cookie-value', { domain: currentDomain }); @@ -119,20 +123,23 @@ const currentUrl = new URL(self.location.href); const currentDomain = currentUrl.hostname; const subDomain = `sub.${currentDomain}`; - await cookieStore.set( - 'cookie-name', 'cookie-value', { domain: currentDomain }); - await cookieStore.delete({ name: 'cookie-name', domain: subDomain }); - const cookie = await cookieStore.get('cookie-name'); - assert_equals(cookie.name, 'cookie-name'); - assert_equals(cookie.value, 'cookie-value'); - - await async_cleanup(async () => { - await cookieStore.delete('cookie-name', { domain: currentDomain }) - }); + await promise_rejects(testCase, new TypeError(), cookieStore.delete( + { name: 'cookie-name', domain: subDomain })); }, 'cookieStore.delete with name in options and domain set to a subdomain of ' + 'the current hostname'); +promise_test(async testCase => { + const currentUrl = new URL(self.location.href); + const currentDomain = currentUrl.hostname; + assert_not_equals(currentDomain[0] === '.', + 'this test assumes that the current hostname does not start with .'); + const domainSuffix = currentDomain.substr(1); + + await promise_rejects(testCase, new TypeError(), cookieStore.delete( + { name: 'cookie-name', domain: domainSuffix })); +}, 'cookieStore.delete with name in options and domain set to a ' + + 'non-domain-matching suffix of the current hostname'); promise_test(async testCase => { const currentUrl = new URL(self.location.href);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_arguments.tentative.window.js b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_arguments.tentative.window.js index 9656acf..c35e8de 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_arguments.tentative.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/cookieStore_set_arguments.tentative.window.js
@@ -129,38 +129,51 @@ const currentUrl = new URL(self.location.href); const currentDomain = currentUrl.hostname; const subDomain = `sub.${currentDomain}`; - await cookieStore.delete('cookie-name', { domain: currentDomain }); - await cookieStore.delete('cookie-name', { domain: subDomain }); - await cookieStore.set( - 'cookie-name', 'cookie-value', { domain: subDomain }); + await promise_rejects(testCase, new TypeError(), cookieStore.set( + 'cookie-name', 'cookie-value', { domain: subDomain })); const cookie = await cookieStore.get('cookie-name'); assert_equals(cookie, null); - - await async_cleanup(async () => { - await cookieStore.delete('cookie-name', { domain: subDomain }); - }); }, 'cookieStore.set with domain set to a subdomain of the current hostname'); promise_test(async testCase => { const currentUrl = new URL(self.location.href); const currentDomain = currentUrl.hostname; + assert_not_equals(currentDomain[0] === '.', + 'this test assumes that the current hostname does not start with .'); + const domainSuffix = currentDomain.substr(1); + + await promise_rejects(testCase, new TypeError(), cookieStore.set( + 'cookie-name', 'cookie-value', { domain: domainSuffix })); + const cookie = await cookieStore.get('cookie-name'); + assert_equals(cookie, null); +}, 'cookieStore.set with domain set to a non-domain-matching suffix of the ' + + 'current hostname'); + +promise_test(async testCase => { + const currentUrl = new URL(self.location.href); + const currentDomain = currentUrl.hostname; await cookieStore.delete('cookie-name'); - await cookieStore.set('cookie-name', 'cookie-old-value'); - await cookieStore.set( - 'cookie-name', 'cookie-new-value', { domain: currentDomain }); + await cookieStore.set('cookie-name', 'cookie-value1'); + await cookieStore.set('cookie-name', 'cookie-value2', + { domain: currentDomain }); const cookies = await cookieStore.getAll('cookie-name'); - assert_equals(cookies.length, 1); + assert_equals(cookies.length, 2); + assert_equals(cookies[0].name, 'cookie-name'); - assert_equals(cookies[0].value, 'cookie-new-value'); + assert_equals(cookies[1].name, 'cookie-name'); + + const values = cookies.map((cookie) => cookie.value); + values.sort(); + assert_array_equals(values, ['cookie-value1', 'cookie-value2']); await async_cleanup(async () => { await cookieStore.delete('cookie-name'); await cookieStore.delete('cookie-name', { domain: currentDomain }); }); -}, 'cookieStore.set default domain is current hostname'); +}, 'cookieStore.set default domain is null and differs from current hostname'); promise_test(async testCase => { const currentUrl = new URL(self.location.href);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/elementFromPoint-mixed-font-sizes.html b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/elementFromPoint-mixed-font-sizes.html new file mode 100644 index 0000000..e2bac90 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/elementFromPoint-mixed-font-sizes.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<link rel="help" href="http://www.w3.org/TR/cssom-view/#extensions-to-the-document-interface"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div style="font-size: 40px"> + <span id="target"> + XXX <span id="small" style="font-size:10px">small</span> YYY + </span> +</div> +<script> +test(() => { + // Find a point in the empty region above the "small" span, but still inside + // the "target" span. + const small = document.getElementById('small'); + const rect = small.getBoundingClientRect(); + const x = rect.left + rect.width / 2; + const y = rect.top - 5; + + const actual = document.elementFromPoint(x, y); + const target = document.getElementById('target'); + assert_equals(actual, target); +}, 'document.elementFromPoint finds container SPAN in the empty region above a child SPAN with a smaller font size'); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/encrypted-media/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/encrypted-media/idlharness.https.html index a609f94..6a2ae80a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/encrypted-media/idlharness.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/encrypted-media/idlharness.https.html
@@ -20,31 +20,18 @@ <div id='log'></div> <script> - setup(function() { + 'use strict'; - fetch( '/interfaces/encrypted-media.idl' ) - .then( function( response ) { - if ( !response.ok ) throw new Error( 'IDL fetch failed' ); - return response.text(); - } ) - .then( function( idls ) { - - var idl_array = new IdlArray(); - idl_array.add_untested_idls("interface Navigator {};"); - idl_array.add_untested_idls("interface HTMLMediaElement {};"); - idl_array.add_untested_idls("interface Event {};"); - idl_array.add_untested_idls("dictionary EventInit {};"); - idl_array.add_untested_idls("interface EventTarget {};"); - - idl_array.add_idls(idls); - - idl_array.test(); - - done(); - - } ); - - }, {explicit_done: true}); + promise_test(async () => { + const idls = await fetch('/interfaces/encrypted-media.idl').then(r => r.text()); + const html = await fetch('/interfaces/html.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + var idl_array = new IdlArray(); + idl_array.add_idls(idls); + idl_array.add_dependency_idls(html); + idl_array.add_dependency_idls(dom); + idl_array.test(); + }, 'Test encrypted-media IDL'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/idl.any.js b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/idl.any.js index 129a7ce..9fd5eccd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/idl.any.js +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/idl.any.js
@@ -4,7 +4,7 @@ promise_test(async() => { const text = await (await fetch("/interfaces/fetch.idl")).text(); - const referrer_policy = await (await fetch("/interfaces/webappsec-referrer-policy.idl")).text(); + const referrer_policy = await (await fetch("/interfaces/referrer-policy.idl")).text(); const idl_array = new IdlArray(); idl_array.add_idls(text); idl_array.add_untested_idls("[Exposed=(Window,Worker)] interface AbortSignal {};");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none-expected.txt new file mode 100644 index 0000000..6fb19bd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none-expected.txt
@@ -0,0 +1,175 @@ +This is a testharness.js-based test. +Found 171 tests; 154 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS <img srcset="/images/green-1x1.png?a2 300w, /images/green-16x16.png?a2 301w"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?b2 450w, /images/green-16x16.png?b2 451w"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?c2 600w, /images/green-16x16.png?c2 601w"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?d2 900w, /images/green-16x16.png?d2 901w"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?e2 50w, /images/green-16x16.png?e2 51w" sizes="0"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e3 50w, /images/green-16x16.png?e3 51w" sizes="-0"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e4 50w, /images/green-16x16.png?e4 51w" sizes="+0"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e5 50w, /images/green-16x16.png?e5 51w" sizes="+1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e6 50w, /images/green-16x16.png?e6 51w" sizes=".1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e7 50w, /images/green-16x16.png?e7 51w" sizes="0.1em"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e8 50w, /images/green-16x16.png?e8 51w" sizes="0.1ex"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e9 50w, /images/green-16x16.png?e9 51w" sizes="0.1ch"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e10 50w, /images/green-16x16.png?e10 51w" sizes="0.1rem"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e11 50w, /images/green-16x16.png?e11 51w" sizes="0.1vw"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e12 50w, /images/green-16x16.png?e12 51w" sizes="0.1vh"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e13 50w, /images/green-16x16.png?e13 51w" sizes="0.1vmin"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e14 50w, /images/green-16x16.png?e14 51w" sizes="0.1vmax"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e15 50w, /images/green-16x16.png?e15 51w" sizes="0.1cm"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e16 50w, /images/green-16x16.png?e16 51w" sizes="1mm"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e17 50w, /images/green-16x16.png?e17 51w" sizes="1q"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e18 50w, /images/green-16x16.png?e18 51w" sizes="0.01in"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e19 50w, /images/green-16x16.png?e19 51w" sizes="0.1pc"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e20 50w, /images/green-16x16.png?e20 51w" sizes="0.1pt"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e21 50w, /images/green-16x16.png?e21 51w" sizes="/* */1px/* */"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e22 50w, /images/green-16x16.png?e22 51w" sizes=" /**/ /**/ 1px /**/ /**/ "> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e23 50w, /images/green-16x16.png?e23 51w" sizes="(),1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e24 50w, /images/green-16x16.png?e24 51w" sizes="x(),1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e25 50w, /images/green-16x16.png?e25 51w" sizes="{},1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e26 50w, /images/green-16x16.png?e26 51w" sizes="[],1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e27 50w, /images/green-16x16.png?e27 51w" sizes="1px,("> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e28 50w, /images/green-16x16.png?e28 51w" sizes="1px,x("> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e29 50w, /images/green-16x16.png?e29 51w" sizes="1px,{"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e30 50w, /images/green-16x16.png?e30 51w" sizes="1px,["> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e31 50w, /images/green-16x16.png?e31 51w" sizes="\(,1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e32 50w, /images/green-16x16.png?e32 51w" sizes="x\(,1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e33 50w, /images/green-16x16.png?e33 51w" sizes="\{,1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e34 50w, /images/green-16x16.png?e34 51w" sizes="\[,1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e35 50w, /images/green-16x16.png?e35 51w" sizes="1\p\x"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e36 50w, /images/green-16x16.png?e36 51w" sizes="calc(1px)"> ref sizes="1px" (display:none) +FAIL <img srcset="/images/green-1x1.png?e36a 50w, /images/green-16x16.png?e36a 51w" sizes="min(1px, 100px)"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e36b 50w, /images/green-16x16.png?e36b 51w" sizes="min(-100px, 1px)"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e37 50w, /images/green-16x16.png?e37 51w" sizes="(min-width:0) calc(1px)"> ref sizes="1px" (display:none) +FAIL <img srcset="/images/green-1x1.png?e37a 50w, /images/green-16x16.png?e37a 51w" sizes="(min-width:0) min(1px, 100px)"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e37b 50w, /images/green-16x16.png?e37b 51w" sizes="(min-width:0) max(-100px, 1px)"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w" sizes="(min-width:calc(0)) 1px"> ref sizes="1px" (display:none) +FAIL <img srcset="/images/green-1x1.png?e38a 50w, /images/green-16x16.png?e38a 51w" sizes="(min-width:min(0, 200vw)) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e38b 50w, /images/green-16x16.png?e38b 51w" sizes="(min-width:max(-200vw, 0)) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e39 50w, /images/green-16x16.png?e39 51w" sizes="(min-width:0) 1px, 100vw"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e40 50w, /images/green-16x16.png?e40 51w" sizes="(min-width:0) 1px, (min-width:0) 100vw, 100vw"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e41 50w, /images/green-16x16.png?e41 51w" sizes="(min-width:0) 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e42 50w, /images/green-16x16.png?e42 51w" sizes="not (min-width:0) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e43 50w, /images/green-16x16.png?e43 51w" sizes="(min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e44 50w, /images/green-16x16.png?e44 51w" sizes="not (min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e45 50w, /images/green-16x16.png?e45 51w" sizes="(min-width:-1px) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e46 50w, /images/green-16x16.png?e46 51w" sizes="not (min-width:-1px) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e47 50w, /images/green-16x16.png?e47 51w" sizes="(unknown-mf-name) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e48 50w, /images/green-16x16.png?e48 51w" sizes="not (unknown-mf-name) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e49 50w, /images/green-16x16.png?e49 51w" sizes="(unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e50 50w, /images/green-16x16.png?e50 51w" sizes="not (unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e51 50w, /images/green-16x16.png?e51 51w" sizes="unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e52 50w, /images/green-16x16.png?e52 51w" sizes="not unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e53 50w, /images/green-16x16.png?e53 51w" sizes="print 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e54 50w, /images/green-16x16.png?e54 51w" sizes="not print 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e55 50w, /images/green-16x16.png?e55 51w" sizes="unknown-media-type 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e56 50w, /images/green-16x16.png?e56 51w" sizes="not unknown-media-type 100vw, 1px"> ref sizes="1px" (display:none) +FAIL <img srcset="/images/green-1x1.png?e57 50w, /images/green-16x16.png?e57 51w" sizes="(min-width:0) or (min-width:0) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e58 50w, /images/green-16x16.png?e58 51w" sizes="(min-width:0) or (unknown-mf-name) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e59 50w, /images/green-16x16.png?e59 51w" sizes="(min-width:0) or (min-width:unknown-mf-value) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e60 50w, /images/green-16x16.png?e60 51w" sizes="(min-width:0) or (min-width:-1px) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e61 50w, /images/green-16x16.png?e61 51w" sizes="(min-width:0) or (unknown "general-enclosed") 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e62 50w, /images/green-16x16.png?e62 51w" sizes="(min-width:0) or unknown-general-enclosed(foo) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e63 50w, /images/green-16x16.png?e63 51w" sizes="(min-width:0) or (!) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e64 50w, /images/green-16x16.png?e64 51w" sizes="(min-width:0) or unknown-media-type 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e65 50w, /images/green-16x16.png?e65 51w" sizes="(123) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e66 50w, /images/green-16x16.png?e66 51w" sizes="not (123) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e67 50w, /images/green-16x16.png?e67 51w" sizes="(!) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e68 50w, /images/green-16x16.png?e68 51w" sizes="not (!) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e69 50w, /images/green-16x16.png?e69 51w" sizes="! 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e70 50w, /images/green-16x16.png?e70 51w" sizes="not ! 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e71 50w, /images/green-16x16.png?e71 51w" sizes="(]) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e72 50w, /images/green-16x16.png?e72 51w" sizes="not (]) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e73 50w, /images/green-16x16.png?e73 51w" sizes="] 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e74 50w, /images/green-16x16.png?e74 51w" sizes="not ] 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e75 50w, /images/green-16x16.png?e75 51w" sizes="(}) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e76 50w, /images/green-16x16.png?e76 51w" sizes="not (}) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e77 50w, /images/green-16x16.png?e77 51w" sizes="} 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e78 50w, /images/green-16x16.png?e78 51w" sizes="not } 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e79 50w, /images/green-16x16.png?e79 51w" sizes=") 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e80 50w, /images/green-16x16.png?e80 51w" sizes="not ) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e81 50w, /images/green-16x16.png?e81 51w" sizes="(;) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e82 50w, /images/green-16x16.png?e82 51w" sizes="not (;) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e83 50w, /images/green-16x16.png?e83 51w" sizes="(.) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e84 50w, /images/green-16x16.png?e84 51w" sizes="not (.) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e85 50w, /images/green-16x16.png?e85 51w" sizes="; 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e86 50w, /images/green-16x16.png?e86 51w" sizes="not ; 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e87 50w, /images/green-16x16.png?e87 51w" sizes=", 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e88 50w, /images/green-16x16.png?e88 51w" sizes="1px,"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e89 50w, /images/green-16x16.png?e89 51w" sizes="(min-width:0) 1px,"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e90 50w, /images/green-16x16.png?e90 51w" sizes="-0e-0px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e91 50w, /images/green-16x16.png?e91 51w" sizes="+0.11e+01px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e92 50w, /images/green-16x16.png?e92 51w" sizes="0.2e1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e93 50w, /images/green-16x16.png?e93 51w" sizes="0.3E1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e94 50w, /images/green-16x16.png?e94 51w" sizes=".4E1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e95 50w, /images/green-16x16.png?e95 51w" sizes="all 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e96 50w, /images/green-16x16.png?e96 51w" sizes="all and (min-width:0) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e97 50w, /images/green-16x16.png?e97 51w" sizes="min-width:0 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e98 50w, /images/green-16x16.png?e98 51w" sizes="1px, 100vw"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e99 50w, /images/green-16x16.png?e99 51w" sizes="1px, (min-width:0) 100vw"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e100 50w, /images/green-16x16.png?e100 51w" sizes="1px, foo bar"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e101 50w, /images/green-16x16.png?e101 51w" sizes="(min-width:0) 1px, foo bar"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e102 50w, /images/green-16x16.png?e102 51w" sizes="("grammar does not match") 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e103 50w, /images/green-16x16.png?e103 51w" sizes="not ("grammar does not match") 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e104 50w, /images/green-16x16.png?e104 51w" sizes="(unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e105 50w, /images/green-16x16.png?e105 51w" sizes="not (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (display:none) +FAIL <img srcset="/images/green-1x1.png?e106 50w, /images/green-16x16.png?e106 51w" sizes="(min-width:0) or (unknown-general-enclosed !) 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e107 50w, /images/green-16x16.png?e107 51w" sizes="not ((min-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e108 50w, /images/green-16x16.png?e108 51w" sizes="(max-width:0) or (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?e109 50w, /images/green-16x16.png?e109 51w" sizes="not ((max-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (display:none) +PASS <img srcset="/images/green-1x1.png?f48 50w, /images/green-16x16.png?f48 51w" sizes="calc(1px"> ref sizes="1px" (display:none) +FAIL <img srcset="/images/green-1x1.png?f48a 50w, /images/green-16x16.png?f48a 51w" sizes="min(1px, 200vw"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f48b 50w, /images/green-16x16.png?f48b 51w" sizes="max(-200vw, 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f49 50w, /images/green-16x16.png?f49 51w" sizes="(min-width:0) calc(1px"> ref sizes="1px" (display:none) +FAIL <img srcset="/images/green-1x1.png?f49a 50w, /images/green-16x16.png?f49a 51w" sizes="(min-width:0) min(1px, 200vw"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f49b 50w, /images/green-16x16.png?f49b 51w" sizes="(min-width:0) max(-200vw, 1px"> ref sizes="1px" (display:none) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f2 50w, /images/green-16x16.png?f2 51w" sizes=""> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f3 50w, /images/green-16x16.png?f3 51w" sizes=","> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f4 50w, /images/green-16x16.png?f4 51w" sizes="-1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f5 50w, /images/green-16x16.png?f5 51w" sizes="1"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f6 50w, /images/green-16x16.png?f6 51w" sizes="0.1%"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f7 50w, /images/green-16x16.png?f7 51w" sizes="0.1deg"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f8 50w, /images/green-16x16.png?f8 51w" sizes="0.1grad"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f9 50w, /images/green-16x16.png?f9 51w" sizes="0.1rad"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f10 50w, /images/green-16x16.png?f10 51w" sizes="0.1turn"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f11 50w, /images/green-16x16.png?f11 51w" sizes="0.1s"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f12 50w, /images/green-16x16.png?f12 51w" sizes="0.1ms"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f13 50w, /images/green-16x16.png?f13 51w" sizes="0.1Hz"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f14 50w, /images/green-16x16.png?f14 51w" sizes="0.1kHz"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f15 50w, /images/green-16x16.png?f15 51w" sizes="0.1dpi"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f16 50w, /images/green-16x16.png?f16 51w" sizes="0.1dpcm"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f17 50w, /images/green-16x16.png?f17 51w" sizes="0.1dppx"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f17a 50w, /images/green-16x16.png?f17a 51w" sizes="0.1x"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f18 50w, /images/green-16x16.png?f18 51w" data-foo="1px" sizes="attr(data-foo, length, 1px)"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f19 50w, /images/green-16x16.png?f19 51w" data-foo="1" sizes="attr(data-foo, px, 1px)"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f20 50w, /images/green-16x16.png?f20 51w" sizes="toggle(1px)"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f21 50w, /images/green-16x16.png?f21 51w" sizes="inherit"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f22 50w, /images/green-16x16.png?f22 51w" sizes="auto"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f23 50w, /images/green-16x16.png?f23 51w" sizes="initial"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f24 50w, /images/green-16x16.png?f24 51w" sizes="unset"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f25 50w, /images/green-16x16.png?f25 51w" sizes="default"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f26 50w, /images/green-16x16.png?f26 51w" sizes="1/* */px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f27 50w, /images/green-16x16.png?f27 51w" sizes="1p/* */x"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f28 50w, /images/green-16x16.png?f28 51w" sizes="-/**/0"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f29 50w, /images/green-16x16.png?f29 51w" sizes="((),1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f30 50w, /images/green-16x16.png?f30 51w" sizes="x(x(),1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f31 50w, /images/green-16x16.png?f31 51w" sizes="{{},1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f32 50w, /images/green-16x16.png?f32 51w" sizes="[[],1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f33 50w, /images/green-16x16.png?f33 51w" sizes="1px !important"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f34 50w, /images/green-16x16.png?f34 51w" sizes="\1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f35 50w, /images/green-16x16.png?f35 51w" sizes="all 1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f36 50w, /images/green-16x16.png?f36 51w" sizes="all and (min-width:0) 1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f37 50w, /images/green-16x16.png?f37 51w" sizes="min-width:0 1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f38 50w, /images/green-16x16.png?f38 51w" sizes="100vw, 1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f39 50w, /images/green-16x16.png?f39 51w" sizes="100vw, (min-width:0) 1px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f40 50w, /images/green-16x16.png?f40 51w" sizes="foo bar"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f41 50w, /images/green-16x16.png?f41 51w" sizes="foo-bar"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f42 50w, /images/green-16x16.png?f42 51w" sizes="(min-width:0) 1px foo bar"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f43 50w, /images/green-16x16.png?f43 51w" sizes="(min-width:0) 0.1%"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f44 50w, /images/green-16x16.png?f44 51w" sizes="(min-width:0) 1"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f45 50w, /images/green-16x16.png?f45 51w" sizes="-1e0px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f46 50w, /images/green-16x16.png?f46 51w" sizes="1e1.5px"> ref sizes="100vw" (display:none) +PASS <img srcset="/images/green-1x1.png?f47 50w, /images/green-16x16.png?f47 51w" style="--foo: 1px" sizes="var(--foo)"> ref sizes="100vw" (display:none) +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none.html new file mode 100644 index 0000000..6aa77eb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-display-none.html
@@ -0,0 +1,7 @@ +<!doctype html> +<title>img parse a sizes attribute (display:none)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<iframe data-desc="display:none" style="width:1000px; height:1000px" src="support/sizes-iframed.sub.html?doctype=doctype%20html&style=display:none"></iframe> +<script src="support/parse-a-sizes-attribute.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode-expected.txt new file mode 100644 index 0000000..0e8e35a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode-expected.txt
@@ -0,0 +1,175 @@ +This is a testharness.js-based test. +Found 171 tests; 154 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS <img srcset="/images/green-1x1.png?a2 300w, /images/green-16x16.png?a2 301w"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?b2 450w, /images/green-16x16.png?b2 451w"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?c2 600w, /images/green-16x16.png?c2 601w"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?d2 900w, /images/green-16x16.png?d2 901w"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e2 50w, /images/green-16x16.png?e2 51w" sizes="0"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e3 50w, /images/green-16x16.png?e3 51w" sizes="-0"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e4 50w, /images/green-16x16.png?e4 51w" sizes="+0"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e5 50w, /images/green-16x16.png?e5 51w" sizes="+1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e6 50w, /images/green-16x16.png?e6 51w" sizes=".1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e7 50w, /images/green-16x16.png?e7 51w" sizes="0.1em"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e8 50w, /images/green-16x16.png?e8 51w" sizes="0.1ex"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e9 50w, /images/green-16x16.png?e9 51w" sizes="0.1ch"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e10 50w, /images/green-16x16.png?e10 51w" sizes="0.1rem"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e11 50w, /images/green-16x16.png?e11 51w" sizes="0.1vw"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e12 50w, /images/green-16x16.png?e12 51w" sizes="0.1vh"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e13 50w, /images/green-16x16.png?e13 51w" sizes="0.1vmin"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e14 50w, /images/green-16x16.png?e14 51w" sizes="0.1vmax"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e15 50w, /images/green-16x16.png?e15 51w" sizes="0.1cm"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e16 50w, /images/green-16x16.png?e16 51w" sizes="1mm"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e17 50w, /images/green-16x16.png?e17 51w" sizes="1q"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e18 50w, /images/green-16x16.png?e18 51w" sizes="0.01in"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e19 50w, /images/green-16x16.png?e19 51w" sizes="0.1pc"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e20 50w, /images/green-16x16.png?e20 51w" sizes="0.1pt"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e21 50w, /images/green-16x16.png?e21 51w" sizes="/* */1px/* */"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e22 50w, /images/green-16x16.png?e22 51w" sizes=" /**/ /**/ 1px /**/ /**/ "> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e23 50w, /images/green-16x16.png?e23 51w" sizes="(),1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e24 50w, /images/green-16x16.png?e24 51w" sizes="x(),1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e25 50w, /images/green-16x16.png?e25 51w" sizes="{},1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e26 50w, /images/green-16x16.png?e26 51w" sizes="[],1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e27 50w, /images/green-16x16.png?e27 51w" sizes="1px,("> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e28 50w, /images/green-16x16.png?e28 51w" sizes="1px,x("> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e29 50w, /images/green-16x16.png?e29 51w" sizes="1px,{"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e30 50w, /images/green-16x16.png?e30 51w" sizes="1px,["> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e31 50w, /images/green-16x16.png?e31 51w" sizes="\(,1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e32 50w, /images/green-16x16.png?e32 51w" sizes="x\(,1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e33 50w, /images/green-16x16.png?e33 51w" sizes="\{,1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e34 50w, /images/green-16x16.png?e34 51w" sizes="\[,1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e35 50w, /images/green-16x16.png?e35 51w" sizes="1\p\x"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e36 50w, /images/green-16x16.png?e36 51w" sizes="calc(1px)"> ref sizes="1px" (quirks mode) +FAIL <img srcset="/images/green-1x1.png?e36a 50w, /images/green-16x16.png?e36a 51w" sizes="min(1px, 100px)"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e36b 50w, /images/green-16x16.png?e36b 51w" sizes="min(-100px, 1px)"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e37 50w, /images/green-16x16.png?e37 51w" sizes="(min-width:0) calc(1px)"> ref sizes="1px" (quirks mode) +FAIL <img srcset="/images/green-1x1.png?e37a 50w, /images/green-16x16.png?e37a 51w" sizes="(min-width:0) min(1px, 100px)"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e37b 50w, /images/green-16x16.png?e37b 51w" sizes="(min-width:0) max(-100px, 1px)"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w" sizes="(min-width:calc(0)) 1px"> ref sizes="1px" (quirks mode) +FAIL <img srcset="/images/green-1x1.png?e38a 50w, /images/green-16x16.png?e38a 51w" sizes="(min-width:min(0, 200vw)) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e38b 50w, /images/green-16x16.png?e38b 51w" sizes="(min-width:max(-200vw, 0)) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e39 50w, /images/green-16x16.png?e39 51w" sizes="(min-width:0) 1px, 100vw"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e40 50w, /images/green-16x16.png?e40 51w" sizes="(min-width:0) 1px, (min-width:0) 100vw, 100vw"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e41 50w, /images/green-16x16.png?e41 51w" sizes="(min-width:0) 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e42 50w, /images/green-16x16.png?e42 51w" sizes="not (min-width:0) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e43 50w, /images/green-16x16.png?e43 51w" sizes="(min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e44 50w, /images/green-16x16.png?e44 51w" sizes="not (min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e45 50w, /images/green-16x16.png?e45 51w" sizes="(min-width:-1px) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e46 50w, /images/green-16x16.png?e46 51w" sizes="not (min-width:-1px) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e47 50w, /images/green-16x16.png?e47 51w" sizes="(unknown-mf-name) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e48 50w, /images/green-16x16.png?e48 51w" sizes="not (unknown-mf-name) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e49 50w, /images/green-16x16.png?e49 51w" sizes="(unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e50 50w, /images/green-16x16.png?e50 51w" sizes="not (unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e51 50w, /images/green-16x16.png?e51 51w" sizes="unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e52 50w, /images/green-16x16.png?e52 51w" sizes="not unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e53 50w, /images/green-16x16.png?e53 51w" sizes="print 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e54 50w, /images/green-16x16.png?e54 51w" sizes="not print 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e55 50w, /images/green-16x16.png?e55 51w" sizes="unknown-media-type 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e56 50w, /images/green-16x16.png?e56 51w" sizes="not unknown-media-type 100vw, 1px"> ref sizes="1px" (quirks mode) +FAIL <img srcset="/images/green-1x1.png?e57 50w, /images/green-16x16.png?e57 51w" sizes="(min-width:0) or (min-width:0) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e58 50w, /images/green-16x16.png?e58 51w" sizes="(min-width:0) or (unknown-mf-name) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e59 50w, /images/green-16x16.png?e59 51w" sizes="(min-width:0) or (min-width:unknown-mf-value) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e60 50w, /images/green-16x16.png?e60 51w" sizes="(min-width:0) or (min-width:-1px) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e61 50w, /images/green-16x16.png?e61 51w" sizes="(min-width:0) or (unknown "general-enclosed") 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e62 50w, /images/green-16x16.png?e62 51w" sizes="(min-width:0) or unknown-general-enclosed(foo) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e63 50w, /images/green-16x16.png?e63 51w" sizes="(min-width:0) or (!) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e64 50w, /images/green-16x16.png?e64 51w" sizes="(min-width:0) or unknown-media-type 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e65 50w, /images/green-16x16.png?e65 51w" sizes="(123) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e66 50w, /images/green-16x16.png?e66 51w" sizes="not (123) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e67 50w, /images/green-16x16.png?e67 51w" sizes="(!) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e68 50w, /images/green-16x16.png?e68 51w" sizes="not (!) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e69 50w, /images/green-16x16.png?e69 51w" sizes="! 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e70 50w, /images/green-16x16.png?e70 51w" sizes="not ! 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e71 50w, /images/green-16x16.png?e71 51w" sizes="(]) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e72 50w, /images/green-16x16.png?e72 51w" sizes="not (]) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e73 50w, /images/green-16x16.png?e73 51w" sizes="] 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e74 50w, /images/green-16x16.png?e74 51w" sizes="not ] 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e75 50w, /images/green-16x16.png?e75 51w" sizes="(}) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e76 50w, /images/green-16x16.png?e76 51w" sizes="not (}) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e77 50w, /images/green-16x16.png?e77 51w" sizes="} 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e78 50w, /images/green-16x16.png?e78 51w" sizes="not } 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e79 50w, /images/green-16x16.png?e79 51w" sizes=") 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e80 50w, /images/green-16x16.png?e80 51w" sizes="not ) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e81 50w, /images/green-16x16.png?e81 51w" sizes="(;) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e82 50w, /images/green-16x16.png?e82 51w" sizes="not (;) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e83 50w, /images/green-16x16.png?e83 51w" sizes="(.) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e84 50w, /images/green-16x16.png?e84 51w" sizes="not (.) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e85 50w, /images/green-16x16.png?e85 51w" sizes="; 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e86 50w, /images/green-16x16.png?e86 51w" sizes="not ; 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e87 50w, /images/green-16x16.png?e87 51w" sizes=", 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e88 50w, /images/green-16x16.png?e88 51w" sizes="1px,"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e89 50w, /images/green-16x16.png?e89 51w" sizes="(min-width:0) 1px,"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e90 50w, /images/green-16x16.png?e90 51w" sizes="-0e-0px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e91 50w, /images/green-16x16.png?e91 51w" sizes="+0.11e+01px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e92 50w, /images/green-16x16.png?e92 51w" sizes="0.2e1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e93 50w, /images/green-16x16.png?e93 51w" sizes="0.3E1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e94 50w, /images/green-16x16.png?e94 51w" sizes=".4E1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e95 50w, /images/green-16x16.png?e95 51w" sizes="all 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e96 50w, /images/green-16x16.png?e96 51w" sizes="all and (min-width:0) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e97 50w, /images/green-16x16.png?e97 51w" sizes="min-width:0 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e98 50w, /images/green-16x16.png?e98 51w" sizes="1px, 100vw"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e99 50w, /images/green-16x16.png?e99 51w" sizes="1px, (min-width:0) 100vw"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e100 50w, /images/green-16x16.png?e100 51w" sizes="1px, foo bar"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e101 50w, /images/green-16x16.png?e101 51w" sizes="(min-width:0) 1px, foo bar"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e102 50w, /images/green-16x16.png?e102 51w" sizes="("grammar does not match") 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e103 50w, /images/green-16x16.png?e103 51w" sizes="not ("grammar does not match") 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e104 50w, /images/green-16x16.png?e104 51w" sizes="(unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e105 50w, /images/green-16x16.png?e105 51w" sizes="not (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (quirks mode) +FAIL <img srcset="/images/green-1x1.png?e106 50w, /images/green-16x16.png?e106 51w" sizes="(min-width:0) or (unknown-general-enclosed !) 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e107 50w, /images/green-16x16.png?e107 51w" sizes="not ((min-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e108 50w, /images/green-16x16.png?e108 51w" sizes="(max-width:0) or (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?e109 50w, /images/green-16x16.png?e109 51w" sizes="not ((max-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f48 50w, /images/green-16x16.png?f48 51w" sizes="calc(1px"> ref sizes="1px" (quirks mode) +FAIL <img srcset="/images/green-1x1.png?f48a 50w, /images/green-16x16.png?f48a 51w" sizes="min(1px, 200vw"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f48b 50w, /images/green-16x16.png?f48b 51w" sizes="max(-200vw, 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f49 50w, /images/green-16x16.png?f49 51w" sizes="(min-width:0) calc(1px"> ref sizes="1px" (quirks mode) +FAIL <img srcset="/images/green-1x1.png?f49a 50w, /images/green-16x16.png?f49a 51w" sizes="(min-width:0) min(1px, 200vw"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f49b 50w, /images/green-16x16.png?f49b 51w" sizes="(min-width:0) max(-200vw, 1px"> ref sizes="1px" (quirks mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f2 50w, /images/green-16x16.png?f2 51w" sizes=""> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f3 50w, /images/green-16x16.png?f3 51w" sizes=","> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f4 50w, /images/green-16x16.png?f4 51w" sizes="-1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f5 50w, /images/green-16x16.png?f5 51w" sizes="1"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f6 50w, /images/green-16x16.png?f6 51w" sizes="0.1%"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f7 50w, /images/green-16x16.png?f7 51w" sizes="0.1deg"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f8 50w, /images/green-16x16.png?f8 51w" sizes="0.1grad"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f9 50w, /images/green-16x16.png?f9 51w" sizes="0.1rad"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f10 50w, /images/green-16x16.png?f10 51w" sizes="0.1turn"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f11 50w, /images/green-16x16.png?f11 51w" sizes="0.1s"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f12 50w, /images/green-16x16.png?f12 51w" sizes="0.1ms"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f13 50w, /images/green-16x16.png?f13 51w" sizes="0.1Hz"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f14 50w, /images/green-16x16.png?f14 51w" sizes="0.1kHz"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f15 50w, /images/green-16x16.png?f15 51w" sizes="0.1dpi"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f16 50w, /images/green-16x16.png?f16 51w" sizes="0.1dpcm"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f17 50w, /images/green-16x16.png?f17 51w" sizes="0.1dppx"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f17a 50w, /images/green-16x16.png?f17a 51w" sizes="0.1x"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f18 50w, /images/green-16x16.png?f18 51w" data-foo="1px" sizes="attr(data-foo, length, 1px)"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f19 50w, /images/green-16x16.png?f19 51w" data-foo="1" sizes="attr(data-foo, px, 1px)"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f20 50w, /images/green-16x16.png?f20 51w" sizes="toggle(1px)"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f21 50w, /images/green-16x16.png?f21 51w" sizes="inherit"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f22 50w, /images/green-16x16.png?f22 51w" sizes="auto"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f23 50w, /images/green-16x16.png?f23 51w" sizes="initial"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f24 50w, /images/green-16x16.png?f24 51w" sizes="unset"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f25 50w, /images/green-16x16.png?f25 51w" sizes="default"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f26 50w, /images/green-16x16.png?f26 51w" sizes="1/* */px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f27 50w, /images/green-16x16.png?f27 51w" sizes="1p/* */x"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f28 50w, /images/green-16x16.png?f28 51w" sizes="-/**/0"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f29 50w, /images/green-16x16.png?f29 51w" sizes="((),1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f30 50w, /images/green-16x16.png?f30 51w" sizes="x(x(),1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f31 50w, /images/green-16x16.png?f31 51w" sizes="{{},1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f32 50w, /images/green-16x16.png?f32 51w" sizes="[[],1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f33 50w, /images/green-16x16.png?f33 51w" sizes="1px !important"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f34 50w, /images/green-16x16.png?f34 51w" sizes="\1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f35 50w, /images/green-16x16.png?f35 51w" sizes="all 1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f36 50w, /images/green-16x16.png?f36 51w" sizes="all and (min-width:0) 1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f37 50w, /images/green-16x16.png?f37 51w" sizes="min-width:0 1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f38 50w, /images/green-16x16.png?f38 51w" sizes="100vw, 1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f39 50w, /images/green-16x16.png?f39 51w" sizes="100vw, (min-width:0) 1px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f40 50w, /images/green-16x16.png?f40 51w" sizes="foo bar"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f41 50w, /images/green-16x16.png?f41 51w" sizes="foo-bar"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f42 50w, /images/green-16x16.png?f42 51w" sizes="(min-width:0) 1px foo bar"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f43 50w, /images/green-16x16.png?f43 51w" sizes="(min-width:0) 0.1%"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f44 50w, /images/green-16x16.png?f44 51w" sizes="(min-width:0) 1"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f45 50w, /images/green-16x16.png?f45 51w" sizes="-1e0px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f46 50w, /images/green-16x16.png?f46 51w" sizes="1e1.5px"> ref sizes="100vw" (quirks mode) +PASS <img srcset="/images/green-1x1.png?f47 50w, /images/green-16x16.png?f47 51w" style="--foo: 1px" sizes="var(--foo)"> ref sizes="100vw" (quirks mode) +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode.html new file mode 100644 index 0000000..2150192 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-quirks-mode.html
@@ -0,0 +1,7 @@ +<!doctype html> +<title>img parse a sizes attribute (quirks mode)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<iframe data-desc="quirks mode" style="width:1000px; height:1000px" src="support/sizes-iframed.sub.html?doctype=----&style="></iframe> +<script src="support/parse-a-sizes-attribute.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode-expected.txt new file mode 100644 index 0000000..c0e0f75 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode-expected.txt
@@ -0,0 +1,175 @@ +This is a testharness.js-based test. +Found 171 tests; 154 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS <img srcset="/images/green-1x1.png?a2 300w, /images/green-16x16.png?a2 301w"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?b2 450w, /images/green-16x16.png?b2 451w"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?c2 600w, /images/green-16x16.png?c2 601w"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?d2 900w, /images/green-16x16.png?d2 901w"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?e2 50w, /images/green-16x16.png?e2 51w" sizes="0"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e3 50w, /images/green-16x16.png?e3 51w" sizes="-0"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e4 50w, /images/green-16x16.png?e4 51w" sizes="+0"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e5 50w, /images/green-16x16.png?e5 51w" sizes="+1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e6 50w, /images/green-16x16.png?e6 51w" sizes=".1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e7 50w, /images/green-16x16.png?e7 51w" sizes="0.1em"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e8 50w, /images/green-16x16.png?e8 51w" sizes="0.1ex"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e9 50w, /images/green-16x16.png?e9 51w" sizes="0.1ch"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e10 50w, /images/green-16x16.png?e10 51w" sizes="0.1rem"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e11 50w, /images/green-16x16.png?e11 51w" sizes="0.1vw"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e12 50w, /images/green-16x16.png?e12 51w" sizes="0.1vh"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e13 50w, /images/green-16x16.png?e13 51w" sizes="0.1vmin"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e14 50w, /images/green-16x16.png?e14 51w" sizes="0.1vmax"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e15 50w, /images/green-16x16.png?e15 51w" sizes="0.1cm"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e16 50w, /images/green-16x16.png?e16 51w" sizes="1mm"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e17 50w, /images/green-16x16.png?e17 51w" sizes="1q"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e18 50w, /images/green-16x16.png?e18 51w" sizes="0.01in"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e19 50w, /images/green-16x16.png?e19 51w" sizes="0.1pc"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e20 50w, /images/green-16x16.png?e20 51w" sizes="0.1pt"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e21 50w, /images/green-16x16.png?e21 51w" sizes="/* */1px/* */"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e22 50w, /images/green-16x16.png?e22 51w" sizes=" /**/ /**/ 1px /**/ /**/ "> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e23 50w, /images/green-16x16.png?e23 51w" sizes="(),1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e24 50w, /images/green-16x16.png?e24 51w" sizes="x(),1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e25 50w, /images/green-16x16.png?e25 51w" sizes="{},1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e26 50w, /images/green-16x16.png?e26 51w" sizes="[],1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e27 50w, /images/green-16x16.png?e27 51w" sizes="1px,("> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e28 50w, /images/green-16x16.png?e28 51w" sizes="1px,x("> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e29 50w, /images/green-16x16.png?e29 51w" sizes="1px,{"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e30 50w, /images/green-16x16.png?e30 51w" sizes="1px,["> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e31 50w, /images/green-16x16.png?e31 51w" sizes="\(,1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e32 50w, /images/green-16x16.png?e32 51w" sizes="x\(,1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e33 50w, /images/green-16x16.png?e33 51w" sizes="\{,1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e34 50w, /images/green-16x16.png?e34 51w" sizes="\[,1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e35 50w, /images/green-16x16.png?e35 51w" sizes="1\p\x"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e36 50w, /images/green-16x16.png?e36 51w" sizes="calc(1px)"> ref sizes="1px" (standards mode) +FAIL <img srcset="/images/green-1x1.png?e36a 50w, /images/green-16x16.png?e36a 51w" sizes="min(1px, 100px)"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e36b 50w, /images/green-16x16.png?e36b 51w" sizes="min(-100px, 1px)"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e37 50w, /images/green-16x16.png?e37 51w" sizes="(min-width:0) calc(1px)"> ref sizes="1px" (standards mode) +FAIL <img srcset="/images/green-1x1.png?e37a 50w, /images/green-16x16.png?e37a 51w" sizes="(min-width:0) min(1px, 100px)"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e37b 50w, /images/green-16x16.png?e37b 51w" sizes="(min-width:0) max(-100px, 1px)"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w" sizes="(min-width:calc(0)) 1px"> ref sizes="1px" (standards mode) +FAIL <img srcset="/images/green-1x1.png?e38a 50w, /images/green-16x16.png?e38a 51w" sizes="(min-width:min(0, 200vw)) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e38b 50w, /images/green-16x16.png?e38b 51w" sizes="(min-width:max(-200vw, 0)) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e39 50w, /images/green-16x16.png?e39 51w" sizes="(min-width:0) 1px, 100vw"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e40 50w, /images/green-16x16.png?e40 51w" sizes="(min-width:0) 1px, (min-width:0) 100vw, 100vw"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e41 50w, /images/green-16x16.png?e41 51w" sizes="(min-width:0) 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e42 50w, /images/green-16x16.png?e42 51w" sizes="not (min-width:0) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e43 50w, /images/green-16x16.png?e43 51w" sizes="(min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e44 50w, /images/green-16x16.png?e44 51w" sizes="not (min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e45 50w, /images/green-16x16.png?e45 51w" sizes="(min-width:-1px) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e46 50w, /images/green-16x16.png?e46 51w" sizes="not (min-width:-1px) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e47 50w, /images/green-16x16.png?e47 51w" sizes="(unknown-mf-name) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e48 50w, /images/green-16x16.png?e48 51w" sizes="not (unknown-mf-name) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e49 50w, /images/green-16x16.png?e49 51w" sizes="(unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e50 50w, /images/green-16x16.png?e50 51w" sizes="not (unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e51 50w, /images/green-16x16.png?e51 51w" sizes="unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e52 50w, /images/green-16x16.png?e52 51w" sizes="not unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e53 50w, /images/green-16x16.png?e53 51w" sizes="print 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e54 50w, /images/green-16x16.png?e54 51w" sizes="not print 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e55 50w, /images/green-16x16.png?e55 51w" sizes="unknown-media-type 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e56 50w, /images/green-16x16.png?e56 51w" sizes="not unknown-media-type 100vw, 1px"> ref sizes="1px" (standards mode) +FAIL <img srcset="/images/green-1x1.png?e57 50w, /images/green-16x16.png?e57 51w" sizes="(min-width:0) or (min-width:0) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e58 50w, /images/green-16x16.png?e58 51w" sizes="(min-width:0) or (unknown-mf-name) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e59 50w, /images/green-16x16.png?e59 51w" sizes="(min-width:0) or (min-width:unknown-mf-value) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e60 50w, /images/green-16x16.png?e60 51w" sizes="(min-width:0) or (min-width:-1px) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e61 50w, /images/green-16x16.png?e61 51w" sizes="(min-width:0) or (unknown "general-enclosed") 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e62 50w, /images/green-16x16.png?e62 51w" sizes="(min-width:0) or unknown-general-enclosed(foo) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e63 50w, /images/green-16x16.png?e63 51w" sizes="(min-width:0) or (!) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e64 50w, /images/green-16x16.png?e64 51w" sizes="(min-width:0) or unknown-media-type 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e65 50w, /images/green-16x16.png?e65 51w" sizes="(123) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e66 50w, /images/green-16x16.png?e66 51w" sizes="not (123) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e67 50w, /images/green-16x16.png?e67 51w" sizes="(!) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e68 50w, /images/green-16x16.png?e68 51w" sizes="not (!) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e69 50w, /images/green-16x16.png?e69 51w" sizes="! 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e70 50w, /images/green-16x16.png?e70 51w" sizes="not ! 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e71 50w, /images/green-16x16.png?e71 51w" sizes="(]) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e72 50w, /images/green-16x16.png?e72 51w" sizes="not (]) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e73 50w, /images/green-16x16.png?e73 51w" sizes="] 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e74 50w, /images/green-16x16.png?e74 51w" sizes="not ] 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e75 50w, /images/green-16x16.png?e75 51w" sizes="(}) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e76 50w, /images/green-16x16.png?e76 51w" sizes="not (}) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e77 50w, /images/green-16x16.png?e77 51w" sizes="} 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e78 50w, /images/green-16x16.png?e78 51w" sizes="not } 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e79 50w, /images/green-16x16.png?e79 51w" sizes=") 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e80 50w, /images/green-16x16.png?e80 51w" sizes="not ) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e81 50w, /images/green-16x16.png?e81 51w" sizes="(;) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e82 50w, /images/green-16x16.png?e82 51w" sizes="not (;) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e83 50w, /images/green-16x16.png?e83 51w" sizes="(.) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e84 50w, /images/green-16x16.png?e84 51w" sizes="not (.) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e85 50w, /images/green-16x16.png?e85 51w" sizes="; 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e86 50w, /images/green-16x16.png?e86 51w" sizes="not ; 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e87 50w, /images/green-16x16.png?e87 51w" sizes=", 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e88 50w, /images/green-16x16.png?e88 51w" sizes="1px,"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e89 50w, /images/green-16x16.png?e89 51w" sizes="(min-width:0) 1px,"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e90 50w, /images/green-16x16.png?e90 51w" sizes="-0e-0px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e91 50w, /images/green-16x16.png?e91 51w" sizes="+0.11e+01px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e92 50w, /images/green-16x16.png?e92 51w" sizes="0.2e1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e93 50w, /images/green-16x16.png?e93 51w" sizes="0.3E1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e94 50w, /images/green-16x16.png?e94 51w" sizes=".4E1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e95 50w, /images/green-16x16.png?e95 51w" sizes="all 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e96 50w, /images/green-16x16.png?e96 51w" sizes="all and (min-width:0) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e97 50w, /images/green-16x16.png?e97 51w" sizes="min-width:0 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e98 50w, /images/green-16x16.png?e98 51w" sizes="1px, 100vw"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e99 50w, /images/green-16x16.png?e99 51w" sizes="1px, (min-width:0) 100vw"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e100 50w, /images/green-16x16.png?e100 51w" sizes="1px, foo bar"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e101 50w, /images/green-16x16.png?e101 51w" sizes="(min-width:0) 1px, foo bar"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e102 50w, /images/green-16x16.png?e102 51w" sizes="("grammar does not match") 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e103 50w, /images/green-16x16.png?e103 51w" sizes="not ("grammar does not match") 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e104 50w, /images/green-16x16.png?e104 51w" sizes="(unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e105 50w, /images/green-16x16.png?e105 51w" sizes="not (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (standards mode) +FAIL <img srcset="/images/green-1x1.png?e106 50w, /images/green-16x16.png?e106 51w" sizes="(min-width:0) or (unknown-general-enclosed !) 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e107 50w, /images/green-16x16.png?e107 51w" sizes="not ((min-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e108 50w, /images/green-16x16.png?e108 51w" sizes="(max-width:0) or (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?e109 50w, /images/green-16x16.png?e109 51w" sizes="not ((max-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (standards mode) +PASS <img srcset="/images/green-1x1.png?f48 50w, /images/green-16x16.png?f48 51w" sizes="calc(1px"> ref sizes="1px" (standards mode) +FAIL <img srcset="/images/green-1x1.png?f48a 50w, /images/green-16x16.png?f48a 51w" sizes="min(1px, 200vw"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f48b 50w, /images/green-16x16.png?f48b 51w" sizes="max(-200vw, 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f49 50w, /images/green-16x16.png?f49 51w" sizes="(min-width:0) calc(1px"> ref sizes="1px" (standards mode) +FAIL <img srcset="/images/green-1x1.png?f49a 50w, /images/green-16x16.png?f49a 51w" sizes="(min-width:0) min(1px, 200vw"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f49b 50w, /images/green-16x16.png?f49b 51w" sizes="(min-width:0) max(-200vw, 1px"> ref sizes="1px" (standards mode) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f2 50w, /images/green-16x16.png?f2 51w" sizes=""> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f3 50w, /images/green-16x16.png?f3 51w" sizes=","> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f4 50w, /images/green-16x16.png?f4 51w" sizes="-1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f5 50w, /images/green-16x16.png?f5 51w" sizes="1"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f6 50w, /images/green-16x16.png?f6 51w" sizes="0.1%"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f7 50w, /images/green-16x16.png?f7 51w" sizes="0.1deg"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f8 50w, /images/green-16x16.png?f8 51w" sizes="0.1grad"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f9 50w, /images/green-16x16.png?f9 51w" sizes="0.1rad"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f10 50w, /images/green-16x16.png?f10 51w" sizes="0.1turn"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f11 50w, /images/green-16x16.png?f11 51w" sizes="0.1s"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f12 50w, /images/green-16x16.png?f12 51w" sizes="0.1ms"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f13 50w, /images/green-16x16.png?f13 51w" sizes="0.1Hz"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f14 50w, /images/green-16x16.png?f14 51w" sizes="0.1kHz"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f15 50w, /images/green-16x16.png?f15 51w" sizes="0.1dpi"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f16 50w, /images/green-16x16.png?f16 51w" sizes="0.1dpcm"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f17 50w, /images/green-16x16.png?f17 51w" sizes="0.1dppx"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f17a 50w, /images/green-16x16.png?f17a 51w" sizes="0.1x"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f18 50w, /images/green-16x16.png?f18 51w" data-foo="1px" sizes="attr(data-foo, length, 1px)"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f19 50w, /images/green-16x16.png?f19 51w" data-foo="1" sizes="attr(data-foo, px, 1px)"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f20 50w, /images/green-16x16.png?f20 51w" sizes="toggle(1px)"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f21 50w, /images/green-16x16.png?f21 51w" sizes="inherit"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f22 50w, /images/green-16x16.png?f22 51w" sizes="auto"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f23 50w, /images/green-16x16.png?f23 51w" sizes="initial"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f24 50w, /images/green-16x16.png?f24 51w" sizes="unset"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f25 50w, /images/green-16x16.png?f25 51w" sizes="default"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f26 50w, /images/green-16x16.png?f26 51w" sizes="1/* */px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f27 50w, /images/green-16x16.png?f27 51w" sizes="1p/* */x"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f28 50w, /images/green-16x16.png?f28 51w" sizes="-/**/0"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f29 50w, /images/green-16x16.png?f29 51w" sizes="((),1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f30 50w, /images/green-16x16.png?f30 51w" sizes="x(x(),1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f31 50w, /images/green-16x16.png?f31 51w" sizes="{{},1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f32 50w, /images/green-16x16.png?f32 51w" sizes="[[],1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f33 50w, /images/green-16x16.png?f33 51w" sizes="1px !important"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f34 50w, /images/green-16x16.png?f34 51w" sizes="\1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f35 50w, /images/green-16x16.png?f35 51w" sizes="all 1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f36 50w, /images/green-16x16.png?f36 51w" sizes="all and (min-width:0) 1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f37 50w, /images/green-16x16.png?f37 51w" sizes="min-width:0 1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f38 50w, /images/green-16x16.png?f38 51w" sizes="100vw, 1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f39 50w, /images/green-16x16.png?f39 51w" sizes="100vw, (min-width:0) 1px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f40 50w, /images/green-16x16.png?f40 51w" sizes="foo bar"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f41 50w, /images/green-16x16.png?f41 51w" sizes="foo-bar"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f42 50w, /images/green-16x16.png?f42 51w" sizes="(min-width:0) 1px foo bar"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f43 50w, /images/green-16x16.png?f43 51w" sizes="(min-width:0) 0.1%"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f44 50w, /images/green-16x16.png?f44 51w" sizes="(min-width:0) 1"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f45 50w, /images/green-16x16.png?f45 51w" sizes="-1e0px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f46 50w, /images/green-16x16.png?f46 51w" sizes="1e1.5px"> ref sizes="100vw" (standards mode) +PASS <img srcset="/images/green-1x1.png?f47 50w, /images/green-16x16.png?f47 51w" style="--foo: 1px" sizes="var(--foo)"> ref sizes="100vw" (standards mode) +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode.html new file mode 100644 index 0000000..6e70c88 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-standards-mode.html
@@ -0,0 +1,7 @@ +<!doctype html> +<title>img parse a sizes attribute (standards mode)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<iframe data-desc="standards mode" style="width:1000px; height:1000px" src="support/sizes-iframed.sub.html?doctype=doctype%20html&style="></iframe> +<script src="support/parse-a-sizes-attribute.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px-expected.txt new file mode 100644 index 0000000..116a409 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px-expected.txt
@@ -0,0 +1,175 @@ +This is a testharness.js-based test. +Found 171 tests; 154 PASS, 17 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS <img srcset="/images/green-1x1.png?a2 300w, /images/green-16x16.png?a2 301w"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?b2 450w, /images/green-16x16.png?b2 451w"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?c2 600w, /images/green-16x16.png?c2 601w"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?d2 900w, /images/green-16x16.png?d2 901w"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e2 50w, /images/green-16x16.png?e2 51w" sizes="0"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e3 50w, /images/green-16x16.png?e3 51w" sizes="-0"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e4 50w, /images/green-16x16.png?e4 51w" sizes="+0"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e5 50w, /images/green-16x16.png?e5 51w" sizes="+1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e6 50w, /images/green-16x16.png?e6 51w" sizes=".1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e7 50w, /images/green-16x16.png?e7 51w" sizes="0.1em"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e8 50w, /images/green-16x16.png?e8 51w" sizes="0.1ex"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e9 50w, /images/green-16x16.png?e9 51w" sizes="0.1ch"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e10 50w, /images/green-16x16.png?e10 51w" sizes="0.1rem"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e11 50w, /images/green-16x16.png?e11 51w" sizes="0.1vw"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e12 50w, /images/green-16x16.png?e12 51w" sizes="0.1vh"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e13 50w, /images/green-16x16.png?e13 51w" sizes="0.1vmin"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e14 50w, /images/green-16x16.png?e14 51w" sizes="0.1vmax"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e15 50w, /images/green-16x16.png?e15 51w" sizes="0.1cm"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e16 50w, /images/green-16x16.png?e16 51w" sizes="1mm"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e17 50w, /images/green-16x16.png?e17 51w" sizes="1q"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e18 50w, /images/green-16x16.png?e18 51w" sizes="0.01in"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e19 50w, /images/green-16x16.png?e19 51w" sizes="0.1pc"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e20 50w, /images/green-16x16.png?e20 51w" sizes="0.1pt"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e21 50w, /images/green-16x16.png?e21 51w" sizes="/* */1px/* */"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e22 50w, /images/green-16x16.png?e22 51w" sizes=" /**/ /**/ 1px /**/ /**/ "> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e23 50w, /images/green-16x16.png?e23 51w" sizes="(),1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e24 50w, /images/green-16x16.png?e24 51w" sizes="x(),1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e25 50w, /images/green-16x16.png?e25 51w" sizes="{},1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e26 50w, /images/green-16x16.png?e26 51w" sizes="[],1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e27 50w, /images/green-16x16.png?e27 51w" sizes="1px,("> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e28 50w, /images/green-16x16.png?e28 51w" sizes="1px,x("> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e29 50w, /images/green-16x16.png?e29 51w" sizes="1px,{"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e30 50w, /images/green-16x16.png?e30 51w" sizes="1px,["> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e31 50w, /images/green-16x16.png?e31 51w" sizes="\(,1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e32 50w, /images/green-16x16.png?e32 51w" sizes="x\(,1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e33 50w, /images/green-16x16.png?e33 51w" sizes="\{,1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e34 50w, /images/green-16x16.png?e34 51w" sizes="\[,1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e35 50w, /images/green-16x16.png?e35 51w" sizes="1\p\x"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e36 50w, /images/green-16x16.png?e36 51w" sizes="calc(1px)"> ref sizes="1px" (width:1000px) +FAIL <img srcset="/images/green-1x1.png?e36a 50w, /images/green-16x16.png?e36a 51w" sizes="min(1px, 100px)"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e36b 50w, /images/green-16x16.png?e36b 51w" sizes="min(-100px, 1px)"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e37 50w, /images/green-16x16.png?e37 51w" sizes="(min-width:0) calc(1px)"> ref sizes="1px" (width:1000px) +FAIL <img srcset="/images/green-1x1.png?e37a 50w, /images/green-16x16.png?e37a 51w" sizes="(min-width:0) min(1px, 100px)"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e37b 50w, /images/green-16x16.png?e37b 51w" sizes="(min-width:0) max(-100px, 1px)"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w" sizes="(min-width:calc(0)) 1px"> ref sizes="1px" (width:1000px) +FAIL <img srcset="/images/green-1x1.png?e38a 50w, /images/green-16x16.png?e38a 51w" sizes="(min-width:min(0, 200vw)) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e38b 50w, /images/green-16x16.png?e38b 51w" sizes="(min-width:max(-200vw, 0)) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e39 50w, /images/green-16x16.png?e39 51w" sizes="(min-width:0) 1px, 100vw"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e40 50w, /images/green-16x16.png?e40 51w" sizes="(min-width:0) 1px, (min-width:0) 100vw, 100vw"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e41 50w, /images/green-16x16.png?e41 51w" sizes="(min-width:0) 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e42 50w, /images/green-16x16.png?e42 51w" sizes="not (min-width:0) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e43 50w, /images/green-16x16.png?e43 51w" sizes="(min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e44 50w, /images/green-16x16.png?e44 51w" sizes="not (min-width:unknown-mf-value) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e45 50w, /images/green-16x16.png?e45 51w" sizes="(min-width:-1px) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e46 50w, /images/green-16x16.png?e46 51w" sizes="not (min-width:-1px) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e47 50w, /images/green-16x16.png?e47 51w" sizes="(unknown-mf-name) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e48 50w, /images/green-16x16.png?e48 51w" sizes="not (unknown-mf-name) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e49 50w, /images/green-16x16.png?e49 51w" sizes="(unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e50 50w, /images/green-16x16.png?e50 51w" sizes="not (unknown "general-enclosed") 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e51 50w, /images/green-16x16.png?e51 51w" sizes="unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e52 50w, /images/green-16x16.png?e52 51w" sizes="not unknown-general-enclosed(foo) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e53 50w, /images/green-16x16.png?e53 51w" sizes="print 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e54 50w, /images/green-16x16.png?e54 51w" sizes="not print 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e55 50w, /images/green-16x16.png?e55 51w" sizes="unknown-media-type 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e56 50w, /images/green-16x16.png?e56 51w" sizes="not unknown-media-type 100vw, 1px"> ref sizes="1px" (width:1000px) +FAIL <img srcset="/images/green-1x1.png?e57 50w, /images/green-16x16.png?e57 51w" sizes="(min-width:0) or (min-width:0) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e58 50w, /images/green-16x16.png?e58 51w" sizes="(min-width:0) or (unknown-mf-name) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e59 50w, /images/green-16x16.png?e59 51w" sizes="(min-width:0) or (min-width:unknown-mf-value) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e60 50w, /images/green-16x16.png?e60 51w" sizes="(min-width:0) or (min-width:-1px) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e61 50w, /images/green-16x16.png?e61 51w" sizes="(min-width:0) or (unknown "general-enclosed") 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?e62 50w, /images/green-16x16.png?e62 51w" sizes="(min-width:0) or unknown-general-enclosed(foo) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e63 50w, /images/green-16x16.png?e63 51w" sizes="(min-width:0) or (!) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e64 50w, /images/green-16x16.png?e64 51w" sizes="(min-width:0) or unknown-media-type 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e65 50w, /images/green-16x16.png?e65 51w" sizes="(123) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e66 50w, /images/green-16x16.png?e66 51w" sizes="not (123) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e67 50w, /images/green-16x16.png?e67 51w" sizes="(!) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e68 50w, /images/green-16x16.png?e68 51w" sizes="not (!) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e69 50w, /images/green-16x16.png?e69 51w" sizes="! 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e70 50w, /images/green-16x16.png?e70 51w" sizes="not ! 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e71 50w, /images/green-16x16.png?e71 51w" sizes="(]) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e72 50w, /images/green-16x16.png?e72 51w" sizes="not (]) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e73 50w, /images/green-16x16.png?e73 51w" sizes="] 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e74 50w, /images/green-16x16.png?e74 51w" sizes="not ] 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e75 50w, /images/green-16x16.png?e75 51w" sizes="(}) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e76 50w, /images/green-16x16.png?e76 51w" sizes="not (}) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e77 50w, /images/green-16x16.png?e77 51w" sizes="} 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e78 50w, /images/green-16x16.png?e78 51w" sizes="not } 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e79 50w, /images/green-16x16.png?e79 51w" sizes=") 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e80 50w, /images/green-16x16.png?e80 51w" sizes="not ) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e81 50w, /images/green-16x16.png?e81 51w" sizes="(;) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e82 50w, /images/green-16x16.png?e82 51w" sizes="not (;) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e83 50w, /images/green-16x16.png?e83 51w" sizes="(.) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e84 50w, /images/green-16x16.png?e84 51w" sizes="not (.) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e85 50w, /images/green-16x16.png?e85 51w" sizes="; 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e86 50w, /images/green-16x16.png?e86 51w" sizes="not ; 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e87 50w, /images/green-16x16.png?e87 51w" sizes=", 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e88 50w, /images/green-16x16.png?e88 51w" sizes="1px,"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e89 50w, /images/green-16x16.png?e89 51w" sizes="(min-width:0) 1px,"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e90 50w, /images/green-16x16.png?e90 51w" sizes="-0e-0px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e91 50w, /images/green-16x16.png?e91 51w" sizes="+0.11e+01px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e92 50w, /images/green-16x16.png?e92 51w" sizes="0.2e1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e93 50w, /images/green-16x16.png?e93 51w" sizes="0.3E1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e94 50w, /images/green-16x16.png?e94 51w" sizes=".4E1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e95 50w, /images/green-16x16.png?e95 51w" sizes="all 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e96 50w, /images/green-16x16.png?e96 51w" sizes="all and (min-width:0) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e97 50w, /images/green-16x16.png?e97 51w" sizes="min-width:0 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e98 50w, /images/green-16x16.png?e98 51w" sizes="1px, 100vw"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e99 50w, /images/green-16x16.png?e99 51w" sizes="1px, (min-width:0) 100vw"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e100 50w, /images/green-16x16.png?e100 51w" sizes="1px, foo bar"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e101 50w, /images/green-16x16.png?e101 51w" sizes="(min-width:0) 1px, foo bar"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e102 50w, /images/green-16x16.png?e102 51w" sizes="("grammar does not match") 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e103 50w, /images/green-16x16.png?e103 51w" sizes="not ("grammar does not match") 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e104 50w, /images/green-16x16.png?e104 51w" sizes="(unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e105 50w, /images/green-16x16.png?e105 51w" sizes="not (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (width:1000px) +FAIL <img srcset="/images/green-1x1.png?e106 50w, /images/green-16x16.png?e106 51w" sizes="(min-width:0) or (unknown-general-enclosed !) 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?e107 50w, /images/green-16x16.png?e107 51w" sizes="not ((min-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e108 50w, /images/green-16x16.png?e108 51w" sizes="(max-width:0) or (unknown-general-enclosed !) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?e109 50w, /images/green-16x16.png?e109 51w" sizes="not ((max-width:0) or (unknown "general-enclosed")) 100vw, 1px"> ref sizes="1px" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f48 50w, /images/green-16x16.png?f48 51w" sizes="calc(1px"> ref sizes="1px" (width:1000px) +FAIL <img srcset="/images/green-1x1.png?f48a 50w, /images/green-16x16.png?f48a 51w" sizes="min(1px, 200vw"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f48b 50w, /images/green-16x16.png?f48b 51w" sizes="max(-200vw, 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f49 50w, /images/green-16x16.png?f49 51w" sizes="(min-width:0) calc(1px"> ref sizes="1px" (width:1000px) +FAIL <img srcset="/images/green-1x1.png?f49a 50w, /images/green-16x16.png?f49a 51w" sizes="(min-width:0) min(1px, 200vw"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +FAIL <img srcset="/images/green-1x1.png?f49b 50w, /images/green-16x16.png?f49b 51w" sizes="(min-width:0) max(-200vw, 1px"> ref sizes="1px" (width:1000px) assert_equals: expected "http://web-platform.test:8001/images/green-1x1.png" but got "http://web-platform.test:8001/images/green-16x16.png" +PASS <img srcset="/images/green-1x1.png?f2 50w, /images/green-16x16.png?f2 51w" sizes=""> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f3 50w, /images/green-16x16.png?f3 51w" sizes=","> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f4 50w, /images/green-16x16.png?f4 51w" sizes="-1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f5 50w, /images/green-16x16.png?f5 51w" sizes="1"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f6 50w, /images/green-16x16.png?f6 51w" sizes="0.1%"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f7 50w, /images/green-16x16.png?f7 51w" sizes="0.1deg"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f8 50w, /images/green-16x16.png?f8 51w" sizes="0.1grad"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f9 50w, /images/green-16x16.png?f9 51w" sizes="0.1rad"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f10 50w, /images/green-16x16.png?f10 51w" sizes="0.1turn"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f11 50w, /images/green-16x16.png?f11 51w" sizes="0.1s"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f12 50w, /images/green-16x16.png?f12 51w" sizes="0.1ms"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f13 50w, /images/green-16x16.png?f13 51w" sizes="0.1Hz"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f14 50w, /images/green-16x16.png?f14 51w" sizes="0.1kHz"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f15 50w, /images/green-16x16.png?f15 51w" sizes="0.1dpi"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f16 50w, /images/green-16x16.png?f16 51w" sizes="0.1dpcm"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f17 50w, /images/green-16x16.png?f17 51w" sizes="0.1dppx"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f17a 50w, /images/green-16x16.png?f17a 51w" sizes="0.1x"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f18 50w, /images/green-16x16.png?f18 51w" data-foo="1px" sizes="attr(data-foo, length, 1px)"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f19 50w, /images/green-16x16.png?f19 51w" data-foo="1" sizes="attr(data-foo, px, 1px)"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f20 50w, /images/green-16x16.png?f20 51w" sizes="toggle(1px)"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f21 50w, /images/green-16x16.png?f21 51w" sizes="inherit"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f22 50w, /images/green-16x16.png?f22 51w" sizes="auto"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f23 50w, /images/green-16x16.png?f23 51w" sizes="initial"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f24 50w, /images/green-16x16.png?f24 51w" sizes="unset"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f25 50w, /images/green-16x16.png?f25 51w" sizes="default"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f26 50w, /images/green-16x16.png?f26 51w" sizes="1/* */px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f27 50w, /images/green-16x16.png?f27 51w" sizes="1p/* */x"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f28 50w, /images/green-16x16.png?f28 51w" sizes="-/**/0"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f29 50w, /images/green-16x16.png?f29 51w" sizes="((),1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f30 50w, /images/green-16x16.png?f30 51w" sizes="x(x(),1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f31 50w, /images/green-16x16.png?f31 51w" sizes="{{},1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f32 50w, /images/green-16x16.png?f32 51w" sizes="[[],1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f33 50w, /images/green-16x16.png?f33 51w" sizes="1px !important"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f34 50w, /images/green-16x16.png?f34 51w" sizes="\1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f35 50w, /images/green-16x16.png?f35 51w" sizes="all 1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f36 50w, /images/green-16x16.png?f36 51w" sizes="all and (min-width:0) 1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f37 50w, /images/green-16x16.png?f37 51w" sizes="min-width:0 1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f38 50w, /images/green-16x16.png?f38 51w" sizes="100vw, 1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f39 50w, /images/green-16x16.png?f39 51w" sizes="100vw, (min-width:0) 1px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f40 50w, /images/green-16x16.png?f40 51w" sizes="foo bar"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f41 50w, /images/green-16x16.png?f41 51w" sizes="foo-bar"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f42 50w, /images/green-16x16.png?f42 51w" sizes="(min-width:0) 1px foo bar"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f43 50w, /images/green-16x16.png?f43 51w" sizes="(min-width:0) 0.1%"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f44 50w, /images/green-16x16.png?f44 51w" sizes="(min-width:0) 1"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f45 50w, /images/green-16x16.png?f45 51w" sizes="-1e0px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f46 50w, /images/green-16x16.png?f46 51w" sizes="1e1.5px"> ref sizes="100vw" (width:1000px) +PASS <img srcset="/images/green-1x1.png?f47 50w, /images/green-16x16.png?f47 51w" style="--foo: 1px" sizes="var(--foo)"> ref sizes="100vw" (width:1000px) +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html new file mode 100644 index 0000000..ab3f69e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html
@@ -0,0 +1,7 @@ +<!doctype html> +<title>img parse a sizes attribute (width:1000px)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<iframe data-desc="width:1000px" style="width:1000px; height:1000px" src="support/sizes-iframed.sub.html?doctype=doctype%20html&style=width:1000px%3B%20height:16px"></iframe> +<script src="support/parse-a-sizes-attribute.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html deleted file mode 100644 index 711af8c..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html +++ /dev/null
@@ -1,42 +0,0 @@ -<!doctype html> -<title>img parse a sizes attribute</title> -<meta name="timeout" content="long"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<div id=log></div> -<iframe data-desc="standards mode" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=doctype%20html&style="></iframe> -<iframe data-desc="quirks mode" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=----&style="></iframe> -<iframe data-desc="display:none" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=doctype%20html&style=display:none"></iframe> -<iframe data-desc="width:1000px" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=doctype%20html&style=width:1000px%3B%20height:16px"></iframe> -<script> -setup({explicit_done:true}); - -function check(p, iframe) { - var current = p.firstElementChild; - var ref_sizes = current.getAttribute('sizes'); - var expect = current.currentSrc; - if (expect) { - expect = expect.split('?')[0]; - } - while (current = current.nextElementSibling) { - test(function() { - if (expect === '' || expect === null || expect === undefined) { - assert_unreached('ref currentSrc was ' + format_value(expect)); - } - var got = current.currentSrc; - assert_greater_than(got.indexOf('?'), -1, 'expected a "?" in currentSrc'); - got = got.split('?')[0]; - assert_equals(got, expect); - }, current.outerHTML + ' ref sizes=' + format_value(ref_sizes) + ' (' + iframe.getAttribute('data-desc') + ')'); - } -} - -onload = function() { - [].forEach.call(document.querySelectorAll('iframe'), function(iframe) { - [].forEach.call(iframe.contentDocument.querySelectorAll('p'), function(p) { - check(p, iframe); - }); - }); - done(); -} -</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/support/parse-a-sizes-attribute.js b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/support/parse-a-sizes-attribute.js new file mode 100644 index 0000000..62ad00a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/support/parse-a-sizes-attribute.js
@@ -0,0 +1,29 @@ +setup({explicit_done:true}); + +function check(p, iframe) { + var current = p.firstElementChild; + var ref_sizes = current.getAttribute('sizes'); + var expect = current.currentSrc; + if (expect) { + expect = expect.split('?')[0]; + } + while (current = current.nextElementSibling) { + test(function() { + if (expect === '' || expect === null || expect === undefined) { + assert_unreached('ref currentSrc was ' + format_value(expect)); + } + var got = current.currentSrc; + assert_greater_than(got.indexOf('?'), -1, 'expected a "?" in currentSrc'); + got = got.split('?')[0]; + assert_equals(got, expect); + }, current.outerHTML + ' ref sizes=' + format_value(ref_sizes) + ' (' + iframe.getAttribute('data-desc') + ')'); + } +} + +onload = function() { + var iframe = document.querySelector('iframe'); + [].forEach.call(iframe.contentDocument.querySelectorAll('p'), function(p) { + check(p, iframe); + }); + done(); +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/support/sizes-iframed.sub.html similarity index 100% rename from third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/sizes/support/sizes-iframed.sub.html
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl index 77cdfff..68509fc1a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/background-fetch.idl
@@ -1,4 +1,7 @@ -// 4.1. Extensions to ServiceWorkerGlobalScope +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "Background Fetch" spec. +// See: https://wicg.github.io/background-fetch/ partial interface ServiceWorkerGlobalScope { attribute EventHandler onbackgroundfetched; @@ -7,14 +10,10 @@ attribute EventHandler onbackgroundfetchclick; }; -// 4.2. Extensions to ServiceWorkerRegistration - partial interface ServiceWorkerRegistration { readonly attribute BackgroundFetchManager backgroundFetch; }; -// 4.3. BackgroundFetchManager - [Exposed=(Window,Worker)] interface BackgroundFetchManager { Promise<BackgroundFetchRegistration> fetch(DOMString id, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options); @@ -24,21 +23,19 @@ }; dictionary BackgroundFetchOptions { - sequence<IconDefinition> icons; - DOMString title; - unsigned long long downloadTotal; + sequence<IconDefinition> icons = []; + DOMString title = ""; + unsigned long long downloadTotal = 0; }; // This is taken from https://w3c.github.io/manifest/#icons-member. // This definition should probably be moved somewhere more general. dictionary IconDefinition { DOMString src; - DOMString sizes; - DOMString type; + DOMString sizes = ""; + DOMString type = ""; }; -// 4.4. BackgroundFetchRegistration - [Exposed=(Window,Worker)] interface BackgroundFetchRegistration : EventTarget { readonly attribute DOMString id; @@ -70,8 +67,6 @@ // In future this will include a fetch observer }; -// 4.4.3. BackgroundFetchEvent - [Constructor(DOMString type, BackgroundFetchEventInit init), Exposed=ServiceWorker] interface BackgroundFetchEvent : ExtendableEvent { readonly attribute DOMString id; @@ -81,8 +76,6 @@ required DOMString id; }; -// 4.4.4. BackgroundFetchSettledEvent - [Constructor(DOMString type, BackgroundFetchSettledEventInit init), Exposed=ServiceWorker] interface BackgroundFetchSettledEvent : BackgroundFetchEvent { readonly attribute BackgroundFetchSettledFetches fetches; @@ -103,15 +96,11 @@ readonly attribute Response? response; }; -// 4.4.5. BackgroundFetchUpdateEvent - [Constructor(DOMString type, BackgroundFetchSettledEventInit init), Exposed=ServiceWorker] interface BackgroundFetchUpdateEvent : BackgroundFetchSettledEvent { Promise<void> updateUI(DOMString title); }; -// 4.4.6. BackgroundFetchClickEvent - [Constructor(DOMString type, BackgroundFetchClickEventInit init), Exposed=ServiceWorker] interface BackgroundFetchClickEvent : BackgroundFetchEvent { readonly attribute BackgroundFetchState state;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/encrypted-media.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/encrypted-media.idl index fbe898b..607ed6be 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/encrypted-media.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/encrypted-media.idl
@@ -1,75 +1,72 @@ -// Encrypted Media Extensions WebIDL -// -// NOTE: Please update the link below to the specification version from -// which this IDL was extracted. -// -// https://www.w3.org/TR/2016/WD-encrypted-media-20160610/ -// + commit 5499821932391ae2c2e53756ae7ab9fae89d5863 -// +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "Encrypted Media Extensions" spec. +// See: https://w3c.github.io/encrypted-media/ +[Exposed=Window] partial interface Navigator { - Promise<MediaKeySystemAccess> requestMediaKeySystemAccess (DOMString keySystem, sequence<MediaKeySystemConfiguration> supportedConfigurations); + [SecureContext] Promise<MediaKeySystemAccess> requestMediaKeySystemAccess(DOMString keySystem, + sequence<MediaKeySystemConfiguration> supportedConfigurations); }; - enum MediaKeysRequirement { "required", "optional", "not-allowed" }; - dictionary MediaKeySystemConfiguration { - DOMString label = ""; - sequence<DOMString> initDataTypes = []; - sequence<MediaKeySystemMediaCapability> audioCapabilities = []; - sequence<MediaKeySystemMediaCapability> videoCapabilities = []; - MediaKeysRequirement distinctiveIdentifier = "optional"; - MediaKeysRequirement persistentState = "optional"; - sequence<DOMString> sessionTypes; + DOMString label = ""; + sequence<DOMString> initDataTypes = []; + sequence<MediaKeySystemMediaCapability> audioCapabilities = []; + sequence<MediaKeySystemMediaCapability> videoCapabilities = []; + MediaKeysRequirement distinctiveIdentifier = "optional"; + MediaKeysRequirement persistentState = "optional"; + sequence<DOMString> sessionTypes; }; - dictionary MediaKeySystemMediaCapability { - DOMString contentType = ""; - DOMString robustness = ""; + DOMString contentType = ""; + DOMString robustness = ""; }; - +[Exposed=Window, + SecureContext] interface MediaKeySystemAccess { - readonly attribute DOMString keySystem; - MediaKeySystemConfiguration getConfiguration (); - Promise<MediaKeys> createMediaKeys (); + readonly attribute DOMString keySystem; + MediaKeySystemConfiguration getConfiguration(); + Promise<MediaKeys> createMediaKeys(); }; - enum MediaKeySessionType { "temporary", - "persistent-usage-record", "persistent-license" }; - +[Exposed=Window, + SecureContext] interface MediaKeys { - MediaKeySession createSession (optional MediaKeySessionType sessionType = "temporary"); - Promise<boolean> setServerCertificate (BufferSource serverCertificate); + MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary"); + Promise<boolean> setServerCertificate(BufferSource serverCertificate); }; - +[Exposed=Window, + SecureContext] interface MediaKeySession : EventTarget { - readonly attribute DOMString sessionId; - readonly attribute unrestricted double expiration; - readonly attribute Promise<void> closed; - readonly attribute MediaKeyStatusMap keyStatuses; - attribute EventHandler onkeystatuseschange; - attribute EventHandler onmessage; - Promise<void> generateRequest (DOMString initDataType, BufferSource initData); - Promise<boolean> load (DOMString sessionId); - Promise<void> update (BufferSource response); - Promise<void> close (); - Promise<void> remove (); + readonly attribute DOMString sessionId; + readonly attribute unrestricted double expiration; + readonly attribute Promise<void> closed; + readonly attribute MediaKeyStatusMap keyStatuses; + attribute EventHandler onkeystatuseschange; + attribute EventHandler onmessage; + Promise<void> generateRequest(DOMString initDataType, + BufferSource initData); + Promise<boolean> load(DOMString sessionId); + Promise<void> update(BufferSource response); + Promise<void> close(); + Promise<void> remove(); }; - +[Exposed=Window, + SecureContext] interface MediaKeyStatusMap { - iterable<BufferSource,MediaKeyStatus>; - readonly attribute unsigned long size; - boolean has (BufferSource keyId); - any get (BufferSource keyId); + iterable<BufferSource, MediaKeyStatus>; + readonly attribute unsigned long size; + boolean has(BufferSource keyId); + any get(BufferSource keyId); }; - enum MediaKeyStatus { "usable", "expired", @@ -79,41 +76,38 @@ "status-pending", "internal-error" }; - enum MediaKeyMessageType { "license-request", "license-renewal", "license-release", "individualization-request" }; - -[Constructor(DOMString type, MediaKeyMessageEventInit eventInitDict)] +[Exposed=Window, + SecureContext, + Constructor(DOMString type, MediaKeyMessageEventInit eventInitDict)] interface MediaKeyMessageEvent : Event { - readonly attribute MediaKeyMessageType messageType; - readonly attribute ArrayBuffer message; + readonly attribute MediaKeyMessageType messageType; + readonly attribute ArrayBuffer message; }; - dictionary MediaKeyMessageEventInit : EventInit { - required MediaKeyMessageType messageType; - required ArrayBuffer message; + required MediaKeyMessageType messageType; + required ArrayBuffer message; }; - -// partial interface HTMLMediaElement : EventTarget { +[Exposed=Window] partial interface HTMLMediaElement { - readonly attribute MediaKeys? mediaKeys; - attribute EventHandler onencrypted; - attribute EventHandler onwaitingforkey; - Promise<void> setMediaKeys (MediaKeys? mediaKeys); + [SecureContext] + readonly attribute MediaKeys? mediaKeys; + attribute EventHandler onencrypted; + attribute EventHandler onwaitingforkey; + [SecureContext] Promise<void> setMediaKeys(MediaKeys? mediaKeys); }; - -[Constructor(DOMString type, optional MediaEncryptedEventInit eventInitDict)] +[Exposed=Window, + Constructor(DOMString type, optional MediaEncryptedEventInit eventInitDict)] interface MediaEncryptedEvent : Event { - readonly attribute DOMString initDataType; - readonly attribute ArrayBuffer? initData; + readonly attribute DOMString initDataType; + readonly attribute ArrayBuffer? initData; }; - dictionary MediaEncryptedEventInit : EventInit { - DOMString initDataType = ""; - ArrayBuffer? initData = null; + DOMString initDataType = ""; + ArrayBuffer? initData = null; }; -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/webappsec-referrer-policy.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/referrer-policy.idl similarity index 63% rename from third_party/WebKit/LayoutTests/external/wpt/interfaces/webappsec-referrer-policy.idl rename to third_party/WebKit/LayoutTests/external/wpt/interfaces/referrer-policy.idl index f0317a4..2f5dab3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/webappsec-referrer-policy.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/referrer-policy.idl
@@ -1,6 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT -// Content of this file was automatically extracted from the Referrer Policy spec. -// See https://w3c.github.io/webappsec-referrer-policy/ +// Content of this file was automatically extracted from the +// "Referrer Policy" spec. +// See: https://w3c.github.io/webappsec-referrer-policy/ enum ReferrerPolicy { "",
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/scroll-animations.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/scroll-animations.idl new file mode 100644 index 0000000..5529cfa --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/scroll-animations.idl
@@ -0,0 +1,33 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "Scroll-linked Animations" spec. +// See: https://wicg.github.io/scroll-animations/ + +enum ScrollDirection { + "auto", + "block", + "inline", + "horizontal", + "vertical" +}; + +enum ScrollTimelineAutoKeyword { "auto" }; + +dictionary ScrollTimelineOptions { + Element scrollSource; + ScrollDirection orientation = "auto"; + DOMString startScrollOffset = "auto"; + DOMString endScrollOffset = "auto"; + (double or ScrollTimelineAutoKeyword) timeRange = "auto"; + FillMode fill = "none"; +}; + +[Constructor(optional ScrollTimelineOptions options)] +interface ScrollTimeline : AnimationTimeline { + readonly attribute Element scrollSource; + readonly attribute ScrollDirection orientation; + readonly attribute DOMString startScrollOffset; + readonly attribute DOMString endScrollOffset; + readonly attribute (double or ScrollTimelineAutoKeyword) timeRange; + readonly attribute FillMode fill; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/secure-contexts.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/secure-contexts.idl new file mode 100644 index 0000000..15bf275 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/secure-contexts.idl
@@ -0,0 +1,8 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "Secure Contexts" spec. +// See: https://w3c.github.io/webappsec-secure-contexts/ + +partial interface WindowOrWorkerGlobalScope { + readonly attribute boolean isSecureContext; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/touch-events.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/touch-events.idl new file mode 100644 index 0000000..5c5a3ef --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/touch-events.idl
@@ -0,0 +1,86 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "Touch Events - Level 2" spec. +// See: https://w3c.github.io/touch-events/ + +enum TouchType { + "direct", + "stylus" +}; + +dictionary TouchInit { + required long identifier; + required EventTarget target; + double clientX = 0; + double clientY = 0; + double screenX = 0; + double screenY = 0; + double pageX = 0; + double pageY = 0; + float radiusX = 0; + float radiusY = 0; + float rotationAngle = 0; + float force = 0; + double altitudeAngle = 0; + double azimuthAngle = 0; + TouchType touchType = "direct"; +}; + +[Constructor(TouchInit touchInitDict), + Exposed=Window] +interface Touch { + readonly attribute long identifier; + readonly attribute EventTarget target; + readonly attribute double screenX; + readonly attribute double screenY; + readonly attribute double clientX; + readonly attribute double clientY; + readonly attribute double pageX; + readonly attribute double pageY; + readonly attribute float radiusX; + readonly attribute float radiusY; + readonly attribute float rotationAngle; + readonly attribute float force; + readonly attribute float altitudeAngle; + readonly attribute float azimuthAngle; + readonly attribute TouchType touchType; +}; +interface TouchList { + readonly attribute unsigned long length; + getter Touch? item(unsigned long index); +}; +dictionary TouchEventInit : EventModifierInit { + sequence<Touch> touches = []; + sequence<Touch> targetTouches = []; + sequence<Touch> changedTouches = []; +}; + +[Constructor(DOMString type, optional TouchEventInit eventInitDict), + Exposed=Window] +interface TouchEvent : UIEvent { + readonly attribute TouchList touches; + readonly attribute TouchList targetTouches; + readonly attribute TouchList changedTouches; + readonly attribute boolean altKey; + readonly attribute boolean metaKey; + readonly attribute boolean ctrlKey; + readonly attribute boolean shiftKey; +}; +partial interface GlobalEventHandlers { + attribute EventHandler ontouchstart; + attribute EventHandler ontouchend; + attribute EventHandler ontouchmove; + attribute EventHandler ontouchcancel; +}; +partial interface Document { + // Deprecated in this specification + Touch createTouch(WindowProxy view, + EventTarget target, + long identifier, + double pageX, + double pageY, + double screenX, + double screenY); + // Deprecated in this specification + TouchList createTouchList(Touch... touches); +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-bluetooth.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-bluetooth.idl new file mode 100644 index 0000000..7046fec --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-bluetooth.idl
@@ -0,0 +1,216 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "Web Bluetooth" spec. +// See: https://webbluetoothcg.github.io/web-bluetooth/ + +dictionary BluetoothDataFilterInit { + BufferSource dataPrefix; + BufferSource mask; +}; +dictionary BluetoothLEScanFilterInit { + sequence<BluetoothServiceUUID> services; + DOMString name; + DOMString namePrefix; + // Maps unsigned shorts to BluetoothDataFilters. + object manufacturerData; + // Maps BluetoothServiceUUIDs to BluetoothDataFilters. + object serviceData; +}; + +dictionary RequestDeviceOptions { + sequence<BluetoothLEScanFilterInit> filters; + sequence<BluetoothServiceUUID> optionalServices = []; + boolean acceptAllDevices = false; +}; + +interface Bluetooth : EventTarget { + [SecureContext] + Promise<boolean> getAvailability(); + [SecureContext] + attribute EventHandler onavailabilitychanged; + [SecureContext, SameObject] + readonly attribute BluetoothDevice? referringDevice; + [SecureContext] + Promise<BluetoothDevice> requestDevice(optional RequestDeviceOptions options); +}; +Bluetooth implements BluetoothDeviceEventHandlers; +Bluetooth implements CharacteristicEventHandlers; +Bluetooth implements ServiceEventHandlers; + +dictionary BluetoothPermissionDescriptor : PermissionDescriptor { + DOMString deviceId; + // These match RequestDeviceOptions. + sequence<BluetoothLEScanFilterInit> filters; + sequence<BluetoothServiceUUID> optionalServices = []; + boolean acceptAllDevices = false; +}; + +dictionary AllowedBluetoothDevice { + required DOMString deviceId; + required boolean mayUseGATT; + // An allowedServices of "all" means all services are allowed. + required (DOMString or sequence<UUID>) allowedServices; +}; +dictionary BluetoothPermissionData { + required sequence<AllowedBluetoothDevice> allowedDevices; +}; + +interface BluetoothPermissionResult : PermissionStatus { + attribute FrozenArray<BluetoothDevice> devices; +}; + +[Constructor(DOMString type, optional ValueEventInit initDict)] +interface ValueEvent : Event { + readonly attribute any value; +}; + +dictionary ValueEventInit : EventInit { + any value = null; +}; + +interface BluetoothDevice { + readonly attribute DOMString id; + readonly attribute DOMString? name; + readonly attribute BluetoothRemoteGATTServer? gatt; + + Promise<void> watchAdvertisements(); + void unwatchAdvertisements(); + readonly attribute boolean watchingAdvertisements; +}; +BluetoothDevice implements EventTarget; +BluetoothDevice implements BluetoothDeviceEventHandlers; +BluetoothDevice implements CharacteristicEventHandlers; +BluetoothDevice implements ServiceEventHandlers; + +interface BluetoothManufacturerDataMap { + readonly maplike<unsigned short, DataView>; +}; +interface BluetoothServiceDataMap { + readonly maplike<UUID, DataView>; +}; +[Constructor(DOMString type, BluetoothAdvertisingEventInit init)] +interface BluetoothAdvertisingEvent : Event { + [SameObject] + readonly attribute BluetoothDevice device; + readonly attribute FrozenArray<UUID> uuids; + readonly attribute DOMString? name; + readonly attribute unsigned short? appearance; + readonly attribute byte? txPower; + readonly attribute byte? rssi; + [SameObject] + readonly attribute BluetoothManufacturerDataMap manufacturerData; + [SameObject] + readonly attribute BluetoothServiceDataMap serviceData; +}; +dictionary BluetoothAdvertisingEventInit : EventInit { + required BluetoothDevice device; + sequence<(DOMString or unsigned long)> uuids; + DOMString name; + unsigned short appearance; + byte txPower; + byte rssi; + Map manufacturerData; + Map serviceData; +}; + +interface BluetoothRemoteGATTServer { + [SameObject] + readonly attribute BluetoothDevice device; + readonly attribute boolean connected; + Promise<BluetoothRemoteGATTServer> connect(); + void disconnect(); + Promise<BluetoothRemoteGATTService> getPrimaryService(BluetoothServiceUUID service); + Promise<sequence<BluetoothRemoteGATTService>> + getPrimaryServices(optional BluetoothServiceUUID service); +}; + +interface BluetoothRemoteGATTService { + [SameObject] + readonly attribute BluetoothDevice device; + readonly attribute UUID uuid; + readonly attribute boolean isPrimary; + Promise<BluetoothRemoteGATTCharacteristic> + getCharacteristic(BluetoothCharacteristicUUID characteristic); + Promise<sequence<BluetoothRemoteGATTCharacteristic>> + getCharacteristics(optional BluetoothCharacteristicUUID characteristic); + Promise<BluetoothRemoteGATTService> + getIncludedService(BluetoothServiceUUID service); + Promise<sequence<BluetoothRemoteGATTService>> + getIncludedServices(optional BluetoothServiceUUID service); +}; +BluetoothRemoteGATTService implements EventTarget; +BluetoothRemoteGATTService implements CharacteristicEventHandlers; +BluetoothRemoteGATTService implements ServiceEventHandlers; + +interface BluetoothRemoteGATTCharacteristic { + [SameObject] + readonly attribute BluetoothRemoteGATTService service; + readonly attribute UUID uuid; + readonly attribute BluetoothCharacteristicProperties properties; + readonly attribute DataView? value; + Promise<BluetoothRemoteGATTDescriptor> getDescriptor(BluetoothDescriptorUUID descriptor); + Promise<sequence<BluetoothRemoteGATTDescriptor>> + getDescriptors(optional BluetoothDescriptorUUID descriptor); + Promise<DataView> readValue(); + Promise<void> writeValue(BufferSource value); + Promise<BluetoothRemoteGATTCharacteristic> startNotifications(); + Promise<BluetoothRemoteGATTCharacteristic> stopNotifications(); +}; +BluetoothRemoteGATTCharacteristic implements EventTarget; +BluetoothRemoteGATTCharacteristic implements CharacteristicEventHandlers; + +interface BluetoothCharacteristicProperties { + readonly attribute boolean broadcast; + readonly attribute boolean read; + readonly attribute boolean writeWithoutResponse; + readonly attribute boolean write; + readonly attribute boolean notify; + readonly attribute boolean indicate; + readonly attribute boolean authenticatedSignedWrites; + readonly attribute boolean reliableWrite; + readonly attribute boolean writableAuxiliaries; +}; + +interface BluetoothRemoteGATTDescriptor { + [SameObject] + readonly attribute BluetoothRemoteGATTCharacteristic characteristic; + readonly attribute UUID uuid; + readonly attribute DataView? value; + Promise<DataView> readValue(); + Promise<void> writeValue(BufferSource value); +}; + +[NoInterfaceObject] +interface CharacteristicEventHandlers { + attribute EventHandler oncharacteristicvaluechanged; +}; + +[NoInterfaceObject] +interface BluetoothDeviceEventHandlers { + attribute EventHandler ongattserverdisconnected; +}; + +[NoInterfaceObject] +interface ServiceEventHandlers { + attribute EventHandler onserviceadded; + attribute EventHandler onservicechanged; + attribute EventHandler onserviceremoved; +}; + +typedef DOMString UUID; +interface BluetoothUUID { + static UUID getService((DOMString or unsigned long) name); + static UUID getCharacteristic((DOMString or unsigned long) name); + static UUID getDescriptor((DOMString or unsigned long) name); + + static UUID canonicalUUID([EnforceRange] unsigned long alias); +}; + +typedef (DOMString or unsigned long) BluetoothServiceUUID; +typedef (DOMString or unsigned long) BluetoothCharacteristicUUID; +typedef (DOMString or unsigned long) BluetoothDescriptorUUID; + +partial interface Navigator { + [SameObject] + readonly attribute Bluetooth bluetooth; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-audio-api.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/webaudio.idl similarity index 95% rename from third_party/WebKit/LayoutTests/external/wpt/interfaces/web-audio-api.idl rename to third_party/WebKit/LayoutTests/external/wpt/interfaces/webaudio.idl index 9c25365..5f3085d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/web-audio-api.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/webaudio.idl
@@ -1,6 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT -// Content of this file was automatically extracted from the Web Audio API spec. -// See https://webaudio.github.io/web-audio-api/ +// Content of this file was automatically extracted from the +// "Web Audio API" spec. +// See: https://webaudio.github.io/web-audio-api/ enum AudioContextState { "suspended", @@ -21,34 +22,35 @@ readonly attribute AudioContextState state; [SameObject, SecureContext] readonly attribute AudioWorklet audioWorklet; - Promise<void> resume (); attribute EventHandler onstatechange; + + AnalyserNode createAnalyser (); + BiquadFilterNode createBiquadFilter (); AudioBuffer createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate); - Promise<AudioBuffer> decodeAudioData (ArrayBuffer audioData, - optional DecodeSuccessCallback successCallback, - optional DecodeErrorCallback errorCallback); AudioBufferSourceNode createBufferSource (); + ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6); + ChannelSplitterNode createChannelSplitter (optional unsigned long numberOfOutputs = 6); ConstantSourceNode createConstantSource (); + ConvolverNode createConvolver (); + DelayNode createDelay (optional double maxDelayTime = 1.0); + DynamicsCompressorNode createDynamicsCompressor (); + GainNode createGain (); + IIRFilterNode createIIRFilter (sequence<double> feedforward, sequence<double> feedback); + OscillatorNode createOscillator (); + PannerNode createPanner (); + PeriodicWave createPeriodicWave (sequence<float> real, sequence<float> imag, optional PeriodicWaveConstraints constraints); ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0, optional unsigned long numberOfInputChannels = 2, optional unsigned long numberOfOutputChannels = 2); - AnalyserNode createAnalyser (); - GainNode createGain (); - DelayNode createDelay (optional double maxDelayTime = 1.0); - BiquadFilterNode createBiquadFilter (); - IIRFilterNode createIIRFilter (sequence<double> feedforward, sequence<double> feedback); - WaveShaperNode createWaveShaper (); - PannerNode createPanner (); StereoPannerNode createStereoPanner (); - ConvolverNode createConvolver (); - ChannelSplitterNode createChannelSplitter (optional unsigned long numberOfOutputs = 6); - ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6); - DynamicsCompressorNode createDynamicsCompressor (); - OscillatorNode createOscillator (); - PeriodicWave createPeriodicWave (sequence<float> real, sequence<float> imag, optional PeriodicWaveConstraints constraints); + WaveShaperNode createWaveShaper (); + + Promise<AudioBuffer> decodeAudioData (ArrayBuffer audioData, + optional DecodeSuccessCallback successCallback, + optional DecodeErrorCallback errorCallback); + Promise<void> resume (); }; -[Exposed=Window] enum AudioContextLatencyCategory { "balanced", "interactive", @@ -69,13 +71,11 @@ MediaStreamAudioDestinationNode createMediaStreamDestination (); }; -[Exposed=Window] dictionary AudioContextOptions { (AudioContextLatencyCategory or double) latencyHint = "interactive"; float sampleRate; }; -[Exposed=Window] dictionary AudioTimestamp { double contextTime; DOMHighResTimeStamp performanceTime; @@ -91,7 +91,6 @@ attribute EventHandler oncomplete; }; -[Exposed=Window] dictionary OfflineAudioContextOptions { unsigned long numberOfChannels = 1; required unsigned long length; @@ -104,7 +103,6 @@ readonly attribute AudioBuffer renderedBuffer; }; -[Exposed=Window] dictionary OfflineAudioCompletionEventInit : EventInit { required AudioBuffer renderedBuffer; }; @@ -148,14 +146,12 @@ attribute ChannelInterpretation channelInterpretation; }; -[Exposed=Window] enum ChannelCountMode { "max", "clamped-max", "explicit" }; -[Exposed=Window] enum ChannelInterpretation { "speakers", "discrete" @@ -228,7 +224,6 @@ void start (optional double when = 0, optional double offset, optional double duration); - void stop (optional double when = 0); }; dictionary AudioBufferSourceOptions { @@ -314,7 +309,7 @@ }; [Exposed=Window, - Constructor (BaseAudioContext context, optional ChannelSplitterNode options)] + Constructor (BaseAudioContext context, optional ChannelSplitterOptions options)] interface ChannelSplitterNode : AudioNode { }; @@ -396,7 +391,7 @@ }; [Exposed=Window, - Constructor (BaseAudioContext context, MediaElementAudioSourceOptions options)] + Constructor (AudioContext context, MediaElementAudioSourceOptions options)] interface MediaElementAudioSourceNode : AudioNode { [SameObject] readonly attribute HTMLMediaElement mediaElement; }; @@ -406,13 +401,13 @@ }; [Exposed=Window, - Constructor (BaseAudioContext context, optional AudioNodeOptions options)] + Constructor (AudioContext context, optional AudioNodeOptions options)] interface MediaStreamAudioDestinationNode : AudioNode { readonly attribute MediaStream stream; }; [Exposed=Window, - Constructor (BaseAudioContext context, MediaStreamAudioSourceOptions options)] + Constructor (AudioContext context, MediaStreamAudioSourceOptions options)] interface MediaStreamAudioSourceNode : AudioNode { [SameObject] readonly attribute MediaStream mediaStream; }; @@ -558,6 +553,7 @@ [Global=(Worklet, AudioWorklet), Exposed=AudioWorklet] interface AudioWorkletGlobalScope : WorkletGlobalScope { void registerProcessor (DOMString name, VoidFunction processorCtor); + readonly attribute unsigned long long currentFrame; readonly attribute double currentTime; readonly attribute float sampleRate; }; @@ -567,21 +563,13 @@ readonly maplike<DOMString, AudioParam>; }; -enum AudioWorkletProcessorState { - "pending", - "running", - "stopped", - "error" -}; - [Exposed=Window, SecureContext, Constructor (BaseAudioContext context, DOMString name, optional AudioWorkletNodeOptions options)] interface AudioWorkletNode : AudioNode { readonly attribute AudioParamMap parameters; readonly attribute MessagePort port; - readonly attribute AudioWorkletProcessorState processorState; - attribute EventHandler onprocessorstatechange; + attribute EventHandler onprocessorerror; }; dictionary AudioWorkletNodeOptions : AudioNodeOptions { @@ -589,7 +577,7 @@ unsigned long numberOfOutputs = 1; sequence<unsigned long> outputChannelCount; record<DOMString, double> parameterData; - object processorOptions = null; + object? processorOptions = null; }; [Exposed=AudioWorklet, @@ -603,4 +591,5 @@ float defaultValue = 0; float minValue = -3.4028235e38; float maxValue = 3.4028235e38; + AutomationRate automationRate = "a-rate"; };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer-expected.txt index 11b2305..52c6861f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer-expected.txt
@@ -1,5 +1,4 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Uncaught Error: assert_true: expected true got false PASS Test SourceBuffer.appendBuffer() event dispatching. PASS Test SourceBuffer.appendBuffer() call during a pending appendBuffer(). PASS Test SourceBuffer.abort() call during a pending appendBuffer(). @@ -15,7 +14,7 @@ PASS Test appending a neutered ArrayBuffer. PASS Test appendBuffer with partial init segments. PASS Test appendBuffer with partial media segments. -PASS Test appendBuffer events order. +FAIL Test appendBuffer events order. assert_true: expected true got false PASS Test abort in the middle of an initialization segment. PASS Test abort after removing sourcebuffer. PASS Test abort after readyState is ended following init segment and media segment.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer.html b/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer.html index 7245f64..ff4cd4e6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer.html +++ b/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-append-buffer.html
@@ -425,11 +425,11 @@ loadedmetadataCalled = true; e.target.removeEventListener(e.type, metadata); }); - sourceBuffer.addEventListener("updateend", function updateend(e) { + sourceBuffer.addEventListener("updateend", test.step_func(function updateend(e) { assert_true(loadedmetadataCalled); assert_equals(mediaElement.readyState, mediaElement.HAVE_METADATA); e.target.removeEventListener(e.type, updateend); - }); + })); test.expectEvent(sourceBuffer, "updateend", "remainingInitSegment append ended."); test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata event received."); sourceBuffer.appendBuffer(initSegment); @@ -444,11 +444,11 @@ loadeddataCalled = true; e.target.removeEventListener(e.type, loadeddata); }); - sourceBuffer.addEventListener("updateend", function updateend(e) { + sourceBuffer.addEventListener("updateend", test.step_func(function updateend(e) { assert_true(loadeddataCalled); assert_greater_than_equal(mediaElement.readyState, mediaElement.HAVE_CURRENT_DATA); e.target.removeEventListener(e.type, updateend); - }); + })); test.expectEvent(sourceBuffer, "updateend", "mediaSegment append ended."); test.expectEvent(mediaElement, "loadeddata", "loadeddata fired."); sourceBuffer.appendBuffer(mediaSegment);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/historical.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-request/historical.https-expected.txt deleted file mode 100644 index b2cb833..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/historical.https-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -This is a testharness.js-based test. -PASS paymentRequestID in PaymentRequest -PASS paymentRequestID in PaymentResponse -PASS careOf in PaymentAddress -PASS totalAmount in PaymentResponse -PASS paymentRequestId in PaymentRequest -PASS paymentRequestId in PaymentResponse -FAIL supportedMethods must not support sequence<DOMString> assert_throws: function "() => { - new PaymentRequest([{supportedMethods: methods}], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}); - }" threw object "[object Object]" ("sequence<DOMString> conversion is not allowed") expected object "[object Object]" ("toString should be called") -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-ctor-pmi-handling.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-ctor-pmi-handling.https-expected.txt deleted file mode 100644 index 9cb986a4..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-ctor-pmi-handling.https-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This is a testharness.js-based test. -PASS Must support valid standard URL PMIs -PASS Must not throw on syntactically valid standardized payment method identifiers, even if they are not supported -FAIL Must throw on syntactically invalid standardized payment method identifiers assert_throws: expected RangeError processing invalid standardized PMI "visa,mastercard" function "() => { - const methods = [{ supportedMethods: invalidMethod }]; - new PaymentRequest(methods, defaultDetails); - }" did not throw -PASS Constructor MUST throw if given an invalid URL-based payment method identifier -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js index b345005..773d552 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
@@ -821,8 +821,15 @@ this.members[name].test(); if (name in this.objects) { - this.objects[name].forEach(function(str) + const objects = this.objects[name]; + if (!objects || !Array.isArray(objects)) { + throw new IdlHarnessError(`Invalid or empty objects for member ${name}`); + } + objects.forEach(function(str) { + if (!this.members[name] || !(this.members[name] instanceof IdlInterface)) { + throw new IdlHarnessError(`Invalid object member name ${name}`); + } this.members[name].test_object(str); }.bind(this)); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml new file mode 100644 index 0000000..73ae3b2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/META.yml
@@ -0,0 +1,4 @@ +suggested_reviewers: + - birtles + - theres-waldo + - manta12
diff --git a/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/idlharness-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/idlharness-expected.txt new file mode 100644 index 0000000..6362d973 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/idlharness-expected.txt
@@ -0,0 +1,30 @@ +This is a testharness.js-based test. +PASS Test scroll-animations IDL implementation +PASS ScrollTimeline interface: existence and properties of interface object +PASS ScrollTimeline interface object length +PASS ScrollTimeline interface object name +PASS ScrollTimeline interface: existence and properties of interface prototype object +PASS ScrollTimeline interface: existence and properties of interface prototype object's "constructor" property +PASS ScrollTimeline interface: existence and properties of interface prototype object's @@unscopables property +PASS ScrollTimeline interface: attribute scrollSource +PASS Unscopable handled correctly for scrollSource property on ScrollTimeline +PASS ScrollTimeline interface: attribute orientation +PASS Unscopable handled correctly for orientation property on ScrollTimeline +FAIL ScrollTimeline interface: attribute startScrollOffset assert_true: The prototype object must have a property "startScrollOffset" expected true got false +PASS Unscopable handled correctly for startScrollOffset property on ScrollTimeline +FAIL ScrollTimeline interface: attribute endScrollOffset assert_true: The prototype object must have a property "endScrollOffset" expected true got false +PASS Unscopable handled correctly for endScrollOffset property on ScrollTimeline +PASS ScrollTimeline interface: attribute timeRange +PASS Unscopable handled correctly for timeRange property on ScrollTimeline +FAIL ScrollTimeline interface: attribute fill assert_true: The prototype object must have a property "fill" expected true got false +PASS Unscopable handled correctly for fill property on ScrollTimeline +FAIL ScrollTimeline must be primary interface of new ScrollTimeline() assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +FAIL Stringification of new ScrollTimeline() assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +FAIL ScrollTimeline interface: new ScrollTimeline() must inherit property "scrollSource" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +FAIL ScrollTimeline interface: new ScrollTimeline() must inherit property "orientation" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +FAIL ScrollTimeline interface: new ScrollTimeline() must inherit property "startScrollOffset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +FAIL ScrollTimeline interface: new ScrollTimeline() must inherit property "endScrollOffset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +FAIL ScrollTimeline interface: new ScrollTimeline() must inherit property "timeRange" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +FAIL ScrollTimeline interface: new ScrollTimeline() must inherit property "fill" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "NotSupportedError: Failed to construct 'ScrollTimeline': 'auto' value for timeRange not yet supported" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/idlharness.html new file mode 100644 index 0000000..82dd59c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/scroll-animations/idlharness.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title>scroll-animations IDL tests</title> + <link rel="help" href="https://wicg.github.io/scroll-animations/"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/WebIDLParser.js"></script> + <script src="/resources/idlharness.js"></script> +</head> + +<body> + + <script> + 'use strict'; + + promise_test(async () => { + const idl = await fetch('/interfaces/scroll-animations.idl').then(r => r.text()); + const web = await fetch('/interfaces/web-animations.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + + const idl_array = new IdlArray(); + idl_array.add_idls(idl); + idl_array.add_dependency_idls(web); + idl_array.add_dependency_idls(dom); + idl_array.add_objects({ + ScrollTimeline: ['new ScrollTimeline()'], + }); + idl_array.test(); + }, 'Test scroll-animations IDL implementation'); + </script> + + <div id="log"></div> +</body> + +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/secure-contexts/idlharness.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/secure-contexts/idlharness.any-expected.txt new file mode 100644 index 0000000..13ebde2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/secure-contexts/idlharness.any-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS Test IDL implementation of Secure Contexts +PASS Partial interface WindowOrWorkerGlobalScope: original interface defined +FAIL WindowOrWorkerGlobalScope interface: self must inherit property "isSecureContext" with the proper type assert_inherits: property "isSecureContext" found on object expected in prototype chain +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/secure-contexts/idlharness.any.js b/third_party/WebKit/LayoutTests/external/wpt/secure-contexts/idlharness.any.js new file mode 100644 index 0000000..88341f3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/secure-contexts/idlharness.any.js
@@ -0,0 +1,20 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://w3c.github.io/webappsec-secure-contexts/ + +'use strict'; + +promise_test(async () => { + const idl = await fetch("/interfaces/secure-contexts.idl").then(r => r.text()); + const workers = await fetch("/interfaces/dedicated-workers.idl").then(r => r.text()); + + const idl_array = new IdlArray(); + idl_array.add_idls(idl); + idl_array.add_dependency_idls(workers); + idl_array.add_objects({ + WindowOrWorkerGlobalScope: ["self"], + }); + idl_array.test(); +}, "Test IDL implementation of Secure Contexts");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window-expected.txt new file mode 100644 index 0000000..3ec6ae3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window-expected.txt
@@ -0,0 +1,119 @@ +This is a testharness.js-based test. +Found 115 tests; 99 PASS, 16 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Test IDL implementation of touch-events API +PASS Partial interface GlobalEventHandlers: original interface defined +PASS Partial interface Document: original interface defined +PASS Touch interface: existence and properties of interface object +PASS Touch interface object length +PASS Touch interface object name +PASS Touch interface: existence and properties of interface prototype object +PASS Touch interface: existence and properties of interface prototype object's "constructor" property +PASS Touch interface: existence and properties of interface prototype object's @@unscopables property +PASS Touch interface: attribute identifier +PASS Unscopable handled correctly for identifier property on Touch +PASS Touch interface: attribute target +PASS Unscopable handled correctly for target property on Touch +PASS Touch interface: attribute screenX +PASS Unscopable handled correctly for screenX property on Touch +PASS Touch interface: attribute screenY +PASS Unscopable handled correctly for screenY property on Touch +PASS Touch interface: attribute clientX +PASS Unscopable handled correctly for clientX property on Touch +PASS Touch interface: attribute clientY +PASS Unscopable handled correctly for clientY property on Touch +PASS Touch interface: attribute pageX +PASS Unscopable handled correctly for pageX property on Touch +PASS Touch interface: attribute pageY +PASS Unscopable handled correctly for pageY property on Touch +PASS Touch interface: attribute radiusX +PASS Unscopable handled correctly for radiusX property on Touch +PASS Touch interface: attribute radiusY +PASS Unscopable handled correctly for radiusY property on Touch +PASS Touch interface: attribute rotationAngle +PASS Unscopable handled correctly for rotationAngle property on Touch +PASS Touch interface: attribute force +PASS Unscopable handled correctly for force property on Touch +FAIL Touch interface: attribute altitudeAngle assert_true: The prototype object must have a property "altitudeAngle" expected true got false +PASS Unscopable handled correctly for altitudeAngle property on Touch +FAIL Touch interface: attribute azimuthAngle assert_true: The prototype object must have a property "azimuthAngle" expected true got false +PASS Unscopable handled correctly for azimuthAngle property on Touch +FAIL Touch interface: attribute touchType assert_true: The prototype object must have a property "touchType" expected true got false +PASS Unscopable handled correctly for touchType property on Touch +PASS Touch must be primary interface of new Touch({identifier: 1, target: document}) +PASS Stringification of new Touch({identifier: 1, target: document}) +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "identifier" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "target" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "screenX" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "screenY" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "clientX" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "clientY" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "pageX" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "pageY" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "radiusX" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "radiusY" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "rotationAngle" with the proper type +PASS Touch interface: new Touch({identifier: 1, target: document}) must inherit property "force" with the proper type +FAIL Touch interface: new Touch({identifier: 1, target: document}) must inherit property "altitudeAngle" with the proper type assert_inherits: property "altitudeAngle" not found in prototype chain +FAIL Touch interface: new Touch({identifier: 1, target: document}) must inherit property "azimuthAngle" with the proper type assert_inherits: property "azimuthAngle" not found in prototype chain +FAIL Touch interface: new Touch({identifier: 1, target: document}) must inherit property "touchType" with the proper type assert_inherits: property "touchType" not found in prototype chain +PASS TouchList interface: existence and properties of interface object +PASS TouchList interface object length +PASS TouchList interface object name +PASS TouchList interface: existence and properties of interface prototype object +PASS TouchList interface: existence and properties of interface prototype object's "constructor" property +PASS TouchList interface: existence and properties of interface prototype object's @@unscopables property +PASS TouchList interface: attribute length +PASS Unscopable handled correctly for length property on TouchList +PASS TouchList interface: operation item(unsigned long) +PASS Unscopable handled correctly for item(unsigned long) on TouchList +PASS TouchEvent interface: existence and properties of interface object +PASS TouchEvent interface object length +PASS TouchEvent interface object name +PASS TouchEvent interface: existence and properties of interface prototype object +PASS TouchEvent interface: existence and properties of interface prototype object's "constructor" property +PASS TouchEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS TouchEvent interface: attribute touches +PASS Unscopable handled correctly for touches property on TouchEvent +PASS TouchEvent interface: attribute targetTouches +PASS Unscopable handled correctly for targetTouches property on TouchEvent +PASS TouchEvent interface: attribute changedTouches +PASS Unscopable handled correctly for changedTouches property on TouchEvent +PASS TouchEvent interface: attribute altKey +PASS Unscopable handled correctly for altKey property on TouchEvent +PASS TouchEvent interface: attribute metaKey +PASS Unscopable handled correctly for metaKey property on TouchEvent +PASS TouchEvent interface: attribute ctrlKey +PASS Unscopable handled correctly for ctrlKey property on TouchEvent +PASS TouchEvent interface: attribute shiftKey +PASS Unscopable handled correctly for shiftKey property on TouchEvent +PASS TouchEvent must be primary interface of new TouchEvent("name") +PASS Stringification of new TouchEvent("name") +PASS TouchEvent interface: new TouchEvent("name") must inherit property "touches" with the proper type +PASS TouchEvent interface: new TouchEvent("name") must inherit property "targetTouches" with the proper type +PASS TouchEvent interface: new TouchEvent("name") must inherit property "changedTouches" with the proper type +PASS TouchEvent interface: new TouchEvent("name") must inherit property "altKey" with the proper type +PASS TouchEvent interface: new TouchEvent("name") must inherit property "metaKey" with the proper type +PASS TouchEvent interface: new TouchEvent("name") must inherit property "ctrlKey" with the proper type +PASS TouchEvent interface: new TouchEvent("name") must inherit property "shiftKey" with the proper type +FAIL Document interface: operation createTouch(WindowProxy, EventTarget, long, double, double, double, double) assert_own_property: interface prototype object missing non-static operation expected property "createTouch" missing +PASS Unscopable handled correctly for createTouch(WindowProxy, EventTarget, long, double, double, double, double) on Document +FAIL Document interface: operation createTouchList(Touch) assert_own_property: interface prototype object missing non-static operation expected property "createTouchList" missing +PASS Unscopable handled correctly for createTouchList(Touch) on Document +FAIL Document interface: document must inherit property "createTouch(WindowProxy, EventTarget, long, double, double, double, double)" with the proper type assert_inherits: property "createTouch" not found in prototype chain +FAIL Document interface: calling createTouch(WindowProxy, EventTarget, long, double, double, double, double) on document with too few arguments must throw TypeError assert_inherits: property "createTouch" not found in prototype chain +FAIL Document interface: document must inherit property "createTouchList(Touch)" with the proper type assert_inherits: property "createTouchList" not found in prototype chain +FAIL Document interface: calling createTouchList(Touch) on document with too few arguments must throw TypeError assert_inherits: property "createTouchList" not found in prototype chain +FAIL GlobalEventHandlers interface: window must inherit property "ontouchstart" with the proper type assert_inherits: property "ontouchstart" found on object expected in prototype chain +FAIL GlobalEventHandlers interface: window must inherit property "ontouchend" with the proper type assert_inherits: property "ontouchend" found on object expected in prototype chain +FAIL GlobalEventHandlers interface: window must inherit property "ontouchmove" with the proper type assert_inherits: property "ontouchmove" found on object expected in prototype chain +FAIL GlobalEventHandlers interface: window must inherit property "ontouchcancel" with the proper type assert_inherits: property "ontouchcancel" found on object expected in prototype chain +PASS GlobalEventHandlers interface: document must inherit property "ontouchstart" with the proper type +PASS GlobalEventHandlers interface: document must inherit property "ontouchend" with the proper type +PASS GlobalEventHandlers interface: document must inherit property "ontouchmove" with the proper type +PASS GlobalEventHandlers interface: document must inherit property "ontouchcancel" with the proper type +PASS GlobalEventHandlers interface: document.body must inherit property "ontouchstart" with the proper type +PASS GlobalEventHandlers interface: document.body must inherit property "ontouchend" with the proper type +PASS GlobalEventHandlers interface: document.body must inherit property "ontouchmove" with the proper type +PASS GlobalEventHandlers interface: document.body must inherit property "ontouchcancel" with the proper type +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window.js b/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window.js new file mode 100644 index 0000000..6a95892 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/touch-events/idlharness.window.js
@@ -0,0 +1,25 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +// https://w3c.github.io/touch-events/ + +'use strict'; + +promise_test(async () => { + const srcs = ['touch-events', 'uievents', 'dom', 'html']; + const [idl, uievents, dom, html] = await Promise.all( + srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); + + const idl_array = new IdlArray(); + idl_array.add_idls(idl); + idl_array.add_dependency_idls(uievents); + idl_array.add_dependency_idls(dom); + idl_array.add_dependency_idls(html); + idl_array.add_objects({ + Document: ['document'], + GlobalEventHandlers: ['window', 'document', 'document.body'], + Touch: ['new Touch({identifier: 1, target: document})'], + TouchEvent: ['new TouchEvent("name")'], + }); + idl_array.test(); +}, 'Test IDL implementation of touch-events API');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https-expected.txt index 50fdb8d..f3d1cd5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https-expected.txt
@@ -18,48 +18,48 @@ PASS Unscopable handled correctly for state property on BaseAudioContext PASS BaseAudioContext interface: attribute audioWorklet PASS Unscopable handled correctly for audioWorklet property on BaseAudioContext -PASS BaseAudioContext interface: operation resume() -PASS Unscopable handled correctly for resume() on BaseAudioContext PASS BaseAudioContext interface: attribute onstatechange PASS Unscopable handled correctly for onstatechange property on BaseAudioContext -PASS BaseAudioContext interface: operation createBuffer(unsigned long, unsigned long, float) -PASS Unscopable handled correctly for createBuffer(unsigned long, unsigned long, float) on BaseAudioContext -PASS BaseAudioContext interface: operation decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) -PASS Unscopable handled correctly for decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on BaseAudioContext -PASS BaseAudioContext interface: operation createBufferSource() -PASS Unscopable handled correctly for createBufferSource() on BaseAudioContext -PASS BaseAudioContext interface: operation createConstantSource() -PASS Unscopable handled correctly for createConstantSource() on BaseAudioContext -PASS BaseAudioContext interface: operation createScriptProcessor(unsigned long, unsigned long, unsigned long) -PASS Unscopable handled correctly for createScriptProcessor(unsigned long, unsigned long, unsigned long) on BaseAudioContext PASS BaseAudioContext interface: operation createAnalyser() PASS Unscopable handled correctly for createAnalyser() on BaseAudioContext -PASS BaseAudioContext interface: operation createGain() -PASS Unscopable handled correctly for createGain() on BaseAudioContext -PASS BaseAudioContext interface: operation createDelay(double) -PASS Unscopable handled correctly for createDelay(double) on BaseAudioContext PASS BaseAudioContext interface: operation createBiquadFilter() PASS Unscopable handled correctly for createBiquadFilter() on BaseAudioContext -PASS BaseAudioContext interface: operation createIIRFilter([object Object], [object Object]) -PASS Unscopable handled correctly for createIIRFilter([object Object], [object Object]) on BaseAudioContext -PASS BaseAudioContext interface: operation createWaveShaper() -PASS Unscopable handled correctly for createWaveShaper() on BaseAudioContext -PASS BaseAudioContext interface: operation createPanner() -PASS Unscopable handled correctly for createPanner() on BaseAudioContext -PASS BaseAudioContext interface: operation createStereoPanner() -PASS Unscopable handled correctly for createStereoPanner() on BaseAudioContext -PASS BaseAudioContext interface: operation createConvolver() -PASS Unscopable handled correctly for createConvolver() on BaseAudioContext -PASS BaseAudioContext interface: operation createChannelSplitter(unsigned long) -PASS Unscopable handled correctly for createChannelSplitter(unsigned long) on BaseAudioContext +PASS BaseAudioContext interface: operation createBuffer(unsigned long, unsigned long, float) +PASS Unscopable handled correctly for createBuffer(unsigned long, unsigned long, float) on BaseAudioContext +PASS BaseAudioContext interface: operation createBufferSource() +PASS Unscopable handled correctly for createBufferSource() on BaseAudioContext PASS BaseAudioContext interface: operation createChannelMerger(unsigned long) PASS Unscopable handled correctly for createChannelMerger(unsigned long) on BaseAudioContext +PASS BaseAudioContext interface: operation createChannelSplitter(unsigned long) +PASS Unscopable handled correctly for createChannelSplitter(unsigned long) on BaseAudioContext +PASS BaseAudioContext interface: operation createConstantSource() +PASS Unscopable handled correctly for createConstantSource() on BaseAudioContext +PASS BaseAudioContext interface: operation createConvolver() +PASS Unscopable handled correctly for createConvolver() on BaseAudioContext +PASS BaseAudioContext interface: operation createDelay(double) +PASS Unscopable handled correctly for createDelay(double) on BaseAudioContext PASS BaseAudioContext interface: operation createDynamicsCompressor() PASS Unscopable handled correctly for createDynamicsCompressor() on BaseAudioContext +PASS BaseAudioContext interface: operation createGain() +PASS Unscopable handled correctly for createGain() on BaseAudioContext +PASS BaseAudioContext interface: operation createIIRFilter([object Object], [object Object]) +PASS Unscopable handled correctly for createIIRFilter([object Object], [object Object]) on BaseAudioContext PASS BaseAudioContext interface: operation createOscillator() PASS Unscopable handled correctly for createOscillator() on BaseAudioContext +PASS BaseAudioContext interface: operation createPanner() +PASS Unscopable handled correctly for createPanner() on BaseAudioContext PASS BaseAudioContext interface: operation createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) PASS Unscopable handled correctly for createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on BaseAudioContext +PASS BaseAudioContext interface: operation createScriptProcessor(unsigned long, unsigned long, unsigned long) +PASS Unscopable handled correctly for createScriptProcessor(unsigned long, unsigned long, unsigned long) on BaseAudioContext +PASS BaseAudioContext interface: operation createStereoPanner() +PASS Unscopable handled correctly for createStereoPanner() on BaseAudioContext +PASS BaseAudioContext interface: operation createWaveShaper() +PASS Unscopable handled correctly for createWaveShaper() on BaseAudioContext +PASS BaseAudioContext interface: operation decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) +PASS Unscopable handled correctly for decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on BaseAudioContext +PASS BaseAudioContext interface: operation resume() +PASS Unscopable handled correctly for resume() on BaseAudioContext PASS AudioContext interface: existence and properties of interface object PASS AudioContext interface object length PASS AudioContext interface object name @@ -84,55 +84,55 @@ PASS Unscopable handled correctly for createMediaStreamTrackSource(MediaStreamTrack) on AudioContext FAIL AudioContext interface: operation createMediaStreamDestination() assert_own_property: interface prototype object missing non-static operation expected property "createMediaStreamDestination" missing PASS Unscopable handled correctly for createMediaStreamDestination() on AudioContext -PASS AudioContext must be primary interface of [object AudioContext] -PASS Stringification of [object AudioContext] -PASS AudioContext interface: [object AudioContext] must inherit property "baseLatency" with the proper type -FAIL AudioContext interface: [object AudioContext] must inherit property "outputLatency" with the proper type assert_inherits: property "outputLatency" not found in prototype chain -PASS AudioContext interface: [object AudioContext] must inherit property "getOutputTimestamp()" with the proper type -PASS AudioContext interface: [object AudioContext] must inherit property "suspend()" with the proper type -PASS AudioContext interface: [object AudioContext] must inherit property "close()" with the proper type -PASS AudioContext interface: [object AudioContext] must inherit property "createMediaElementSource(HTMLMediaElement)" with the proper type -PASS AudioContext interface: calling createMediaElementSource(HTMLMediaElement) on [object AudioContext] with too few arguments must throw TypeError -PASS AudioContext interface: [object AudioContext] must inherit property "createMediaStreamSource(MediaStream)" with the proper type -PASS AudioContext interface: calling createMediaStreamSource(MediaStream) on [object AudioContext] with too few arguments must throw TypeError -FAIL AudioContext interface: [object AudioContext] must inherit property "createMediaStreamTrackSource(MediaStreamTrack)" with the proper type assert_inherits: property "createMediaStreamTrackSource" not found in prototype chain -FAIL AudioContext interface: calling createMediaStreamTrackSource(MediaStreamTrack) on [object AudioContext] with too few arguments must throw TypeError assert_inherits: property "createMediaStreamTrackSource" not found in prototype chain -PASS AudioContext interface: [object AudioContext] must inherit property "createMediaStreamDestination()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "destination" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "sampleRate" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "currentTime" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "listener" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "state" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "audioWorklet" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "resume()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "onstatechange" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createBuffer(unsigned long, unsigned long, float)" with the proper type -PASS BaseAudioContext interface: calling createBuffer(unsigned long, unsigned long, float) on [object AudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object AudioContext] must inherit property "decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback)" with the proper type -PASS BaseAudioContext interface: calling decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on [object AudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createBufferSource()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createConstantSource()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createScriptProcessor(unsigned long, unsigned long, unsigned long)" with the proper type -PASS BaseAudioContext interface: calling createScriptProcessor(unsigned long, unsigned long, unsigned long) on [object AudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createAnalyser()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createGain()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createDelay(double)" with the proper type -PASS BaseAudioContext interface: calling createDelay(double) on [object AudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createBiquadFilter()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createIIRFilter([object Object], [object Object])" with the proper type -PASS BaseAudioContext interface: calling createIIRFilter([object Object], [object Object]) on [object AudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createWaveShaper()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createPanner()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createStereoPanner()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createConvolver()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createChannelSplitter(unsigned long)" with the proper type -PASS BaseAudioContext interface: calling createChannelSplitter(unsigned long) on [object AudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createChannelMerger(unsigned long)" with the proper type -PASS BaseAudioContext interface: calling createChannelMerger(unsigned long) on [object AudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createDynamicsCompressor()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createOscillator()" with the proper type -PASS BaseAudioContext interface: [object AudioContext] must inherit property "createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints)" with the proper type -PASS BaseAudioContext interface: calling createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on [object AudioContext] with too few arguments must throw TypeError +PASS AudioContext must be primary interface of context +PASS Stringification of context +PASS AudioContext interface: context must inherit property "baseLatency" with the proper type +FAIL AudioContext interface: context must inherit property "outputLatency" with the proper type assert_inherits: property "outputLatency" not found in prototype chain +PASS AudioContext interface: context must inherit property "getOutputTimestamp()" with the proper type +PASS AudioContext interface: context must inherit property "suspend()" with the proper type +PASS AudioContext interface: context must inherit property "close()" with the proper type +PASS AudioContext interface: context must inherit property "createMediaElementSource(HTMLMediaElement)" with the proper type +PASS AudioContext interface: calling createMediaElementSource(HTMLMediaElement) on context with too few arguments must throw TypeError +PASS AudioContext interface: context must inherit property "createMediaStreamSource(MediaStream)" with the proper type +PASS AudioContext interface: calling createMediaStreamSource(MediaStream) on context with too few arguments must throw TypeError +FAIL AudioContext interface: context must inherit property "createMediaStreamTrackSource(MediaStreamTrack)" with the proper type assert_inherits: property "createMediaStreamTrackSource" not found in prototype chain +FAIL AudioContext interface: calling createMediaStreamTrackSource(MediaStreamTrack) on context with too few arguments must throw TypeError assert_inherits: property "createMediaStreamTrackSource" not found in prototype chain +PASS AudioContext interface: context must inherit property "createMediaStreamDestination()" with the proper type +PASS BaseAudioContext interface: context must inherit property "destination" with the proper type +PASS BaseAudioContext interface: context must inherit property "sampleRate" with the proper type +PASS BaseAudioContext interface: context must inherit property "currentTime" with the proper type +PASS BaseAudioContext interface: context must inherit property "listener" with the proper type +PASS BaseAudioContext interface: context must inherit property "state" with the proper type +PASS BaseAudioContext interface: context must inherit property "audioWorklet" with the proper type +PASS BaseAudioContext interface: context must inherit property "onstatechange" with the proper type +PASS BaseAudioContext interface: context must inherit property "createAnalyser()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createBiquadFilter()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createBuffer(unsigned long, unsigned long, float)" with the proper type +PASS BaseAudioContext interface: calling createBuffer(unsigned long, unsigned long, float) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createBufferSource()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createChannelMerger(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelMerger(unsigned long) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createChannelSplitter(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelSplitter(unsigned long) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createConstantSource()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createConvolver()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createDelay(double)" with the proper type +PASS BaseAudioContext interface: calling createDelay(double) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createDynamicsCompressor()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createGain()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createIIRFilter([object Object], [object Object])" with the proper type +PASS BaseAudioContext interface: calling createIIRFilter([object Object], [object Object]) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createOscillator()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createPanner()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints)" with the proper type +PASS BaseAudioContext interface: calling createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createScriptProcessor(unsigned long, unsigned long, unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createScriptProcessor(unsigned long, unsigned long, unsigned long) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "createStereoPanner()" with the proper type +PASS BaseAudioContext interface: context must inherit property "createWaveShaper()" with the proper type +PASS BaseAudioContext interface: context must inherit property "decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback)" with the proper type +PASS BaseAudioContext interface: calling decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on context with too few arguments must throw TypeError +PASS BaseAudioContext interface: context must inherit property "resume()" with the proper type PASS OfflineAudioContext interface: existence and properties of interface object PASS OfflineAudioContext interface object length PASS OfflineAudioContext interface object name @@ -147,48 +147,48 @@ PASS Unscopable handled correctly for length property on OfflineAudioContext PASS OfflineAudioContext interface: attribute oncomplete PASS Unscopable handled correctly for oncomplete property on OfflineAudioContext -PASS OfflineAudioContext must be primary interface of [object OfflineAudioContext] -PASS Stringification of [object OfflineAudioContext] -PASS OfflineAudioContext interface: [object OfflineAudioContext] must inherit property "startRendering()" with the proper type -PASS OfflineAudioContext interface: [object OfflineAudioContext] must inherit property "suspend(double)" with the proper type -PASS OfflineAudioContext interface: calling suspend(double) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS OfflineAudioContext interface: [object OfflineAudioContext] must inherit property "length" with the proper type -PASS OfflineAudioContext interface: [object OfflineAudioContext] must inherit property "oncomplete" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "destination" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "sampleRate" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "currentTime" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "listener" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "state" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "audioWorklet" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "resume()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "onstatechange" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createBuffer(unsigned long, unsigned long, float)" with the proper type -PASS BaseAudioContext interface: calling createBuffer(unsigned long, unsigned long, float) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback)" with the proper type -PASS BaseAudioContext interface: calling decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createBufferSource()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createConstantSource()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createScriptProcessor(unsigned long, unsigned long, unsigned long)" with the proper type -PASS BaseAudioContext interface: calling createScriptProcessor(unsigned long, unsigned long, unsigned long) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createAnalyser()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createGain()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createDelay(double)" with the proper type -PASS BaseAudioContext interface: calling createDelay(double) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createBiquadFilter()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createIIRFilter([object Object], [object Object])" with the proper type -PASS BaseAudioContext interface: calling createIIRFilter([object Object], [object Object]) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createWaveShaper()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createPanner()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createStereoPanner()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createConvolver()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createChannelSplitter(unsigned long)" with the proper type -PASS BaseAudioContext interface: calling createChannelSplitter(unsigned long) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createChannelMerger(unsigned long)" with the proper type -PASS BaseAudioContext interface: calling createChannelMerger(unsigned long) on [object OfflineAudioContext] with too few arguments must throw TypeError -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createDynamicsCompressor()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createOscillator()" with the proper type -PASS BaseAudioContext interface: [object OfflineAudioContext] must inherit property "createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints)" with the proper type -PASS BaseAudioContext interface: calling createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on [object OfflineAudioContext] with too few arguments must throw TypeError +PASS OfflineAudioContext must be primary interface of new OfflineAudioContext(1, 1, sample_rate) +PASS Stringification of new OfflineAudioContext(1, 1, sample_rate) +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "startRendering()" with the proper type +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "suspend(double)" with the proper type +PASS OfflineAudioContext interface: calling suspend(double) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "length" with the proper type +PASS OfflineAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "oncomplete" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "destination" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "sampleRate" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "currentTime" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "listener" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "state" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "audioWorklet" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "onstatechange" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createAnalyser()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createBiquadFilter()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createBuffer(unsigned long, unsigned long, float)" with the proper type +PASS BaseAudioContext interface: calling createBuffer(unsigned long, unsigned long, float) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createBufferSource()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createChannelMerger(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelMerger(unsigned long) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createChannelSplitter(unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createChannelSplitter(unsigned long) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createConstantSource()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createConvolver()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createDelay(double)" with the proper type +PASS BaseAudioContext interface: calling createDelay(double) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createDynamicsCompressor()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createGain()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createIIRFilter([object Object], [object Object])" with the proper type +PASS BaseAudioContext interface: calling createIIRFilter([object Object], [object Object]) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createOscillator()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createPanner()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints)" with the proper type +PASS BaseAudioContext interface: calling createPeriodicWave([object Object], [object Object], PeriodicWaveConstraints) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createScriptProcessor(unsigned long, unsigned long, unsigned long)" with the proper type +PASS BaseAudioContext interface: calling createScriptProcessor(unsigned long, unsigned long, unsigned long) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createStereoPanner()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "createWaveShaper()" with the proper type +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback)" with the proper type +PASS BaseAudioContext interface: calling decodeAudioData(ArrayBuffer, DecodeSuccessCallback, DecodeErrorCallback) on new OfflineAudioContext(1, 1, sample_rate) with too few arguments must throw TypeError +PASS BaseAudioContext interface: new OfflineAudioContext(1, 1, sample_rate) must inherit property "resume()" with the proper type PASS OfflineAudioCompletionEvent interface: existence and properties of interface object PASS OfflineAudioCompletionEvent interface object length PASS OfflineAudioCompletionEvent interface object name @@ -197,9 +197,9 @@ PASS OfflineAudioCompletionEvent interface: existence and properties of interface prototype object's @@unscopables property PASS OfflineAudioCompletionEvent interface: attribute renderedBuffer PASS Unscopable handled correctly for renderedBuffer property on OfflineAudioCompletionEvent -PASS OfflineAudioCompletionEvent must be primary interface of [object OfflineAudioCompletionEvent] -PASS Stringification of [object OfflineAudioCompletionEvent] -PASS OfflineAudioCompletionEvent interface: [object OfflineAudioCompletionEvent] must inherit property "renderedBuffer" with the proper type +PASS OfflineAudioCompletionEvent must be primary interface of new OfflineAudioCompletionEvent("", {renderedBuffer: buffer}) +PASS Stringification of new OfflineAudioCompletionEvent("", {renderedBuffer: buffer}) +PASS OfflineAudioCompletionEvent interface: new OfflineAudioCompletionEvent("", {renderedBuffer: buffer}) must inherit property "renderedBuffer" with the proper type PASS AudioBuffer interface: existence and properties of interface object PASS AudioBuffer interface object length PASS AudioBuffer interface object name @@ -220,18 +220,18 @@ PASS Unscopable handled correctly for copyFromChannel(Float32Array, unsigned long, unsigned long) on AudioBuffer PASS AudioBuffer interface: operation copyToChannel(Float32Array, unsigned long, unsigned long) PASS Unscopable handled correctly for copyToChannel(Float32Array, unsigned long, unsigned long) on AudioBuffer -PASS AudioBuffer must be primary interface of [object AudioBuffer] -PASS Stringification of [object AudioBuffer] -PASS AudioBuffer interface: [object AudioBuffer] must inherit property "sampleRate" with the proper type -PASS AudioBuffer interface: [object AudioBuffer] must inherit property "length" with the proper type -PASS AudioBuffer interface: [object AudioBuffer] must inherit property "duration" with the proper type -PASS AudioBuffer interface: [object AudioBuffer] must inherit property "numberOfChannels" with the proper type -PASS AudioBuffer interface: [object AudioBuffer] must inherit property "getChannelData(unsigned long)" with the proper type -PASS AudioBuffer interface: calling getChannelData(unsigned long) on [object AudioBuffer] with too few arguments must throw TypeError -PASS AudioBuffer interface: [object AudioBuffer] must inherit property "copyFromChannel(Float32Array, unsigned long, unsigned long)" with the proper type -PASS AudioBuffer interface: calling copyFromChannel(Float32Array, unsigned long, unsigned long) on [object AudioBuffer] with too few arguments must throw TypeError -PASS AudioBuffer interface: [object AudioBuffer] must inherit property "copyToChannel(Float32Array, unsigned long, unsigned long)" with the proper type -PASS AudioBuffer interface: calling copyToChannel(Float32Array, unsigned long, unsigned long) on [object AudioBuffer] with too few arguments must throw TypeError +PASS AudioBuffer must be primary interface of buffer +PASS Stringification of buffer +PASS AudioBuffer interface: buffer must inherit property "sampleRate" with the proper type +PASS AudioBuffer interface: buffer must inherit property "length" with the proper type +PASS AudioBuffer interface: buffer must inherit property "duration" with the proper type +PASS AudioBuffer interface: buffer must inherit property "numberOfChannels" with the proper type +PASS AudioBuffer interface: buffer must inherit property "getChannelData(unsigned long)" with the proper type +PASS AudioBuffer interface: calling getChannelData(unsigned long) on buffer with too few arguments must throw TypeError +PASS AudioBuffer interface: buffer must inherit property "copyFromChannel(Float32Array, unsigned long, unsigned long)" with the proper type +PASS AudioBuffer interface: calling copyFromChannel(Float32Array, unsigned long, unsigned long) on buffer with too few arguments must throw TypeError +PASS AudioBuffer interface: buffer must inherit property "copyToChannel(Float32Array, unsigned long, unsigned long)" with the proper type +PASS AudioBuffer interface: calling copyToChannel(Float32Array, unsigned long, unsigned long) on buffer with too few arguments must throw TypeError PASS AudioNode interface: existence and properties of interface object PASS AudioNode interface object length PASS AudioNode interface object name @@ -298,27 +298,27 @@ PASS Unscopable handled correctly for cancelScheduledValues(double) on AudioParam PASS AudioParam interface: operation cancelAndHoldAtTime(double) PASS Unscopable handled correctly for cancelAndHoldAtTime(double) on AudioParam -PASS AudioParam must be primary interface of [object AudioParam] -PASS Stringification of [object AudioParam] -PASS AudioParam interface: [object AudioParam] must inherit property "value" with the proper type -PASS AudioParam interface: [object AudioParam] must inherit property "automationRate" with the proper type -PASS AudioParam interface: [object AudioParam] must inherit property "defaultValue" with the proper type -PASS AudioParam interface: [object AudioParam] must inherit property "minValue" with the proper type -PASS AudioParam interface: [object AudioParam] must inherit property "maxValue" with the proper type -PASS AudioParam interface: [object AudioParam] must inherit property "setValueAtTime(float, double)" with the proper type -PASS AudioParam interface: calling setValueAtTime(float, double) on [object AudioParam] with too few arguments must throw TypeError -PASS AudioParam interface: [object AudioParam] must inherit property "linearRampToValueAtTime(float, double)" with the proper type -PASS AudioParam interface: calling linearRampToValueAtTime(float, double) on [object AudioParam] with too few arguments must throw TypeError -PASS AudioParam interface: [object AudioParam] must inherit property "exponentialRampToValueAtTime(float, double)" with the proper type -PASS AudioParam interface: calling exponentialRampToValueAtTime(float, double) on [object AudioParam] with too few arguments must throw TypeError -PASS AudioParam interface: [object AudioParam] must inherit property "setTargetAtTime(float, double, float)" with the proper type -PASS AudioParam interface: calling setTargetAtTime(float, double, float) on [object AudioParam] with too few arguments must throw TypeError -PASS AudioParam interface: [object AudioParam] must inherit property "setValueCurveAtTime([object Object], double, double)" with the proper type -PASS AudioParam interface: calling setValueCurveAtTime([object Object], double, double) on [object AudioParam] with too few arguments must throw TypeError -PASS AudioParam interface: [object AudioParam] must inherit property "cancelScheduledValues(double)" with the proper type -PASS AudioParam interface: calling cancelScheduledValues(double) on [object AudioParam] with too few arguments must throw TypeError -PASS AudioParam interface: [object AudioParam] must inherit property "cancelAndHoldAtTime(double)" with the proper type -PASS AudioParam interface: calling cancelAndHoldAtTime(double) on [object AudioParam] with too few arguments must throw TypeError +PASS AudioParam must be primary interface of new AudioBufferSourceNode(context).playbackRate +PASS Stringification of new AudioBufferSourceNode(context).playbackRate +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "value" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "automationRate" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "defaultValue" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "minValue" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "maxValue" with the proper type +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "setValueAtTime(float, double)" with the proper type +PASS AudioParam interface: calling setValueAtTime(float, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "linearRampToValueAtTime(float, double)" with the proper type +PASS AudioParam interface: calling linearRampToValueAtTime(float, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "exponentialRampToValueAtTime(float, double)" with the proper type +PASS AudioParam interface: calling exponentialRampToValueAtTime(float, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "setTargetAtTime(float, double, float)" with the proper type +PASS AudioParam interface: calling setTargetAtTime(float, double, float) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "setValueCurveAtTime([object Object], double, double)" with the proper type +PASS AudioParam interface: calling setValueCurveAtTime([object Object], double, double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "cancelScheduledValues(double)" with the proper type +PASS AudioParam interface: calling cancelScheduledValues(double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError +PASS AudioParam interface: new AudioBufferSourceNode(context).playbackRate must inherit property "cancelAndHoldAtTime(double)" with the proper type +PASS AudioParam interface: calling cancelAndHoldAtTime(double) on new AudioBufferSourceNode(context).playbackRate with too few arguments must throw TypeError PASS AudioScheduledSourceNode interface: existence and properties of interface object PASS AudioScheduledSourceNode interface object length PASS AudioScheduledSourceNode interface object name @@ -355,44 +355,44 @@ PASS Unscopable handled correctly for maxDecibels property on AnalyserNode PASS AnalyserNode interface: attribute smoothingTimeConstant PASS Unscopable handled correctly for smoothingTimeConstant property on AnalyserNode -PASS AnalyserNode must be primary interface of [object AnalyserNode] -PASS Stringification of [object AnalyserNode] -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "getFloatFrequencyData(Float32Array)" with the proper type -PASS AnalyserNode interface: calling getFloatFrequencyData(Float32Array) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "getByteFrequencyData(Uint8Array)" with the proper type -PASS AnalyserNode interface: calling getByteFrequencyData(Uint8Array) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "getFloatTimeDomainData(Float32Array)" with the proper type -PASS AnalyserNode interface: calling getFloatTimeDomainData(Float32Array) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "getByteTimeDomainData(Uint8Array)" with the proper type -PASS AnalyserNode interface: calling getByteTimeDomainData(Uint8Array) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "fftSize" with the proper type -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "frequencyBinCount" with the proper type -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "minDecibels" with the proper type -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "maxDecibels" with the proper type -PASS AnalyserNode interface: [object AnalyserNode] must inherit property "smoothingTimeConstant" with the proper type -PASS AudioNode interface: [object AnalyserNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object AnalyserNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object AnalyserNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AnalyserNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object AnalyserNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object AnalyserNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object AnalyserNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object AnalyserNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object AnalyserNode] must inherit property "channelInterpretation" with the proper type +PASS AnalyserNode must be primary interface of new AnalyserNode(context) +PASS Stringification of new AnalyserNode(context) +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getFloatFrequencyData(Float32Array)" with the proper type +PASS AnalyserNode interface: calling getFloatFrequencyData(Float32Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getByteFrequencyData(Uint8Array)" with the proper type +PASS AnalyserNode interface: calling getByteFrequencyData(Uint8Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getFloatTimeDomainData(Float32Array)" with the proper type +PASS AnalyserNode interface: calling getFloatTimeDomainData(Float32Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "getByteTimeDomainData(Uint8Array)" with the proper type +PASS AnalyserNode interface: calling getByteTimeDomainData(Uint8Array) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "fftSize" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "frequencyBinCount" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "minDecibels" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "maxDecibels" with the proper type +PASS AnalyserNode interface: new AnalyserNode(context) must inherit property "smoothingTimeConstant" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new AnalyserNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AnalyserNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new AnalyserNode(context) must inherit property "channelInterpretation" with the proper type PASS AudioBufferSourceNode interface: existence and properties of interface object PASS AudioBufferSourceNode interface object length PASS AudioBufferSourceNode interface object name @@ -413,48 +413,44 @@ PASS Unscopable handled correctly for loopEnd property on AudioBufferSourceNode PASS AudioBufferSourceNode interface: operation start(double, double, double) PASS Unscopable handled correctly for start(double, double, double) on AudioBufferSourceNode -FAIL AudioBufferSourceNode interface: operation stop(double) assert_own_property: interface prototype object missing non-static operation expected property "stop" missing -PASS Unscopable handled correctly for stop(double) on AudioBufferSourceNode -PASS AudioBufferSourceNode must be primary interface of [object AudioBufferSourceNode] -PASS Stringification of [object AudioBufferSourceNode] -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "buffer" with the proper type -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "playbackRate" with the proper type -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "detune" with the proper type -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "loop" with the proper type -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "loopStart" with the proper type -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "loopEnd" with the proper type -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "start(double, double, double)" with the proper type -PASS AudioBufferSourceNode interface: calling start(double, double, double) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioBufferSourceNode interface: [object AudioBufferSourceNode] must inherit property "stop(double)" with the proper type -PASS AudioBufferSourceNode interface: calling stop(double) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioScheduledSourceNode interface: [object AudioBufferSourceNode] must inherit property "onended" with the proper type -PASS AudioScheduledSourceNode interface: [object AudioBufferSourceNode] must inherit property "start(double)" with the proper type -PASS AudioScheduledSourceNode interface: calling start(double) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioScheduledSourceNode interface: [object AudioBufferSourceNode] must inherit property "stop(double)" with the proper type -PASS AudioScheduledSourceNode interface: calling stop(double) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object AudioBufferSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object AudioBufferSourceNode] must inherit property "channelInterpretation" with the proper type +PASS AudioBufferSourceNode must be primary interface of new AudioBufferSourceNode(context) +PASS Stringification of new AudioBufferSourceNode(context) +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "buffer" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "playbackRate" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "detune" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "loop" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "loopStart" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "loopEnd" with the proper type +PASS AudioBufferSourceNode interface: new AudioBufferSourceNode(context) must inherit property "start(double, double, double)" with the proper type +PASS AudioBufferSourceNode interface: calling start(double, double, double) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new AudioBufferSourceNode(context) must inherit property "onended" with the proper type +PASS AudioScheduledSourceNode interface: new AudioBufferSourceNode(context) must inherit property "start(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling start(double) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new AudioBufferSourceNode(context) must inherit property "stop(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling stop(double) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new AudioBufferSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new AudioBufferSourceNode(context) must inherit property "channelInterpretation" with the proper type PASS AudioDestinationNode interface: existence and properties of interface object PASS AudioDestinationNode interface object length PASS AudioDestinationNode interface object name @@ -463,32 +459,32 @@ PASS AudioDestinationNode interface: existence and properties of interface prototype object's @@unscopables property PASS AudioDestinationNode interface: attribute maxChannelCount PASS Unscopable handled correctly for maxChannelCount property on AudioDestinationNode -PASS AudioDestinationNode must be primary interface of [object AudioDestinationNode] -PASS Stringification of [object AudioDestinationNode] -PASS AudioDestinationNode interface: [object AudioDestinationNode] must inherit property "maxChannelCount" with the proper type -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object AudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object AudioDestinationNode] must inherit property "channelInterpretation" with the proper type +PASS AudioDestinationNode must be primary interface of context.destination +PASS Stringification of context.destination +PASS AudioDestinationNode interface: context.destination must inherit property "maxChannelCount" with the proper type +PASS AudioNode interface: context.destination must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect()" with the proper type +PASS AudioNode interface: context.destination must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on context.destination with too few arguments must throw TypeError +PASS AudioNode interface: context.destination must inherit property "context" with the proper type +PASS AudioNode interface: context.destination must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: context.destination must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: context.destination must inherit property "channelCount" with the proper type +PASS AudioNode interface: context.destination must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: context.destination must inherit property "channelInterpretation" with the proper type PASS AudioListener interface: existence and properties of interface object PASS AudioListener interface object length PASS AudioListener interface object name @@ -517,21 +513,21 @@ PASS Unscopable handled correctly for setPosition(float, float, float) on AudioListener PASS AudioListener interface: operation setOrientation(float, float, float, float, float, float) PASS Unscopable handled correctly for setOrientation(float, float, float, float, float, float) on AudioListener -PASS AudioListener must be primary interface of [object AudioListener] -PASS Stringification of [object AudioListener] -PASS AudioListener interface: [object AudioListener] must inherit property "positionX" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "positionY" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "positionZ" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "forwardX" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "forwardY" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "forwardZ" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "upX" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "upY" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "upZ" with the proper type -PASS AudioListener interface: [object AudioListener] must inherit property "setPosition(float, float, float)" with the proper type -PASS AudioListener interface: calling setPosition(float, float, float) on [object AudioListener] with too few arguments must throw TypeError -PASS AudioListener interface: [object AudioListener] must inherit property "setOrientation(float, float, float, float, float, float)" with the proper type -PASS AudioListener interface: calling setOrientation(float, float, float, float, float, float) on [object AudioListener] with too few arguments must throw TypeError +PASS AudioListener must be primary interface of context.listener +PASS Stringification of context.listener +PASS AudioListener interface: context.listener must inherit property "positionX" with the proper type +PASS AudioListener interface: context.listener must inherit property "positionY" with the proper type +PASS AudioListener interface: context.listener must inherit property "positionZ" with the proper type +PASS AudioListener interface: context.listener must inherit property "forwardX" with the proper type +PASS AudioListener interface: context.listener must inherit property "forwardY" with the proper type +PASS AudioListener interface: context.listener must inherit property "forwardZ" with the proper type +PASS AudioListener interface: context.listener must inherit property "upX" with the proper type +PASS AudioListener interface: context.listener must inherit property "upY" with the proper type +PASS AudioListener interface: context.listener must inherit property "upZ" with the proper type +PASS AudioListener interface: context.listener must inherit property "setPosition(float, float, float)" with the proper type +PASS AudioListener interface: calling setPosition(float, float, float) on context.listener with too few arguments must throw TypeError +PASS AudioListener interface: context.listener must inherit property "setOrientation(float, float, float, float, float, float)" with the proper type +PASS AudioListener interface: calling setOrientation(float, float, float, float, float, float) on context.listener with too few arguments must throw TypeError PASS AudioProcessingEvent interface: existence and properties of interface object PASS AudioProcessingEvent interface object length PASS AudioProcessingEvent interface object name @@ -544,11 +540,21 @@ PASS Unscopable handled correctly for inputBuffer property on AudioProcessingEvent PASS AudioProcessingEvent interface: attribute outputBuffer PASS Unscopable handled correctly for outputBuffer property on AudioProcessingEvent -PASS AudioProcessingEvent must be primary interface of [object AudioProcessingEvent] -PASS Stringification of [object AudioProcessingEvent] -PASS AudioProcessingEvent interface: [object AudioProcessingEvent] must inherit property "playbackTime" with the proper type -PASS AudioProcessingEvent interface: [object AudioProcessingEvent] must inherit property "inputBuffer" with the proper type -PASS AudioProcessingEvent interface: [object AudioProcessingEvent] must inherit property "outputBuffer" with the proper type +PASS AudioProcessingEvent must be primary interface of new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) +PASS Stringification of new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) +PASS AudioProcessingEvent interface: new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) must inherit property "playbackTime" with the proper type +PASS AudioProcessingEvent interface: new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) must inherit property "inputBuffer" with the proper type +PASS AudioProcessingEvent interface: new AudioProcessingEvent('', { + playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer + }) must inherit property "outputBuffer" with the proper type PASS BiquadFilterNode interface: existence and properties of interface object PASS BiquadFilterNode interface object length PASS BiquadFilterNode interface object name @@ -567,100 +573,100 @@ PASS Unscopable handled correctly for gain property on BiquadFilterNode PASS BiquadFilterNode interface: operation getFrequencyResponse(Float32Array, Float32Array, Float32Array) PASS Unscopable handled correctly for getFrequencyResponse(Float32Array, Float32Array, Float32Array) on BiquadFilterNode -PASS BiquadFilterNode must be primary interface of [object BiquadFilterNode] -PASS Stringification of [object BiquadFilterNode] -PASS BiquadFilterNode interface: [object BiquadFilterNode] must inherit property "type" with the proper type -PASS BiquadFilterNode interface: [object BiquadFilterNode] must inherit property "frequency" with the proper type -PASS BiquadFilterNode interface: [object BiquadFilterNode] must inherit property "detune" with the proper type -PASS BiquadFilterNode interface: [object BiquadFilterNode] must inherit property "Q" with the proper type -PASS BiquadFilterNode interface: [object BiquadFilterNode] must inherit property "gain" with the proper type -PASS BiquadFilterNode interface: [object BiquadFilterNode] must inherit property "getFrequencyResponse(Float32Array, Float32Array, Float32Array)" with the proper type -PASS BiquadFilterNode interface: calling getFrequencyResponse(Float32Array, Float32Array, Float32Array) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object BiquadFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object BiquadFilterNode] must inherit property "channelInterpretation" with the proper type +PASS BiquadFilterNode must be primary interface of new BiquadFilterNode(context) +PASS Stringification of new BiquadFilterNode(context) +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "type" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "frequency" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "detune" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "Q" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "gain" with the proper type +PASS BiquadFilterNode interface: new BiquadFilterNode(context) must inherit property "getFrequencyResponse(Float32Array, Float32Array, Float32Array)" with the proper type +PASS BiquadFilterNode interface: calling getFrequencyResponse(Float32Array, Float32Array, Float32Array) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new BiquadFilterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new BiquadFilterNode(context) must inherit property "channelInterpretation" with the proper type PASS ChannelMergerNode interface: existence and properties of interface object PASS ChannelMergerNode interface object length PASS ChannelMergerNode interface object name PASS ChannelMergerNode interface: existence and properties of interface prototype object PASS ChannelMergerNode interface: existence and properties of interface prototype object's "constructor" property PASS ChannelMergerNode interface: existence and properties of interface prototype object's @@unscopables property -PASS ChannelMergerNode must be primary interface of [object ChannelMergerNode] -PASS Stringification of [object ChannelMergerNode] -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object ChannelMergerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object ChannelMergerNode] must inherit property "channelInterpretation" with the proper type +PASS ChannelMergerNode must be primary interface of new ChannelMergerNode(context) +PASS Stringification of new ChannelMergerNode(context) +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ChannelMergerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ChannelMergerNode(context) must inherit property "channelInterpretation" with the proper type PASS ChannelSplitterNode interface: existence and properties of interface object PASS ChannelSplitterNode interface object length PASS ChannelSplitterNode interface object name PASS ChannelSplitterNode interface: existence and properties of interface prototype object PASS ChannelSplitterNode interface: existence and properties of interface prototype object's "constructor" property PASS ChannelSplitterNode interface: existence and properties of interface prototype object's @@unscopables property -PASS ChannelSplitterNode must be primary interface of [object ChannelSplitterNode] -PASS Stringification of [object ChannelSplitterNode] -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object ChannelSplitterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object ChannelSplitterNode] must inherit property "channelInterpretation" with the proper type +PASS ChannelSplitterNode must be primary interface of new ChannelSplitterNode(context) +PASS Stringification of new ChannelSplitterNode(context) +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ChannelSplitterNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ChannelSplitterNode(context) must inherit property "channelInterpretation" with the proper type PASS ConstantSourceNode interface: existence and properties of interface object PASS ConstantSourceNode interface object length PASS ConstantSourceNode interface object name @@ -669,37 +675,37 @@ PASS ConstantSourceNode interface: existence and properties of interface prototype object's @@unscopables property PASS ConstantSourceNode interface: attribute offset PASS Unscopable handled correctly for offset property on ConstantSourceNode -PASS ConstantSourceNode must be primary interface of [object ConstantSourceNode] -PASS Stringification of [object ConstantSourceNode] -PASS ConstantSourceNode interface: [object ConstantSourceNode] must inherit property "offset" with the proper type -PASS AudioScheduledSourceNode interface: [object ConstantSourceNode] must inherit property "onended" with the proper type -PASS AudioScheduledSourceNode interface: [object ConstantSourceNode] must inherit property "start(double)" with the proper type -PASS AudioScheduledSourceNode interface: calling start(double) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioScheduledSourceNode interface: [object ConstantSourceNode] must inherit property "stop(double)" with the proper type -PASS AudioScheduledSourceNode interface: calling stop(double) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object ConstantSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object ConstantSourceNode] must inherit property "channelInterpretation" with the proper type +PASS ConstantSourceNode must be primary interface of new ConstantSourceNode(context) +PASS Stringification of new ConstantSourceNode(context) +PASS ConstantSourceNode interface: new ConstantSourceNode(context) must inherit property "offset" with the proper type +PASS AudioScheduledSourceNode interface: new ConstantSourceNode(context) must inherit property "onended" with the proper type +PASS AudioScheduledSourceNode interface: new ConstantSourceNode(context) must inherit property "start(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling start(double) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new ConstantSourceNode(context) must inherit property "stop(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling stop(double) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ConstantSourceNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ConstantSourceNode(context) must inherit property "channelInterpretation" with the proper type PASS ConvolverNode interface: existence and properties of interface object PASS ConvolverNode interface object length PASS ConvolverNode interface object name @@ -710,33 +716,33 @@ PASS Unscopable handled correctly for buffer property on ConvolverNode PASS ConvolverNode interface: attribute normalize PASS Unscopable handled correctly for normalize property on ConvolverNode -PASS ConvolverNode must be primary interface of [object ConvolverNode] -PASS Stringification of [object ConvolverNode] -PASS ConvolverNode interface: [object ConvolverNode] must inherit property "buffer" with the proper type -PASS ConvolverNode interface: [object ConvolverNode] must inherit property "normalize" with the proper type -PASS AudioNode interface: [object ConvolverNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object ConvolverNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object ConvolverNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ConvolverNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object ConvolverNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object ConvolverNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object ConvolverNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object ConvolverNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object ConvolverNode] must inherit property "channelInterpretation" with the proper type +PASS ConvolverNode must be primary interface of new ConvolverNode(context) +PASS Stringification of new ConvolverNode(context) +PASS ConvolverNode interface: new ConvolverNode(context) must inherit property "buffer" with the proper type +PASS ConvolverNode interface: new ConvolverNode(context) must inherit property "normalize" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new ConvolverNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new ConvolverNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new ConvolverNode(context) must inherit property "channelInterpretation" with the proper type PASS DelayNode interface: existence and properties of interface object PASS DelayNode interface object length PASS DelayNode interface object name @@ -745,32 +751,32 @@ PASS DelayNode interface: existence and properties of interface prototype object's @@unscopables property PASS DelayNode interface: attribute delayTime PASS Unscopable handled correctly for delayTime property on DelayNode -PASS DelayNode must be primary interface of [object DelayNode] -PASS Stringification of [object DelayNode] -PASS DelayNode interface: [object DelayNode] must inherit property "delayTime" with the proper type -PASS AudioNode interface: [object DelayNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object DelayNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object DelayNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DelayNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object DelayNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object DelayNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object DelayNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object DelayNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object DelayNode] must inherit property "channelInterpretation" with the proper type +PASS DelayNode must be primary interface of new DelayNode(context) +PASS Stringification of new DelayNode(context) +PASS DelayNode interface: new DelayNode(context) must inherit property "delayTime" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new DelayNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DelayNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new DelayNode(context) must inherit property "channelInterpretation" with the proper type PASS DynamicsCompressorNode interface: existence and properties of interface object PASS DynamicsCompressorNode interface object length PASS DynamicsCompressorNode interface object name @@ -789,37 +795,37 @@ PASS Unscopable handled correctly for attack property on DynamicsCompressorNode PASS DynamicsCompressorNode interface: attribute release PASS Unscopable handled correctly for release property on DynamicsCompressorNode -PASS DynamicsCompressorNode must be primary interface of [object DynamicsCompressorNode] -PASS Stringification of [object DynamicsCompressorNode] -PASS DynamicsCompressorNode interface: [object DynamicsCompressorNode] must inherit property "threshold" with the proper type -PASS DynamicsCompressorNode interface: [object DynamicsCompressorNode] must inherit property "knee" with the proper type -PASS DynamicsCompressorNode interface: [object DynamicsCompressorNode] must inherit property "ratio" with the proper type -PASS DynamicsCompressorNode interface: [object DynamicsCompressorNode] must inherit property "reduction" with the proper type -PASS DynamicsCompressorNode interface: [object DynamicsCompressorNode] must inherit property "attack" with the proper type -PASS DynamicsCompressorNode interface: [object DynamicsCompressorNode] must inherit property "release" with the proper type -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object DynamicsCompressorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object DynamicsCompressorNode] must inherit property "channelInterpretation" with the proper type +PASS DynamicsCompressorNode must be primary interface of new DynamicsCompressorNode(context) +PASS Stringification of new DynamicsCompressorNode(context) +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "threshold" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "knee" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "ratio" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "reduction" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "attack" with the proper type +PASS DynamicsCompressorNode interface: new DynamicsCompressorNode(context) must inherit property "release" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new DynamicsCompressorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new DynamicsCompressorNode(context) must inherit property "channelInterpretation" with the proper type PASS GainNode interface: existence and properties of interface object PASS GainNode interface object length PASS GainNode interface object name @@ -828,32 +834,32 @@ PASS GainNode interface: existence and properties of interface prototype object's @@unscopables property PASS GainNode interface: attribute gain PASS Unscopable handled correctly for gain property on GainNode -PASS GainNode must be primary interface of [object GainNode] -PASS Stringification of [object GainNode] -PASS GainNode interface: [object GainNode] must inherit property "gain" with the proper type -PASS AudioNode interface: [object GainNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object GainNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object GainNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object GainNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object GainNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object GainNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object GainNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object GainNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object GainNode] must inherit property "channelInterpretation" with the proper type +PASS GainNode must be primary interface of new GainNode(context) +PASS Stringification of new GainNode(context) +PASS GainNode interface: new GainNode(context) must inherit property "gain" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new GainNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new GainNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new GainNode(context) must inherit property "channelInterpretation" with the proper type PASS IIRFilterNode interface: existence and properties of interface object PASS IIRFilterNode interface object length PASS IIRFilterNode interface object name @@ -862,33 +868,33 @@ PASS IIRFilterNode interface: existence and properties of interface prototype object's @@unscopables property PASS IIRFilterNode interface: operation getFrequencyResponse(Float32Array, Float32Array, Float32Array) PASS Unscopable handled correctly for getFrequencyResponse(Float32Array, Float32Array, Float32Array) on IIRFilterNode -PASS IIRFilterNode must be primary interface of [object IIRFilterNode] -PASS Stringification of [object IIRFilterNode] -PASS IIRFilterNode interface: [object IIRFilterNode] must inherit property "getFrequencyResponse(Float32Array, Float32Array, Float32Array)" with the proper type -PASS IIRFilterNode interface: calling getFrequencyResponse(Float32Array, Float32Array, Float32Array) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object IIRFilterNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object IIRFilterNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object IIRFilterNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object IIRFilterNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object IIRFilterNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object IIRFilterNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object IIRFilterNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object IIRFilterNode] must inherit property "channelInterpretation" with the proper type +PASS IIRFilterNode must be primary interface of new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) +PASS Stringification of new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) +PASS IIRFilterNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "getFrequencyResponse(Float32Array, Float32Array, Float32Array)" with the proper type +PASS IIRFilterNode interface: calling getFrequencyResponse(Float32Array, Float32Array, Float32Array) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) with too few arguments must throw TypeError +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "context" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new IIRFilterNode(context, {feedforward: [1], feedback: [1]}) must inherit property "channelInterpretation" with the proper type PASS MediaElementAudioSourceNode interface: existence and properties of interface object PASS MediaElementAudioSourceNode interface object length PASS MediaElementAudioSourceNode interface object name @@ -897,32 +903,32 @@ PASS MediaElementAudioSourceNode interface: existence and properties of interface prototype object's @@unscopables property PASS MediaElementAudioSourceNode interface: attribute mediaElement PASS Unscopable handled correctly for mediaElement property on MediaElementAudioSourceNode -PASS MediaElementAudioSourceNode must be primary interface of [object MediaElementAudioSourceNode] -PASS Stringification of [object MediaElementAudioSourceNode] -PASS MediaElementAudioSourceNode interface: [object MediaElementAudioSourceNode] must inherit property "mediaElement" with the proper type -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object MediaElementAudioSourceNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object MediaElementAudioSourceNode] must inherit property "channelInterpretation" with the proper type +PASS MediaElementAudioSourceNode must be primary interface of new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) +PASS Stringification of new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) +PASS MediaElementAudioSourceNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "mediaElement" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "context" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new MediaElementAudioSourceNode(context, {mediaElement: new Audio}) must inherit property "channelInterpretation" with the proper type PASS MediaStreamAudioDestinationNode interface: existence and properties of interface object PASS MediaStreamAudioDestinationNode interface object length PASS MediaStreamAudioDestinationNode interface object name @@ -931,32 +937,32 @@ PASS MediaStreamAudioDestinationNode interface: existence and properties of interface prototype object's @@unscopables property PASS MediaStreamAudioDestinationNode interface: attribute stream PASS Unscopable handled correctly for stream property on MediaStreamAudioDestinationNode -PASS MediaStreamAudioDestinationNode must be primary interface of [object MediaStreamAudioDestinationNode] -PASS Stringification of [object MediaStreamAudioDestinationNode] -PASS MediaStreamAudioDestinationNode interface: [object MediaStreamAudioDestinationNode] must inherit property "stream" with the proper type -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object MediaStreamAudioDestinationNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object MediaStreamAudioDestinationNode] must inherit property "channelInterpretation" with the proper type +PASS MediaStreamAudioDestinationNode must be primary interface of new MediaStreamAudioDestinationNode(context) +PASS Stringification of new MediaStreamAudioDestinationNode(context) +PASS MediaStreamAudioDestinationNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "stream" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new MediaStreamAudioDestinationNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new MediaStreamAudioDestinationNode(context) must inherit property "channelInterpretation" with the proper type PASS MediaStreamAudioSourceNode interface: existence and properties of interface object PASS MediaStreamAudioSourceNode interface object length PASS MediaStreamAudioSourceNode interface object name @@ -985,41 +991,41 @@ PASS Unscopable handled correctly for detune property on OscillatorNode PASS OscillatorNode interface: operation setPeriodicWave(PeriodicWave) PASS Unscopable handled correctly for setPeriodicWave(PeriodicWave) on OscillatorNode -PASS OscillatorNode must be primary interface of [object OscillatorNode] -PASS Stringification of [object OscillatorNode] -PASS OscillatorNode interface: [object OscillatorNode] must inherit property "type" with the proper type -PASS OscillatorNode interface: [object OscillatorNode] must inherit property "frequency" with the proper type -PASS OscillatorNode interface: [object OscillatorNode] must inherit property "detune" with the proper type -PASS OscillatorNode interface: [object OscillatorNode] must inherit property "setPeriodicWave(PeriodicWave)" with the proper type -PASS OscillatorNode interface: calling setPeriodicWave(PeriodicWave) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioScheduledSourceNode interface: [object OscillatorNode] must inherit property "onended" with the proper type -PASS AudioScheduledSourceNode interface: [object OscillatorNode] must inherit property "start(double)" with the proper type -PASS AudioScheduledSourceNode interface: calling start(double) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioScheduledSourceNode interface: [object OscillatorNode] must inherit property "stop(double)" with the proper type -PASS AudioScheduledSourceNode interface: calling stop(double) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object OscillatorNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object OscillatorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object OscillatorNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object OscillatorNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object OscillatorNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object OscillatorNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object OscillatorNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object OscillatorNode] must inherit property "channelInterpretation" with the proper type +PASS OscillatorNode must be primary interface of new OscillatorNode(context) +PASS Stringification of new OscillatorNode(context) +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "type" with the proper type +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "frequency" with the proper type +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "detune" with the proper type +PASS OscillatorNode interface: new OscillatorNode(context) must inherit property "setPeriodicWave(PeriodicWave)" with the proper type +PASS OscillatorNode interface: calling setPeriodicWave(PeriodicWave) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new OscillatorNode(context) must inherit property "onended" with the proper type +PASS AudioScheduledSourceNode interface: new OscillatorNode(context) must inherit property "start(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling start(double) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioScheduledSourceNode interface: new OscillatorNode(context) must inherit property "stop(double)" with the proper type +PASS AudioScheduledSourceNode interface: calling stop(double) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new OscillatorNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new OscillatorNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new OscillatorNode(context) must inherit property "channelInterpretation" with the proper type PASS PannerNode interface: existence and properties of interface object PASS PannerNode interface object length PASS PannerNode interface object name @@ -1058,57 +1064,57 @@ PASS Unscopable handled correctly for setPosition(float, float, float) on PannerNode PASS PannerNode interface: operation setOrientation(float, float, float) PASS Unscopable handled correctly for setOrientation(float, float, float) on PannerNode -PASS PannerNode must be primary interface of [object PannerNode] -PASS Stringification of [object PannerNode] -PASS PannerNode interface: [object PannerNode] must inherit property "panningModel" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "positionX" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "positionY" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "positionZ" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "orientationX" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "orientationY" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "orientationZ" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "distanceModel" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "refDistance" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "maxDistance" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "rolloffFactor" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "coneInnerAngle" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "coneOuterAngle" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "coneOuterGain" with the proper type -PASS PannerNode interface: [object PannerNode] must inherit property "setPosition(float, float, float)" with the proper type -PASS PannerNode interface: calling setPosition(float, float, float) on [object PannerNode] with too few arguments must throw TypeError -PASS PannerNode interface: [object PannerNode] must inherit property "setOrientation(float, float, float)" with the proper type -PASS PannerNode interface: calling setOrientation(float, float, float) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object PannerNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object PannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object PannerNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object PannerNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object PannerNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object PannerNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object PannerNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object PannerNode] must inherit property "channelInterpretation" with the proper type +PASS PannerNode must be primary interface of new PannerNode(context) +PASS Stringification of new PannerNode(context) +PASS PannerNode interface: new PannerNode(context) must inherit property "panningModel" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "positionX" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "positionY" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "positionZ" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "orientationX" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "orientationY" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "orientationZ" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "distanceModel" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "refDistance" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "maxDistance" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "rolloffFactor" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "coneInnerAngle" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "coneOuterAngle" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "coneOuterGain" with the proper type +PASS PannerNode interface: new PannerNode(context) must inherit property "setPosition(float, float, float)" with the proper type +PASS PannerNode interface: calling setPosition(float, float, float) on new PannerNode(context) with too few arguments must throw TypeError +PASS PannerNode interface: new PannerNode(context) must inherit property "setOrientation(float, float, float)" with the proper type +PASS PannerNode interface: calling setOrientation(float, float, float) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new PannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new PannerNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new PannerNode(context) must inherit property "channelInterpretation" with the proper type PASS PeriodicWave interface: existence and properties of interface object PASS PeriodicWave interface object length PASS PeriodicWave interface object name PASS PeriodicWave interface: existence and properties of interface prototype object PASS PeriodicWave interface: existence and properties of interface prototype object's "constructor" property PASS PeriodicWave interface: existence and properties of interface prototype object's @@unscopables property -PASS PeriodicWave must be primary interface of [object PeriodicWave] -PASS Stringification of [object PeriodicWave] +PASS PeriodicWave must be primary interface of new PeriodicWave(context) +PASS Stringification of new PeriodicWave(context) PASS ScriptProcessorNode interface: existence and properties of interface object PASS ScriptProcessorNode interface object length PASS ScriptProcessorNode interface object name @@ -1119,33 +1125,33 @@ PASS Unscopable handled correctly for onaudioprocess property on ScriptProcessorNode PASS ScriptProcessorNode interface: attribute bufferSize PASS Unscopable handled correctly for bufferSize property on ScriptProcessorNode -PASS ScriptProcessorNode must be primary interface of [object ScriptProcessorNode] -PASS Stringification of [object ScriptProcessorNode] -PASS ScriptProcessorNode interface: [object ScriptProcessorNode] must inherit property "onaudioprocess" with the proper type -PASS ScriptProcessorNode interface: [object ScriptProcessorNode] must inherit property "bufferSize" with the proper type -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object ScriptProcessorNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object ScriptProcessorNode] must inherit property "channelInterpretation" with the proper type +PASS ScriptProcessorNode must be primary interface of context.createScriptProcessor() +PASS Stringification of context.createScriptProcessor() +PASS ScriptProcessorNode interface: context.createScriptProcessor() must inherit property "onaudioprocess" with the proper type +PASS ScriptProcessorNode interface: context.createScriptProcessor() must inherit property "bufferSize" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect()" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on context.createScriptProcessor() with too few arguments must throw TypeError +PASS AudioNode interface: context.createScriptProcessor() must inherit property "context" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "channelCount" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: context.createScriptProcessor() must inherit property "channelInterpretation" with the proper type PASS StereoPannerNode interface: existence and properties of interface object PASS StereoPannerNode interface object length PASS StereoPannerNode interface object name @@ -1154,32 +1160,32 @@ PASS StereoPannerNode interface: existence and properties of interface prototype object's @@unscopables property PASS StereoPannerNode interface: attribute pan PASS Unscopable handled correctly for pan property on StereoPannerNode -PASS StereoPannerNode must be primary interface of [object StereoPannerNode] -PASS Stringification of [object StereoPannerNode] -PASS StereoPannerNode interface: [object StereoPannerNode] must inherit property "pan" with the proper type -PASS AudioNode interface: [object StereoPannerNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object StereoPannerNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object StereoPannerNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object StereoPannerNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object StereoPannerNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object StereoPannerNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object StereoPannerNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object StereoPannerNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object StereoPannerNode] must inherit property "channelInterpretation" with the proper type +PASS StereoPannerNode must be primary interface of new StereoPannerNode(context) +PASS Stringification of new StereoPannerNode(context) +PASS StereoPannerNode interface: new StereoPannerNode(context) must inherit property "pan" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new StereoPannerNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new StereoPannerNode(context) must inherit property "channelInterpretation" with the proper type PASS WaveShaperNode interface: existence and properties of interface object PASS WaveShaperNode interface object length PASS WaveShaperNode interface object name @@ -1190,41 +1196,41 @@ PASS Unscopable handled correctly for curve property on WaveShaperNode PASS WaveShaperNode interface: attribute oversample PASS Unscopable handled correctly for oversample property on WaveShaperNode -PASS WaveShaperNode must be primary interface of [object WaveShaperNode] -PASS Stringification of [object WaveShaperNode] -PASS WaveShaperNode interface: [object WaveShaperNode] must inherit property "curve" with the proper type -PASS WaveShaperNode interface: [object WaveShaperNode] must inherit property "oversample" with the proper type -PASS AudioNode interface: [object WaveShaperNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object WaveShaperNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object WaveShaperNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object WaveShaperNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object WaveShaperNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object WaveShaperNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object WaveShaperNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object WaveShaperNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object WaveShaperNode] must inherit property "channelInterpretation" with the proper type +PASS WaveShaperNode must be primary interface of new WaveShaperNode(context) +PASS Stringification of new WaveShaperNode(context) +PASS WaveShaperNode interface: new WaveShaperNode(context) must inherit property "curve" with the proper type +PASS WaveShaperNode interface: new WaveShaperNode(context) must inherit property "oversample" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect()" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on new WaveShaperNode(context) with too few arguments must throw TypeError +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "context" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "channelCount" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: new WaveShaperNode(context) must inherit property "channelInterpretation" with the proper type PASS AudioWorklet interface: existence and properties of interface object PASS AudioWorklet interface object length PASS AudioWorklet interface object name PASS AudioWorklet interface: existence and properties of interface prototype object PASS AudioWorklet interface: existence and properties of interface prototype object's "constructor" property PASS AudioWorklet interface: existence and properties of interface prototype object's @@unscopables property -PASS AudioWorklet must be primary interface of [object AudioWorklet] -PASS Stringification of [object AudioWorklet] +PASS AudioWorklet must be primary interface of context.audioWorklet +PASS Stringification of context.audioWorklet PASS AudioWorkletGlobalScope interface: existence and properties of interface object PASS AudioParamMap interface: existence and properties of interface object PASS AudioParamMap interface object length @@ -1232,8 +1238,8 @@ PASS AudioParamMap interface: existence and properties of interface prototype object PASS AudioParamMap interface: existence and properties of interface prototype object's "constructor" property PASS AudioParamMap interface: existence and properties of interface prototype object's @@unscopables property -PASS AudioParamMap must be primary interface of [object AudioParamMap] -PASS Stringification of [object AudioParamMap] +PASS AudioParamMap must be primary interface of worklet_node.parameters +PASS Stringification of worklet_node.parameters PASS AudioWorkletNode interface: existence and properties of interface object PASS AudioWorkletNode interface object length PASS AudioWorkletNode interface object name @@ -1244,39 +1250,36 @@ PASS Unscopable handled correctly for parameters property on AudioWorkletNode PASS AudioWorkletNode interface: attribute port PASS Unscopable handled correctly for port property on AudioWorkletNode -FAIL AudioWorkletNode interface: attribute processorState assert_true: The prototype object must have a property "processorState" expected true got false -PASS Unscopable handled correctly for processorState property on AudioWorkletNode -FAIL AudioWorkletNode interface: attribute onprocessorstatechange assert_true: The prototype object must have a property "onprocessorstatechange" expected true got false -PASS Unscopable handled correctly for onprocessorstatechange property on AudioWorkletNode -PASS AudioWorkletNode must be primary interface of [object AudioWorkletNode] -PASS Stringification of [object AudioWorkletNode] -PASS AudioWorkletNode interface: [object AudioWorkletNode] must inherit property "parameters" with the proper type -PASS AudioWorkletNode interface: [object AudioWorkletNode] must inherit property "port" with the proper type -FAIL AudioWorkletNode interface: [object AudioWorkletNode] must inherit property "processorState" with the proper type assert_inherits: property "processorState" not found in prototype chain -FAIL AudioWorkletNode interface: [object AudioWorkletNode] must inherit property "onprocessorstatechange" with the proper type assert_inherits: property "onprocessorstatechange" not found in prototype chain -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "connect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling connect(AudioParam, unsigned long) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "disconnect()" with the proper type -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "disconnect(unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(unsigned long) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "disconnect(AudioNode)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "disconnect(AudioNode, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "disconnect(AudioParam)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "disconnect(AudioParam, unsigned long)" with the proper type -PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on [object AudioWorkletNode] with too few arguments must throw TypeError -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "context" with the proper type -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "numberOfInputs" with the proper type -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "numberOfOutputs" with the proper type -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "channelCount" with the proper type -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "channelCountMode" with the proper type -PASS AudioNode interface: [object AudioWorkletNode] must inherit property "channelInterpretation" with the proper type +PASS AudioWorkletNode interface: attribute onprocessorerror +PASS Unscopable handled correctly for onprocessorerror property on AudioWorkletNode +PASS AudioWorkletNode must be primary interface of worklet_node +PASS Stringification of worklet_node +PASS AudioWorkletNode interface: worklet_node must inherit property "parameters" with the proper type +PASS AudioWorkletNode interface: worklet_node must inherit property "port" with the proper type +PASS AudioWorkletNode interface: worklet_node must inherit property "onprocessorerror" with the proper type +PASS AudioNode interface: worklet_node must inherit property "connect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioNode, unsigned long, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "connect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling connect(AudioParam, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect()" with the proper type +PASS AudioNode interface: worklet_node must inherit property "disconnect(unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioNode)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioNode, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioNode, unsigned long, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioNode, unsigned long, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioParam)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "disconnect(AudioParam, unsigned long)" with the proper type +PASS AudioNode interface: calling disconnect(AudioParam, unsigned long) on worklet_node with too few arguments must throw TypeError +PASS AudioNode interface: worklet_node must inherit property "context" with the proper type +PASS AudioNode interface: worklet_node must inherit property "numberOfInputs" with the proper type +PASS AudioNode interface: worklet_node must inherit property "numberOfOutputs" with the proper type +PASS AudioNode interface: worklet_node must inherit property "channelCount" with the proper type +PASS AudioNode interface: worklet_node must inherit property "channelCountMode" with the proper type +PASS AudioNode interface: worklet_node must inherit property "channelInterpretation" with the proper type PASS AudioWorkletProcessor interface: existence and properties of interface object Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.html b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.html index cfdb602..063e4cc9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webaudio/idlharness.https.html
@@ -10,13 +10,13 @@ <script> 'use strict'; +let sample_rate, context, buffer, worklet_node; + promise_test(async t => { - const cssom = await fetch('/interfaces/cssom.idl').then(r => r.text()); - const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); - const html = await fetch('/interfaces/html.idl').then(r => r.text()); - const uievents = await fetch('/interfaces/uievents.idl').then(r => r.text()); - const mediacapture = await fetch('/interfaces/mediacapture-main.idl').then(r => r.text()); - const webaudio = await fetch('/interfaces/web-audio-api.idl').then(r => r.text()); + const srcs = ['cssom', 'dom', 'html', 'uievents', 'mediacapture-main', 'webaudio']; + const [cssom, dom, html, uievents, mediacapture, webaudio] = + await Promise.all( + srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); const idl_array = new IdlArray(); idl_array.add_idls(webaudio); @@ -32,56 +32,63 @@ idl_array.add_untested_idls('interface WorkletGlobalScope {};'); idl_array.add_untested_idls('interface Worklet {};'); - const sample_rate = 44100; - const context = new AudioContext; - const buffer = new AudioBuffer({length: 1, sampleRate: sample_rate}); - await context.audioWorklet.addModule( - 'the-audio-api/the-audioworklet-interface/processors/dummy-processor.js'); - const worklet_node = new AudioWorkletNode(context, 'dummy'); + try { + sample_rate = 44100; + context = new AudioContext; + buffer = new AudioBuffer({length: 1, sampleRate: sample_rate}); + await context.audioWorklet.addModule( + 'the-audio-api/the-audioworklet-interface/processors/dummy-processor.js'); + worklet_node = new AudioWorkletNode(context, 'dummy'); + } catch (e) { + // Ignore - errors will surface in each test_object below. + } idl_array.add_objects({ BaseAudioContext: [], - AudioContext: [context], - OfflineAudioContext: [new OfflineAudioContext(1, 1, sample_rate)], + AudioContext: ['context'], + OfflineAudioContext: ['new OfflineAudioContext(1, 1, sample_rate)'], OfflineAudioCompletionEvent: [ - new OfflineAudioCompletionEvent('', {renderedBuffer: buffer})], - AudioBuffer: [buffer], + 'new OfflineAudioCompletionEvent("", {renderedBuffer: buffer})'], + AudioBuffer: ['buffer'], AudioNode: [], - AudioParam: [new AudioBufferSourceNode(context).playbackRate], + AudioParam: ['new AudioBufferSourceNode(context).playbackRate'], AudioScheduledSourceNode: [], - AnalyserNode: [new AnalyserNode(context)], - AudioBufferSourceNode: [new AudioBufferSourceNode(context)], - AudioDestinationNode: [context.destination], - AudioListener: [context.listener], - AudioProcessingEvent: [new AudioProcessingEvent('', { + AnalyserNode: ['new AnalyserNode(context)'], + AudioBufferSourceNode: ['new AudioBufferSourceNode(context)'], + AudioDestinationNode: ['context.destination'], + AudioListener: ['context.listener'], + AudioProcessingEvent: [`new AudioProcessingEvent('', { playbackTime: 0, inputBuffer: buffer, outputBuffer: buffer - })], - BiquadFilterNode: [new BiquadFilterNode(context)], - ChannelMergerNode: [new ChannelMergerNode(context)], - ChannelSplitterNode: [new ChannelSplitterNode(context)], - ConstantSourceNode: [new ConstantSourceNode(context)], - ConvolverNode: [new ConvolverNode(context)], - DelayNode: [new DelayNode(context)], - DynamicsCompressorNode: [new DynamicsCompressorNode(context)], - GainNode: [new GainNode(context)], + })`], + BiquadFilterNode: ['new BiquadFilterNode(context)'], + ChannelMergerNode: ['new ChannelMergerNode(context)'], + ChannelSplitterNode: ['new ChannelSplitterNode(context)'], + ConstantSourceNode: ['new ConstantSourceNode(context)'], + ConvolverNode: ['new ConvolverNode(context)'], + DelayNode: ['new DelayNode(context)'], + DynamicsCompressorNode: ['new DynamicsCompressorNode(context)'], + GainNode: ['new GainNode(context)'], IIRFilterNode: [ - new IIRFilterNode(context, {feedforward: [1], feedback: [1]})], + 'new IIRFilterNode(context, {feedforward: [1], feedback: [1]})' + ], MediaElementAudioSourceNode: [ - new MediaElementAudioSourceNode(context, {mediaElement: new Audio})], + 'new MediaElementAudioSourceNode(context, {mediaElement: new Audio})' + ], MediaStreamAudioDestinationNode: [ - new MediaStreamAudioDestinationNode(context)], + 'new MediaStreamAudioDestinationNode(context)' + ], MediaStreamAudioSourceNode: [], MediaStreamTrackAudioSourceNode: [], - OscillatorNode: [new OscillatorNode(context)], - PannerNode: [new PannerNode(context)], - PeriodicWave: [new PeriodicWave(context)], - ScriptProcessorNode: [context.createScriptProcessor()], - StereoPannerNode: [new StereoPannerNode(context)], - WaveShaperNode: [new WaveShaperNode(context)], - AudioWorklet: [context.audioWorklet], + OscillatorNode: ['new OscillatorNode(context)'], + PannerNode: ['new PannerNode(context)'], + PeriodicWave: ['new PeriodicWave(context)'], + ScriptProcessorNode: ['context.createScriptProcessor()'], + StereoPannerNode: ['new StereoPannerNode(context)'], + WaveShaperNode: ['new WaveShaperNode(context)'], + AudioWorklet: ['context.audioWorklet'], AudioWorkletGlobalScope: [], - AudioParamMap: [worklet_node.parameters], - AudioWorkletNode: [worklet_node], + AudioParamMap: ['worklet_node.parameters'], + AudioWorkletNode: ['worklet_node'], AudioWorkletProcessor: [], }); idl_array.test();
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png index ea3d7fc..52bb367b 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom-expected.txt b/third_party/WebKit/LayoutTests/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom-expected.txt deleted file mode 100644 index 996a66d..0000000 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This is a test for http://crbug.com/516245. It ensures that pinch-zooming and selecting doesn't autoscroll the page. To manually test, on Mac, pinch-zoom in and select text below. The page should not autoscroll. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS Scroll offset did not change when text selected. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom.html index c273230..eca7c8f 100644 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom.html +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom.html
@@ -5,7 +5,9 @@ height: 1000px; } </style> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/gesture-util.js"></script> <div id="content"> <span id="select">This text is selected.</span> @@ -13,45 +15,32 @@ <script type="text/javascript"> var scrollTopBefore; - - jsTestIsAsync = true; - description("This is a test for http://crbug.com/516245. It ensures that pinch-zooming and selecting doesn't autoscroll the page. To manually test, on Mac, pinch-zoom in and select text below. The page should not autoscroll."); - - function finishTest() { - eventSender.mouseUp(); - - if (document.scrollingElement.scrollTop == scrollTopBefore) { - testPassed("Scroll offset did not change when text selected."); - } else { - testFailed("Scroll offset changed when text selected."); - } - document.getElementById('content').style.display = 'none'; - finishJSTest(); - } + var element = document.getElementById('select'); function MouseWheelHandler(e) { return false; } + // The autoscroll bug happens when there is a mousewheel event listener on + // the page. + element.addEventListener("mousewheel", MouseWheelHandler, false); - window.onload = function () { - var element = document.getElementById('select'); - // The autoscroll bug happens when there is a mousewheel event listener on - // the page. - element.addEventListener("mousewheel", MouseWheelHandler, false); - - if (window.internals && internals.magnifyScaleAroundAnchor(2.5, 0, 30.2)) { + promise_test (async () => { + if (window.internals && internals.setPageScaleFactor(2.5) && + internals.setVisualViewportOffset(0, 30.2)) { element.scrollIntoView(); scrollTopBefore = document.scrollingElement.scrollTop; - var y = element.offsetHeight / 2; var endX = element.offsetWidth + 100; - eventSender.dragMode = false; - eventSender.mouseMoveTo(element.offsetLeft, y); - eventSender.mouseDown(); - eventSender.mouseMoveTo(endX - 30, y); - eventSender.mouseMoveTo(endX, y); + await mouseMoveTo(element.offsetLeft, y); + await mouseDownAt(element.offsetLeft, y); + await mouseMoveTo(endX - 30, y); + await mouseMoveTo(endX, y); // Wait for the autoscroll timer to fire. - window.requestAnimationFrame(finishTest); + await waitForCompositorCommit(); + assert_equals(document.scrollingElement.scrollTop, scrollTopBefore); + document.getElementById('content').style.display = 'none'; } - } + }, "This is a test for http://crbug.com/516245. It ensures that pinch-zooming" + + " and selecting doesn't autoscroll the page. To manually test, on Mac" + + " pinch-zoom in and select text below. The page should not autoscroll."); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-padding-page-scrolling.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-padding-page-scrolling.html new file mode 100644 index 0000000..7f604a5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-padding-page-scrolling.html
@@ -0,0 +1,158 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test that scroll-padding correctly adjust page sroll operations</title> + +<style> +:root { + --test-size: 200px; +} + +section { + /* put them side-by-side */ + display: flex; + flex-direction: row; + border: 1px solid black; + padding: 2px; +} + +section#top { + --sp-left : 0px; + --sp-right : 0px; + --sp-top: 30px; + --sp-bottom: 0px; +} + +section#bottom { + --sp-left : 0px; + --sp-right : 0px; + --sp-top: 0px; + --sp-bottom: 20px; +} + +section#vertical { + --sp-left : 0px; + --sp-right : 0px; + --sp-top: 30px; + --sp-bottom: 20px; +} + +section#horizontal { + --sp-left : 20px; + --sp-right : 10px; + --sp-top: 0px; + --sp-bottom: 0px; +} + +.actual { + height: var(--test-size); + width: var(--test-size); + scroll-padding-left: var(--sp-left); + scroll-padding-right: var(--sp-right); + scroll-padding-top: var(--sp-top); + scroll-padding-bottom: var(--sp-bottom); + +} + +.reference { + height: calc(var(--test-size) - var(--sp-top) - var(--sp-bottom)); + width: calc(var(--test-size) - var(--sp-left) - var(--sp-right)); +} + +.actual, .reference { + overflow: scroll; +} + +.actual > div,.reference > div { + height: 1200px; + width: 1200px; + background-image: + linear-gradient( + to bottom, + #fffdc2, + #fffdc2 calc(var(--test-size) - 20px), + #d7f0a2 calc(var(--test-size) - 20px), + #d7f0a2 + ); +} +</style> + +PageDown: +<section id="top" data-scroll-action="PageDown"> + <div class="actual" tabindex="0"> + <div>With scroll-padding</div> + </div> + <div class="reference" tabindex="0"> + <div>Without scroll-padding</div> + </div> +</section> + +PageDown: +<section id="bottom" data-scroll-action="PageDown"> + <div class="actual" tabindex="0"> + <div>With scroll-padding</div> + </div> + <div class="reference" tabindex="0"> + <div>Without scroll-padding</div> + </div> +</section> + +PageDown: +<section id="vertical" data-scroll-action="PageDown"> + <div class="actual" tabindex="0"> + <div>With scroll-padding</div> + </div> + <div class="reference" tabindex="0"> + <div>Without scroll-padding</div> + </div> +</section> + +PageRight: +<section id="horizontal" data-scroll-action="PageRight"> + <div class="actual" tabindex="0"> + <div>With scroll-padding</div> + </div> + <div class="reference" tabindex="0"> + <div>Without scroll-padding</div> + </div> +</section> + +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> + +<script> +// Disable scroll animations to have immediate results. +if (window.internals) + internals.settings.setScrollAnimatorEnabled(false); + +function pageScroll(target, action){ + if (!window.eventSender) + throw "This test requires eventSender"; + + target.focus(); + + switch (action) { + case "PageDown": + eventSender.keyDown("PageDown"); break; + case "PageRight": + // TODO(majidvp): This actually does not scroll horizontally. Find a way that works. + eventSender.keyDown("PageDown", ["shiftKey"]); break; + default: + throw "Unsupported scroll action"; + } +} + +[].forEach.call(document.querySelectorAll('section'), function(testCase) { + const scrollAction = testCase.dataset.scrollAction; + const actual = testCase.querySelector('.actual'); + const reference = testCase.querySelector('.reference'); + + const description = 'scrollPadding: ' + getComputedStyle(actual).scrollPadding; + + test(function(){ + pageScroll(actual, scrollAction); + pageScroll(reference, scrollAction); + assert_equals(actual.scrollTop, reference.scrollTop); + assert_equals(actual.scrollLeft, reference.scrollLeft); + }, 'Page scroll operation ' + scrollAction + ' correctly uses scroll snapport with ' + description); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll-expected.txt b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll-expected.txt deleted file mode 100644 index b5ed9c5..0000000 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This test ensures that consecutive mouse wheel ticks scroll to the right offset. The main purpose of this test is to ensure that smooth scrolling on the compositor works as intended (tested via virtual suite virtual/threaded/). - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS document.scrollingElement.scrollTop == 80 && document.scrollingElement.scrollLeft == 80 became true -PASS document.scrollingElement.scrollTop == 40 && document.scrollingElement.scrollLeft == 40 became true -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html index 222d084..ed5e4f0 100644 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html
@@ -1,59 +1,69 @@ <!DOCTYPE html> -<script src="../../../resources/js-test.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../../resources/gesture-util.js"></script> <style> - body { - height: 2000px; - width: 2000px; - } + body { + height: 2000px; + width: 2000px; + } </style> <script> - window.jsTestIsAsync = true; + // Turn on smooth scrolling. + internals.settings.setScrollAnimatorEnabled(true); - description("This test ensures that consecutive mouse wheel ticks scroll\ - to the right offset. The main purpose of this test is to ensure that\ - smooth scrolling on the compositor works as intended (tested via\ - virtual suite virtual/threaded/)."); + var x = 20; + var y = 20; + var px_per_tick = 40; + var source = GestureSourceType.MOUSE_INPUT; - function testDiagonalScroll() { - // Reset - document.scrollingElement.scrollTop = 0; - document.scrollingElement.scrollLeft = 0; + promise_test(async () => { + // Scroll 3 ticks diagonally. + await smoothScroll(3 * px_per_tick , x, y, source, 'downright', + SPEED_INSTANT); + // Undo 2 ticks in each direction. + await smoothScroll(2 * px_per_tick, x, y, source, 'upleft', + SPEED_INSTANT); - eventSender.mouseMoveTo(20, 20); - // Scroll 3 ticks diagonally. - eventSender.mouseScrollBy(-3, -3); - // Undo 2 ticks in each direction. - eventSender.mouseScrollBy(2, 2); - // 40px per tick. - shouldBecomeEqual("document.scrollingElement.scrollTop == 40 && " + - "document.scrollingElement.scrollLeft == 40", "true", finishJSTest); - } + // 40px per tick. + await waitFor( () => {return document.scrollingElement.scrollTop == 40 && + document.scrollingElement.scrollLeft == 40;}); - function runTest() { - if (!window.eventSender || !window.internals) { - finishJSTest(); - return; - } + // Undo the last tick in each direction to reset the scroll state before + // starting the second test. + await smoothScroll(1 * px_per_tick, x, y, source, 'upleft', + SPEED_INSTANT); + await waitFor( () => {return document.scrollingElement.scrollTop == 0 && + document.scrollingElement.scrollLeft == 0;}); - // Turn on smooth scrolling. - internals.settings.setScrollAnimatorEnabled(true); + }, "This test ensures that consecutive mouse wheel ticks diagonally " + + "scroll to the right offset. The main purpose of this test is to " + + "ensure that smooth scrolling on the compositor works as intended " + + "(tested via virtual suite virtual/threaded/)."); - eventSender.mouseMoveTo(20, 20); - // Scroll down 3 ticks. - eventSender.mouseScrollBy(0, -1); - eventSender.mouseScrollBy(0, -2); - // Scroll right 3 ticks. - eventSender.mouseScrollBy(-1, 0); - eventSender.mouseScrollBy(-2, 0); - // Undo 1 tick in each direction. - eventSender.mouseScrollBy(0, 1); - eventSender.mouseScrollBy(1, 0); + promise_test(async () => { + // Scroll down 3 ticks. + await smoothScroll(1 * px_per_tick, x, y, source, 'down', + SPEED_INSTANT); + await smoothScroll(2 * px_per_tick, x, y, source, 'down', + SPEED_INSTANT); + // Scroll right 3 ticks. + await smoothScroll(1 * px_per_tick, x, y, source, 'right', + SPEED_INSTANT); + await smoothScroll(2 * px_per_tick, x, y, source, 'right', + SPEED_INSTANT); + // Undo 1 tick in each direction. + await smoothScroll(1 * px_per_tick, x, y, source, 'up', + SPEED_INSTANT); + await smoothScroll(1 * px_per_tick, x, y, source, 'left', + SPEED_INSTANT); - // 40px per tick. - shouldBecomeEqual("document.scrollingElement.scrollTop == 80 && " + - "document.scrollingElement.scrollLeft == 80", "true", testDiagonalScroll); - } + // 40px per tick. + await waitFor( () => {return document.scrollingElement.scrollTop == 80 && + document.scrollingElement.scrollLeft == 80;}); + }, "This test ensures that consecutive mouse wheel ticks vertically or " + + "horizontally scroll to the right offset. The main purpose of this " + + "test is to ensure that smooth scrolling on the compositor works as " + + "intended (tested via virtual suite virtual/threaded/)."); </script> - -<body onload="runTest()"></body>
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/scroll-during-selection-expected.txt b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/scroll-during-selection-expected.txt deleted file mode 100644 index 25670b1..0000000 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/scroll-during-selection-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -TEXT -This test verifies that text selection does not prevent smooth scrolls running on the main thread. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS scrollY became 40 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/scroll-during-selection.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/scroll-during-selection.html index 03bedac..0a2a862 100644 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/scroll-during-selection.html +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/scroll-during-selection.html
@@ -1,5 +1,7 @@ <!DOCTYPE html> -<script src="../../../resources/js-test.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../../resources/gesture-util.js"></script> <style> body { height: 1000px; @@ -19,21 +21,16 @@ <div id="text">TEXT</div> <div id="console"></div> <script> + promise_test (async () => { + // Start a text selection. + await mouseMoveTo(20, 20); + await mouseDownAt(20, 20); + await mouseMoveTo(40, 20); -var jsTestIsAsync = true; - -description( - "This test verifies that text selection does not prevent smooth " + + // Scroll before releasing the mouse. + await smoothScroll(40, 40, 20, GestureSourceType.MOUSE_INPUT, 'down', + SPEED_INSTANT); + await waitFor( () => {return scrollY == 40;}); + }, "This test verifies that text selection does not prevent smooth " + "scrolls running on the main thread."); - -eventSender.dragMode = false; - -// Start a text selection. -eventSender.mouseMoveTo(20, 20); -eventSender.mouseDown(); -eventSender.mouseMoveTo(40, 20); - -eventSender.mouseScrollBy(0, -1); -shouldBecomeEqual("scrollY", "40", finishJSTest); - </script>
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/track-scroll-expected.txt b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/track-scroll-expected.txt deleted file mode 100644 index 3d1d3eae..0000000 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/track-scroll-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This test scrolls by clicking in the scrollbar track. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS scrollY became pageStep -PASS scrollY is pageStep -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/track-scroll.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/track-scroll.html index 1b90c01..bd73232 100644 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/track-scroll.html +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/smooth-scroll/track-scroll.html
@@ -1,5 +1,7 @@ <!DOCTYPE html> -<script src="../../../resources/js-test.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../../resources/gesture-util.js"></script> <style> body { height: 1800px; @@ -7,41 +9,24 @@ </style> <body> <script> -window.jsTestIsAsync = true; - -description("This test scrolls by clicking in the scrollbar track."); // Compute ScrollableArea::pageStep. var pageStep = innerHeight * 0.875; if (navigator.userAgent.indexOf("Mac OS X") >= 0) pageStep = Math.max(pageStep, innerHeight - 40); -onload = function() { - if (!window.eventSender || !window.internals) { - finishJSTest(); - return; - } +// Turn on smooth scrolling. +internals.settings.setScrollAnimatorEnabled(true); - // Turn on smooth scrolling. - internals.settings.setScrollAnimatorEnabled(true); - +promise_test(async () => { // Click in the vertical scrollbar track, below the thumb. - eventSender.mouseMoveTo(790, 280); - eventSender.mouseDown(); - eventSender.mouseUp(); + await mouseClickOn(790, 280); // A second click should have no effect since we will be under the thumb // by the time the animation completes. - eventSender.mouseDown(); - eventSender.mouseUp(); + await mouseClickOn(790, 280); - shouldBecomeEqual("scrollY", "pageStep", function() { - requestAnimationFrame(function() { - // Make sure we stopped here. - shouldBe("scrollY", "pageStep"); - finishJSTest(); - }); - }); -}; + await waitFor( () => {return scrollY == pageStep;}); +}, 'This test scrolls by clicking in the scrollbar track.'); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t0905-c414-flt-wrap-01-d-g-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t0905-c414-flt-wrap-01-d-g-expected.png new file mode 100644 index 0000000..dda4c05 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t0905-c414-flt-wrap-01-d-g-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t0905-c414-flt-wrap-01-d-g-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t0905-c414-flt-wrap-01-d-g-expected.txt new file mode 100644 index 0000000..d5af9659 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t0905-c414-flt-wrap-01-d-g-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x264 + LayoutNGBlockFlow {HTML} at (0,0) size 800x264 + LayoutNGBlockFlow {BODY} at (8,16) size 784x232 + LayoutNGBlockFlow {P} at (0,0) size 784x20 [color=#000080] + LayoutText {#text} at (0,0) size 381x19 + text run at (0,0) width 381: "The word \"fail\" should not appear below, just a green block." + LayoutNGBlockFlow {DIV} at (16,36) size 240x196 [color=#FFFFFF] [bgcolor=#FFFFFF] + LayoutImage (floating) {IMG} at (0,0) size 1x1 + LayoutImage (floating) {IMG} at (0,1) size 240x112 + LayoutNGBlockFlow (anonymous) at (0,0) size 240x196 + LayoutInline {SPAN} at (0,0) size 188x83 + LayoutText {#text} at (0,113) size 188x83 + text run at (0,113) width 188: "FAIL" + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-00-a-ag-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-00-a-ag-expected.png new file mode 100644 index 0000000..ce2a97c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-00-a-ag-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-00-a-ag-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-00-a-ag-expected.txt new file mode 100644 index 0000000..4d90595 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-00-a-ag-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x260 + LayoutNGBlockFlow {HTML} at (0,0) size 800x259.66 + LayoutNGBlockFlow {BODY} at (8,16) size 784x193.66 + LayoutNGBlockFlow {P} at (0,0) size 784x40 + LayoutText {#text} at (0,0) size 754x39 + text run at (0,0) width 754: "There should be four identical white boxes in the teal block below, all the same size, each one a little lower down on the" + text run at (0,20) width 134: "line, in a step pattern." + LayoutNGBlockFlow {DIV} at (50,90) size 684x103.66 [color=#FFFFFF] [bgcolor=#008080] + LayoutInline {SPAN} at (0,0) size 51x51 + LayoutText {#text} at (12,12) size 51x51 + text run at (12,12) width 51: "X" + LayoutText {#text} at (62,30) size 51x51 + text run at (62,30) width 51: " " + LayoutImage {IMG} at (112.50,20.16) size 50x50 + LayoutText {#text} at (162,30) size 151x51 + text run at (162,30) width 151: " X " + LayoutInline {SPAN} at (0,0) size 51x51 + LayoutText {#text} at (312,41) size 51x51 + text run at (312,41) width 51: "X"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-03-d-agi-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-03-d-agi-expected.png new file mode 100644 index 0000000..338fe7c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-03-d-agi-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-03-d-agi-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-03-d-agi-expected.txt new file mode 100644 index 0000000..95e24753 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t100801-c544-valgn-03-d-agi-expected.txt
@@ -0,0 +1,75 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x323 + LayoutNGBlockFlow {HTML} at (0,0) size 800x323 + LayoutNGBlockFlow {BODY} at (8,16) size 784x292 + LayoutNGBlockFlow {P} at (0,0) size 784x40 + LayoutText {#text} at (0,0) size 750x39 + text run at (0,0) width 750: "Change your window size. However the lines wrap, the blue rectanglues should always have their middles on the same" + text run at (0,20) width 287: "alignment as other blue rectangles on the line." + LayoutNGBlockFlow {P} at (15,56) size 754x236 [color=#0000FF] [bgcolor=#FFFFFF] [border: (1px solid #C0C0C0)] + LayoutText {#text} at (8,35) size 61x15 + text run at (8,35) width 61: "\x{C9}\x{C9}\x{C9} " + LayoutImage {IMG} at (68.50,26) size 30x30 + LayoutText {#text} at (98,35) size 16x15 + text run at (98,35) width 16: " " + LayoutInline {SPAN} at (0,0) size 115x38 [color=#C0C0C0] + LayoutText {#text} at (113,17) size 115x38 + text run at (113,17) width 115: "xxx" + LayoutText {#text} at (227,35) size 16x15 + text run at (227,35) width 16: " " + LayoutImage {IMG} at (242.50,16) size 50x50 + LayoutText {#text} at (292,35) size 76x15 + text run at (292,35) width 76: " \x{C9}\x{C9}\x{C9} " + LayoutImage {IMG} at (367.50,36) size 10x10 + LayoutText {#text} at (377,35) size 16x15 + text run at (377,35) width 16: " " + LayoutInline {SMALL} at (0,0) size 31x10 [color=#C0C0C0] + LayoutText {#text} at (392,39) size 31x10 + text run at (392,39) width 31: "xxx" + LayoutText {#text} at (422,35) size 16x15 + text run at (422,35) width 16: " " + LayoutImage {IMG} at (437.50,31) size 20x20 + LayoutText {#text} at (457,35) size 76x15 + text run at (457,35) width 76: " \x{C9}\x{C9}\x{C9} " + LayoutImage {IMG} at (532.50,8.50) size 65x65 + LayoutText {#text} at (597,35) size 76x15 + text run at (597,35) width 76: " \x{C9}\x{C9}\x{C9} " + LayoutImage {IMG} at (672.50,23.50) size 35x35 + LayoutText {#text} at (0,0) size 0x0 + LayoutInline {SPAN} at (0,0) size 91x31 [color=#C0C0C0] + LayoutText {#text} at (8,94) size 91x31 + text run at (8,94) width 91: "xxx" + LayoutText {#text} at (98,106) size 16x16 + text run at (98,106) width 16: " " + LayoutImage {IMG} at (113.50,87.50) size 50x50 + LayoutText {#text} at (163,106) size 16x16 + text run at (163,106) width 16: " " + LayoutInline {SPAN} at (0,0) size 353x57 [color=#C0C0C0] + LayoutText {#text} at (178,100) size 93x24 + text run at (178,100) width 93: "xxx " + LayoutInline {SPAN} at (0,0) size 169x57 + LayoutText {#text} at (270,73) size 169x57 + text run at (270,73) width 169: "xxx" + LayoutText {#text} at (438,100) size 93x24 + text run at (438,100) width 93: " xxx" + LayoutText {#text} at (530,106) size 16x16 + text run at (530,106) width 16: " " + LayoutImage {IMG} at (545.50,87.50) size 50x50 + LayoutText {#text} at (595,106) size 16x16 + text run at (595,106) width 16: " " + LayoutInline {SMALL} at (0,0) size 31x11 [color=#C0C0C0] + LayoutText {#text} at (610,110) size 31x11 + text run at (610,110) width 31: "xxx" + LayoutText {#text} at (640,106) size 16x16 + text run at (640,106) width 16: " " + LayoutImage {IMG} at (655.50,105) size 15x15 + LayoutText {#text} at (670,106) size 16x16 + text run at (670,106) width 16: " " + LayoutInline {BIG} at (0,0) size 61x21 [color=#C0C0C0] + LayoutText {#text} at (685,102) size 61x21 + text run at (685,102) width 61: "xxx" + LayoutText {#text} at (0,0) size 0x0 + LayoutImage {IMG} at (8.50,137.50) size 90x90 + LayoutText {#text} at (98,176) size 61x16 + text run at (98,176) width 61: " \x{C9}\x{C9}\x{C9}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/margin-top-bottom-dynamic-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/margin-top-bottom-dynamic-expected.txt new file mode 100644 index 0000000..03a09ba --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/margin-top-bottom-dynamic-expected.txt
@@ -0,0 +1,71 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 249x19 + text run at (0,0) width 249: "What it should look like (positive case):" + LayoutNGBlockFlow {DIV} at (0,36) size 784x76 [border: (1px solid #008000)] + LayoutNGBlockFlow {DIV} at (1,11) size 782x22 [border: (1px solid #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow {DIV} at (1,43) size 782x22 [border: (1px dotted #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow {P} at (0,128) size 784x20 + LayoutText {#text} at (0,0) size 253x19 + text run at (0,0) width 253: "What it should look like (negative case):" + LayoutNGBlockFlow {DIV} at (0,164) size 784x36 [border: (1px solid #008000)] + LayoutNGBlockFlow {DIV} at (1,11) size 782x22 [border: (1px solid #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow {DIV} at (1,23) size 782x22 [border: (1px dotted #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow {P} at (0,216) size 784x20 + LayoutText {#text} at (0,0) size 369x19 + text run at (0,0) width 369: "Dynamic case (automatically testing positive --> negative):" + LayoutNGBlockFlow {DIV} at (0,252) size 784x36 [border: (1px solid #008000)] + LayoutNGBlockFlow {DIV} at (1,11) size 782x22 [border: (1px solid #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow {DIV} at (1,23) size 782x22 [border: (1px dotted #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow (anonymous) at (0,288) size 784x42 + LayoutBR {BR} at (0,0) size 0x0 + LayoutButton {INPUT} at (0,20) size 110x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] + LayoutBlockFlow (anonymous) at (8,3) size 94x16 + LayoutText {#text} at (0,0) size 94x16 + text run at (0,0) width 94: "Negative margin" + LayoutText {#text} at (110,21) size 4x19 + text run at (110,21) width 4: " " + LayoutButton {INPUT} at (114,20) size 106x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] + LayoutBlockFlow (anonymous) at (8,3) size 90x16 + LayoutText {#text} at (0,0) size 90x16 + text run at (0,0) width 90: "Positive margin" + LayoutText {#text} at (0,0) size 0x0 + LayoutNGBlockFlow {P} at (0,346) size 784x20 + LayoutText {#text} at (0,0) size 445x19 + text run at (0,0) width 445: "Dynamic case (automatically testing positive --> negative --> positive):" + LayoutNGBlockFlow {DIV} at (0,382) size 784x76 [border: (1px solid #008000)] + LayoutNGBlockFlow {DIV} at (1,11) size 782x22 [border: (1px solid #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow {DIV} at (1,43) size 782x22 [border: (1px dotted #0000FF)] + LayoutText {#text} at (1,1) size 84x19 + text run at (1,1) width 84: "Lorem ipsum" + LayoutNGBlockFlow (anonymous) at (0,458) size 784x42 + LayoutBR {BR} at (0,0) size 0x0 + LayoutButton {INPUT} at (0,20) size 110x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] + LayoutBlockFlow (anonymous) at (8,3) size 94x16 + LayoutText {#text} at (0,0) size 94x16 + text run at (0,0) width 94: "Negative margin" + LayoutText {#text} at (110,21) size 4x19 + text run at (110,21) width 4: " " + LayoutButton {INPUT} at (114,20) size 106x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] + LayoutBlockFlow (anonymous) at (8,3) size 90x16 + LayoutText {#text} at (0,0) size 90x16 + text run at (0,0) width 90: "Positive margin" + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/deprecated-flexbox/crash-flexbox-no-layout-child-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/deprecated-flexbox/crash-flexbox-no-layout-child-expected.txt deleted file mode 100644 index 27317bf..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/deprecated-flexbox/crash-flexbox-no-layout-child-expected.txt +++ /dev/null
@@ -1,3 +0,0 @@ - -Bug 64842: LayoutDeprecatedFlexibleBox does not call its children's layout method -This test passes if it does not CRASH.
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/background-tab-on-submit-ctrl-click-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/background-tab-on-submit-ctrl-click-expected.txt new file mode 100644 index 0000000..565b766 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/background-tab-on-submit-ctrl-click-expected.txt
@@ -0,0 +1,5 @@ +Default policy for navigation to 'notify-done.html' is 'new background tab' +Default policy for navigation to 'notify-done.html' is 'current tab' +Tests that ctrl-clicking on a submit button results in a new background tab. + +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt new file mode 100644 index 0000000..776fb47 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt
@@ -0,0 +1,5 @@ +Default policy for navigation to 'notify-done.html' is 'new foreground tab' +Default policy for navigation to 'notify-done.html' is 'current tab' +Tests that synthesizing ctrl-click on a submit button does not result in a new background tab. + +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt index 41349ec..8bc8834 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/form-element-geometry-expected.txt
@@ -19,14 +19,14 @@ LayoutNGBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)] LayoutInline {FONT} at (0,0) size 52x22 LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 36x16 + LayoutBlockFlow (anonymous) at (8,3) size 36x16 LayoutText {#text} at (0,0) size 36x16 text run at (0,0) width 36: "button" LayoutNGTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1] LayoutNGBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)] LayoutInline {FONT} at (0,0) size 54x20 LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 52x18 + LayoutBlockFlow (anonymous) at (1,1) size 52x18 LayoutText (anonymous) at (4,1) size 32x16 text run at (4,1) width 32: "menu" LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1] @@ -43,13 +43,13 @@ LayoutNGTableCell {TD} at (2,2) size 58x28 [r=0 c=0 rs=1 cs=1] LayoutNGBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)] LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 36x16 + LayoutBlockFlow (anonymous) at (8,3) size 36x16 LayoutText {#text} at (0,0) size 36x16 text run at (0,0) width 36: "button" LayoutNGTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1] LayoutNGBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)] LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 52x18 + LayoutBlockFlow (anonymous) at (1,1) size 52x18 LayoutText (anonymous) at (4,1) size 32x16 text run at (4,1) width 32: "menu" LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1] @@ -65,14 +65,14 @@ LayoutNGBlockFlow {DIV} at (1,1) size 56x26 [border: (2px solid #0000FF)] LayoutInline {FONT} at (0,0) size 52x22 LayoutButton {INPUT} at (2,2) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 36x16 + LayoutBlockFlow (anonymous) at (8,3) size 36x16 LayoutText {#text} at (0,0) size 36x16 text run at (0,0) width 36: "button" LayoutNGTableCell {TD} at (62,3) size 60x26 [r=0 c=1 rs=1 cs=1] LayoutNGBlockFlow {DIV} at (1,1) size 58x24 [border: (2px solid #0000FF)] LayoutInline {FONT} at (0,0) size 54x20 LayoutMenuList {SELECT} at (2,2) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 52x18 + LayoutBlockFlow (anonymous) at (1,1) size 52x18 LayoutText (anonymous) at (4,1) size 32x16 text run at (4,1) width 32: "menu" LayoutNGTableCell {TD} at (124,6) size 19x19 [r=0 c=2 rs=1 cs=1] @@ -95,7 +95,7 @@ LayoutNGBlockFlow {DIV} at (1,1) size 242x26 [border: (2px solid #0000FF)] LayoutFileUploadControl {INPUT} at (2,2) size 238x22 "No file chosen" LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 69x16 + LayoutBlockFlow (anonymous) at (8,3) size 69x16 LayoutText {#text} at (0,0) size 69x16 text run at (0,0) width 69: "Choose File" LayoutNGTableCell {TD} at (403,2) size 185x42 [r=0 c=3 rs=1 cs=1] @@ -104,17 +104,17 @@ LayoutText {#text} at (0,0) size 199x26 text run at (0,0) width 199: "Baseline Alignment" LayoutNGBlockFlow {DIV} at (0,388.06) size 784x28 - LayoutInline {FONT} at (0,0) size 205x27 + LayoutInline {FONT} at (0,0) size 212x27 LayoutText {#text} at (0,0) size 43x27 text run at (0,0) width 43: "text " LayoutButton {INPUT} at (43,5) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 36x16 + LayoutBlockFlow (anonymous) at (8,3) size 36x16 LayoutText {#text} at (0,0) size 36x16 text run at (0,0) width 36: "button" LayoutText {#text} at (95,0) size 6x27 text run at (95,0) width 6: " " LayoutMenuList {SELECT} at (101,6) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 52x18 + LayoutBlockFlow (anonymous) at (1,1) size 52x18 LayoutText (anonymous) at (4,1) size 32x16 text run at (4,1) width 32: "menu" LayoutText {#text} at (155,0) size 6x27 @@ -128,13 +128,13 @@ LayoutText {#text} at (0,1) size 27x19 text run at (0,1) width 27: "text " LayoutButton {INPUT} at (27,0) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 36x16 + LayoutBlockFlow (anonymous) at (8,3) size 36x16 LayoutText {#text} at (0,0) size 36x16 text run at (0,0) width 36: "button" LayoutText {#text} at (79,1) size 4x19 text run at (79,1) width 4: " " LayoutMenuList {SELECT} at (83,1) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 52x18 + LayoutBlockFlow (anonymous) at (1,1) size 52x18 LayoutText (anonymous) at (4,1) size 32x16 text run at (4,1) width 32: "menu" LayoutText {#text} at (137,1) size 4x19 @@ -145,17 +145,17 @@ LayoutBlockFlow {INPUT} at (170,3) size 13x13 LayoutText {#text} at (0,0) size 0x0 LayoutNGBlockFlow {DIV} at (0,438.06) size 784x22 - LayoutInline {FONT} at (0,0) size 171x22 + LayoutInline {FONT} at (0,0) size 178x12 LayoutText {#text} at (0,6) size 18x12 text run at (0,6) width 18: "text " LayoutButton {INPUT} at (18,0) size 52x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 36x16 + LayoutBlockFlow (anonymous) at (8,3) size 36x16 LayoutText {#text} at (0,0) size 36x16 text run at (0,0) width 36: "button" LayoutText {#text} at (70,6) size 3x12 text run at (70,6) width 3: " " LayoutMenuList {SELECT} at (73,1) size 54x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 52x18 + LayoutBlockFlow (anonymous) at (1,1) size 52x18 LayoutText (anonymous) at (4,1) size 32x16 text run at (4,1) width 32: "menu" LayoutText {#text} at (127,6) size 3x12 @@ -173,7 +173,7 @@ text run at (128,21) width 4: " " LayoutFileUploadControl {INPUT} at (132,20) size 238x22 "No file chosen" LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] - LayoutNGBlockFlow (anonymous) at (8,3) size 69x16 + LayoutBlockFlow (anonymous) at (8,3) size 69x16 LayoutText {#text} at (0,0) size 69x16 text run at (0,0) width 69: "Choose File" LayoutText {#text} at (370,21) size 4x19 @@ -186,37 +186,37 @@ LayoutInline {FONT} at (0,0) size 137x27 LayoutText {#text} at (0,0) size 0x0 LayoutMenuList {SELECT} at (0,6) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 20x18 + LayoutBlockFlow (anonymous) at (1,1) size 20x18 LayoutText (anonymous) at (4,1) size 4x16 text run at (4,1) width 4: " " LayoutText {#text} at (22,0) size 6x27 text run at (22,0) width 6: " " LayoutMenuList {SELECT} at (28,6) size 25x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 23x18 + LayoutBlockFlow (anonymous) at (1,1) size 23x18 LayoutText (anonymous) at (4,1) size 3x16 text run at (4,1) width 3: "|" LayoutText {#text} at (53,0) size 6x27 text run at (53,0) width 6: " " LayoutMenuList {SELECT} at (59,6) size 78x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 76x18 + LayoutBlockFlow (anonymous) at (1,1) size 76x18 LayoutText (anonymous) at (4,1) size 56x16 text run at (4,1) width 56: "xxxxxxxx" LayoutText {#text} at (0,0) size 0x0 LayoutNGBlockFlow {DIV} at (0,596.88) size 784x20 LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 20x18 + LayoutBlockFlow (anonymous) at (1,1) size 20x18 LayoutText (anonymous) at (4,1) size 4x16 text run at (4,1) width 4: " " LayoutText {#text} at (22,0) size 4x19 text run at (22,0) width 4: " " LayoutMenuList {SELECT} at (26,0) size 25x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 23x18 + LayoutBlockFlow (anonymous) at (1,1) size 23x18 LayoutText (anonymous) at (4,1) size 3x16 text run at (4,1) width 3: "|" LayoutText {#text} at (51,0) size 4x19 text run at (51,0) width 4: " " LayoutMenuList {SELECT} at (55,0) size 78x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 76x18 + LayoutBlockFlow (anonymous) at (1,1) size 76x18 LayoutText (anonymous) at (4,1) size 56x16 text run at (4,1) width 56: "xxxxxxxx" LayoutText {#text} at (0,0) size 0x0 @@ -224,19 +224,19 @@ LayoutInline {FONT} at (0,0) size 131x20 LayoutText {#text} at (0,0) size 0x0 LayoutMenuList {SELECT} at (0,0) size 22x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 20x18 + LayoutBlockFlow (anonymous) at (1,1) size 20x18 LayoutText (anonymous) at (4,1) size 4x16 text run at (4,1) width 4: " " LayoutText {#text} at (22,5) size 3x12 text run at (22,5) width 3: " " LayoutMenuList {SELECT} at (25,0) size 25x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 23x18 + LayoutBlockFlow (anonymous) at (1,1) size 23x18 LayoutText (anonymous) at (4,1) size 3x16 text run at (4,1) width 3: "|" LayoutText {#text} at (50,5) size 3x12 text run at (50,5) width 3: " " LayoutMenuList {SELECT} at (53,0) size 78x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)] - LayoutNGBlockFlow (anonymous) at (1,1) size 76x18 + LayoutBlockFlow (anonymous) at (1,1) size 76x18 LayoutText (anonymous) at (4,1) size 56x16 text run at (4,1) width 56: "xxxxxxxx" LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew-expected.png deleted file mode 100644 index 22bc421..0000000 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/justify-emphasis-inline-box-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/justify-emphasis-inline-box-expected.png new file mode 100644 index 0000000..2b4bdc4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/justify-emphasis-inline-box-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/place-ellipsis-in-inline-block-adjacent-float-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/place-ellipsis-in-inline-block-adjacent-float-2-expected.png new file mode 100644 index 0000000..f3512156 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/place-ellipsis-in-inline-block-adjacent-float-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/place-ellipsis-in-inline-block-adjacent-float-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/place-ellipsis-in-inline-block-adjacent-float-expected.png new file mode 100644 index 0000000..cd0afc44 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/place-ellipsis-in-inline-block-adjacent-float-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/writing-mode/vertical-lr-replaced-selection-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/writing-mode/vertical-lr-replaced-selection-expected.png new file mode 100644 index 0000000..832c0c3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/writing-mode/vertical-lr-replaced-selection-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/list-marker-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/list-marker-expected.txt new file mode 100644 index 0000000..30da73547 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/list-marker-expected.txt
@@ -0,0 +1,53 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x576 + LayoutNGBlockFlow {P} at (0,0) size 784x40 + LayoutText {#text} at (0,0) size 52x19 + text run at (0,0) width 52: "Test for " + LayoutInline {I} at (0,0) size 784x39 + LayoutInline {A} at (0,0) size 300x19 [color=#0000EE] + LayoutText {#text} at (52,0) size 300x19 + text run at (52,0) width 300: "http://bugs.webkit.org/show_bug.cgi?id=12910" + LayoutText {#text} at (352,0) size 784x39 + text run at (352,0) width 432: " REGRESSION (r18756-r18765): list-bullet doesn't redraw properly" + text run at (0,20) width 310: "when changing the list's content using JavaScript" + LayoutText {#text} at (310,20) size 4x19 + text run at (310,20) width 4: "." + LayoutNGBlockFlow {UL} at (0,56) size 784x20 + LayoutNGListItem {LI} at (40,0) size 744x20 + LayoutNGListMarker (anonymous) at (-18,0) size 7x20 + LayoutText (anonymous) at (0,0) size 7x19 + text run at (0,0) width 7: "\x{2022} " + LayoutNGBlockFlow (anonymous) at (0,0) size 744x20 + LayoutText {#text} at (0,0) size 21x19 + text run at (0,0) width 21: "foo" + LayoutNGBlockFlow {DIV} at (10,30) size 724x0 + LayoutNGBlockFlow {UL} at (0,92) size 784x20 + LayoutNGListItem {LI} at (40,0) size 744x20 + LayoutNGBlockFlow (anonymous) at (0,0) size 744x20 + LayoutInline (anonymous) at (0,0) size 7x19 + LayoutText (anonymous) at (-1,0) size 7x19 + text run at (-1,0) width 7: "\x{2022} " + LayoutText {#text} at (22,0) size 20x19 + text run at (22,0) width 20: "bar" + LayoutNGBlockFlow {DIV} at (10,30) size 724x0 + LayoutNGBlockFlow {UL} at (0,128) size 784x20 + LayoutNGListItem {LI} at (0,0) size 744x20 + LayoutNGListMarker (anonymous) at (755,0) size 7x20 + LayoutText (anonymous) at (0,0) size 7x19 + text run at (0,0) width 7: "\x{2022} " + LayoutNGBlockFlow (anonymous) at (0,0) size 744x20 + LayoutText {#text} at (723,0) size 21x19 + text run at (723,0) width 21: "foo" + LayoutNGBlockFlow {DIV} at (10,30) size 724x0 + LayoutNGBlockFlow {UL} at (0,164) size 784x20 + LayoutNGListItem {LI} at (0,0) size 744x20 + LayoutNGBlockFlow (anonymous) at (0,0) size 744x20 + LayoutInline (anonymous) at (0,0) size 7x19 + LayoutText (anonymous) at (738,0) size 7x19 + text run at (738,0) width 7: "\x{2022} " + LayoutText {#text} at (702,0) size 20x19 + text run at (702,0) width 20: "bar" + LayoutNGBlockFlow {DIV} at (10,30) size 724x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/active-suggestion-marker-split-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/active-suggestion-marker-split-expected.txt new file mode 100644 index 0000000..e2878e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/active-suggestion-marker-split-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x56 + LayoutNGBlockFlow {HTML} at (0,0) size 800x56 + LayoutNGBlockFlow {BODY} at (8,8) size 784x40 + LayoutNGBlockFlow {DIV} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 22x19 + text run at (0,0) width 22: "abc" + LayoutText {#text} at (22,0) size 32x19 + text run at (22,0) width 32: " xxx " + LayoutText {#text} at (54,0) size 20x19 + text run at (54,0) width 20: "def" +layer at (8,28) size 128x20 scrollWidth 159 + LayoutNGBlockFlow {DIV} at (0,20) size 128x20 + LayoutText {#text} at (0,0) size 62x19 + text run at (0,0) width 62: "abcdefghi" + LayoutText {#text} at (62,0) size 32x19 + text run at (62,0) width 32: " xxx " + LayoutText {#text} at (94,0) size 32x19 + text run at (94,0) width 16: "jkl" + text run at (110,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/composition-marker-split-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/composition-marker-split-expected.txt new file mode 100644 index 0000000..e2878e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/composition-marker-split-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x56 + LayoutNGBlockFlow {HTML} at (0,0) size 800x56 + LayoutNGBlockFlow {BODY} at (8,8) size 784x40 + LayoutNGBlockFlow {DIV} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 22x19 + text run at (0,0) width 22: "abc" + LayoutText {#text} at (22,0) size 32x19 + text run at (22,0) width 32: " xxx " + LayoutText {#text} at (54,0) size 20x19 + text run at (54,0) width 20: "def" +layer at (8,28) size 128x20 scrollWidth 159 + LayoutNGBlockFlow {DIV} at (0,20) size 128x20 + LayoutText {#text} at (0,0) size 62x19 + text run at (0,0) width 62: "abcdefghi" + LayoutText {#text} at (62,0) size 32x19 + text run at (62,0) width 32: " xxx " + LayoutText {#text} at (94,0) size 32x19 + text run at (94,0) width 16: "jkl" + text run at (110,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.png new file mode 100644 index 0000000..c30ddb52 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.txt new file mode 100644 index 0000000..fcc817e --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.txt
@@ -0,0 +1,50 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x196 + LayoutNGBlockFlow {HTML} at (0,0) size 800x196 + LayoutNGBlockFlow {BODY} at (8,8) size 784x180 +layer at (8,8) size 100x20 scrollWidth 133 + LayoutNGBlockFlow {DIV} at (0,0) size 100x20 + LayoutText {#text} at (0,0) size 99x19 + text run at (0,0) width 83: "markAllCom" + text run at (83,0) width 16: "\x{2026}" +layer at (8,28) size 100x20 scrollWidth 142 + LayoutNGBlockFlow {DIV} at (0,20) size 100x20 + LayoutText {#text} at (0,0) size 96x19 + text run at (0,0) width 80: "markStartCo" + text run at (80,0) width 16: "\x{2026}" +layer at (8,48) size 100x20 scrollWidth 139 + LayoutNGBlockFlow {DIV} at (0,40) size 100x20 + LayoutText {#text} at (0,0) size 93x19 + text run at (0,0) width 77: "markEndCo" + text run at (77,0) width 16: "\x{2026}" +layer at (8,68) size 100x20 scrollWidth 104 + LayoutNGBlockFlow {DIV} at (0,60) size 100x20 + LayoutText {#text} at (0,0) size 100x19 + text run at (0,0) width 84: "markAllSpell" + text run at (84,0) width 16: "\x{2026}" +layer at (8,88) size 100x20 scrollWidth 113 + LayoutNGBlockFlow {DIV} at (0,80) size 100x20 + LayoutText {#text} at (0,0) size 94x19 + text run at (0,0) width 78: "markStartSp" + text run at (78,0) width 16: "\x{2026}" +layer at (8,108) size 100x20 scrollWidth 110 + LayoutNGBlockFlow {DIV} at (0,100) size 100x20 + LayoutText {#text} at (0,0) size 98x19 + text run at (0,0) width 82: "markEndSpe" + text run at (82,0) width 16: "\x{2026}" +layer at (8,128) size 100x20 scrollWidth 120 + LayoutNGBlockFlow {DIV} at (0,120) size 100x20 + LayoutText {#text} at (0,0) size 96x19 + text run at (0,0) width 80: "markAllText" + text run at (80,0) width 16: "\x{2026}" +layer at (8,148) size 100x20 scrollWidth 129 + LayoutNGBlockFlow {DIV} at (0,140) size 100x20 + LayoutText {#text} at (0,0) size 93x19 + text run at (0,0) width 77: "markStartTe" + text run at (77,0) width 16: "\x{2026}" +layer at (8,168) size 100x20 scrollWidth 126 + LayoutNGBlockFlow {DIV} at (0,160) size 100x20 + LayoutText {#text} at (0,0) size 98x19 + text run at (0,0) width 82: "markEndTex" + text run at (82,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.png new file mode 100644 index 0000000..0b98b3f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.txt new file mode 100644 index 0000000..f533984 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.txt
@@ -0,0 +1,50 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x196 + LayoutNGBlockFlow {HTML} at (0,0) size 800x196 + LayoutNGBlockFlow {BODY} at (8,8) size 784x180 +layer at (8,8) size 100x20 scrollX 33.00 scrollWidth 133 + LayoutNGBlockFlow {DIV} at (0,0) size 100x20 + LayoutText {#text} at (19,0) size 97x19 + text run at (19,0) width 81: "Composition" + text run at (3,0) width 16: "\x{2026}" +layer at (8,28) size 100x20 scrollX 42.00 scrollWidth 142 + LayoutNGBlockFlow {DIV} at (0,20) size 100x20 + LayoutText {#text} at (19,0) size 97x19 + text run at (19,0) width 81: "Composition" + text run at (3,0) width 16: "\x{2026}" +layer at (8,48) size 100x20 scrollX 39.00 scrollWidth 139 + LayoutNGBlockFlow {DIV} at (0,40) size 100x20 + LayoutText {#text} at (19,0) size 97x19 + text run at (19,0) width 81: "Composition" + text run at (3,0) width 16: "\x{2026}" +layer at (8,68) size 100x20 scrollX 4.00 scrollWidth 104 + LayoutNGBlockFlow {DIV} at (0,60) size 100x20 + LayoutText {#text} at (20,0) size 96x19 + text run at (20,0) width 80: "kAllSpelling" + text run at (4,0) width 16: "\x{2026}" +layer at (8,88) size 100x20 scrollX 13.00 scrollWidth 113 + LayoutNGBlockFlow {DIV} at (0,80) size 100x20 + LayoutText {#text} at (19,0) size 97x19 + text run at (19,0) width 81: "StartSpelling" + text run at (3,0) width 16: "\x{2026}" +layer at (8,108) size 100x20 scrollX 10.00 scrollWidth 110 + LayoutNGBlockFlow {DIV} at (0,100) size 100x20 + LayoutText {#text} at (22,0) size 94x19 + text run at (22,0) width 78: "EndSpelling" + text run at (6,0) width 16: "\x{2026}" +layer at (8,128) size 100x20 scrollX 20.00 scrollWidth 120 + LayoutNGBlockFlow {DIV} at (0,120) size 100x20 + LayoutText {#text} at (24,0) size 92x19 + text run at (24,0) width 76: "llTextMatch" + text run at (8,0) width 16: "\x{2026}" +layer at (8,148) size 100x20 scrollX 29.00 scrollWidth 129 + LayoutNGBlockFlow {DIV} at (0,140) size 100x20 + LayoutText {#text} at (23,0) size 93x19 + text run at (23,0) width 77: "rtTextMatch" + text run at (7,0) width 16: "\x{2026}" +layer at (8,168) size 100x20 scrollX 26.00 scrollWidth 126 + LayoutNGBlockFlow {DIV} at (0,160) size 100x20 + LayoutText {#text} at (24,0) size 92x19 + text run at (24,0) width 76: "dTextMatch" + text run at (8,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.png new file mode 100644 index 0000000..241d681 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.txt new file mode 100644 index 0000000..7c7690ac --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.txt
@@ -0,0 +1,101 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x256 + LayoutNGBlockFlow {HTML} at (0,0) size 800x256 + LayoutNGBlockFlow {BODY} at (8,8) size 784x240 +layer at (8,8) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,0) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,28) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,20) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,48) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,40) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,68) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,60) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,88) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,80) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,108) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,100) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,128) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,120) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,148) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,140) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,168) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,160) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,188) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,180) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,208) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,200) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,228) size 100x20 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,220) size 100x20 + LayoutText {#text} at (0,0) size 134x19 + text run at (0,0) width 35: "Hello" + text run at (35,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (67,0) width 12: "H" + text run at (102,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (79,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.png new file mode 100644 index 0000000..13749c5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.txt new file mode 100644 index 0000000..210c26e --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.txt
@@ -0,0 +1,101 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x256 + LayoutNGBlockFlow {HTML} at (0,0) size 800x256 + LayoutNGBlockFlow {BODY} at (8,8) size 784x240 +layer at (8,8) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,0) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,28) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,20) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,48) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,40) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,68) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,60) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,88) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,80) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,108) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,100) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,128) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,120) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,148) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,140) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,168) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,160) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,188) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,180) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,208) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,200) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}" +layer at (8,228) size 100x20 scrollX 34.00 scrollWidth 134 + LayoutNGBlockFlow {DIV} at (0,220) size 100x20 + LayoutText {#text} at (-34,0) size 134x19 + text run at (-34,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (17,0) width 16: "llo" + text run at (33,0) width 32: "\x{5E9}\x{5DC}\x{5D5}\x{5DD}" + text run at (65,0) width 35: "Hello" + text run at (1,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.png new file mode 100644 index 0000000..a5706a2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.txt new file mode 100644 index 0000000..eb80cfc --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.txt
@@ -0,0 +1,50 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x196 + LayoutNGBlockFlow {HTML} at (0,0) size 800x196 + LayoutNGBlockFlow {BODY} at (8,8) size 784x180 +layer at (8,8) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,0) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,28) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,20) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,48) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,40) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,68) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,60) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,88) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,80) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,108) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,100) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,128) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,120) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,148) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,140) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}" +layer at (8,168) size 100x20 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,160) size 100x20 + LayoutText {#text} at (0,0) size 95x19 + text run at (0,0) width 79: "\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (79,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.png new file mode 100644 index 0000000..c0645ef1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.txt new file mode 100644 index 0000000..b86bdc8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.txt
@@ -0,0 +1,50 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x196 + LayoutNGBlockFlow {HTML} at (0,0) size 800x196 + LayoutNGBlockFlow {BODY} at (8,8) size 784x180 +layer at (8,8) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,0) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,28) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,20) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,48) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,40) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,68) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,60) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,88) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,80) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,108) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,100) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,128) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,120) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,148) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,140) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}" +layer at (8,168) size 100x20 scrollX 101.00 scrollWidth 201 + LayoutNGBlockFlow {DIV} at (0,160) size 100x20 + LayoutText {#text} at (21,0) size 95x19 + text run at (21,0) width 79: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}" + text run at (5,0) width 16: "\x{2026}"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/iframe-plugin-bgcolor-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/iframe-plugin-bgcolor-expected.txt index fe7e4d1..18d2b87 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/iframe-plugin-bgcolor-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/iframe-plugin-bgcolor-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE MESSAGE: Blink Test Plugin: initializing layer at (0,0) size 800x600 LayoutView at (0,0) size 800x600 layer at (0,0) size 800x171
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/text-match-highlight-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/text-match-highlight-expected.txt new file mode 100644 index 0000000..6e777401 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/svg/custom/text-match-highlight-expected.txt
@@ -0,0 +1,87 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x421 + LayoutNGBlockFlow {HTML} at (0,0) size 800x421 + LayoutNGBlockFlow {BODY} at (8,8) size 784x405 + LayoutText {#text} at (0,0) size 449x19 + text run at (0,0) width 449: "Test for crbug.com/56580: There should be 9 highlighted instances of \"" + LayoutInline {SPAN} at (0,0) size 44x19 + LayoutText {#text} at (449,0) size 44x19 + text run at (449,0) width 44: "findme" + LayoutText {#text} at (493,0) size 744x39 + text run at (493,0) width 251: "\". The 6th higlighted instance should be" + text run at (0,20) width 41: "active." + LayoutBR {BR} at (41,20) size 0x0 + LayoutBR {BR} at (0,40) size 0x0 + LayoutText {#text} at (0,60) size 89x19 + text run at (0,60) width 89: "Lorum ipsum " + LayoutInline {SPAN} at (0,0) size 44x19 + LayoutText {#text} at (89,60) size 44x19 + text run at (89,60) width 44: "findme" + LayoutText {#text} at (133,60) size 87x19 + text run at (133,60) width 87: " lorum ipsum " + LayoutInline {SPAN} at (0,0) size 44x19 + LayoutText {#text} at (220,60) size 44x19 + text run at (220,60) width 44: "findme" + LayoutInline {SPAN} at (0,0) size 44x19 + LayoutText {#text} at (264,60) size 44x19 + text run at (264,60) width 44: "findme" + LayoutText {#text} at (308,60) size 45x19 + text run at (308,60) width 45: " lorum." + LayoutBR {BR} at (353,60) size 0x0 + LayoutText {#text} at (0,80) size 51x19 + text run at (0,80) width 51: "longtext" + LayoutInline {SPAN} at (0,0) size 44x19 + LayoutText {#text} at (51,80) size 44x19 + text run at (51,80) width 44: "findme" + LayoutText {#text} at (95,80) size 44x19 + text run at (95,80) width 44: "noyou." + LayoutBR {BR} at (139,80) size 0x0 + LayoutSVGRoot {svg} at (0,100) size 450x300 + LayoutSVGHiddenContainer {defs} at (100,58.58) size 800x182.84 + LayoutSVGPath {path} at (100,58.58) size 800x182.84 [fill={[type=SOLID] [color=#000000]}] [data="M 100 200 C 200 100 300 0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100"] + LayoutSVGText {text} at (10,35) size 228x19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,35) size 228x19 + chunk 1 text run 1 at (10.00,50.00) startOffset 0 endOffset 36 width 228.00: "Can you findme in this stroked text?" + LayoutSVGText {text} at (10,91) size 138x12 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,91) size 138x12 + chunk 1 text run 1 at (10.00,100.00) startOffset 0 endOffset 23 width 138.00: "Findme in a typewriter!" + LayoutSVGContainer {g} at (69.42,14.89) size 599.64x237.67 [transform={m=((0.30,0.00)(0.00,0.30)) t=(0.00,120.00)}] + LayoutSVGText {text} at (69.42,14.89) size 599.64x237.67 contains 1 chunk(s) + LayoutSVGTextPath {textPath} at (69.42,14.89) size 599.64x237.67 + LayoutSVGInlineText {#text} at (69.42,14.89) size 599.64x237.67 + chunk 1 text run 1 at (109.48,190.53) startOffset 0 endOffset 1 width 26.67: "F" + chunk 1 text run 2 at (122.51,177.58) startOffset 1 endOffset 2 width 10.00: "i" + chunk 1 text run 3 at (134.36,165.95) startOffset 2 endOffset 3 width 23.33: "n" + chunk 1 text run 4 at (151.21,149.79) startOffset 3 endOffset 4 width 23.33: "d" + chunk 1 text run 5 at (173.34,129.58) startOffset 4 endOffset 5 width 36.67: "m" + chunk 1 text run 6 at (196.35,110.28) startOffset 5 endOffset 6 width 23.33: "e" + chunk 1 text run 7 at (210.92,99.19) startOffset 6 endOffset 7 width 13.33: " " + chunk 1 text run 8 at (226.09,88.76) startOffset 7 endOffset 8 width 23.33: "o" + chunk 1 text run 9 at (246.19,76.95) startOffset 8 endOffset 9 width 23.33: "n" + chunk 1 text run 10 at (262.81,69.16) startOffset 9 endOffset 10 width 13.33: " " + chunk 1 text run 11 at (280.12,63.17) startOffset 10 endOffset 11 width 23.33: "a" + chunk 1 text run 12 at (297.99,59.50) startOffset 11 endOffset 12 width 13.33: " " + chunk 1 text run 13 at (316.28,58.66) startOffset 12 endOffset 13 width 23.33: "p" + chunk 1 text run 14 at (339.27,62.20) startOffset 13 endOffset 14 width 23.33: "a" + chunk 1 text run 15 at (356.46,68.49) startOffset 14 endOffset 15 width 13.33: "t" + chunk 1 text run 16 at (372.50,77.39) startOffset 15 endOffset 16 width 23.33: "h" + chunk 1 text run 17 at (387.18,88.26) startOffset 16 endOffset 17 width 13.33: "!" + chunk 1 text run 18 at (397.11,97.16) startOffset 17 endOffset 18 width 13.33: " " + chunk 1 text run 19 at (412.58,112.56) startOffset 18 endOffset 19 width 30.00: "D" + chunk 1 text run 20 at (426.80,126.65) startOffset 19 endOffset 20 width 10.00: "i" + chunk 1 text run 21 at (438.66,138.24) startOffset 20 endOffset 21 width 23.33: "d" + chunk 1 text run 22 at (451.95,150.91) startOffset 21 endOffset 22 width 13.33: " " + chunk 1 text run 23 at (465.45,163.38) startOffset 22 endOffset 23 width 23.33: "y" + chunk 1 text run 24 at (483.01,178.77) startOffset 23 endOffset 24 width 23.33: "o" + chunk 1 text run 25 at (501.14,193.48) startOffset 24 endOffset 25 width 23.33: "u" + chunk 1 text run 26 at (515.86,204.34) startOffset 25 endOffset 26 width 13.33: " " + chunk 1 text run 27 at (526.94,211.79) startOffset 26 endOffset 27 width 13.33: "f" + chunk 1 text run 28 at (536.91,217.90) startOffset 27 endOffset 28 width 10.00: "i" + chunk 1 text run 29 at (551.53,225.76) startOffset 28 endOffset 29 width 23.33: "n" + chunk 1 text run 30 at (573.12,234.69) startOffset 29 endOffset 30 width 23.33: "d" + chunk 1 text run 31 at (602.33,240.98) startOffset 30 endOffset 31 width 36.67: "m" + chunk 1 text run 32 at (632.18,239.47) startOffset 31 endOffset 32 width 23.33: "e" + chunk 1 text run 33 at (654.38,232.45) startOffset 32 endOffset 33 width 23.33: "?" + LayoutSVGInlineText {#text} at (0,0) size 0x0 + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/background-tab-on-submit-ctrl-click-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/background-tab-on-submit-ctrl-click-expected.txt new file mode 100644 index 0000000..565b766 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/background-tab-on-submit-ctrl-click-expected.txt
@@ -0,0 +1,5 @@ +Default policy for navigation to 'notify-done.html' is 'new background tab' +Default policy for navigation to 'notify-done.html' is 'current tab' +Tests that ctrl-clicking on a submit button results in a new background tab. + +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt new file mode 100644 index 0000000..776fb47 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt
@@ -0,0 +1,5 @@ +Default policy for navigation to 'notify-done.html' is 'new foreground tab' +Default policy for navigation to 'notify-done.html' is 'current tab' +Tests that synthesizing ctrl-click on a submit button does not result in a new background tab. + +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/user-activation-v2/fast/events/background-tab-on-submit-ctrl-click-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/user-activation-v2/fast/events/background-tab-on-submit-ctrl-click-expected.txt new file mode 100644 index 0000000..565b766 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/user-activation-v2/fast/events/background-tab-on-submit-ctrl-click-expected.txt
@@ -0,0 +1,5 @@ +Default policy for navigation to 'notify-done.html' is 'new background tab' +Default policy for navigation to 'notify-done.html' is 'current tab' +Tests that ctrl-clicking on a submit button results in a new background tab. + +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/user-activation-v2/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/user-activation-v2/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt new file mode 100644 index 0000000..776fb47 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/user-activation-v2/fast/events/background-tab-on-submit-synthesized-ctrl-click-expected.txt
@@ -0,0 +1,5 @@ +Default policy for navigation to 'notify-done.html' is 'new foreground tab' +Default policy for navigation to 'notify-done.html' is 'current tab' +Tests that synthesizing ctrl-click on a submit button does not result in a new background tab. + +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-colorspace-yuv420-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-colorspace-yuv420-expected.txt new file mode 100644 index 0000000..f7d6b59 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-colorspace-yuv420-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 327x19 + text run at (0,0) width 327: "Test correct colorspace for yuv420, i.e. YU12 video" + LayoutNGBlockFlow (anonymous) at (0,36) size 784x156 +layer at (8,44) size 206x156 + LayoutVideo {VIDEO} at (0,0) size 206x156 [border: (3px solid #FF0000)] +layer at (11,47) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutFlexibleBox {DIV} at (0,0) size 200x150 +layer at (11,47) size 200x150 + LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-colorspace-yuv422-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-colorspace-yuv422-expected.txt new file mode 100644 index 0000000..97ae83f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-colorspace-yuv422-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 327x19 + text run at (0,0) width 327: "Test correct colorspace for yuv422, i.e. YU16 video" + LayoutNGBlockFlow (anonymous) at (0,36) size 784x156 +layer at (8,44) size 206x156 + LayoutVideo {VIDEO} at (0,0) size 206x156 [border: (3px solid #FF0000)] +layer at (11,47) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutFlexibleBox {DIV} at (0,0) size 200x150 +layer at (11,47) size 200x150 + LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-layer-crash-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-layer-crash-expected.txt new file mode 100644 index 0000000..abfcc54 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-layer-crash-expected.txt
@@ -0,0 +1,32 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutNGBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 359x19 + text run at (0,0) width 359: "Test dynamic removal of transformed and reflected video" + LayoutNGBlockFlow (anonymous) at (0,36) size 784x342 + LayoutText {#text} at (0,0) size 4x19 + text run at (0,0) width 4: " " + LayoutBR {BR} at (4,0) size 0x0 + LayoutText {#text} at (0,161) size 4x19 + text run at (0,161) width 4: " " + LayoutBR {BR} at (210,161) size 0x0 + LayoutText {#text} at (0,322) size 4x19 + text run at (0,322) width 4: " " + LayoutBR {BR} at (210,322) size 0x0 +layer at (12,64) size 206x156 + LayoutVideo {VIDEO} at (4,20) size 206x156 [border: (3px solid #FF0000)] +layer at (15,67) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutFlexibleBox {DIV} at (0,0) size 200x150 +layer at (15,67) size 200x150 + LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150 +layer at (12,225) size 206x156 + LayoutVideo {VIDEO} at (4,181) size 206x156 [border: (3px solid #FF0000)] +layer at (15,228) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutFlexibleBox {DIV} at (0,0) size 200x150 +layer at (15,228) size 200x150 + LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 200x150
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-replaces-poster-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-replaces-poster-expected.txt new file mode 100644 index 0000000..2a117fb --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-replaces-poster-expected.txt
@@ -0,0 +1,25 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x355 + LayoutNGBlockFlow {HTML} at (0,0) size 800x355 + LayoutNGBlockFlow {BODY} at (8,16) size 784x331 + LayoutNGBlockFlow {P} at (0,0) size 784x40 + LayoutText {#text} at (0,0) size 52x19 + text run at (0,0) width 52: "Test for " + LayoutInline {A} at (0,0) size 305x19 [color=#0000EE] + LayoutText {#text} at (52,0) size 305x19 + text run at (52,0) width 305: "https://bugs.webkit.org/show_bug.cgi?id=34966" + LayoutText {#text} at (357,0) size 4x19 + text run at (357,0) width 4: "." + LayoutBR {BR} at (361,0) size 0x0 + LayoutText {#text} at (0,20) size 204x19 + text run at (0,20) width 204: "You should see the video below." + LayoutNGBlockFlow (anonymous) at (0,56) size 784x275 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,72) size 480x270 + LayoutVideo {VIDEO} at (0,0) size 480x270 +layer at (8,72) size 480x270 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 480x270 + LayoutFlexibleBox {DIV} at (0,0) size 480x270 +layer at (8,72) size 480x270 + LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 480x270
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-zoom-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-zoom-expected.txt new file mode 100644 index 0000000..a714a20e --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/video-surface-layer/media/video-zoom-expected.txt
@@ -0,0 +1,33 @@ +layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 852 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 785x852 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutNGBlockFlow {HTML} at (0,0) size 785x852 + LayoutNGBlockFlow {BODY} at (8,8) size 769x836 + LayoutNGBlockFlow {P} at (0,0) size 769x20 + LayoutText {#text} at (0,0) size 283x19 + text run at (0,0) width 283: "150% zoom, with width and height attributes" + LayoutNGBlockFlow (anonymous) at (0,36) size 769x374 + LayoutText {#text} at (0,354) size 4x19 + text run at (0,354) width 4: " " + LayoutBR {BR} at (493,354) size 0x0 + LayoutNGBlockFlow {P} at (0,426) size 769x20 + LayoutText {#text} at (0,0) size 303x19 + text run at (0,0) width 303: "150% zoom, without width and height attributes" + LayoutNGBlockFlow (anonymous) at (0,462) size 769x374 + LayoutText {#text} at (0,354) size 4x19 + text run at (0,354) width 4: " " + LayoutBR {BR} at (493,354) size 0x0 +layer at (12,44) size 489x369 + LayoutVideo {VIDEO} at (4,0) size 489x369 [border: (4.50px solid #FF0000)] +layer at (12,470) size 489x369 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutVideo {VIDEO} at (4,0) size 489x369 [border: (4.50px solid #FF0000)] +layer at (17,49) size 480x360 + LayoutFlexibleBox (relative positioned) {DIV} at (4.50,4.50) size 480x360 + LayoutFlexibleBox {DIV} at (0,0) size 480x360 +layer at (17,49) size 480x360 + LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 480x360 +layer at (17,475) size 480x360 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutFlexibleBox (relative positioned) {DIV} at (4.50,4.50) size 480x360 + LayoutFlexibleBox {DIV} at (0,0) size 480x360 +layer at (17,475) size 480x360 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutNGBlockFlow (positioned) {DIV} at (0,0) size 480x360
diff --git a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-bufferbeforeonload.html b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-bufferbeforeonload.html index 3f8e857a..1aa1147 100644 --- a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-bufferbeforeonload.html +++ b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-bufferbeforeonload.html
@@ -23,7 +23,7 @@ } function validateEntries() { - const entries = performance.getEntriesByName('click'); + const entries = performance.getEntriesByName('click', 'event'); const onloadTime = performance.timing.loadEventStart - performance.timeOrigin; const entriesBeforeOnload = entries.filter( @@ -31,7 +31,7 @@ assert_equals(entriesBeforeOnload.length, 1, "Long latency events before onload should be buffered."); const entry = entriesBeforeOnload[0]; - verifyClickEvent(entry); + verifyClickEvent(entry, true); assert_greater_than(entry.processingStart, processingStartMin, "The entry should be processed later than processingStartMin.");
diff --git a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-crossiframe.html b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-crossiframe.html index bf3afc9..529e0ff8 100644 --- a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-crossiframe.html +++ b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-crossiframe.html
@@ -21,14 +21,14 @@ let processingStartMin; function validateEntries() { - const entries = performance.getEntriesByName('click'); + const entries = performance.getEntriesByName('click', 'event'); const onloadTime = performance.timing.loadEventStart - performance.timeOrigin; assert_equals(entries.length, 1, "Observer of main frames should only capture main-frame event-timing entries." ); const entry = entries[0]; - verifyClickEvent(entry); + verifyClickEvent(entry, true); assert_greater_than(entry.processingStart, processingStartMin, "The entry's processing start should be later than processingStartMin.");
diff --git a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-observethenonload.html b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-observethenonload.html index 2363936b..6b089e5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-observethenonload.html +++ b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-observethenonload.html
@@ -23,7 +23,7 @@ "onload should be later than entry's start time."); assert_greater_than(entry.processingStart, timeAfterFirstClick, "The entry's processing start should be later than timeAfterFirstClick."); - verifyClickEvent(entry); + verifyClickEvent(entry, true); } function verifyObserverEntries(observedEntries) { @@ -79,7 +79,7 @@ const bufferPromise = clickAndBlockMain('button').then(wait); Promise.all([observerPromise, bufferPromise]).then((results) => { t.step(verifyObserverEntries.bind(null, results[0])); - t.step(verifyBuffer.bind(null, performance.getEntriesByName('click'))); + t.step(verifyBuffer.bind(null, performance.getEntriesByName('click', 'event'))); t.done(); }); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-onloadthenobserve.html b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-onloadthenobserve.html index 9fcaab4..4a18631 100644 --- a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-onloadthenobserve.html +++ b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-onloadthenobserve.html
@@ -15,7 +15,7 @@ function verifyBufferAndObserverEntries(observedEntries) { // Verify buffer entries - const bufferedEntries = performance.getEntriesByName('click'); + const bufferedEntries = performance.getEntriesByName('click', 'event'); const bufferedEntriesBeforeObserver = bufferedEntries.filter(e => e.startTime < observerStart); assert_equals(bufferedEntries.length, 0,
diff --git a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-retrievability.html b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-retrievability.html index 02cd25e59..93f76e48 100644 --- a/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-retrievability.html +++ b/third_party/WebKit/LayoutTests/http/tests/event-timing/event-timing-retrievability.html
@@ -10,7 +10,7 @@ <script> function validateEntries() { - const entriesByName = performance.getEntriesByName('click'); + const entriesByName = performance.getEntriesByName('click', 'event'); const entriesByType = performance.getEntriesByType('event'); const allEntries = performance.getEntries(); assert_equals(entriesByName.length, 1, 'event-timing entry should be retrievable by getEntriesByName');
diff --git a/third_party/WebKit/LayoutTests/http/tests/event-timing/resources/event-timing-support.js b/third_party/WebKit/LayoutTests/http/tests/event-timing/resources/event-timing-support.js index b9c1b9d..5268ef9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/event-timing/resources/event-timing-support.js +++ b/third_party/WebKit/LayoutTests/http/tests/event-timing/resources/event-timing-support.js
@@ -21,7 +21,10 @@ while (performance.now() < now + duration); } -function verifyClickEvent(entry) { +// This method should receive an entry of type 'event'. |is_false| is true only +// when the event also happens to correspond to the first event. In this case, +// the timings of the 'firstInput' entry should be equal to those of this entry. +function verifyClickEvent(entry, is_first=false) { assert_true(entry.cancelable); assert_equals(entry.name, 'click'); assert_equals(entry.entryType, 'event'); @@ -33,6 +36,18 @@ "The entry's processingEnd must be at least as large as processingStart."); assert_greater_than_equal(entry.duration, entry.processingEnd - entry.startTime, "The entry's duration must be at least as large as processingEnd - startTime."); + if (is_first) { + let firstInputs = performance.getEntriesByType('firstInput'); + assert_equals(firstInputs.length, 1, 'There should be a single firstInput entry'); + let firstInput = firstInputs[0]; + assert_equals(firstInput.name, entry.name); + assert_equals(firstInput.entryType, 'firstInput'); + assert_equals(firstInput.startTime, entry.startTime); + assert_equals(firstInput.duration, entry.duration); + assert_equals(firstInput.processingStart, entry.processingStart); + assert_equals(firstInput.processingEnd, entry.processingEnd); + assert_equals(firstInput.cancelable, entry.cancelable); + } } function wait() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/payments/resources/payment-request-event.js b/third_party/WebKit/LayoutTests/http/tests/payments/resources/payment-request-event.js index a0a1d94..2de553e0 100644 --- a/third_party/WebKit/LayoutTests/http/tests/payments/resources/payment-request-event.js +++ b/third_party/WebKit/LayoutTests/http/tests/payments/resources/payment-request-event.js
@@ -20,14 +20,14 @@ paymentRequestOrigin: 'https://example.com', paymentRequestId: 'payment-request-id', methodData: [{ - supportedMethods: ['basic-card'] + supportedMethods: 'basic-card' }], total: { currency: 'USD', value: '55.00' }, modifiers: [{ - supportedMethods: ['basic-card'] + supportedMethods: 'basic-card' }], instrumentKey: 'payment-instrument-key' }); @@ -37,13 +37,11 @@ assert_equals(e.paymentRequestOrigin, 'https://example.com'); assert_equals(e.paymentRequestId, 'payment-request-id'); assert_equals(e.methodData.length, 1); - assert_equals(e.methodData[0].supportedMethods.length, 1); - assert_equals(e.methodData[0].supportedMethods[0], 'basic-card'); + assert_equals(e.methodData[0].supportedMethods, 'basic-card'); assert_equals(e.total.currency, 'USD'); assert_equals(e.total.value, '55.00'); assert_equals(e.modifiers.length, 1); - assert_equals(e.modifiers[0].supportedMethods.length, 1); - assert_equals(e.modifiers[0].supportedMethods[0], 'basic-card'); + assert_equals(e.modifiers[0].supportedMethods, 'basic-card'); assert_equals(e.instrumentKey, 'payment-instrument-key'); resolve(); });
diff --git a/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png index c9bd86f..483dd3ac 100644 --- a/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled-expected.txt index d3097e23..9031295 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled-expected.txt
@@ -1,4 +1,3 @@ Tests mutation observer invocation. -Count: 2. -Count: 2. +Count: 1.
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled.js b/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled.js index f75cf3f..8c9bba66 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled.js +++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/not-invoke-mutation-observer-after-script-disabled.js
@@ -1,21 +1,19 @@ (async function(testRunner) { var {page, session, dp} = - await testRunner.startHTML(` - <body><script> - count = 0; - var observer = new MutationObserver(() => {count++;}); - observer.observe(document.body, {childList: true}); - </script></body> -`, 'Tests mutation observer invocation.'); - async function triggerMutation() { - await session.evaluate(`document.body.appendChild(document.createTextNode('ha'))`); - let result = await session.evaluate(`count`); - testRunner.log(`Count: ${result}.`); - } + await testRunner.startBlank('Tests mutation observer invocation.'); - await triggerMutation(); - await dp.Emulation.setScriptExecutionDisabled({value: true}); - await triggerMutation(); + await dp.Runtime.enable(); + let promise = page.navigate('../resources/mutation-observer-triggered-by-parser.html') + + await dp.Runtime.onceConsoleAPICalled(); + await Promise.all([ + dp.Emulation.setScriptExecutionDisabled({value: true}), + dp.Runtime.terminateExecution(), + promise + ]); + + let result = await session.evaluate(`count`); + testRunner.log(`Count: ${result}.`); testRunner.completeTest(); })
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/mutation-observer-triggered-by-parser.html b/third_party/WebKit/LayoutTests/inspector-protocol/resources/mutation-observer-triggered-by-parser.html new file mode 100644 index 0000000..8517afe --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/mutation-observer-triggered-by-parser.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<body> +<script> +count = 0; +let observer = new MutationObserver(() => { count++; if (count==1) { console.log(42); while(true){} } }); +observer.observe(document.body, {childList: true}); +</script> +<b>0</b><b>1</b><b>2</b><b>3</b><b>4</b><b>5</b><b>6</b><b>7</b><b>8</b><b>9</b> +<b>0</b><b>1</b><b>2</b><b>3</b><b>4</b><b>5</b><b>6</b><b>7</b><b>8</b><b>9</b> +<b>0</b><b>1</b><b>2</b><b>3</b><b>4</b><b>5</b><b>6</b><b>7</b><b>8</b><b>9</b> +<b>0</b><b>1</b><b>2</b><b>3</b><b>4</b><b>5</b><b>6</b><b>7</b><b>8</b><b>9</b> +<b>0</b><b>1</b><b>2</b><b>3</b><b>4</b><b>5</b><b>6</b><b>7</b><b>8</b><b>9</b> +<b>0</b><b>1</b><b>2</b><b>3</b><b>4</b><b>5</b><b>6</b><b>7</b><b>8</b><b>9</b> +<script> + // Remove this script block to prevent parser from yeilding, so the parsing work can be done in one task, then the mutation observer handler just runs once. +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/controls/overlay-play-button-resizes-with-video.html b/third_party/WebKit/LayoutTests/media/controls/overlay-play-button-resizes-with-video.html index 0dc4fd8..34731ce 100644 --- a/third_party/WebKit/LayoutTests/media/controls/overlay-play-button-resizes-with-video.html +++ b/third_party/WebKit/LayoutTests/media/controls/overlay-play-button-resizes-with-video.html
@@ -9,14 +9,13 @@ const testCases = [ { width: 0, height: 0, expected: 48 }, { width: 1, height: 1, expected: 48 }, - { width: 300, height: 200, expected: 60 }, - { width: 200, height: 300, expected: 60 }, - { width: 600, height: 300, expected: 90 }, - { width: 1500, height: 1000, expected: 300 }, + { width: 300, height: 200, expected: 50 }, + { width: 200, height: 300, expected: 50 }, + { width: 600, height: 300, expected: 75 }, + { width: 1500, height: 1000, expected: 250 }, { width: 700, height: 100, expected: 48 }, - { width: 700, height: 180, expected: 54 }, - { width: 700, height: 500, expected: 150 }, - { width: 700, height: 1500, expected: 210 }, + { width: 700, height: 500, expected: 125 }, + { width: 700, height: 1500, expected: 175 }, ]; testCases.forEach(test => {
diff --git a/third_party/WebKit/LayoutTests/media/controls/resizing-changes-css-class.html b/third_party/WebKit/LayoutTests/media/controls/resizing-changes-css-class.html index ca25862..0934356 100644 --- a/third_party/WebKit/LayoutTests/media/controls/resizing-changes-css-class.html +++ b/third_party/WebKit/LayoutTests/media/controls/resizing-changes-css-class.html
@@ -14,7 +14,7 @@ { width: 800, expect: expectMedium }, { width: 2000, expect: expectLarge }, { width: 0, expect: expectSmall }, - { width: 641, expect: expectMedium }, + { width: 741, expect: expectMedium }, { width: 308, expect: expectSmall }, { width: 150, expect: expectSmall }, ];
diff --git a/third_party/WebKit/LayoutTests/payments/payment-request-interface.html b/third_party/WebKit/LayoutTests/payments/payment-request-interface.html index e3172fa..315b91b 100644 --- a/third_party/WebKit/LayoutTests/payments/payment-request-interface.html +++ b/third_party/WebKit/LayoutTests/payments/payment-request-interface.html
@@ -49,7 +49,7 @@ 'displayItems': [buildItem()], 'shippingOptions': [buildItem()], 'modifiers': [{ - 'supportedMethods': ['foo'], + 'supportedMethods': 'foo', 'total': buildItem(), 'additionalDisplayItems': [buildItem()] }] @@ -62,96 +62,96 @@ } test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {}); + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {}); }, 'Creating a PaymentRequest with empty parameters should not throw or crash.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {}, ''); + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {}, ''); }, 'Creating a PaymentRequest with extra parameters should not throw or crash.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails()); }, 'Creating a PaymentRequest with omitted optional parameters should not throw or crash.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), undefined); + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), undefined); }, 'Creating a PaymentRequest with undefined optional parameters should not throw or crash.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), null); + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), null); }, 'Creating a PaymentRequest with null optional parameters should not throw or crash.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails()); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails()); assert_readonly(request, 'shippingAddress', 'PaymentRequest should have a readonly shippingAddress property.'); assert_readonly(request, 'shippingOption', 'PaymentRequest should have a readonly shippingOption property.'); assert_readonly(request, 'shippingType', 'PaymentRequest should have a readonly shippingType property.'); }, 'PaymentRequest should have readonly shippingAddress and shippingOption properties.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails()); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails()); assert_not_equals(request.onshippingaddresschange, undefined, 'PaymentRequest should have onShippingAddressChange event.'); assert_not_equals(request.onshippingoptionchange, undefined, 'PaymentRequest should have onShippingOptionChange event.'); }, 'PaymentRequest should have onShippingAddressChange and onShippingOptionChange events.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails()); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails()); assert_not_equals(request.abort, undefined, 'PaymentRequest should have abort() method.'); assert_not_equals(request.show, undefined, 'PaymentRequest should have show() method.'); }, 'PaymentRequest should have methods abort() and show().'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails()); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails()); request.show(); request.abort(); }, 'PaymentRequest.abort() and PaymentRequest.show() should take no parameters.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo'], 'data': {'foo': {'gateway': 'bar'}}}], buildDetails(), {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo', 'data': {'foo': {'gateway': 'bar'}}}], buildDetails(), {'requestShipping': true}); request.show(); request.abort(); }, 'Valid data causes no errors.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails('shippingOptions.0', {'id': 'standard'})); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails('shippingOptions.0', {'id': 'standard'})); assert_equals(null, request.shippingOption); }, 'Shipping option identifier should be null if shipping request is omitted.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails('shippingOptions.0', {'id': 'standard'}), {'requestShipping': false}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails('shippingOptions.0', {'id': 'standard'}), {'requestShipping': false}); assert_equals(null, request.shippingOption); }, 'Shipping option identifier should be null if shipping is explicitly not requested.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': [buildItem()]}, {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': [buildItem()]}, {'requestShipping': true}); assert_equals(null, request.shippingOption); }, 'Shipping option identifier should be null if no shipping options are provided.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails('shippingOptions.0', {'selected': false}), {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails('shippingOptions.0', {'selected': false}), {'requestShipping': true}); assert_equals(null, request.shippingOption); }, 'Shipping option identifier should be null if the single provided option is not selected.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails('shippingOptions.0', {'id': 'standard', 'selected': true}), {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails('shippingOptions.0', {'id': 'standard', 'selected': true}), {'requestShipping': true}); assert_equals('standard', request.shippingOption); }, 'Shipping option identifier should default to the single provided option if it is selected.'); test(function() { var shippingOptions = [buildItem({'id': 'standard'}), buildItem({'id': 'express'})]; - var request = new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); assert_equals(null, request.shippingOption); }, 'Shipping option identifier should be null if multiple unselected shipping options are provided.'); test(function() { var shippingOptions = [buildItem({'id': 'standard', 'selected': true}), buildItem({'id': 'express'})]; - var request = new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); assert_equals('standard', request.shippingOption); }, 'Shipping option identifier should default to the selected shipping option.'); test(function() { var shippingOptions = [buildItem({'id': 'standard', 'selected': true}), buildItem({'id': 'express', 'selected': true})]; - var request = new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); assert_equals('express', request.shippingOption); }, 'Shipping option identifier should default to the last selected shipping option, if multiple are selected.'); @@ -160,129 +160,121 @@ assert_throws( new TypeError(), () => { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': shippingOptions}, {'requestShipping': true}); }, "Expected to throw a TypeError because duplicate shipping option IDs" ); }, 'A TypeError should be thrown for duplicate shipping option identifiers.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': false}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': false}); assert_equals(null, request.shippingType); }, 'Shipping type should be null if shipping is explicitly not requested.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true}); assert_equals('shipping', request.shippingType); }, 'Shipping type should be \'shipping\' by default if shipping type isn\'t specified.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': false, 'shippingType': 'shipping'}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': false, 'shippingType': 'shipping'}); assert_equals(null, request.shippingType); }, 'Shipping type should be null if shipping type is specified but requestShipping is false.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': 'shipping'}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': 'shipping'}); assert_equals('shipping', request.shippingType); }, 'Shipping type should be \'shipping\' if shipping type is specified as \'shipping\'.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': 'delivery'}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': 'delivery'}); assert_equals('delivery', request.shippingType); }, 'Shipping type should be \'delivery\' if shipping type is specified as \'delivery\'.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': 'pickup'}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': 'pickup'}); assert_equals('pickup', request.shippingType); }, 'Shipping type should be \'pickup\' if shipping type is specified as \'pickup\'.'); test(function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': undefined}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': undefined}); assert_equals('shipping', request.shippingType); }, 'Shipping type should be \'shipping\' if shipping type is specified as undefined.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': undefined}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': undefined}); }, 'Undefined display items should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': []}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': []}); }, 'Empty display items should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails('total', {'value': '0'})); + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails('total', {'value': '0'})); }, 'Non-negative total value should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails('displayItems.0', {'value': '-0.01'})); + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails('displayItems.0', {'value': '-0.01'})); }, 'Negative line item value should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': undefined}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'modifiers': undefined}); }, 'Undefined modifiers should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': [{'supportedMethods': ['foo'], 'total': buildItem({'value': '0.0'})}]}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'modifiers': [{'supportedMethods': 'foo', 'total': buildItem({'value': '0.0'})}]}); }, 'Non-negative total value in PaymentDetailsModifier should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo', 'foo']}], buildDetails(), {}); -}, 'Duplicate supported payment method identifiers should not throw.'); - -test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}, {'supportedMethods': ['foo']}], buildDetails(), {}); + new PaymentRequest([{'supportedMethods': 'foo'}, {'supportedMethods': 'foo'}], buildDetails(), {}); }, 'Duplicate supported payment method identifiers in separate methodData objects should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': [{'supportedMethods': ['foo', 'foo']}]}); -}, 'Duplicate supported payment method identifiers in modifiers should not throw.'); - -test(function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': [{'supportedMethods': ['foo']}, {'supportedMethods': ['foo']}]}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'modifiers': [{'supportedMethods': 'foo'}, {'supportedMethods': 'foo'}]}); }, 'Duplicate supported payment method identifiers in separate methoData objects of modifiers should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['https://android.com/pay'], 'data': {'environment': 'TEST', 'merchantName': 'Merchant Inc', 'merchantId': '123', 'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'], 'paymentMethodTokenizationParameters': {'tokenizationType': 'GATEWAY_TOKEN', 'parameters': {'key': 'value'}}}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'https://android.com/pay', 'data': {'environment': 'TEST', 'merchantName': 'Merchant Inc', 'merchantId': '123', 'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'], 'paymentMethodTokenizationParameters': {'tokenizationType': 'GATEWAY_TOKEN', 'parameters': {'key': 'value'}}}}], buildDetails()); }, 'Android Pay parameters for test environment with gateway token should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['https://android.com/pay'], 'data': {'environment': 'PRODUCTION', 'merchantName': 'Merchant Inc', 'merchantId': '123', 'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'], 'paymentMethodTokenizationParameters': {'tokenizationType': 'NETWORK_TOKEN', 'parameters': {'key': 'value'}}}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'https://android.com/pay', 'data': {'environment': 'PRODUCTION', 'merchantName': 'Merchant Inc', 'merchantId': '123', 'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'], 'paymentMethodTokenizationParameters': {'tokenizationType': 'NETWORK_TOKEN', 'parameters': {'key': 'value'}}}}], buildDetails()); }, 'Android Pay parameters for produciton environment with network token should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['basic-card'], 'data': {'supportedTypes': ['debit'], 'supportedNetworks': ['visa']}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'basic-card', 'data': {'supportedTypes': ['debit'], 'supportedNetworks': ['visa']}}], buildDetails()); }, 'Basic card parameters should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['basic-card'], 'data': {'supportedTypes': [], 'supportedNetworks': []}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'basic-card', 'data': {'supportedTypes': [], 'supportedNetworks': []}}], buildDetails()); }, 'Empty basic card parameters should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['not-basic-card'], 'data': {'supportedTypes': 0, 'supportedNetworks': 'foo'}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'not-basic-card', 'data': {'supportedTypes': 0, 'supportedNetworks': 'foo'}}], buildDetails()); }, 'Invalid basic card parameters should not throw when method name is not "basic-card".'); test(function() { - new PaymentRequest([{'supportedMethods': ['basic-card'], 'data': {'supportedTypes': 0, 'supportedNetworks': 'foo'}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'basic-card', 'data': {'supportedTypes': 0, 'supportedNetworks': 'foo'}}], buildDetails()); }, 'Invalid basic card parameters should not throw even when method name is "basic-card".'); test(function() { - new PaymentRequest([{'supportedMethods': ['https://android.com/pay'], 'data': {'merchantName': 'Merchant Inc', 'merchantId': '123', 'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'], 'paymentMethodTokenizationParameters': {'tokenizationType': 'NETWORK_TOKEN', 'parameters': {'key': 'value'}}}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'https://android.com/pay', 'data': {'merchantName': 'Merchant Inc', 'merchantId': '123', 'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'], 'paymentMethodTokenizationParameters': {'tokenizationType': 'NETWORK_TOKEN', 'parameters': {'key': 'value'}}}}], buildDetails()); }, 'Android Pay parameters for network token without environment key should not throw.'); test(function() { - new PaymentRequest([{'supportedMethods': ['https://bobpay.com'], 'data': {'allowedCardNetworks': 0}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'https://bobpay.com', 'data': {'allowedCardNetworks': 0}}], buildDetails()); }, 'Invalid Android Pay parameters should not throw when method name is not "https://android.com/pay".'); test(function() { - new PaymentRequest([{'supportedMethods': ['https://android.com/pay'], 'data': {'allowedCardNetworks': 0}}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'https://android.com/pay', 'data': {'allowedCardNetworks': 0}}], buildDetails()); }, 'Invalid Android Pay parameters should not throw even when method name is "https://android.com/pay".'); test(function() { - new PaymentRequest([{'supportedMethods': ['foo'], 'data': []}], buildDetails()); + new PaymentRequest([{'supportedMethods': 'foo', 'data': []}], buildDetails()); }, 'Array value for payment method specific data parameter should not throw'); promise_test(function(t) { - return promise_rejects(t, 'InvalidStateError', new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails()).abort()); + return promise_rejects(t, 'InvalidStateError', new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails()).abort()); }, 'abort() without show() should reject with error'); generate_tests(assert_throws, [ @@ -298,69 +290,69 @@ ['Empty list of supported payment method identifiers should throw TypeError.', new TypeError(), function() { new PaymentRequest([], buildDetails()) }], - ['Empty supported payment method identifiers should throw TypeError.', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': []}], buildDetails()) + ['Empty supported payment method identifier should throw RangeError.', new RangeError(), function() { + new PaymentRequest([{'supportedMethods': ''}], buildDetails()) }], ['Absence of total should throw TypeError.', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'displayItems': [buildItem()]}) + new PaymentRequest([{'supportedMethods': 'foo'}], {'displayItems': [buildItem()]}) }], ['Negative total value should throw a TypeError.', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails('total', {'value': '-0.01'})) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails('total', {'value': '-0.01'})) }], ['Negative total value in PaymentDetailsModifier should throw a TypeError.', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': [{'supportedMethods': ['foo'], 'total': buildItem({'value': '-0.01'})}]}) + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'modifiers': [{'supportedMethods': 'foo', 'total': buildItem({'value': '-0.01'})}]}) }], ['Undefined supportedMethods in modifiers should throw TypeError.', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': [{'supportedMethods': undefined}]}) + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'modifiers': [{'supportedMethods': undefined}]}) }], - ['Empty supportedMethods in modifiers should throw TypeError.', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': [{'supportedMethods': []}]}) + ['Empty supportedMethods in modifiers should throw RangeError.', new RangeError(), function() { + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'modifiers': [{'supportedMethods': ''}]}) }], ['Absence of supportedMethods in modifiers should throw TypeError.', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'modifiers': [{'total': buildItem()}]}) + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'modifiers': [{'total': buildItem()}]}) }], ['Empty details should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {}) + new PaymentRequest([{'supportedMethods': 'foo'}], {}) }], ['Null items should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': null}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': null}); }], ['Null shipping options should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': null}); + new PaymentRequest([{'supportedMethods': 'foo'}], {'total': buildItem(), 'displayItems': [buildItem()], 'shippingOptions': null}); }], ['Undefined PaymentShippingType value for shppingType should throw a TypeError', new TypeError(), function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': 'invalid'}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': 'invalid'}); }], ['Null for shppingType should throw a TypeError', new TypeError(), function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': null}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': null}); }], ['Array value for shppingType should throw a TypeError', new TypeError(), function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': []}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': []}); }], ['Object value for shppingType should throw a TypeError', new TypeError(), function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': {}}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': {}}); }], ['Numeric value for shppingType should throw a TypeError', new TypeError(), function() { - var request = new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(), {'requestShipping': true, 'shippingType': 0}); + var request = new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(), {'requestShipping': true, 'shippingType': 0}); }], // Payment method specific data should be a JSON-serializable object. ['String value for payment method specific data parameter should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo'], 'data': 'foo'}], buildDetails(), {}) + new PaymentRequest([{'supportedMethods': 'foo', 'data': 'foo'}], buildDetails(), {}) }], ['Numeric value for payment method specific data parameter should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo'], 'data': 42}], buildDetails(), {}) + new PaymentRequest([{'supportedMethods': 'foo', 'data': 42}], buildDetails(), {}) }], ['Infinite JSON value for one of the payment method specific data pieces should throw', new TypeError(), function() { var infiniteData = {'foo': {}}; infiniteData.foo = infiniteData; - new PaymentRequest([{'supportedMethods': ['foo'], 'data': infiniteData}], buildDetails()) + new PaymentRequest([{'supportedMethods': 'foo', 'data': infiniteData}], buildDetails()) }], ['Null for payment method specific data parameter should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo'], 'data': null}], buildDetails()) + new PaymentRequest([{'supportedMethods': 'foo', 'data': null}], buildDetails()) }], ['Empty string for payment method specific data parameter should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo'], 'data': ''}], buildDetails()) + new PaymentRequest([{'supportedMethods': 'foo', 'data': ''}], buildDetails()) }] ]); @@ -369,51 +361,51 @@ generate_tests(assert_throws, [ // Invalid currency code formats. ['Undefined currency code in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'currency': undefined}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'currency': undefined}), {requestShipping: true}) }], // Invalid amount formats. ['Invalid amount "-" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '-'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '-'}), {requestShipping: true}) }], ['Invalid amount "notdigits" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': 'notdigits'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': 'notdigits'}), {requestShipping: true}) }], ['Invalid amount "ALSONOTDIGITS" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': 'ALSONOTDIGITS'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': 'ALSONOTDIGITS'}), {requestShipping: true}) }], ['Invalid amount "10." in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '10.'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '10.'}), {requestShipping: true}) }], ['Invalid amount ".99" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '.99'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '.99'}), {requestShipping: true}) }], ['Invalid amount "-10." in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '-10.'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '-10.'}), {requestShipping: true}) }], ['Invalid amount "-.99" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '-.99'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '-.99'}), {requestShipping: true}) }], ['Invalid amount "10-" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '10-'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '10-'}), {requestShipping: true}) }], ['Invalid amount "1-0" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '1-0'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '1-0'}), {requestShipping: true}) }], ['Invalid amount "1.0.0" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '1.0.0'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '1.0.0'}), {requestShipping: true}) }], ['Invalid amount "1/3" in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': '1/3'}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': '1/3'}), {requestShipping: true}) }], ['Empty amount in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': ''}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': ''}), {requestShipping: true}) }], ['Null amount in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': null}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': null}), {requestShipping: true}) }], ['Undefined amount in ' + detailNames[i] + ' should throw', new TypeError(), function() { - new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails(detailNames[i], {'value': undefined}), {requestShipping: true}) + new PaymentRequest([{'supportedMethods': 'foo'}], buildDetails(detailNames[i], {'value': undefined}), {requestShipping: true}) }], ]); }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png index 82123a95..70e9ba14 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-of-video-outline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.png index fd70920..ee632b57 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.txt index 877094b..818f6ce3 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-after-reload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.png index 7317e480..eae4b1e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.txt index c2a1b64..d834463 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-strict-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.png index 36e5360..144d887 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.txt index a48e324..96ed78c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (18,44) size 320x228 clip at (20,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (18,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,284) size 320x228 clip at (10,286) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,464) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.png index 369bd6e..726bd27 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.txt index 48747b1..f3af60ae 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-styling-strict-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (332,52) size 320x228 clip at (334,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (332,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.png index dcc8f55..e18ab36 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.txt index ff2db59c1..4b1b685 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls-without-preload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls/lazy-loaded-style-expected.txt index 4423ba2..0ebe34e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/lazy-loaded-style-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/lazy-loaded-style-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x300 layer at (8,8) size 400x288 clip at (10,10) size 396x284 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x288 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,99) size 384x90 - LayoutBlockFlow {DIV} at (147,0) size 90x90 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,106.50) size 384x75 + LayoutBlockFlow {DIV} at (154.50,0) size 75x75 [bgcolor=#FFFFFFE6] layer at (8,248) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,240) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index bb06713..fc5ae80 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt index 5ddccb11..a2f7ec0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.png index bb06713..fc5ae80 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.txt index 5ddccb11..a2f7ec0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png index 06ac00e5..7e49008 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt index 3d545b91..41212fa7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -24,8 +24,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -60,8 +60,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,297) size 320x228 clip at (10,299) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,477) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -98,8 +98,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,542) size 320x228 backgroundClip at (8,542) size 320x58 clip at (10,544) size 316x56 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,722) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.png index 59703ba..17bb262 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.txt index 7de9140..89745fe 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-controls-rendering-expected.txt
@@ -24,8 +24,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -59,8 +59,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,284) size 320x228 clip at (10,286) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,464) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -96,8 +96,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,524) size 320x228 backgroundClip at (8,524) size 320x76 clip at (10,526) size 316x74 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,704) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.png index dad1d19c..d3533633 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.txt index 2867c0e..edbc1b5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-display-toggle-expected.txt
@@ -18,8 +18,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,28) size 320x228 clip at (10,30) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,208) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.png index 4ef7111c..5ccb46a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.txt index 4b32b7a..ce3cd1c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-no-audio-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 352x288 layer at (8,44) size 352x276 clip at (10,46) size 348x272 LayoutButton (relative positioned) {INPUT} at (0,0) size 352x276 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,94.80) size 336x86.39 - LayoutBlockFlow {DIV} at (124.80,0) size 86.39x86.39 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,102) size 336x72 + LayoutBlockFlow {DIV} at (132,0) size 72x72 [bgcolor=#FFFFFFE6] layer at (8,272) size 352x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,228) size 352x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png index c112041..de549cf9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/full-screen-iframe-allowed-video-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png index b6b5386..59c4cc2 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-controls-timeline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png index c112041..de549cf9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/android/fullscreen/video-scrolled-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-filter-expected.png index c7ce59f..6c0a8da 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png index ca9cda3..c3a5e64 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png index 2e9b32ce..b18c0982 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png index f2c9be8..d4e39a7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/lazy-loaded-style-expected.txt index 4423ba2..0ebe34e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/lazy-loaded-style-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/lazy-loaded-style-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x300 layer at (8,8) size 400x288 clip at (10,10) size 396x284 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x288 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,99) size 384x90 - LayoutBlockFlow {DIV} at (147,0) size 90x90 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,106.50) size 384x75 + LayoutBlockFlow {DIV} at (154.50,0) size 75x75 [bgcolor=#FFFFFFE6] layer at (8,248) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,240) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index bb06713..fc5ae80 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt index 5ddccb11..a2f7ec0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png index bb06713..fc5ae80 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.txt index 5ddccb11..a2f7ec0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png index 06ac00e5..7e49008 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt index 3d545b91..41212fa7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -24,8 +24,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -60,8 +60,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,297) size 320x228 clip at (10,299) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,477) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -98,8 +98,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,542) size 320x228 backgroundClip at (8,542) size 320x58 clip at (10,544) size 316x56 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,722) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png index fd70920..ee632b57 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt index 877094b..818f6ce3 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png index 7317e480..eae4b1e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt index c2a1b64..d834463 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png index 36e5360..144d887 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt index a48e324..96ed78c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (18,44) size 320x228 clip at (20,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (18,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,284) size 320x228 clip at (10,286) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,464) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png index 369bd6e..726bd27 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt index 48747b1..f3af60ae 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (332,52) size 320x228 clip at (334,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (332,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png index dcc8f55..e18ab36 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt index ff2db59c1..4b1b685 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt index 4423ba2..0ebe34e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x300 layer at (8,8) size 400x288 clip at (10,10) size 396x284 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x288 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,99) size 384x90 - LayoutBlockFlow {DIV} at (147,0) size 90x90 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,106.50) size 384x75 + LayoutBlockFlow {DIV} at (154.50,0) size 75x75 [bgcolor=#FFFFFFE6] layer at (8,248) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,240) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index bb06713..fc5ae80 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt index 5ddccb11..a2f7ec0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png index bb06713..fc5ae80 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt index 5ddccb11..a2f7ec0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.png index 06ac00e5..7e49008 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.txt index 3d545b91..41212fa7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering-expected.txt
@@ -24,8 +24,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -60,8 +60,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,297) size 320x228 clip at (10,299) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,477) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -98,8 +98,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,542) size 320x228 backgroundClip at (8,542) size 320x58 clip at (10,544) size 316x56 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,722) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png index 59703ba..17bb262 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt index 7de9140..89745fe 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt
@@ -24,8 +24,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -59,8 +59,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,284) size 320x228 clip at (10,286) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,464) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -96,8 +96,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,524) size 320x228 backgroundClip at (8,524) size 320x76 clip at (10,526) size 316x74 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,704) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png index dad1d19c..d3533633 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt index 2867c0e..edbc1b5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt
@@ -18,8 +18,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,28) size 320x228 clip at (10,30) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,208) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png index 4ef7111c..5ccb46a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt index 4b32b7a..ce3cd1c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 352x288 layer at (8,44) size 352x276 clip at (10,46) size 348x272 LayoutButton (relative positioned) {INPUT} at (0,0) size 352x276 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,94.80) size 336x86.39 - LayoutBlockFlow {DIV} at (124.80,0) size 86.39x86.39 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,102) size 336x72 + LayoutBlockFlow {DIV} at (132,0) size 72x72 [bgcolor=#FFFFFFE6] layer at (8,272) size 352x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,228) size 352x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-after-reload-expected.png index 0b668f0..9572641 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-strict-expected.png index e8987ab..84408c0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-expected.png index fcf709f..2059245 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-strict-expected.png index 3f53f1e..aef5df62 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-without-preload-expected.png index b5eab1e2..09432703 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index 8c1f60c3..98e5b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-expected.png index 8c1f60c3..98e5b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-controls-rendering-expected.png index d88cb29..689c664 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-display-toggle-expected.png index 9b4b3db2..6838b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-no-audio-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-no-audio-expected.png index 076e549..b287b5f37 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-no-audio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/media/video-no-audio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index 8c1f60c3..98e5b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png index 8c1f60c3..98e5b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png index 0b668f0..9572641 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png index e8987ab..84408c0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png index fcf709f..2059245 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png index 3f53f1e..aef5df62 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png index b5eab1e2..09432703 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index 8c1f60c3..98e5b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png index 8c1f60c3..98e5b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png index d88cb29..689c664 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png index 9b4b3db2..6838b85 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https-expected.txt new file mode 100644 index 0000000..281823c5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS AbsoluteOrientationSensor: sensor is suspended and resumed when focus traverses from to cross-origin frame +FAIL AbsoluteOrientationSensor: sensor is not suspended when focus traverses from to same-origin frame assert_true: Not expecting event, but got reading event expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt deleted file mode 100644 index 8c8ac90..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ /dev/null
@@ -1,44 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x347 - LayoutBlockFlow {HTML} at (0,0) size 800x347.27 - LayoutBlockFlow {BODY} at (8,8) size 784x331.27 - LayoutText {#text} at (0,0) size 0x0 -layer at (8,8) size 400x327 - LayoutVideo {VIDEO} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x327.27 - LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x315 clip at (9,9) size 398x313 - LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,108.08) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] -layer at (8,275) size 400x48 - LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 - LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 32x18 - text run at (0,15) width 32: "0:00" - LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 41x18 - text run at (0,15) width 41: "/ 0:09" - LayoutBlockFlow {DIV} at (91.17,48) size 212.83x0 - LayoutButton {INPUT} at (352,0) size 48x48 -layer at (312,275) size 48x48 transparent - LayoutButton {INPUT} at (304,0) size 48x48 [color=#7F7F7F] -layer at (8,323) size 400x12 - LayoutSlider {INPUT} at (0,315.27) size 400x12 [color=#909090] - LayoutFlexibleBox {DIV} at (16,0) size 368x4 -layer at (24,323) size 368x4 - LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] -layer at (24,319) size 12x12 - LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] -layer at (24,323) size 368x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 -layer at (24,323) size 0x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] -layer at (24,323) size 368x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.png new file mode 100644 index 0000000..4c42fc7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/background/background-large-position-and-size-remains-stable-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/background/background-large-position-and-size-remains-stable-expected.png index e2678d2..701c5a9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/background/background-large-position-and-size-remains-stable-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/background/background-large-position-and-size-remains-stable-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png index 6108655e..30350ba8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-of-video-outline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.png index ba805fa..19e749d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.txt index 1687625..3262bc4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-after-reload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,42) size 320x228 clip at (9,43) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,222) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.png index 1458423c..5f2511e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.txt index 75051a17..e8de402 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-strict-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,50) size 320x228 clip at (9,51) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,230) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.png index 75c5d98..827ce26 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.txt index 3183e0b1..837dca6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (18,42) size 320x228 clip at (19,43) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (18,222) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,282) size 320x228 clip at (9,283) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,462) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.png index f5c2162..ac08922 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.txt index 75390eaa..dd68b633a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-styling-strict-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,50) size 320x228 clip at (9,51) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,230) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (332,50) size 320x228 clip at (333,51) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (332,230) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.png index 5cbcb66..1768ed6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.txt index d7acddb..74888269 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls-without-preload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,42) size 320x228 clip at (9,43) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,222) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls/lazy-loaded-style-expected.txt index 346d9e5..8415a36 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/lazy-loaded-style-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/lazy-loaded-style-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x300 layer at (8,8) size 400x288 clip at (9,9) size 398x286 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x288 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,98.50) size 384x90 - LayoutBlockFlow {DIV} at (147,0) size 90x90 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,106) size 384x75 + LayoutBlockFlow {DIV} at (154.50,0) size 75x75 [bgcolor=#FFFFFFE6] layer at (8,248) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,240) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index 25f8371..522b1b9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt index e661bcc..17284320 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -13,10 +13,10 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x327 LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x315 clip at (9,9) size 398x313 transparent - LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (1px inset #D8D8D8) (1px inset #D1D1D1) (1px inset #BABABA) (1px inset #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,108.08) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] +layer at (8,8) size 400x315 clip at (9,9) size 398x313 + LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,116.25) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] @@ -40,5 +40,5 @@ LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 layer at (24,323) size 0x4 LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] -layer at (24,323) size 367x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 367x4 [bgcolor=#FFFFFF8A] +layer at (24,323) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.png index 25f8371..522b1b9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.txt index 8c8ac90..17284320 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (9,9) size 398x313 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,108.08) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.25) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.png index 7e66da1..0998242 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.txt index 301ef01f..eaee44d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-controls-rendering-expected.txt
@@ -24,8 +24,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,42) size 320x228 clip at (9,43) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,222) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] @@ -59,8 +59,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,282) size 320x228 clip at (9,283) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,462) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] @@ -96,8 +96,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,522) size 320x228 backgroundClip at (8,522) size 320x78 clip at (9,523) size 318x77 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,702) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.png index ff391b0f..1d5c62c7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.txt index b8d892ca..d298c95 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-display-toggle-expected.txt
@@ -18,8 +18,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,26) size 320x228 clip at (9,27) size 318x226 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,77.50) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,83.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,206) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.png index 6f0c857..a302b76 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.txt index 8099eaf..560048aa 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-no-audio-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 352x288 layer at (8,42) size 352x276 clip at (9,43) size 350x274 LayoutButton (relative positioned) {INPUT} at (0,0) size 352x276 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,94.30) size 336x86.39 - LayoutBlockFlow {DIV} at (124.80,0) size 86.39x86.39 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,101.50) size 336x72 + LayoutBlockFlow {DIV} at (132,0) size 72x72 [bgcolor=#FFFFFFE6] layer at (8,270) size 352x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,228) size 352x48 LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png index 636445b..a377a59b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-expected.png index 74d6d3e..73f03c55 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png index 5407464..c7a5478 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png index 1503675..89a557b5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png index a714ed1..d7e0af9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt deleted file mode 100644 index 8c8ac90..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/new-remote-playback-pipeline/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ /dev/null
@@ -1,44 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x347 - LayoutBlockFlow {HTML} at (0,0) size 800x347.27 - LayoutBlockFlow {BODY} at (8,8) size 784x331.27 - LayoutText {#text} at (0,0) size 0x0 -layer at (8,8) size 400x327 - LayoutVideo {VIDEO} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x327.27 - LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x315 clip at (9,9) size 398x313 - LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,108.08) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] -layer at (8,275) size 400x48 - LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 - LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 32x18 - text run at (0,15) width 32: "0:00" - LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 41x18 - text run at (0,15) width 41: "/ 0:09" - LayoutBlockFlow {DIV} at (91.17,48) size 212.83x0 - LayoutButton {INPUT} at (352,0) size 48x48 -layer at (312,275) size 48x48 transparent - LayoutButton {INPUT} at (304,0) size 48x48 [color=#7F7F7F] -layer at (8,323) size 400x12 - LayoutSlider {INPUT} at (0,315.27) size 400x12 [color=#909090] - LayoutFlexibleBox {DIV} at (16,0) size 368x4 -layer at (24,323) size 368x4 - LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] -layer at (24,319) size 12x12 - LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] -layer at (24,323) size 368x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 -layer at (24,323) size 0x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] -layer at (24,323) size 368x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt deleted file mode 100644 index 8c8ac90..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ /dev/null
@@ -1,44 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x347 - LayoutBlockFlow {HTML} at (0,0) size 800x347.27 - LayoutBlockFlow {BODY} at (8,8) size 784x331.27 - LayoutText {#text} at (0,0) size 0x0 -layer at (8,8) size 400x327 - LayoutVideo {VIDEO} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x327.27 - LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x327 - LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 -layer at (8,8) size 400x315 clip at (9,9) size 398x313 - LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] - LayoutFlexibleBox (anonymous) at (8,108.08) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] -layer at (8,275) size 400x48 - LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 - LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 32x18 - text run at (0,15) width 32: "0:00" - LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] - LayoutText {#text} at (0,15) size 41x18 - text run at (0,15) width 41: "/ 0:09" - LayoutBlockFlow {DIV} at (91.17,48) size 212.83x0 - LayoutButton {INPUT} at (352,0) size 48x48 -layer at (312,275) size 48x48 transparent - LayoutButton {INPUT} at (304,0) size 48x48 [color=#7F7F7F] -layer at (8,323) size 400x12 - LayoutSlider {INPUT} at (0,315.27) size 400x12 [color=#909090] - LayoutFlexibleBox {DIV} at (16,0) size 368x4 -layer at (24,323) size 368x4 - LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] -layer at (24,319) size 12x12 - LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] -layer at (24,323) size 368x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 -layer at (24,323) size 0x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] -layer at (24,323) size 368x4 - LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/background/background-large-position-and-size-remains-stable-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/background/background-large-position-and-size-remains-stable-expected.png index 2901946..82441b96 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/background/background-large-position-and-size-remains-stable-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css3/background/background-large-position-and-size-remains-stable-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-of-video-outline-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-of-video-outline-expected.png index 4229eb8..d856bf8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-of-video-outline-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-of-video-outline-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.png index 7639b23..b841722 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.txt index 81051ce..45838e42 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-after-reload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.png index 4d7f2bd6..f8581609 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.txt index 17b040ef..bfb9e21 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-strict-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.png index e4217c3..106c244d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.txt index c74e1f460..e7e3559 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (18,44) size 320x228 clip at (20,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (18,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,284) size 320x228 clip at (10,286) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,464) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.png index cf80833..cbb47c1c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.txt index 00bb8d8..1c60fd4 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-styling-strict-expected.txt
@@ -23,8 +23,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,52) size 320x228 clip at (10,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -58,8 +58,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (332,52) size 320x228 clip at (334,54) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (332,232) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.png index dee9996..7a30966 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.txt index cf97b55c92..96454bf7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls-without-preload-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls/lazy-loaded-style-expected.txt index afc253c..b099dfa 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls/lazy-loaded-style-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls/lazy-loaded-style-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x300 layer at (8,8) size 400x288 clip at (10,10) size 396x284 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x288 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,99) size 384x90 - LayoutBlockFlow {DIV} at (147,0) size 90x90 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,106.50) size 384x75 + LayoutBlockFlow {DIV} at (154.50,0) size 75x75 [bgcolor=#FFFFFFE6] layer at (8,248) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,240) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index 012a5b8..11b43f5d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt index 8d9c7c8..b6958982 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.png index 012a5b8..11b43f5d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.txt index 8d9c7c8..b6958982 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -15,8 +15,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 layer at (8,8) size 400x315 clip at (10,10) size 396x311 LayoutButton (relative positioned) {INPUT} at (0,0) size 400x315.27 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,108.58) size 384x98.09 - LayoutBlockFlow {DIV} at (142.95,0) size 98.09x98.09 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,116.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] layer at (8,275) size 400x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,267.27) size 400x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.png index 20678bc..eac729c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.txt index 696e5bdd..049f933 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-controls-rendering-expected.txt
@@ -24,8 +24,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,44) size 320x228 clip at (10,46) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,224) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -59,8 +59,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,284) size 320x228 clip at (10,286) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,464) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] @@ -96,8 +96,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,524) size 320x228 backgroundClip at (8,524) size 320x76 clip at (10,526) size 316x74 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,704) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.png index d2385ea..3bcb7f1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.txt index 12a5739..f804650f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-display-toggle-expected.txt
@@ -18,8 +18,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 320x240 layer at (8,28) size 320x228 clip at (10,30) size 316x224 LayoutButton (relative positioned) {INPUT} at (0,0) size 320x228 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,78) size 304x72 - LayoutBlockFlow {DIV} at (116,0) size 72x72 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,84) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] layer at (8,208) size 320x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,180) size 320x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.png index 37da4bdf..a063fe1a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.txt index 3e9f4ab..0b6032b5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-no-audio-expected.txt
@@ -19,8 +19,8 @@ LayoutFlexibleBox {DIV} at (0,0) size 352x288 layer at (8,44) size 352x276 clip at (10,46) size 348x272 LayoutButton (relative positioned) {INPUT} at (0,0) size 352x276 [border: (2px outset #C0C0C0)] - LayoutFlexibleBox (anonymous) at (8,94.80) size 336x86.39 - LayoutBlockFlow {DIV} at (124.80,0) size 86.39x86.39 [bgcolor=#FFFFFFE6] + LayoutFlexibleBox (anonymous) at (8,102) size 336x72 + LayoutBlockFlow {DIV} at (132,0) size 72x72 [bgcolor=#FFFFFFE6] layer at (8,272) size 352x48 LayoutFlexibleBox (relative positioned) {DIV} at (0,228) size 352x48 LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF]
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png index 0356f4f6..89f7974 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png index 312375b..254957f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-expected.png new file mode 100644 index 0000000..19a2d45 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png index 37ee211..e711e03 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png index 2407548e..140832ec 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png index 025412c..e713b59 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/reporting-observer/resources/intervention.js b/third_party/WebKit/LayoutTests/reporting-observer/resources/intervention.js index cf8c2fc..4b2fe00 100644 --- a/third_party/WebKit/LayoutTests/reporting-observer/resources/intervention.js +++ b/third_party/WebKit/LayoutTests/reporting-observer/resources/intervention.js
@@ -4,9 +4,12 @@ var targetX = rect.left + rect.width / 2; var targetY = rect.top + rect.height / 2; - document.body.addEventListener('touchstart', function(e) { + var pd = function(e) { e.preventDefault(); - }); + document.body.removeEventListener('touchstart', pd); + }; + + document.body.addEventListener('touchstart', pd); var touches = [new Touch({identifier: 1, clientX: targetX, clientY: targetY, target: target})]; var touchEventInit = {
diff --git a/third_party/WebKit/LayoutTests/reporting-observer/take-records.html b/third_party/WebKit/LayoutTests/reporting-observer/take-records.html new file mode 100644 index 0000000..94b4ab9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/reporting-observer/take-records.html
@@ -0,0 +1,31 @@ +<!doctype html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="resources/intervention.js"></script> + +<div id="target" style="padding: 10px; background-color: blue;"> + <p>Testing ReportingObserver's takeRecords().</p> +</div> + +<script> +async_test(function(test) { + var observer = new ReportingObserver(function(reports, observer) { + test.step(function() { + // Only 1 report should be observed, since the first report should have + // been returned by takeRecords(). + assert_equals(reports.length, 1); + }); + + test.done(); + }, { buffered: true }); + observer.observe(); + + // Generate two reports, one before and one after calling takeRecords(). + causeIntervention(); + var reports = observer.takeRecords(); + causeIntervention(); + + assert_equals(reports.length, 1); + assert_equals(reports[0].type, "intervention"); +}, "takeRecords"); +</script>
diff --git a/third_party/WebKit/LayoutTests/reporting-observer/type-filtering.html b/third_party/WebKit/LayoutTests/reporting-observer/type-filtering.html new file mode 100644 index 0000000..cf77153 --- /dev/null +++ b/third_party/WebKit/LayoutTests/reporting-observer/type-filtering.html
@@ -0,0 +1,51 @@ +<!doctype html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="resources/intervention.js"></script> + +<div id="target" style="padding: 10px; background-color: blue;"> + <p>Testing ReportingObserver's |types| option.</p> +</div> + +<script> +async_test(function(test) { + var observer1 = new ReportingObserver(function(reports, observer) { + test.step(function() { + // Only the deprecation report should be observed, as specified by the + // |types| option. + assert_equals(reports.length, 1); + assert_equals(reports[0].type, "deprecation"); + assert_equals(reports[0].body.id, "PrefixedWindowURL"); + }); + + test.done(); + }, { types: [ "deprecation" ] }); + observer1.observe(); + + // Generate a deprecation report and an intervention report. + window.webkitURL; // id = "PrefixedWindowURL" + causeIntervention(); + + observer1.disconnect(); +}, "Types filtered"); + + +async_test(function(test) { + var observer2 = new ReportingObserver(function(reports, observer) { + test.step(function() { + // Both reports should be observed, since there is no |types| filter + // specified. + assert_equals(reports.length, 2); + }); + + test.done(); + }); + observer2.observe(); + + // Generate a deprecation report and an intervention report. + window.webkitStorageInfo; + causeIntervention(); + + observer2.disconnect(); +}, "Types accepted by default"); +</script>
diff --git a/third_party/WebKit/LayoutTests/resources/gesture-util.js b/third_party/WebKit/LayoutTests/resources/gesture-util.js index 2c184870..84fbde0d 100644 --- a/third_party/WebKit/LayoutTests/resources/gesture-util.js +++ b/third_party/WebKit/LayoutTests/resources/gesture-util.js
@@ -90,6 +90,34 @@ }); } +function mouseDownAt(xPosition, yPosition) { + return new Promise(function(resolve, reject) { + if (chrome && chrome.gpuBenchmarking) { + chrome.gpuBenchmarking.pointerActionSequence([ + {source: 'mouse', + actions: [ + { name: 'pointerDown', x: xPosition, y: yPosition }, + ]}], resolve); + } else { + reject('This test requires chrome.gpuBenchmarking'); + } + }); +} + +function mouseUpAt(xPosition, yPosition) { + return new Promise(function(resolve, reject) { + if (chrome && chrome.gpuBenchmarking) { + chrome.gpuBenchmarking.pointerActionSequence([ + {source: 'mouse', + actions: [ + { name: 'pointerUp', x: xPosition, y: yPosition }, + ]}], resolve); + } else { + reject('This test requires chrome.gpuBenchmarking'); + } + }); +} + // Simulate a mouse click on point. function mouseClickOn(x, y) { return new Promise((resolve, reject) => {
diff --git a/third_party/WebKit/LayoutTests/shapedetection/detected-boundingBox-read-only.html b/third_party/WebKit/LayoutTests/shapedetection/detected-boundingBox-read-only.html index 31a58ff8..57bef86 100644 --- a/third_party/WebKit/LayoutTests/shapedetection/detected-boundingBox-read-only.html +++ b/third_party/WebKit/LayoutTests/shapedetection/detected-boundingBox-read-only.html
@@ -2,9 +2,10 @@ <script src="../resources/testharness.js"></script> <script src="../resources/testharnessreport.js"></script> <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/shape_detection/public/mojom/facedetection.mojom.js"></script> +<script src="file:///gen/services/shape_detection/public/mojom/barcodedetection_provider.mojom.js"></script> <script src="file:///gen/services/shape_detection/public/mojom/facedetection_provider.mojom.js"></script> <script src="resources/big-buffer-helpers.js"></script> +<script src="resources/mock-barcodedetection.js"></script> <script src="resources/mock-facedetection.js"></script> <script> @@ -32,15 +33,15 @@ }); }; -function CheckDetectedFaceReadOnlyObjects(detectedFaces) { - assert_readonly(detectedFaces[0].boundingBox, 'x'); - assert_readonly(detectedFaces[0].boundingBox, 'y'); - assert_readonly(detectedFaces[0].boundingBox, 'width'); - assert_readonly(detectedFaces[0].boundingBox, 'height'); - assert_readonly(detectedFaces[0].boundingBox, 'top'); - assert_readonly(detectedFaces[0].boundingBox, 'right'); - assert_readonly(detectedFaces[0].boundingBox, 'bottom'); - assert_readonly(detectedFaces[0].boundingBox, 'left'); +function CheckDetectedReadOnlyBoundingBoxes(detectedObject) { + assert_readonly(detectedObject[0].boundingBox, 'x'); + assert_readonly(detectedObject[0].boundingBox, 'y'); + assert_readonly(detectedObject[0].boundingBox, 'width'); + assert_readonly(detectedObject[0].boundingBox, 'height'); + assert_readonly(detectedObject[0].boundingBox, 'top'); + assert_readonly(detectedObject[0].boundingBox, 'right'); + assert_readonly(detectedObject[0].boundingBox, 'bottom'); + assert_readonly(detectedObject[0].boundingBox, 'left'); } // These tests verify that detectedFace's boundingBox should be DOMRectReadOnly. @@ -49,7 +50,13 @@ "Face - detectedFace.boundingBox should be DOMRectReadOnly", () => { return new FaceDetector(); }, mockFaceDetectionProvider, - CheckDetectedFaceReadOnlyObjects + CheckDetectedReadOnlyBoundingBoxes + ], + [ + "Barcode - detectedBarcode.boundingBox should be DOMRectReadOnly", + () => { return new BarcodeDetector(); }, + mockBarcodeDetectionProvider, + CheckDetectedReadOnlyBoundingBoxes ] ]);
diff --git a/third_party/WebKit/LayoutTests/svg/zoom/page/zoom-background-image-tiled-expected.png b/third_party/WebKit/LayoutTests/svg/zoom/page/zoom-background-image-tiled-expected.png index 3da19f18..8012ede 100644 --- a/third_party/WebKit/LayoutTests/svg/zoom/page/zoom-background-image-tiled-expected.png +++ b/third_party/WebKit/LayoutTests/svg/zoom/page/zoom-background-image-tiled-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png index f077bcc..39e68bc 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png index cc0a68b5..a74bde2 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png index 7d3e3b434..101b27a 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png index cd5c8961..dfd49fd 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png index 6fdb944..0986d47 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png index 3a76580..ae3b23bd 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-expected.png deleted file mode 100644 index cc5053a..0000000 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png index 5f12845..5ebe727 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png index c678a34e..ef0b751 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png index 8b926716..c593a283 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png index 0ba7e83..4039258 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png index 19e07c8..42913af 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/README.txt b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/README.txt new file mode 100644 index 0000000..ef3197a --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/README.txt
@@ -0,0 +1,2 @@ +# This suite runs tests with --enable-features=UserActivationV2. +# See http://bit.ly/2E9E3IA
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-click-expected.txt b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-click-expected.txt new file mode 100644 index 0000000..d5d3ba3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-click-expected.txt
@@ -0,0 +1,11 @@ +PASS undefined is undefined. +PASS results.webAudio is "running" +PASS successfullyParsed is true + +TEST COMPLETE + + +============== Back Forward List ============== + http://127.0.0.1:8000/media/autoplay/document-user-activation-navigation-click.html +curr-> http://127.0.0.1:8000/media/autoplay/resources/test-autoplay.html +===============================================
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-keypress-expected.txt b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-keypress-expected.txt new file mode 100644 index 0000000..cd0091580 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-keypress-expected.txt
@@ -0,0 +1,11 @@ +PASS undefined is undefined. +PASS results.webAudio is "running" +PASS successfullyParsed is true + +TEST COMPLETE + + +============== Back Forward List ============== + http://127.0.0.1:8000/media/autoplay/document-user-activation-navigation-keypress.html +curr-> http://127.0.0.1:8000/media/autoplay/resources/test-autoplay.html +===============================================
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-tap-expected.txt b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-tap-expected.txt new file mode 100644 index 0000000..5000d5a7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/http/tests/media/autoplay/document-user-activation-navigation-tap-expected.txt
@@ -0,0 +1,11 @@ +PASS undefined is undefined. +PASS results.webAudio is "running" +PASS successfullyParsed is true + +TEST COMPLETE + + +============== Back Forward List ============== + http://127.0.0.1:8000/media/autoplay/document-user-activation-navigation-tap.html +curr-> http://127.0.0.1:8000/media/autoplay/resources/test-autoplay.html +===============================================
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index beb74c5..785c98e 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -5580,6 +5580,7 @@ method constructor method disconnect method observe + method takeRecords interface Request attribute @@toStringTag getter bodyUsed @@ -9152,6 +9153,7 @@ getter depthFar getter depthNear getter device + getter environmentBlendMode getter exclusive getter onblur getter onend
diff --git a/third_party/WebKit/LayoutTests/xr/xrSession_environmentBlendMode.html b/third_party/WebKit/LayoutTests/xr/xrSession_environmentBlendMode.html new file mode 100644 index 0000000..6019e5b --- /dev/null +++ b/third_party/WebKit/LayoutTests/xr/xrSession_environmentBlendMode.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script> +<script src="../xr/resources/xr-device-mocking.js"></script> +<script src="../xr/resources/xr-test-utils.js"></script> +<script src="../xr/resources/test-constants.js"></script> +<canvas id="webgl-canvas"></canvas> + +<script> +let fakeDevices = fakeXRDevices(); + +xr_session_promise_test( (session, t) => { + t.step(() => { + assert_equals(session.environmentBlendMode, 'opaque'); + }); +}, fakeDevices["FakeGooglePixelPhone"], [ + { exclusive: true }, + { outputContext: getOutputContext() } +], +"environmentBlendMode is correct for a VR device"); + +// TODO(https://crbug.com/828321): Enable once session options for AR are in place. +/*xr_session_promise_test( (session, t) => { + t.step(() => { + assert_equals(session.environmentBlendMode, 'alpha-blend'); + }); +}, fakeDevices["FakeARPhone"], [ + { ar: true, outputContext: getOutputContext() } +], +"environmentBlendMode is correct for an AR device");*/ + +</script>
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index 1de41c3..03bd420d 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@ License: Apache 2.0 License File: LICENSE Version: 0 -Revision: e5be80532b5d998813f9db952d2cc5401b1532df +Revision: bd40a41cc142b36c73b881099d08a9d83f7f4780 Security Critical: yes Description:
diff --git a/third_party/abseil-cpp/WORKSPACE b/third_party/abseil-cpp/WORKSPACE index 9c95065..89a80bbf 100644 --- a/third_party/abseil-cpp/WORKSPACE +++ b/third_party/abseil-cpp/WORKSPACE
@@ -1,13 +1,13 @@ workspace(name = "com_google_absl") # Bazel toolchains http_archive( - name = "bazel_toolchains", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/f8847f64e6950e8ab9fde1c0aba768550b0d9ab2.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/f8847f64e6950e8ab9fde1c0aba768550b0d9ab2.tar.gz", - ], - strip_prefix = "bazel-toolchains-f8847f64e6950e8ab9fde1c0aba768550b0d9ab2", - sha256 = "794366f51fea224b3656a0b0f8f1518e739748646523a572fcd3d68614a0e670", + name = "bazel_toolchains", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/2cec6c9f6d12224e93d9b3f337b24e41602de3ba.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/2cec6c9f6d12224e93d9b3f337b24e41602de3ba.tar.gz", + ], + strip_prefix = "bazel-toolchains-2cec6c9f6d12224e93d9b3f337b24e41602de3ba", + sha256 = "9b8d85b61d8945422e86ac31e4d4d2d967542c080d1da1b45364da7fd6bdd638", ) # GoogleTest/GoogleMock framework. Used by most unit-tests. @@ -15,6 +15,7 @@ name = "com_google_googletest", urls = ["https://github.com/google/googletest/archive/4e4df226fc197c0dda6e37f5c8c3845ca1e73a49.zip"], strip_prefix = "googletest-4e4df226fc197c0dda6e37f5c8c3845ca1e73a49", + sha256 = "d4179caf54410968d1fff0b869e7d74803dd30209ee6645ccf1ca65ab6cf5e5a", ) # Google benchmark. @@ -22,6 +23,7 @@ name = "com_github_google_benchmark", urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"], strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be", + sha256 = "59f918c8ccd4d74b6ac43484467b500f1d64b40cc1010daa055375b322a43ba3", ) # RE2 regular-expression framework. Used by some unit-tests. @@ -29,4 +31,5 @@ name = "com_googlesource_code_re2", urls = ["https://github.com/google/re2/archive/6cf8ccd82dbaab2668e9b13596c68183c9ecd13f.zip"], strip_prefix = "re2-6cf8ccd82dbaab2668e9b13596c68183c9ecd13f", + sha256 = "279a852219dbfc504501775596089d30e9c0b29664ce4128b0ac4c841471a16a", )
diff --git a/third_party/abseil-cpp/absl/LTS.md b/third_party/abseil-cpp/absl/LTS.md new file mode 100644 index 0000000..f7be0997 --- /dev/null +++ b/third_party/abseil-cpp/absl/LTS.md
@@ -0,0 +1,13 @@ +# Long Term Support (LTS) Branches + +This repository contains periodic snapshots of the Abseil codebase that are +Long Term Support (LTS) branches. An LTS branch allows you to use a known +version of Abseil without interfering with other projects which may also, in +turn, use Abseil. (For more information about our releases, see the +[Abseil Release Management](https://abseil.io/about/releases) guide. + +## LTS Branches + +The following lists LTS branches and the date they have been released: + +* [LTS Branch June 18, 2018](https://github.com/abseil/abseil-cpp/tree/lts_2018_06_18/)
diff --git a/third_party/abseil-cpp/absl/base/BUILD.bazel b/third_party/abseil-cpp/absl/base/BUILD.bazel index 1e93d97..d117a4f 100644 --- a/third_party/abseil-cpp/absl/base/BUILD.bazel +++ b/third_party/abseil-cpp/absl/base/BUILD.bazel
@@ -371,11 +371,6 @@ size = "small", srcs = ["internal/sysinfo_test.cc"], copts = ABSL_TEST_COPTS, - tags = [ - "no_test_android_arm", - "no_test_android_arm64", - "no_test_android_x86", - ], deps = [ ":base", "//absl/synchronization",
diff --git a/third_party/abseil-cpp/absl/base/internal/identity.h b/third_party/abseil-cpp/absl/base/internal/identity.h index a6734b4..a1a5d70a 100644 --- a/third_party/abseil-cpp/absl/base/internal/identity.h +++ b/third_party/abseil-cpp/absl/base/internal/identity.h
@@ -27,7 +27,7 @@ template <typename T> using identity_t = typename identity<T>::type; -} // namespace internal -} // namespace absl +} // namespace internal +} // namespace absl #endif // ABSL_BASE_INTERNAL_IDENTITY_H_
diff --git a/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h b/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h index 5f65821..5c6cc7f 100644 --- a/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h +++ b/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h
@@ -84,7 +84,7 @@ inline void absl::base_internal::SpinLockDelay( std::atomic<uint32_t> *w, uint32_t value, int loop, - base_internal::SchedulingMode scheduling_mode) { + absl::base_internal::SchedulingMode scheduling_mode) { AbslInternalSpinLockDelay(w, value, loop, scheduling_mode); }
diff --git a/third_party/abseil-cpp/absl/base/macros.h b/third_party/abseil-cpp/absl/base/macros.h index afa3030..ca3d5edb 100644 --- a/third_party/abseil-cpp/absl/base/macros.h +++ b/third_party/abseil-cpp/absl/base/macros.h
@@ -194,8 +194,9 @@ #if defined(NDEBUG) #define ABSL_ASSERT(expr) (false ? (void)(expr) : (void)0) #else -#define ABSL_ASSERT(expr) \ - (ABSL_PREDICT_TRUE((expr)) ? (void)0 : [] { assert(false && #expr); }()) +#define ABSL_ASSERT(expr) \ + (ABSL_PREDICT_TRUE((expr)) ? (void)0 \ + : [] { assert(false && #expr); }()) // NOLINT #endif #endif // ABSL_BASE_MACROS_H_
diff --git a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc index 5977bc9..24f2174 100644 --- a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc +++ b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc
@@ -63,18 +63,34 @@ } BENCHMARK(BM_StdVectorFill)->Range(0, 1024); +// The purpose of the next two benchmarks is to verify that +// absl::InlinedVector is efficient when moving is more efficent than +// copying. To do so, we use strings that are larger than the short +// std::string optimization. bool StringRepresentedInline(std::string s) { const char* chars = s.data(); std::string s1 = std::move(s); return s1.data() != chars; } +int GetNonShortStringOptimizationSize() { + for (int i = 24; i <= 192; i *= 2) { + if (!StringRepresentedInline(std::string(i, 'A'))) { + return i; + } + } + ABSL_RAW_LOG( + FATAL, + "Failed to find a std::string larger than the short std::string optimization"); + return -1; +} + void BM_InlinedVectorFillString(benchmark::State& state) { const int len = state.range(0); - std::string strings[4] = {"a quite long string", - "another long string", - "012345678901234567", - "to cause allocation"}; + const int no_sso = GetNonShortStringOptimizationSize(); + std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'), + std::string(no_sso, 'C'), std::string(no_sso, 'D')}; + for (auto _ : state) { absl::InlinedVector<std::string, 8> v; for (int i = 0; i < len; i++) { @@ -87,10 +103,10 @@ void BM_StdVectorFillString(benchmark::State& state) { const int len = state.range(0); - std::string strings[4] = {"a quite long string", - "another long string", - "012345678901234567", - "to cause allocation"}; + const int no_sso = GetNonShortStringOptimizationSize(); + std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'), + std::string(no_sso, 'C'), std::string(no_sso, 'D')}; + for (auto _ : state) { std::vector<std::string> v; for (int i = 0; i < len; i++) { @@ -98,11 +114,6 @@ } } state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len); - // The purpose of the benchmark is to verify that inlined vector is - // efficient when moving is more efficent than copying. To do so, we - // use strings that are larger than the small std::string optimization. - ABSL_RAW_CHECK(!StringRepresentedInline(strings[0]), - "benchmarked with strings that are too small"); } BENCHMARK(BM_StdVectorFillString)->Range(0, 1024);
diff --git a/third_party/abseil-cpp/absl/memory/BUILD.bazel b/third_party/abseil-cpp/absl/memory/BUILD.bazel index d5c6226..46f47b1 100644 --- a/third_party/abseil-cpp/absl/memory/BUILD.bazel +++ b/third_party/abseil-cpp/absl/memory/BUILD.bazel
@@ -18,6 +18,7 @@ "//absl:copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_TEST_COPTS", + "ABSL_EXCEPTIONS_FLAG", ) package(default_visibility = ["//visibility:public"]) @@ -45,3 +46,16 @@ "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "memory_exception_safety_test", + srcs = [ + "memory_exception_safety_test.cc", + ], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + deps = [ + ":memory", + "//absl/base:exception_safety_testing", + "@com_google_googletest//:gtest_main", + ], +)
diff --git a/third_party/abseil-cpp/absl/memory/CMakeLists.txt b/third_party/abseil-cpp/absl/memory/CMakeLists.txt index 21bfc87..5958f5c52 100644 --- a/third_party/abseil-cpp/absl/memory/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/memory/CMakeLists.txt
@@ -49,4 +49,23 @@ ) +# test memory_exception_safety_test +set(MEMORY_EXCEPTION_SAFETY_TEST_SRC "memory_exception_safety_test.cc") +set(MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES + absl::memory + absl_base_internal_exception_safety_testing +) + +absl_test( + TARGET + memory_exception_safety_test + SOURCES + ${MEMORY_EXCEPTION_SAFETY_TEST_SRC} + PUBLIC_LIBRARIES + ${MEMORY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${ABSL_EXCEPTIONS_FLAG} +) + +
diff --git a/third_party/abseil-cpp/absl/memory/memory_exception_safety_test.cc b/third_party/abseil-cpp/absl/memory/memory_exception_safety_test.cc new file mode 100644 index 0000000..55e8f36 --- /dev/null +++ b/third_party/abseil-cpp/absl/memory/memory_exception_safety_test.cc
@@ -0,0 +1,49 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/memory/memory.h" + +#include "gtest/gtest.h" +#include "absl/base/internal/exception_safety_testing.h" + +namespace absl { +namespace { + +using Thrower = ::testing::ThrowingValue<>; + +TEST(MakeUnique, CheckForLeaks) { + constexpr int kValue = 321; + constexpr size_t kLength = 10; + auto tester = testing::MakeExceptionSafetyTester() + .WithInitialValue(Thrower(kValue)) + // Ensures make_unique does not modify the input. The real + // test, though, is ConstructorTracker checking for leaks. + .WithInvariants(testing::strong_guarantee); + + EXPECT_TRUE(tester.Test([](Thrower* thrower) { + static_cast<void>(absl::make_unique<Thrower>(*thrower)); + })); + + EXPECT_TRUE(tester.Test([](Thrower* thrower) { + static_cast<void>(absl::make_unique<Thrower>(std::move(*thrower))); + })); + + // Test T[n] overload + EXPECT_TRUE(tester.Test([&](Thrower*) { + static_cast<void>(absl::make_unique<Thrower[]>(kLength)); + })); +} + +} // namespace +} // namespace absl
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.bazel b/third_party/abseil-cpp/absl/strings/BUILD.bazel index f06bdc0..328f52f3 100644 --- a/third_party/abseil-cpp/absl/strings/BUILD.bazel +++ b/third_party/abseil-cpp/absl/strings/BUILD.bazel
@@ -32,7 +32,12 @@ name = "strings", srcs = [ "ascii.cc", + "charconv.cc", "escaping.cc", + "internal/charconv_bigint.cc", + "internal/charconv_bigint.h", + "internal/charconv_parse.cc", + "internal/charconv_parse.h", "internal/memutil.cc", "internal/memutil.h", "internal/stl_type_traits.h", @@ -48,6 +53,7 @@ ], hdrs = [ "ascii.h", + "charconv.h", "escaping.h", "match.h", "numbers.h", @@ -144,11 +150,6 @@ size = "small", srcs = ["ascii_test.cc"], copts = ABSL_TEST_COPTS, - tags = [ - "no_test_android_arm", - "no_test_android_arm64", - "no_test_android_x86", - ], visibility = ["//visibility:private"], deps = [ ":strings", @@ -398,12 +399,6 @@ "numbers_test.cc", ], copts = ABSL_TEST_COPTS, - tags = [ - "no_test_android_arm", - "no_test_android_arm64", - "no_test_android_x86", - "no_test_loonix", - ], visibility = ["//visibility:private"], deps = [ ":strings", @@ -429,11 +424,6 @@ name = "char_map_test", srcs = ["internal/char_map_test.cc"], copts = ABSL_TEST_COPTS, - tags = [ - "no_test_android_arm", - "no_test_android_arm64", - "no_test_android_x86", - ], deps = [ ":internal", "@com_google_googletest//:gtest_main", @@ -450,3 +440,55 @@ "@com_github_google_benchmark//:benchmark_main", ], ) + +cc_test( + name = "charconv_test", + srcs = ["charconv_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":strings", + "//absl/base", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "charconv_parse_test", + srcs = [ + "internal/charconv_parse.h", + "internal/charconv_parse_test.cc", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":strings", + "//absl/base", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "charconv_bigint_test", + srcs = [ + "internal/charconv_bigint.h", + "internal/charconv_bigint_test.cc", + "internal/charconv_parse.h", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":strings", + "//absl/base", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "charconv_benchmark", + srcs = [ + "charconv_benchmark.cc", + ], + deps = [ + ":strings", + "//absl/base", + "@com_github_google_benchmark//:benchmark_main", + ], +)
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.gn b/third_party/abseil-cpp/absl/strings/BUILD.gn index 7434eb2..117570c 100644 --- a/third_party/abseil-cpp/absl/strings/BUILD.gn +++ b/third_party/abseil-cpp/absl/strings/BUILD.gn
@@ -22,7 +22,12 @@ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] sources = [ "ascii.cc", + "charconv.cc", "escaping.cc", + "internal/charconv_bigint.cc", + "internal/charconv_bigint.h", + "internal/charconv_parse.cc", + "internal/charconv_parse.h", "internal/memutil.cc", "internal/memutil.h", "internal/stl_type_traits.h", @@ -38,6 +43,7 @@ ] public = [ "ascii.h", + "charconv.h", "escaping.h", "match.h", "numbers.h",
diff --git a/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/third_party/abseil-cpp/absl/strings/CMakeLists.txt index 9dc4732..cab2c45 100644 --- a/third_party/abseil-cpp/absl/strings/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/strings/CMakeLists.txt
@@ -17,6 +17,7 @@ list(APPEND STRINGS_PUBLIC_HEADERS "ascii.h" + "charconv.h" "escaping.h" "match.h" "numbers.h" @@ -33,6 +34,8 @@ list(APPEND STRINGS_INTERNAL_HEADERS "internal/bits.h" "internal/char_map.h" + "internal/charconv_bigint.h" + "internal/charconv_parse.h" "internal/memutil.h" "internal/ostringstream.h" "internal/resize_uninitialized.h" @@ -47,7 +50,10 @@ # add string library list(APPEND STRINGS_SRC "ascii.cc" + "charconv.cc" "escaping.cc" + "internal/charconv_bigint.cc" + "internal/charconv_parse.cc" "internal/memutil.cc" "internal/memutil.h" "internal/utf8.cc" @@ -301,5 +307,43 @@ ) +# test charconv_test +set(CHARCONV_TEST_SRC "charconv_test.cc") +set(CHARCONV_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + charconv_test + SOURCES + ${CHARCONV_TEST_SRC} + PUBLIC_LIBRARIES + ${CHARCONV_TEST_PUBLIC_LIBRARIES} +) +# test charconv_parse_test +set(CHARCONV_PARSE_TEST_SRC "internal/charconv_parse_test.cc") +set(CHARCONV_PARSE_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + charconv_parse_test + SOURCES + ${CHARCONV_PARSE_TEST_SRC} + PUBLIC_LIBRARIES + ${CHARCONV_PARSE_TEST_PUBLIC_LIBRARIES} +) + + +# test charconv_bigint_test +set(CHARCONV_BIGINT_TEST_SRC "internal/charconv_bigint_test.cc") +set(CHARCONV_BIGINT_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + charconv_bigint_test + SOURCES + ${CHARCONV_BIGINT_TEST_SRC} + PUBLIC_LIBRARIES + ${CHARCONV_BIGINT_TEST_PUBLIC_LIBRARIES} +)
diff --git a/third_party/abseil-cpp/absl/strings/charconv.cc b/third_party/abseil-cpp/absl/strings/charconv.cc new file mode 100644 index 0000000..08c3947 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/charconv.cc
@@ -0,0 +1,982 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/charconv.h" + +#include <algorithm> +#include <cassert> +#include <cmath> +#include <cstring> + +#include "absl/base/casts.h" +#include "absl/numeric/int128.h" +#include "absl/strings/internal/bits.h" +#include "absl/strings/internal/charconv_bigint.h" +#include "absl/strings/internal/charconv_parse.h" + +// The macro ABSL_BIT_PACK_FLOATS is defined on x86-64, where IEEE floating +// point numbers have the same endianness in memory as a bitfield struct +// containing the corresponding parts. +// +// When set, we replace calls to ldexp() with manual bit packing, which is +// faster and is unaffected by floating point environment. +#ifdef ABSL_BIT_PACK_FLOATS +#error ABSL_BIT_PACK_FLOATS cannot be directly set +#elif defined(__x86_64__) || defined(_M_X64) +#define ABSL_BIT_PACK_FLOATS 1 +#endif + +// A note about subnormals: +// +// The code below talks about "normals" and "subnormals". A normal IEEE float +// has a fixed-width mantissa and power of two exponent. For example, a normal +// `double` has a 53-bit mantissa. Because the high bit is always 1, it is not +// stored in the representation. The implicit bit buys an extra bit of +// resolution in the datatype. +// +// The downside of this scheme is that there is a large gap between DBL_MIN and +// zero. (Large, at least, relative to the different between DBL_MIN and the +// next representable number). This gap is softened by the "subnormal" numbers, +// which have the same power-of-two exponent as DBL_MIN, but no implicit 53rd +// bit. An all-bits-zero exponent in the encoding represents subnormals. (Zero +// is represented as a subnormal with an all-bits-zero mantissa.) +// +// The code below, in calculations, represents the mantissa as a uint64_t. The +// end result normally has the 53rd bit set. It represents subnormals by using +// narrower mantissas. + +namespace absl { +namespace { + +template <typename FloatType> +struct FloatTraits; + +template <> +struct FloatTraits<double> { + // The number of mantissa bits in the given float type. This includes the + // implied high bit. + static constexpr int kTargetMantissaBits = 53; + + // The largest supported IEEE exponent, in our integral mantissa + // representation. + // + // If `m` is the largest possible int kTargetMantissaBits bits wide, then + // m * 2**kMaxExponent is exactly equal to DBL_MAX. + static constexpr int kMaxExponent = 971; + + // The smallest supported IEEE normal exponent, in our integral mantissa + // representation. + // + // If `m` is the smallest possible int kTargetMantissaBits bits wide, then + // m * 2**kMinNormalExponent is exactly equal to DBL_MIN. + static constexpr int kMinNormalExponent = -1074; + + static double MakeNan(const char* tagp) { + // Support nan no matter which namespace it's in. Some platforms + // incorrectly don't put it in namespace std. + using namespace std; // NOLINT + return nan(tagp); + } + + // Builds a nonzero floating point number out of the provided parts. + // + // This is intended to do the same operation as ldexp(mantissa, exponent), + // but using purely integer math, to avoid -ffastmath and floating + // point environment issues. Using type punning is also faster. We fall back + // to ldexp on a per-platform basis for portability. + // + // `exponent` must be between kMinNormalExponent and kMaxExponent. + // + // `mantissa` must either be exactly kTargetMantissaBits wide, in which case + // a normal value is made, or it must be less narrow than that, in which case + // `exponent` must be exactly kMinNormalExponent, and a subnormal value is + // made. + static double Make(uint64_t mantissa, int exponent, bool sign) { +#ifndef ABSL_BIT_PACK_FLOATS + // Support ldexp no matter which namespace it's in. Some platforms + // incorrectly don't put it in namespace std. + using namespace std; // NOLINT + return sign ? -ldexp(mantissa, exponent) : ldexp(mantissa, exponent); +#else + constexpr uint64_t kMantissaMask = + (uint64_t(1) << (kTargetMantissaBits - 1)) - 1; + uint64_t dbl = static_cast<uint64_t>(sign) << 63; + if (mantissa > kMantissaMask) { + // Normal value. + // Adjust by 1023 for the exponent representation bias, and an additional + // 52 due to the implied decimal point in the IEEE mantissa represenation. + dbl += uint64_t{exponent + 1023u + kTargetMantissaBits - 1} << 52; + mantissa &= kMantissaMask; + } else { + // subnormal value + assert(exponent == kMinNormalExponent); + } + dbl += mantissa; + return absl::bit_cast<double>(dbl); +#endif // ABSL_BIT_PACK_FLOATS + } +}; + +// Specialization of floating point traits for the `float` type. See the +// FloatTraits<double> specialization above for meaning of each of the following +// members and methods. +template <> +struct FloatTraits<float> { + static constexpr int kTargetMantissaBits = 24; + static constexpr int kMaxExponent = 104; + static constexpr int kMinNormalExponent = -149; + static float MakeNan(const char* tagp) { + // Support nanf no matter which namespace it's in. Some platforms + // incorrectly don't put it in namespace std. + using namespace std; // NOLINT + return nanf(tagp); + } + static float Make(uint32_t mantissa, int exponent, bool sign) { +#ifndef ABSL_BIT_PACK_FLOATS + // Support ldexpf no matter which namespace it's in. Some platforms + // incorrectly don't put it in namespace std. + using namespace std; // NOLINT + return sign ? -ldexpf(mantissa, exponent) : ldexpf(mantissa, exponent); +#else + constexpr uint32_t kMantissaMask = + (uint32_t(1) << (kTargetMantissaBits - 1)) - 1; + uint32_t flt = static_cast<uint32_t>(sign) << 31; + if (mantissa > kMantissaMask) { + // Normal value. + // Adjust by 127 for the exponent representation bias, and an additional + // 23 due to the implied decimal point in the IEEE mantissa represenation. + flt += uint32_t{exponent + 127u + kTargetMantissaBits - 1} << 23; + mantissa &= kMantissaMask; + } else { + // subnormal value + assert(exponent == kMinNormalExponent); + } + flt += mantissa; + return absl::bit_cast<float>(flt); +#endif // ABSL_BIT_PACK_FLOATS + } +}; + +// Decimal-to-binary conversions require coercing powers of 10 into a mantissa +// and a power of 2. The two helper functions Power10Mantissa(n) and +// Power10Exponent(n) perform this task. Together, these represent a hand- +// rolled floating point value which is equal to or just less than 10**n. +// +// The return values satisfy two range guarantees: +// +// Power10Mantissa(n) * 2**Power10Exponent(n) <= 10**n +// < (Power10Mantissa(n) + 1) * 2**Power10Exponent(n) +// +// 2**63 <= Power10Mantissa(n) < 2**64. +// +// Lookups into the power-of-10 table must first check the Power10Overflow() and +// Power10Underflow() functions, to avoid out-of-bounds table access. +// +// Indexes into these tables are biased by -kPower10TableMin, and the table has +// values in the range [kPower10TableMin, kPower10TableMax]. +extern const uint64_t kPower10MantissaTable[]; +extern const int16_t kPower10ExponentTable[]; + +// The smallest allowed value for use with the Power10Mantissa() and +// Power10Exponent() functions below. (If a smaller exponent is needed in +// calculations, the end result is guaranteed to underflow.) +constexpr int kPower10TableMin = -342; + +// The largest allowed value for use with the Power10Mantissa() and +// Power10Exponent() functions below. (If a smaller exponent is needed in +// calculations, the end result is guaranteed to overflow.) +constexpr int kPower10TableMax = 308; + +uint64_t Power10Mantissa(int n) { + return kPower10MantissaTable[n - kPower10TableMin]; +} + +int Power10Exponent(int n) { + return kPower10ExponentTable[n - kPower10TableMin]; +} + +// Returns true if n is large enough that 10**n always results in an IEEE +// overflow. +bool Power10Overflow(int n) { return n > kPower10TableMax; } + +// Returns true if n is small enough that 10**n times a ParsedFloat mantissa +// always results in an IEEE underflow. +bool Power10Underflow(int n) { return n < kPower10TableMin; } + +// Returns true if Power10Mantissa(n) * 2**Power10Exponent(n) is exactly equal +// to 10**n numerically. Put another way, this returns true if there is no +// truncation error in Power10Mantissa(n). +bool Power10Exact(int n) { return n >= 0 && n <= 27; } + +// Sentinel exponent values for representing numbers too large or too close to +// zero to represent in a double. +constexpr int kOverflow = 99999; +constexpr int kUnderflow = -99999; + +// Struct representing the calculated conversion result of a positive (nonzero) +// floating point number. +// +// The calculated number is mantissa * 2**exponent (mantissa is treated as an +// integer.) `mantissa` is chosen to be the correct width for the IEEE float +// representation being calculated. (`mantissa` will always have the same bit +// width for normal values, and narrower bit widths for subnormals.) +// +// If the result of conversion was an underflow or overflow, exponent is set +// to kUnderflow or kOverflow. +struct CalculatedFloat { + uint64_t mantissa = 0; + int exponent = 0; +}; + +// Returns the bit width of the given uint128. (Equivalently, returns 128 +// minus the number of leading zero bits.) +int BitWidth(uint128 value) { + if (Uint128High64(value) == 0) { + return 64 - strings_internal::CountLeadingZeros64(Uint128Low64(value)); + } + return 128 - strings_internal::CountLeadingZeros64(Uint128High64(value)); +} + +// Calculates how far to the right a mantissa needs to be shifted to create a +// properly adjusted mantissa for an IEEE floating point number. +// +// `mantissa_width` is the bit width of the mantissa to be shifted, and +// `binary_exponent` is the exponent of the number before the shift. +// +// This accounts for subnormal values, and will return a larger-than-normal +// shift if binary_exponent would otherwise be too low. +template <typename FloatType> +int NormalizedShiftSize(int mantissa_width, int binary_exponent) { + const int normal_shift = + mantissa_width - FloatTraits<FloatType>::kTargetMantissaBits; + const int minimum_shift = + FloatTraits<FloatType>::kMinNormalExponent - binary_exponent; + return std::max(normal_shift, minimum_shift); +} + +// Right shifts a uint128 so that it has the requested bit width. (The +// resulting value will have 128 - bit_width leading zeroes.) The initial +// `value` must be wider than the requested bit width. +// +// Returns the number of bits shifted. +int TruncateToBitWidth(int bit_width, uint128* value) { + const int current_bit_width = BitWidth(*value); + const int shift = current_bit_width - bit_width; + *value >>= shift; + return shift; +} + +// Checks if the given ParsedFloat represents one of the edge cases that are +// not dependent on number base: zero, infinity, or NaN. If so, sets *value +// the appropriate double, and returns true. +template <typename FloatType> +bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative, + FloatType* value) { + if (input.type == strings_internal::FloatType::kNan) { + // A bug in both clang and gcc would cause the compiler to optimize away the + // buffer we are building below. Declaring the buffer volatile avoids the + // issue, and has no measurable performance impact in microbenchmarks. + // + // https://bugs.llvm.org/show_bug.cgi?id=37778 + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86113 + constexpr ptrdiff_t kNanBufferSize = 128; + volatile char n_char_sequence[kNanBufferSize]; + if (input.subrange_begin == nullptr) { + n_char_sequence[0] = '\0'; + } else { + ptrdiff_t nan_size = input.subrange_end - input.subrange_begin; + nan_size = std::min(nan_size, kNanBufferSize - 1); + std::copy_n(input.subrange_begin, nan_size, n_char_sequence); + n_char_sequence[nan_size] = '\0'; + } + char* nan_argument = const_cast<char*>(n_char_sequence); + *value = negative ? -FloatTraits<FloatType>::MakeNan(nan_argument) + : FloatTraits<FloatType>::MakeNan(nan_argument); + return true; + } + if (input.type == strings_internal::FloatType::kInfinity) { + *value = negative ? -std::numeric_limits<FloatType>::infinity() + : std::numeric_limits<FloatType>::infinity(); + return true; + } + if (input.mantissa == 0) { + *value = negative ? -0.0 : 0.0; + return true; + } + return false; +} + +// Given a CalculatedFloat result of a from_chars conversion, generate the +// correct output values. +// +// CalculatedFloat can represent an underflow or overflow, in which case the +// error code in *result is set. Otherwise, the calculated floating point +// number is stored in *value. +template <typename FloatType> +void EncodeResult(const CalculatedFloat& calculated, bool negative, + absl::from_chars_result* result, FloatType* value) { + if (calculated.exponent == kOverflow) { + result->ec = std::errc::result_out_of_range; + *value = negative ? -std::numeric_limits<FloatType>::max() + : std::numeric_limits<FloatType>::max(); + return; + } else if (calculated.mantissa == 0 || calculated.exponent == kUnderflow) { + result->ec = std::errc::result_out_of_range; + *value = negative ? -0.0 : 0.0; + return; + } + *value = FloatTraits<FloatType>::Make(calculated.mantissa, + calculated.exponent, negative); +} + +// Returns the given uint128 shifted to the right by `shift` bits, and rounds +// the remaining bits using round_to_nearest logic. The value is returned as a +// uint64_t, since this is the type used by this library for storing calculated +// floating point mantissas. +// +// It is expected that the width of the input value shifted by `shift` will +// be the correct bit-width for the target mantissa, which is strictly narrower +// than a uint64_t. +// +// If `input_exact` is false, then a nonzero error epsilon is assumed. For +// rounding purposes, the true value being rounded is strictly greater than the +// input value. The error may represent a single lost carry bit. +// +// When input_exact, shifted bits of the form 1000000... represent a tie, which +// is broken by rounding to even -- the rounding direction is chosen so the low +// bit of the returned value is 0. +// +// When !input_exact, shifted bits of the form 10000000... represent a value +// strictly greater than one half (due to the error epsilon), and so ties are +// always broken by rounding up. +// +// When !input_exact, shifted bits of the form 01111111... are uncertain; +// the true value may or may not be greater than 10000000..., due to the +// possible lost carry bit. The correct rounding direction is unknown. In this +// case, the result is rounded down, and `output_exact` is set to false. +// +// Zero and negative values of `shift` are accepted, in which case the word is +// shifted left, as necessary. +uint64_t ShiftRightAndRound(uint128 value, int shift, bool input_exact, + bool* output_exact) { + if (shift <= 0) { + *output_exact = input_exact; + return static_cast<uint64_t>(value << -shift); + } + if (shift >= 128) { + // Exponent is so small that we are shifting away all significant bits. + // Answer will not be representable, even as a subnormal, so return a zero + // mantissa (which represents underflow). + *output_exact = true; + return 0; + } + + *output_exact = true; + const uint128 shift_mask = (uint128(1) << shift) - 1; + const uint128 halfway_point = uint128(1) << (shift - 1); + + const uint128 shifted_bits = value & shift_mask; + value >>= shift; + if (shifted_bits > halfway_point) { + // Shifted bits greater than 10000... require rounding up. + return static_cast<uint64_t>(value + 1); + } + if (shifted_bits == halfway_point) { + // In exact mode, shifted bits of 10000... mean we're exactly halfway + // between two numbers, and we must round to even. So only round up if + // the low bit of `value` is set. + // + // In inexact mode, the nonzero error means the actual value is greater + // than the halfway point and we must alway round up. + if ((value & 1) == 1 || !input_exact) { + ++value; + } + return static_cast<uint64_t>(value); + } + if (!input_exact && shifted_bits == halfway_point - 1) { + // Rounding direction is unclear, due to error. + *output_exact = false; + } + // Otherwise, round down. + return static_cast<uint64_t>(value); +} + +// Checks if a floating point guess needs to be rounded up, using high precision +// math. +// +// `guess_mantissa` and `guess_exponent` represent a candidate guess for the +// number represented by `parsed_decimal`. +// +// The exact number represented by `parsed_decimal` must lie between the two +// numbers: +// A = `guess_mantissa * 2**guess_exponent` +// B = `(guess_mantissa + 1) * 2**guess_exponent` +// +// This function returns false if `A` is the better guess, and true if `B` is +// the better guess, with rounding ties broken by rounding to even. +bool MustRoundUp(uint64_t guess_mantissa, int guess_exponent, + const strings_internal::ParsedFloat& parsed_decimal) { + // 768 is the number of digits needed in the worst case. We could determine a + // better limit dynamically based on the value of parsed_decimal.exponent. + // This would optimize pathological input cases only. (Sane inputs won't have + // hundreds of digits of mantissa.) + absl::strings_internal::BigUnsigned<84> exact_mantissa; + int exact_exponent = exact_mantissa.ReadFloatMantissa(parsed_decimal, 768); + + // Adjust the `guess` arguments to be halfway between A and B. + guess_mantissa = guess_mantissa * 2 + 1; + guess_exponent -= 1; + + // In our comparison: + // lhs = exact = exact_mantissa * 10**exact_exponent + // = exact_mantissa * 5**exact_exponent * 2**exact_exponent + // rhs = guess = guess_mantissa * 2**guess_exponent + // + // Because we are doing integer math, we can't directly deal with negative + // exponents. We instead move these to the other side of the inequality. + absl::strings_internal::BigUnsigned<84>& lhs = exact_mantissa; + int comparison; + if (exact_exponent >= 0) { + lhs.MultiplyByFiveToTheNth(exact_exponent); + absl::strings_internal::BigUnsigned<84> rhs(guess_mantissa); + // There are powers of 2 on both sides of the inequality; reduce this to + // a single bit-shift. + if (exact_exponent > guess_exponent) { + lhs.ShiftLeft(exact_exponent - guess_exponent); + } else { + rhs.ShiftLeft(guess_exponent - exact_exponent); + } + comparison = Compare(lhs, rhs); + } else { + // Move the power of 5 to the other side of the equation, giving us: + // lhs = exact_mantissa * 2**exact_exponent + // rhs = guess_mantissa * 5**(-exact_exponent) * 2**guess_exponent + absl::strings_internal::BigUnsigned<84> rhs = + absl::strings_internal::BigUnsigned<84>::FiveToTheNth(-exact_exponent); + rhs.MultiplyBy(guess_mantissa); + if (exact_exponent > guess_exponent) { + lhs.ShiftLeft(exact_exponent - guess_exponent); + } else { + rhs.ShiftLeft(guess_exponent - exact_exponent); + } + comparison = Compare(lhs, rhs); + } + if (comparison < 0) { + return false; + } else if (comparison > 0) { + return true; + } else { + // When lhs == rhs, the decimal input is exactly between A and B. + // Round towards even -- round up only if the low bit of the initial + // `guess_mantissa` was a 1. We shifted guess_mantissa left 1 bit at + // the beginning of this function, so test the 2nd bit here. + return (guess_mantissa & 2) == 2; + } +} + +// Constructs a CalculatedFloat from a given mantissa and exponent, but +// with the following normalizations applied: +// +// If rounding has caused mantissa to increase just past the allowed bit +// width, shift and adjust exponent. +// +// If exponent is too high, sets kOverflow. +// +// If mantissa is zero (representing a non-zero value not representable, even +// as a subnormal), sets kUnderflow. +template <typename FloatType> +CalculatedFloat CalculatedFloatFromRawValues(uint64_t mantissa, int exponent) { + CalculatedFloat result; + if (mantissa == uint64_t(1) << FloatTraits<FloatType>::kTargetMantissaBits) { + mantissa >>= 1; + exponent += 1; + } + if (exponent > FloatTraits<FloatType>::kMaxExponent) { + result.exponent = kOverflow; + } else if (mantissa == 0) { + result.exponent = kUnderflow; + } else { + result.exponent = exponent; + result.mantissa = mantissa; + } + return result; +} + +template <typename FloatType> +CalculatedFloat CalculateFromParsedHexadecimal( + const strings_internal::ParsedFloat& parsed_hex) { + uint64_t mantissa = parsed_hex.mantissa; + int exponent = parsed_hex.exponent; + int mantissa_width = 64 - strings_internal::CountLeadingZeros64(mantissa); + const int shift = NormalizedShiftSize<FloatType>(mantissa_width, exponent); + bool result_exact; + exponent += shift; + mantissa = ShiftRightAndRound(mantissa, shift, + /* input exact= */ true, &result_exact); + // ParseFloat handles rounding in the hexadecimal case, so we don't have to + // check `result_exact` here. + return CalculatedFloatFromRawValues<FloatType>(mantissa, exponent); +} + +template <typename FloatType> +CalculatedFloat CalculateFromParsedDecimal( + const strings_internal::ParsedFloat& parsed_decimal) { + CalculatedFloat result; + + // Large or small enough decimal exponents will always result in overflow + // or underflow. + if (Power10Underflow(parsed_decimal.exponent)) { + result.exponent = kUnderflow; + return result; + } else if (Power10Overflow(parsed_decimal.exponent)) { + result.exponent = kOverflow; + return result; + } + + // Otherwise convert our power of 10 into a power of 2 times an integer + // mantissa, and multiply this by our parsed decimal mantissa. + uint128 wide_binary_mantissa = parsed_decimal.mantissa; + wide_binary_mantissa *= Power10Mantissa(parsed_decimal.exponent); + int binary_exponent = Power10Exponent(parsed_decimal.exponent); + + // Discard bits that are inaccurate due to truncation error. The magic + // `mantissa_width` constants below are justified in charconv_algorithm.md. + // They represent the number of bits in `wide_binary_mantissa` that are + // guaranteed to be unaffected by error propagation. + bool mantissa_exact; + int mantissa_width; + if (parsed_decimal.subrange_begin) { + // Truncated mantissa + mantissa_width = 58; + mantissa_exact = false; + binary_exponent += + TruncateToBitWidth(mantissa_width, &wide_binary_mantissa); + } else if (!Power10Exact(parsed_decimal.exponent)) { + // Exact mantissa, truncated power of ten + mantissa_width = 63; + mantissa_exact = false; + binary_exponent += + TruncateToBitWidth(mantissa_width, &wide_binary_mantissa); + } else { + // Product is exact + mantissa_width = BitWidth(wide_binary_mantissa); + mantissa_exact = true; + } + + // Shift into an FloatType-sized mantissa, and round to nearest. + const int shift = + NormalizedShiftSize<FloatType>(mantissa_width, binary_exponent); + bool result_exact; + binary_exponent += shift; + uint64_t binary_mantissa = ShiftRightAndRound(wide_binary_mantissa, shift, + mantissa_exact, &result_exact); + if (!result_exact) { + // We could not determine the rounding direction using int128 math. Use + // full resolution math instead. + if (MustRoundUp(binary_mantissa, binary_exponent, parsed_decimal)) { + binary_mantissa += 1; + } + } + + return CalculatedFloatFromRawValues<FloatType>(binary_mantissa, + binary_exponent); +} + +template <typename FloatType> +from_chars_result FromCharsImpl(const char* first, const char* last, + FloatType& value, chars_format fmt_flags) { + from_chars_result result; + result.ptr = first; // overwritten on successful parse + result.ec = std::errc(); + + bool negative = false; + if (first != last && *first == '-') { + ++first; + negative = true; + } + // If the `hex` flag is *not* set, then we will accept a 0x prefix and try + // to parse a hexadecimal float. + if ((fmt_flags & chars_format::hex) == chars_format{} && last - first >= 2 && + *first == '0' && (first[1] == 'x' || first[1] == 'X')) { + const char* hex_first = first + 2; + strings_internal::ParsedFloat hex_parse = + strings_internal::ParseFloat<16>(hex_first, last, fmt_flags); + if (hex_parse.end == nullptr || + hex_parse.type != strings_internal::FloatType::kNumber) { + // Either we failed to parse a hex float after the "0x", or we read + // "0xinf" or "0xnan" which we don't want to match. + // + // However, a std::string that begins with "0x" also begins with "0", which + // is normally a valid match for the number zero. So we want these + // strings to match zero unless fmt_flags is `scientific`. (This flag + // means an exponent is required, which the std::string "0" does not have.) + if (fmt_flags == chars_format::scientific) { + result.ec = std::errc::invalid_argument; + } else { + result.ptr = first + 1; + value = negative ? -0.0 : 0.0; + } + return result; + } + // We matched a value. + result.ptr = hex_parse.end; + if (HandleEdgeCase(hex_parse, negative, &value)) { + return result; + } + CalculatedFloat calculated = + CalculateFromParsedHexadecimal<FloatType>(hex_parse); + EncodeResult(calculated, negative, &result, &value); + return result; + } + // Otherwise, we choose the number base based on the flags. + if ((fmt_flags & chars_format::hex) == chars_format::hex) { + strings_internal::ParsedFloat hex_parse = + strings_internal::ParseFloat<16>(first, last, fmt_flags); + if (hex_parse.end == nullptr) { + result.ec = std::errc::invalid_argument; + return result; + } + result.ptr = hex_parse.end; + if (HandleEdgeCase(hex_parse, negative, &value)) { + return result; + } + CalculatedFloat calculated = + CalculateFromParsedHexadecimal<FloatType>(hex_parse); + EncodeResult(calculated, negative, &result, &value); + return result; + } else { + strings_internal::ParsedFloat decimal_parse = + strings_internal::ParseFloat<10>(first, last, fmt_flags); + if (decimal_parse.end == nullptr) { + result.ec = std::errc::invalid_argument; + return result; + } + result.ptr = decimal_parse.end; + if (HandleEdgeCase(decimal_parse, negative, &value)) { + return result; + } + CalculatedFloat calculated = + CalculateFromParsedDecimal<FloatType>(decimal_parse); + EncodeResult(calculated, negative, &result, &value); + return result; + } + return result; +} +} // namespace + +from_chars_result from_chars(const char* first, const char* last, double& value, + chars_format fmt) { + return FromCharsImpl(first, last, value, fmt); +} + +from_chars_result from_chars(const char* first, const char* last, float& value, + chars_format fmt) { + return FromCharsImpl(first, last, value, fmt); +} + +namespace { + +// Table of powers of 10, from kPower10TableMin to kPower10TableMax. +// +// kPower10MantissaTable[i - kPower10TableMin] stores the 64-bit mantissa (high +// bit always on), and kPower10ExponentTable[i - kPower10TableMin] stores the +// power-of-two exponent. For a given number i, this gives the unique mantissa +// and exponent such that mantissa * 2**exponent <= 10**i < (mantissa + 1) * +// 2**exponent. + +const uint64_t kPower10MantissaTable[] = { + 0xeef453d6923bd65aU, 0x9558b4661b6565f8U, 0xbaaee17fa23ebf76U, + 0xe95a99df8ace6f53U, 0x91d8a02bb6c10594U, 0xb64ec836a47146f9U, + 0xe3e27a444d8d98b7U, 0x8e6d8c6ab0787f72U, 0xb208ef855c969f4fU, + 0xde8b2b66b3bc4723U, 0x8b16fb203055ac76U, 0xaddcb9e83c6b1793U, + 0xd953e8624b85dd78U, 0x87d4713d6f33aa6bU, 0xa9c98d8ccb009506U, + 0xd43bf0effdc0ba48U, 0x84a57695fe98746dU, 0xa5ced43b7e3e9188U, + 0xcf42894a5dce35eaU, 0x818995ce7aa0e1b2U, 0xa1ebfb4219491a1fU, + 0xca66fa129f9b60a6U, 0xfd00b897478238d0U, 0x9e20735e8cb16382U, + 0xc5a890362fddbc62U, 0xf712b443bbd52b7bU, 0x9a6bb0aa55653b2dU, + 0xc1069cd4eabe89f8U, 0xf148440a256e2c76U, 0x96cd2a865764dbcaU, + 0xbc807527ed3e12bcU, 0xeba09271e88d976bU, 0x93445b8731587ea3U, + 0xb8157268fdae9e4cU, 0xe61acf033d1a45dfU, 0x8fd0c16206306babU, + 0xb3c4f1ba87bc8696U, 0xe0b62e2929aba83cU, 0x8c71dcd9ba0b4925U, + 0xaf8e5410288e1b6fU, 0xdb71e91432b1a24aU, 0x892731ac9faf056eU, + 0xab70fe17c79ac6caU, 0xd64d3d9db981787dU, 0x85f0468293f0eb4eU, + 0xa76c582338ed2621U, 0xd1476e2c07286faaU, 0x82cca4db847945caU, + 0xa37fce126597973cU, 0xcc5fc196fefd7d0cU, 0xff77b1fcbebcdc4fU, + 0x9faacf3df73609b1U, 0xc795830d75038c1dU, 0xf97ae3d0d2446f25U, + 0x9becce62836ac577U, 0xc2e801fb244576d5U, 0xf3a20279ed56d48aU, + 0x9845418c345644d6U, 0xbe5691ef416bd60cU, 0xedec366b11c6cb8fU, + 0x94b3a202eb1c3f39U, 0xb9e08a83a5e34f07U, 0xe858ad248f5c22c9U, + 0x91376c36d99995beU, 0xb58547448ffffb2dU, 0xe2e69915b3fff9f9U, + 0x8dd01fad907ffc3bU, 0xb1442798f49ffb4aU, 0xdd95317f31c7fa1dU, + 0x8a7d3eef7f1cfc52U, 0xad1c8eab5ee43b66U, 0xd863b256369d4a40U, + 0x873e4f75e2224e68U, 0xa90de3535aaae202U, 0xd3515c2831559a83U, + 0x8412d9991ed58091U, 0xa5178fff668ae0b6U, 0xce5d73ff402d98e3U, + 0x80fa687f881c7f8eU, 0xa139029f6a239f72U, 0xc987434744ac874eU, + 0xfbe9141915d7a922U, 0x9d71ac8fada6c9b5U, 0xc4ce17b399107c22U, + 0xf6019da07f549b2bU, 0x99c102844f94e0fbU, 0xc0314325637a1939U, + 0xf03d93eebc589f88U, 0x96267c7535b763b5U, 0xbbb01b9283253ca2U, + 0xea9c227723ee8bcbU, 0x92a1958a7675175fU, 0xb749faed14125d36U, + 0xe51c79a85916f484U, 0x8f31cc0937ae58d2U, 0xb2fe3f0b8599ef07U, + 0xdfbdcece67006ac9U, 0x8bd6a141006042bdU, 0xaecc49914078536dU, + 0xda7f5bf590966848U, 0x888f99797a5e012dU, 0xaab37fd7d8f58178U, + 0xd5605fcdcf32e1d6U, 0x855c3be0a17fcd26U, 0xa6b34ad8c9dfc06fU, + 0xd0601d8efc57b08bU, 0x823c12795db6ce57U, 0xa2cb1717b52481edU, + 0xcb7ddcdda26da268U, 0xfe5d54150b090b02U, 0x9efa548d26e5a6e1U, + 0xc6b8e9b0709f109aU, 0xf867241c8cc6d4c0U, 0x9b407691d7fc44f8U, + 0xc21094364dfb5636U, 0xf294b943e17a2bc4U, 0x979cf3ca6cec5b5aU, + 0xbd8430bd08277231U, 0xece53cec4a314ebdU, 0x940f4613ae5ed136U, + 0xb913179899f68584U, 0xe757dd7ec07426e5U, 0x9096ea6f3848984fU, + 0xb4bca50b065abe63U, 0xe1ebce4dc7f16dfbU, 0x8d3360f09cf6e4bdU, + 0xb080392cc4349decU, 0xdca04777f541c567U, 0x89e42caaf9491b60U, + 0xac5d37d5b79b6239U, 0xd77485cb25823ac7U, 0x86a8d39ef77164bcU, + 0xa8530886b54dbdebU, 0xd267caa862a12d66U, 0x8380dea93da4bc60U, + 0xa46116538d0deb78U, 0xcd795be870516656U, 0x806bd9714632dff6U, + 0xa086cfcd97bf97f3U, 0xc8a883c0fdaf7df0U, 0xfad2a4b13d1b5d6cU, + 0x9cc3a6eec6311a63U, 0xc3f490aa77bd60fcU, 0xf4f1b4d515acb93bU, + 0x991711052d8bf3c5U, 0xbf5cd54678eef0b6U, 0xef340a98172aace4U, + 0x9580869f0e7aac0eU, 0xbae0a846d2195712U, 0xe998d258869facd7U, + 0x91ff83775423cc06U, 0xb67f6455292cbf08U, 0xe41f3d6a7377eecaU, + 0x8e938662882af53eU, 0xb23867fb2a35b28dU, 0xdec681f9f4c31f31U, + 0x8b3c113c38f9f37eU, 0xae0b158b4738705eU, 0xd98ddaee19068c76U, + 0x87f8a8d4cfa417c9U, 0xa9f6d30a038d1dbcU, 0xd47487cc8470652bU, + 0x84c8d4dfd2c63f3bU, 0xa5fb0a17c777cf09U, 0xcf79cc9db955c2ccU, + 0x81ac1fe293d599bfU, 0xa21727db38cb002fU, 0xca9cf1d206fdc03bU, + 0xfd442e4688bd304aU, 0x9e4a9cec15763e2eU, 0xc5dd44271ad3cdbaU, + 0xf7549530e188c128U, 0x9a94dd3e8cf578b9U, 0xc13a148e3032d6e7U, + 0xf18899b1bc3f8ca1U, 0x96f5600f15a7b7e5U, 0xbcb2b812db11a5deU, + 0xebdf661791d60f56U, 0x936b9fcebb25c995U, 0xb84687c269ef3bfbU, + 0xe65829b3046b0afaU, 0x8ff71a0fe2c2e6dcU, 0xb3f4e093db73a093U, + 0xe0f218b8d25088b8U, 0x8c974f7383725573U, 0xafbd2350644eeacfU, + 0xdbac6c247d62a583U, 0x894bc396ce5da772U, 0xab9eb47c81f5114fU, + 0xd686619ba27255a2U, 0x8613fd0145877585U, 0xa798fc4196e952e7U, + 0xd17f3b51fca3a7a0U, 0x82ef85133de648c4U, 0xa3ab66580d5fdaf5U, + 0xcc963fee10b7d1b3U, 0xffbbcfe994e5c61fU, 0x9fd561f1fd0f9bd3U, + 0xc7caba6e7c5382c8U, 0xf9bd690a1b68637bU, 0x9c1661a651213e2dU, + 0xc31bfa0fe5698db8U, 0xf3e2f893dec3f126U, 0x986ddb5c6b3a76b7U, + 0xbe89523386091465U, 0xee2ba6c0678b597fU, 0x94db483840b717efU, + 0xba121a4650e4ddebU, 0xe896a0d7e51e1566U, 0x915e2486ef32cd60U, + 0xb5b5ada8aaff80b8U, 0xe3231912d5bf60e6U, 0x8df5efabc5979c8fU, + 0xb1736b96b6fd83b3U, 0xddd0467c64bce4a0U, 0x8aa22c0dbef60ee4U, + 0xad4ab7112eb3929dU, 0xd89d64d57a607744U, 0x87625f056c7c4a8bU, + 0xa93af6c6c79b5d2dU, 0xd389b47879823479U, 0x843610cb4bf160cbU, + 0xa54394fe1eedb8feU, 0xce947a3da6a9273eU, 0x811ccc668829b887U, + 0xa163ff802a3426a8U, 0xc9bcff6034c13052U, 0xfc2c3f3841f17c67U, + 0x9d9ba7832936edc0U, 0xc5029163f384a931U, 0xf64335bcf065d37dU, + 0x99ea0196163fa42eU, 0xc06481fb9bcf8d39U, 0xf07da27a82c37088U, + 0x964e858c91ba2655U, 0xbbe226efb628afeaU, 0xeadab0aba3b2dbe5U, + 0x92c8ae6b464fc96fU, 0xb77ada0617e3bbcbU, 0xe55990879ddcaabdU, + 0x8f57fa54c2a9eab6U, 0xb32df8e9f3546564U, 0xdff9772470297ebdU, + 0x8bfbea76c619ef36U, 0xaefae51477a06b03U, 0xdab99e59958885c4U, + 0x88b402f7fd75539bU, 0xaae103b5fcd2a881U, 0xd59944a37c0752a2U, + 0x857fcae62d8493a5U, 0xa6dfbd9fb8e5b88eU, 0xd097ad07a71f26b2U, + 0x825ecc24c873782fU, 0xa2f67f2dfa90563bU, 0xcbb41ef979346bcaU, + 0xfea126b7d78186bcU, 0x9f24b832e6b0f436U, 0xc6ede63fa05d3143U, + 0xf8a95fcf88747d94U, 0x9b69dbe1b548ce7cU, 0xc24452da229b021bU, + 0xf2d56790ab41c2a2U, 0x97c560ba6b0919a5U, 0xbdb6b8e905cb600fU, + 0xed246723473e3813U, 0x9436c0760c86e30bU, 0xb94470938fa89bceU, + 0xe7958cb87392c2c2U, 0x90bd77f3483bb9b9U, 0xb4ecd5f01a4aa828U, + 0xe2280b6c20dd5232U, 0x8d590723948a535fU, 0xb0af48ec79ace837U, + 0xdcdb1b2798182244U, 0x8a08f0f8bf0f156bU, 0xac8b2d36eed2dac5U, + 0xd7adf884aa879177U, 0x86ccbb52ea94baeaU, 0xa87fea27a539e9a5U, + 0xd29fe4b18e88640eU, 0x83a3eeeef9153e89U, 0xa48ceaaab75a8e2bU, + 0xcdb02555653131b6U, 0x808e17555f3ebf11U, 0xa0b19d2ab70e6ed6U, + 0xc8de047564d20a8bU, 0xfb158592be068d2eU, 0x9ced737bb6c4183dU, + 0xc428d05aa4751e4cU, 0xf53304714d9265dfU, 0x993fe2c6d07b7fabU, + 0xbf8fdb78849a5f96U, 0xef73d256a5c0f77cU, 0x95a8637627989aadU, + 0xbb127c53b17ec159U, 0xe9d71b689dde71afU, 0x9226712162ab070dU, + 0xb6b00d69bb55c8d1U, 0xe45c10c42a2b3b05U, 0x8eb98a7a9a5b04e3U, + 0xb267ed1940f1c61cU, 0xdf01e85f912e37a3U, 0x8b61313bbabce2c6U, + 0xae397d8aa96c1b77U, 0xd9c7dced53c72255U, 0x881cea14545c7575U, + 0xaa242499697392d2U, 0xd4ad2dbfc3d07787U, 0x84ec3c97da624ab4U, + 0xa6274bbdd0fadd61U, 0xcfb11ead453994baU, 0x81ceb32c4b43fcf4U, + 0xa2425ff75e14fc31U, 0xcad2f7f5359a3b3eU, 0xfd87b5f28300ca0dU, + 0x9e74d1b791e07e48U, 0xc612062576589ddaU, 0xf79687aed3eec551U, + 0x9abe14cd44753b52U, 0xc16d9a0095928a27U, 0xf1c90080baf72cb1U, + 0x971da05074da7beeU, 0xbce5086492111aeaU, 0xec1e4a7db69561a5U, + 0x9392ee8e921d5d07U, 0xb877aa3236a4b449U, 0xe69594bec44de15bU, + 0x901d7cf73ab0acd9U, 0xb424dc35095cd80fU, 0xe12e13424bb40e13U, + 0x8cbccc096f5088cbU, 0xafebff0bcb24aafeU, 0xdbe6fecebdedd5beU, + 0x89705f4136b4a597U, 0xabcc77118461cefcU, 0xd6bf94d5e57a42bcU, + 0x8637bd05af6c69b5U, 0xa7c5ac471b478423U, 0xd1b71758e219652bU, + 0x83126e978d4fdf3bU, 0xa3d70a3d70a3d70aU, 0xccccccccccccccccU, + 0x8000000000000000U, 0xa000000000000000U, 0xc800000000000000U, + 0xfa00000000000000U, 0x9c40000000000000U, 0xc350000000000000U, + 0xf424000000000000U, 0x9896800000000000U, 0xbebc200000000000U, + 0xee6b280000000000U, 0x9502f90000000000U, 0xba43b74000000000U, + 0xe8d4a51000000000U, 0x9184e72a00000000U, 0xb5e620f480000000U, + 0xe35fa931a0000000U, 0x8e1bc9bf04000000U, 0xb1a2bc2ec5000000U, + 0xde0b6b3a76400000U, 0x8ac7230489e80000U, 0xad78ebc5ac620000U, + 0xd8d726b7177a8000U, 0x878678326eac9000U, 0xa968163f0a57b400U, + 0xd3c21bcecceda100U, 0x84595161401484a0U, 0xa56fa5b99019a5c8U, + 0xcecb8f27f4200f3aU, 0x813f3978f8940984U, 0xa18f07d736b90be5U, + 0xc9f2c9cd04674edeU, 0xfc6f7c4045812296U, 0x9dc5ada82b70b59dU, + 0xc5371912364ce305U, 0xf684df56c3e01bc6U, 0x9a130b963a6c115cU, + 0xc097ce7bc90715b3U, 0xf0bdc21abb48db20U, 0x96769950b50d88f4U, + 0xbc143fa4e250eb31U, 0xeb194f8e1ae525fdU, 0x92efd1b8d0cf37beU, + 0xb7abc627050305adU, 0xe596b7b0c643c719U, 0x8f7e32ce7bea5c6fU, + 0xb35dbf821ae4f38bU, 0xe0352f62a19e306eU, 0x8c213d9da502de45U, + 0xaf298d050e4395d6U, 0xdaf3f04651d47b4cU, 0x88d8762bf324cd0fU, + 0xab0e93b6efee0053U, 0xd5d238a4abe98068U, 0x85a36366eb71f041U, + 0xa70c3c40a64e6c51U, 0xd0cf4b50cfe20765U, 0x82818f1281ed449fU, + 0xa321f2d7226895c7U, 0xcbea6f8ceb02bb39U, 0xfee50b7025c36a08U, + 0x9f4f2726179a2245U, 0xc722f0ef9d80aad6U, 0xf8ebad2b84e0d58bU, + 0x9b934c3b330c8577U, 0xc2781f49ffcfa6d5U, 0xf316271c7fc3908aU, + 0x97edd871cfda3a56U, 0xbde94e8e43d0c8ecU, 0xed63a231d4c4fb27U, + 0x945e455f24fb1cf8U, 0xb975d6b6ee39e436U, 0xe7d34c64a9c85d44U, + 0x90e40fbeea1d3a4aU, 0xb51d13aea4a488ddU, 0xe264589a4dcdab14U, + 0x8d7eb76070a08aecU, 0xb0de65388cc8ada8U, 0xdd15fe86affad912U, + 0x8a2dbf142dfcc7abU, 0xacb92ed9397bf996U, 0xd7e77a8f87daf7fbU, + 0x86f0ac99b4e8dafdU, 0xa8acd7c0222311bcU, 0xd2d80db02aabd62bU, + 0x83c7088e1aab65dbU, 0xa4b8cab1a1563f52U, 0xcde6fd5e09abcf26U, + 0x80b05e5ac60b6178U, 0xa0dc75f1778e39d6U, 0xc913936dd571c84cU, + 0xfb5878494ace3a5fU, 0x9d174b2dcec0e47bU, 0xc45d1df942711d9aU, + 0xf5746577930d6500U, 0x9968bf6abbe85f20U, 0xbfc2ef456ae276e8U, + 0xefb3ab16c59b14a2U, 0x95d04aee3b80ece5U, 0xbb445da9ca61281fU, + 0xea1575143cf97226U, 0x924d692ca61be758U, 0xb6e0c377cfa2e12eU, + 0xe498f455c38b997aU, 0x8edf98b59a373fecU, 0xb2977ee300c50fe7U, + 0xdf3d5e9bc0f653e1U, 0x8b865b215899f46cU, 0xae67f1e9aec07187U, + 0xda01ee641a708de9U, 0x884134fe908658b2U, 0xaa51823e34a7eedeU, + 0xd4e5e2cdc1d1ea96U, 0x850fadc09923329eU, 0xa6539930bf6bff45U, + 0xcfe87f7cef46ff16U, 0x81f14fae158c5f6eU, 0xa26da3999aef7749U, + 0xcb090c8001ab551cU, 0xfdcb4fa002162a63U, 0x9e9f11c4014dda7eU, + 0xc646d63501a1511dU, 0xf7d88bc24209a565U, 0x9ae757596946075fU, + 0xc1a12d2fc3978937U, 0xf209787bb47d6b84U, 0x9745eb4d50ce6332U, + 0xbd176620a501fbffU, 0xec5d3fa8ce427affU, 0x93ba47c980e98cdfU, + 0xb8a8d9bbe123f017U, 0xe6d3102ad96cec1dU, 0x9043ea1ac7e41392U, + 0xb454e4a179dd1877U, 0xe16a1dc9d8545e94U, 0x8ce2529e2734bb1dU, + 0xb01ae745b101e9e4U, 0xdc21a1171d42645dU, 0x899504ae72497ebaU, + 0xabfa45da0edbde69U, 0xd6f8d7509292d603U, 0x865b86925b9bc5c2U, + 0xa7f26836f282b732U, 0xd1ef0244af2364ffU, 0x8335616aed761f1fU, + 0xa402b9c5a8d3a6e7U, 0xcd036837130890a1U, 0x802221226be55a64U, + 0xa02aa96b06deb0fdU, 0xc83553c5c8965d3dU, 0xfa42a8b73abbf48cU, + 0x9c69a97284b578d7U, 0xc38413cf25e2d70dU, 0xf46518c2ef5b8cd1U, + 0x98bf2f79d5993802U, 0xbeeefb584aff8603U, 0xeeaaba2e5dbf6784U, + 0x952ab45cfa97a0b2U, 0xba756174393d88dfU, 0xe912b9d1478ceb17U, + 0x91abb422ccb812eeU, 0xb616a12b7fe617aaU, 0xe39c49765fdf9d94U, + 0x8e41ade9fbebc27dU, 0xb1d219647ae6b31cU, 0xde469fbd99a05fe3U, + 0x8aec23d680043beeU, 0xada72ccc20054ae9U, 0xd910f7ff28069da4U, + 0x87aa9aff79042286U, 0xa99541bf57452b28U, 0xd3fa922f2d1675f2U, + 0x847c9b5d7c2e09b7U, 0xa59bc234db398c25U, 0xcf02b2c21207ef2eU, + 0x8161afb94b44f57dU, 0xa1ba1ba79e1632dcU, 0xca28a291859bbf93U, + 0xfcb2cb35e702af78U, 0x9defbf01b061adabU, 0xc56baec21c7a1916U, + 0xf6c69a72a3989f5bU, 0x9a3c2087a63f6399U, 0xc0cb28a98fcf3c7fU, + 0xf0fdf2d3f3c30b9fU, 0x969eb7c47859e743U, 0xbc4665b596706114U, + 0xeb57ff22fc0c7959U, 0x9316ff75dd87cbd8U, 0xb7dcbf5354e9beceU, + 0xe5d3ef282a242e81U, 0x8fa475791a569d10U, 0xb38d92d760ec4455U, + 0xe070f78d3927556aU, 0x8c469ab843b89562U, 0xaf58416654a6babbU, + 0xdb2e51bfe9d0696aU, 0x88fcf317f22241e2U, 0xab3c2fddeeaad25aU, + 0xd60b3bd56a5586f1U, 0x85c7056562757456U, 0xa738c6bebb12d16cU, + 0xd106f86e69d785c7U, 0x82a45b450226b39cU, 0xa34d721642b06084U, + 0xcc20ce9bd35c78a5U, 0xff290242c83396ceU, 0x9f79a169bd203e41U, + 0xc75809c42c684dd1U, 0xf92e0c3537826145U, 0x9bbcc7a142b17ccbU, + 0xc2abf989935ddbfeU, 0xf356f7ebf83552feU, 0x98165af37b2153deU, + 0xbe1bf1b059e9a8d6U, 0xeda2ee1c7064130cU, 0x9485d4d1c63e8be7U, + 0xb9a74a0637ce2ee1U, 0xe8111c87c5c1ba99U, 0x910ab1d4db9914a0U, + 0xb54d5e4a127f59c8U, 0xe2a0b5dc971f303aU, 0x8da471a9de737e24U, + 0xb10d8e1456105dadU, 0xdd50f1996b947518U, 0x8a5296ffe33cc92fU, + 0xace73cbfdc0bfb7bU, 0xd8210befd30efa5aU, 0x8714a775e3e95c78U, + 0xa8d9d1535ce3b396U, 0xd31045a8341ca07cU, 0x83ea2b892091e44dU, + 0xa4e4b66b68b65d60U, 0xce1de40642e3f4b9U, 0x80d2ae83e9ce78f3U, + 0xa1075a24e4421730U, 0xc94930ae1d529cfcU, 0xfb9b7cd9a4a7443cU, + 0x9d412e0806e88aa5U, 0xc491798a08a2ad4eU, 0xf5b5d7ec8acb58a2U, + 0x9991a6f3d6bf1765U, 0xbff610b0cc6edd3fU, 0xeff394dcff8a948eU, + 0x95f83d0a1fb69cd9U, 0xbb764c4ca7a4440fU, 0xea53df5fd18d5513U, + 0x92746b9be2f8552cU, 0xb7118682dbb66a77U, 0xe4d5e82392a40515U, + 0x8f05b1163ba6832dU, 0xb2c71d5bca9023f8U, 0xdf78e4b2bd342cf6U, + 0x8bab8eefb6409c1aU, 0xae9672aba3d0c320U, 0xda3c0f568cc4f3e8U, + 0x8865899617fb1871U, 0xaa7eebfb9df9de8dU, 0xd51ea6fa85785631U, + 0x8533285c936b35deU, 0xa67ff273b8460356U, 0xd01fef10a657842cU, + 0x8213f56a67f6b29bU, 0xa298f2c501f45f42U, 0xcb3f2f7642717713U, + 0xfe0efb53d30dd4d7U, 0x9ec95d1463e8a506U, 0xc67bb4597ce2ce48U, + 0xf81aa16fdc1b81daU, 0x9b10a4e5e9913128U, 0xc1d4ce1f63f57d72U, + 0xf24a01a73cf2dccfU, 0x976e41088617ca01U, 0xbd49d14aa79dbc82U, + 0xec9c459d51852ba2U, 0x93e1ab8252f33b45U, 0xb8da1662e7b00a17U, + 0xe7109bfba19c0c9dU, 0x906a617d450187e2U, 0xb484f9dc9641e9daU, + 0xe1a63853bbd26451U, 0x8d07e33455637eb2U, 0xb049dc016abc5e5fU, + 0xdc5c5301c56b75f7U, 0x89b9b3e11b6329baU, 0xac2820d9623bf429U, + 0xd732290fbacaf133U, 0x867f59a9d4bed6c0U, 0xa81f301449ee8c70U, + 0xd226fc195c6a2f8cU, 0x83585d8fd9c25db7U, 0xa42e74f3d032f525U, + 0xcd3a1230c43fb26fU, 0x80444b5e7aa7cf85U, 0xa0555e361951c366U, + 0xc86ab5c39fa63440U, 0xfa856334878fc150U, 0x9c935e00d4b9d8d2U, + 0xc3b8358109e84f07U, 0xf4a642e14c6262c8U, 0x98e7e9cccfbd7dbdU, + 0xbf21e44003acdd2cU, 0xeeea5d5004981478U, 0x95527a5202df0ccbU, + 0xbaa718e68396cffdU, 0xe950df20247c83fdU, 0x91d28b7416cdd27eU, + 0xb6472e511c81471dU, 0xe3d8f9e563a198e5U, 0x8e679c2f5e44ff8fU, +}; + +const int16_t kPower10ExponentTable[] = { + -1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173, -1170, -1166, + -1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140, -1136, -1133, -1130, + -1127, -1123, -1120, -1117, -1113, -1110, -1107, -1103, -1100, -1097, -1093, + -1090, -1087, -1083, -1080, -1077, -1073, -1070, -1067, -1063, -1060, -1057, + -1053, -1050, -1047, -1043, -1040, -1037, -1034, -1030, -1027, -1024, -1020, + -1017, -1014, -1010, -1007, -1004, -1000, -997, -994, -990, -987, -984, + -980, -977, -974, -970, -967, -964, -960, -957, -954, -950, -947, + -944, -940, -937, -934, -931, -927, -924, -921, -917, -914, -911, + -907, -904, -901, -897, -894, -891, -887, -884, -881, -877, -874, + -871, -867, -864, -861, -857, -854, -851, -847, -844, -841, -838, + -834, -831, -828, -824, -821, -818, -814, -811, -808, -804, -801, + -798, -794, -791, -788, -784, -781, -778, -774, -771, -768, -764, + -761, -758, -754, -751, -748, -744, -741, -738, -735, -731, -728, + -725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691, + -688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655, + -651, -648, -645, -642, -638, -635, -632, -628, -625, -622, -618, + -615, -612, -608, -605, -602, -598, -595, -592, -588, -585, -582, + -578, -575, -572, -568, -565, -562, -558, -555, -552, -549, -545, + -542, -539, -535, -532, -529, -525, -522, -519, -515, -512, -509, + -505, -502, -499, -495, -492, -489, -485, -482, -479, -475, -472, + -469, -465, -462, -459, -455, -452, -449, -446, -442, -439, -436, + -432, -429, -426, -422, -419, -416, -412, -409, -406, -402, -399, + -396, -392, -389, -386, -382, -379, -376, -372, -369, -366, -362, + -359, -356, -353, -349, -346, -343, -339, -336, -333, -329, -326, + -323, -319, -316, -313, -309, -306, -303, -299, -296, -293, -289, + -286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253, + -250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216, + -213, -210, -206, -203, -200, -196, -193, -190, -186, -183, -180, + -176, -173, -170, -166, -163, -160, -157, -153, -150, -147, -143, + -140, -137, -133, -130, -127, -123, -120, -117, -113, -110, -107, + -103, -100, -97, -93, -90, -87, -83, -80, -77, -73, -70, + -67, -63, -60, -57, -54, -50, -47, -44, -40, -37, -34, + -30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3, + 6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 39, + 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76, + 79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113, + 116, 119, 123, 126, 129, 132, 136, 139, 142, 146, 149, + 152, 156, 159, 162, 166, 169, 172, 176, 179, 182, 186, + 189, 192, 196, 199, 202, 206, 209, 212, 216, 219, 222, + 226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259, + 262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295, + 299, 302, 305, 309, 312, 315, 319, 322, 325, 328, 332, + 335, 338, 342, 345, 348, 352, 355, 358, 362, 365, 368, + 372, 375, 378, 382, 385, 388, 392, 395, 398, 402, 405, + 408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441, + 445, 448, 451, 455, 458, 461, 465, 468, 471, 475, 478, + 481, 485, 488, 491, 495, 498, 501, 505, 508, 511, 515, + 518, 521, 524, 528, 531, 534, 538, 541, 544, 548, 551, + 554, 558, 561, 564, 568, 571, 574, 578, 581, 584, 588, + 591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624, + 627, 631, 634, 637, 641, 644, 647, 651, 654, 657, 661, + 664, 667, 671, 674, 677, 681, 684, 687, 691, 694, 697, + 701, 704, 707, 711, 714, 717, 720, 724, 727, 730, 734, + 737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770, + 774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, + 810, 813, 817, 820, 823, 827, 830, 833, 837, 840, 843, + 847, 850, 853, 857, 860, 863, 867, 870, 873, 877, 880, + 883, 887, 890, 893, 897, 900, 903, 907, 910, 913, 916, + 920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953, + 956, 960, +}; + +} // namespace +} // namespace absl
diff --git a/third_party/abseil-cpp/absl/strings/charconv.h b/third_party/abseil-cpp/absl/strings/charconv.h new file mode 100644 index 0000000..3e313679 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/charconv.h
@@ -0,0 +1,115 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_CHARCONV_H_ +#define ABSL_STRINGS_CHARCONV_H_ + +#include <system_error> // NOLINT(build/c++11) + +namespace absl { + +// Workalike compatibilty version of std::chars_format from C++17. +// +// This is an bitfield enumerator which can be passed to absl::from_chars to +// configure the std::string-to-float conversion. +enum class chars_format { + scientific = 1, + fixed = 2, + hex = 4, + general = fixed | scientific, +}; + +// The return result of a std::string-to-number conversion. +// +// `ec` will be set to `invalid_argument` if a well-formed number was not found +// at the start of the input range, `result_out_of_range` if a well-formed +// number was found, but it was out of the representable range of the requested +// type, or to std::errc() otherwise. +// +// If a well-formed number was found, `ptr` is set to one past the sequence of +// characters that were successfully parsed. If none was found, `ptr` is set +// to the `first` argument to from_chars. +struct from_chars_result { + const char* ptr; + std::errc ec; +}; + +// Workalike compatibilty version of std::from_chars from C++17. Currently +// this only supports the `double` and `float` types. +// +// This interface incorporates the proposed resolutions for library issues +// DR 3800 and DR 3801. If these are adopted with different wording, +// Abseil's behavior will change to match the standard. (The behavior most +// likely to change is for DR 3801, which says what `value` will be set to in +// the case of overflow and underflow. Code that wants to avoid possible +// breaking changes in this area should not depend on `value` when the returned +// from_chars_result indicates a range error.) +// +// Searches the range [first, last) for the longest matching pattern beginning +// at `first` that represents a floating point number. If one is found, store +// the result in `value`. +// +// The matching pattern format is almost the same as that of strtod(), except +// that C locale is not respected, and an initial '+' character in the input +// range will never be matched. +// +// If `fmt` is set, it must be one of the enumerator values of the chars_format. +// (This is despite the fact that chars_format is a bitmask type.) If set to +// `scientific`, a matching number must contain an exponent. If set to `fixed`, +// then an exponent will never match. (For example, the std::string "1e5" will be +// parsed as "1".) If set to `hex`, then a hexadecimal float is parsed in the +// format that strtod() accepts, except that a "0x" prefix is NOT matched. +// (In particular, in `hex` mode, the input "0xff" results in the largest +// matching pattern "0".) +absl::from_chars_result from_chars(const char* first, const char* last, + double& value, // NOLINT + chars_format fmt = chars_format::general); + +absl::from_chars_result from_chars(const char* first, const char* last, + float& value, // NOLINT + chars_format fmt = chars_format::general); + +// std::chars_format is specified as a bitmask type, which means the following +// operations must be provided: +inline constexpr chars_format operator&(chars_format lhs, chars_format rhs) { + return static_cast<chars_format>(static_cast<int>(lhs) & + static_cast<int>(rhs)); +} +inline constexpr chars_format operator|(chars_format lhs, chars_format rhs) { + return static_cast<chars_format>(static_cast<int>(lhs) | + static_cast<int>(rhs)); +} +inline constexpr chars_format operator^(chars_format lhs, chars_format rhs) { + return static_cast<chars_format>(static_cast<int>(lhs) ^ + static_cast<int>(rhs)); +} +inline constexpr chars_format operator~(chars_format arg) { + return static_cast<chars_format>(~static_cast<int>(arg)); +} +inline chars_format& operator&=(chars_format& lhs, chars_format rhs) { + lhs = lhs & rhs; + return lhs; +} +inline chars_format& operator|=(chars_format& lhs, chars_format rhs) { + lhs = lhs | rhs; + return lhs; +} +inline chars_format& operator^=(chars_format& lhs, chars_format rhs) { + lhs = lhs ^ rhs; + return lhs; +} + +} // namespace absl + +#endif // ABSL_STRINGS_CHARCONV_H_
diff --git a/third_party/abseil-cpp/absl/strings/charconv_benchmark.cc b/third_party/abseil-cpp/absl/strings/charconv_benchmark.cc new file mode 100644 index 0000000..fd83f44 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/charconv_benchmark.cc
@@ -0,0 +1,204 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/charconv.h" + +#include <cstdlib> +#include <cstring> +#include <string> + +#include "benchmark/benchmark.h" + +namespace { + +void BM_Strtod_Pi(benchmark::State& state) { + const char* pi = "3.14159"; + for (auto s : state) { + benchmark::DoNotOptimize(pi); + benchmark::DoNotOptimize(strtod(pi, nullptr)); + } +} +BENCHMARK(BM_Strtod_Pi); + +void BM_Absl_Pi(benchmark::State& state) { + const char* pi = "3.14159"; + const char* pi_end = pi + strlen(pi); + for (auto s : state) { + benchmark::DoNotOptimize(pi); + double v; + absl::from_chars(pi, pi_end, v); + benchmark::DoNotOptimize(v); + } +} +BENCHMARK(BM_Absl_Pi); + +void BM_Strtod_Pi_float(benchmark::State& state) { + const char* pi = "3.14159"; + for (auto s : state) { + benchmark::DoNotOptimize(pi); + benchmark::DoNotOptimize(strtof(pi, nullptr)); + } +} +BENCHMARK(BM_Strtod_Pi_float); + +void BM_Absl_Pi_float(benchmark::State& state) { + const char* pi = "3.14159"; + const char* pi_end = pi + strlen(pi); + for (auto s : state) { + benchmark::DoNotOptimize(pi); + float v; + absl::from_chars(pi, pi_end, v); + benchmark::DoNotOptimize(v); + } +} +BENCHMARK(BM_Absl_Pi_float); + +void BM_Strtod_HardLarge(benchmark::State& state) { + const char* num = "272104041512242479.e200"; + for (auto s : state) { + benchmark::DoNotOptimize(num); + benchmark::DoNotOptimize(strtod(num, nullptr)); + } +} +BENCHMARK(BM_Strtod_HardLarge); + +void BM_Absl_HardLarge(benchmark::State& state) { + const char* numstr = "272104041512242479.e200"; + const char* numstr_end = numstr + strlen(numstr); + for (auto s : state) { + benchmark::DoNotOptimize(numstr); + double v; + absl::from_chars(numstr, numstr_end, v); + benchmark::DoNotOptimize(v); + } +} +BENCHMARK(BM_Absl_HardLarge); + +void BM_Strtod_HardSmall(benchmark::State& state) { + const char* num = "94080055902682397.e-242"; + for (auto s : state) { + benchmark::DoNotOptimize(num); + benchmark::DoNotOptimize(strtod(num, nullptr)); + } +} +BENCHMARK(BM_Strtod_HardSmall); + +void BM_Absl_HardSmall(benchmark::State& state) { + const char* numstr = "94080055902682397.e-242"; + const char* numstr_end = numstr + strlen(numstr); + for (auto s : state) { + benchmark::DoNotOptimize(numstr); + double v; + absl::from_chars(numstr, numstr_end, v); + benchmark::DoNotOptimize(v); + } +} +BENCHMARK(BM_Absl_HardSmall); + +void BM_Strtod_HugeMantissa(benchmark::State& state) { + std::string huge(200, '3'); + const char* num = huge.c_str(); + for (auto s : state) { + benchmark::DoNotOptimize(num); + benchmark::DoNotOptimize(strtod(num, nullptr)); + } +} +BENCHMARK(BM_Strtod_HugeMantissa); + +void BM_Absl_HugeMantissa(benchmark::State& state) { + std::string huge(200, '3'); + const char* num = huge.c_str(); + const char* num_end = num + 200; + for (auto s : state) { + benchmark::DoNotOptimize(num); + double v; + absl::from_chars(num, num_end, v); + benchmark::DoNotOptimize(v); + } +} +BENCHMARK(BM_Absl_HugeMantissa); + +std::string MakeHardCase(int length) { + // The number 1.1521...e-297 is exactly halfway between 12345 * 2**-1000 and + // the next larger representable number. The digits of this number are in + // the std::string below. + const std::string digits = + "1." + "152113937042223790993097181572444900347587985074226836242307364987727724" + "831384300183638649152607195040591791364113930628852279348613864894524591" + "272746490313676832900762939595690019745859128071117417798540258114233761" + "012939937017879509401007964861774960297319002612457273148497158989073482" + "171377406078223015359818300988676687994537274548940612510414856761641652" + "513434981938564294004070500716200446656421722229202383105446378511678258" + "370570631774499359748259931676320916632111681001853983492795053244971606" + "922718923011680846577744433974087653954904214152517799883551075537146316" + "168973685866425605046988661997658648354773076621610279716804960009043764" + "038392994055171112475093876476783502487512538082706095923790634572014823" + "78877699375152587890625" + + std::string(5000, '0'); + // generate the hard cases on either side for the given length. + // Lengths between 3 and 1000 are reasonable. + return digits.substr(0, length) + "1e-297"; +} + +void BM_Strtod_Big_And_Difficult(benchmark::State& state) { + std::string testcase = MakeHardCase(state.range(0)); + const char* begin = testcase.c_str(); + for (auto s : state) { + benchmark::DoNotOptimize(begin); + benchmark::DoNotOptimize(strtod(begin, nullptr)); + } +} +BENCHMARK(BM_Strtod_Big_And_Difficult)->Range(3, 5000); + +void BM_Absl_Big_And_Difficult(benchmark::State& state) { + std::string testcase = MakeHardCase(state.range(0)); + const char* begin = testcase.c_str(); + const char* end = begin + testcase.size(); + for (auto s : state) { + benchmark::DoNotOptimize(begin); + double v; + absl::from_chars(begin, end, v); + benchmark::DoNotOptimize(v); + } +} +BENCHMARK(BM_Absl_Big_And_Difficult)->Range(3, 5000); + +} // namespace + +// ------------------------------------------------------------------------ +// Benchmark Time CPU Iterations +// ------------------------------------------------------------------------ +// BM_Strtod_Pi 96 ns 96 ns 6337454 +// BM_Absl_Pi 35 ns 35 ns 20031996 +// BM_Strtod_Pi_float 91 ns 91 ns 7745851 +// BM_Absl_Pi_float 35 ns 35 ns 20430298 +// BM_Strtod_HardLarge 133 ns 133 ns 5288341 +// BM_Absl_HardLarge 181 ns 181 ns 3855615 +// BM_Strtod_HardSmall 279 ns 279 ns 2517243 +// BM_Absl_HardSmall 287 ns 287 ns 2458744 +// BM_Strtod_HugeMantissa 433 ns 433 ns 1604293 +// BM_Absl_HugeMantissa 160 ns 160 ns 4403671 +// BM_Strtod_Big_And_Difficult/3 236 ns 236 ns 2942496 +// BM_Strtod_Big_And_Difficult/8 232 ns 232 ns 2983796 +// BM_Strtod_Big_And_Difficult/64 437 ns 437 ns 1591951 +// BM_Strtod_Big_And_Difficult/512 1738 ns 1738 ns 402519 +// BM_Strtod_Big_And_Difficult/4096 3943 ns 3943 ns 176128 +// BM_Strtod_Big_And_Difficult/5000 4397 ns 4397 ns 157878 +// BM_Absl_Big_And_Difficult/3 39 ns 39 ns 17799583 +// BM_Absl_Big_And_Difficult/8 43 ns 43 ns 16096859 +// BM_Absl_Big_And_Difficult/64 550 ns 550 ns 1259717 +// BM_Absl_Big_And_Difficult/512 4167 ns 4167 ns 171414 +// BM_Absl_Big_And_Difficult/4096 9160 ns 9159 ns 76297 +// BM_Absl_Big_And_Difficult/5000 9738 ns 9738 ns 70140
diff --git a/third_party/abseil-cpp/absl/strings/charconv_test.cc b/third_party/abseil-cpp/absl/strings/charconv_test.cc new file mode 100644 index 0000000..f8d71cc --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/charconv_test.cc
@@ -0,0 +1,766 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/charconv.h" + +#include <cstdlib> +#include <string> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" + +#ifdef _MSC_FULL_VER +#define ABSL_COMPILER_DOES_EXACT_ROUNDING 0 +#define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 0 +#else +#define ABSL_COMPILER_DOES_EXACT_ROUNDING 1 +#define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 1 +#endif + +namespace { + +#if ABSL_COMPILER_DOES_EXACT_ROUNDING + +// Tests that the given std::string is accepted by absl::from_chars, and that it +// converts exactly equal to the given number. +void TestDoubleParse(absl::string_view str, double expected_number) { + SCOPED_TRACE(str); + double actual_number = 0.0; + absl::from_chars_result result = + absl::from_chars(str.data(), str.data() + str.length(), actual_number); + EXPECT_EQ(result.ec, std::errc()); + EXPECT_EQ(result.ptr, str.data() + str.length()); + EXPECT_EQ(actual_number, expected_number); +} + +void TestFloatParse(absl::string_view str, float expected_number) { + SCOPED_TRACE(str); + float actual_number = 0.0; + absl::from_chars_result result = + absl::from_chars(str.data(), str.data() + str.length(), actual_number); + EXPECT_EQ(result.ec, std::errc()); + EXPECT_EQ(result.ptr, str.data() + str.length()); + EXPECT_EQ(actual_number, expected_number); +} + +// Tests that the given double or single precision floating point literal is +// parsed correctly by absl::from_chars. +// +// These convenience macros assume that the C++ compiler being used also does +// fully correct decimal-to-binary conversions. +#define FROM_CHARS_TEST_DOUBLE(number) \ + { \ + TestDoubleParse(#number, number); \ + TestDoubleParse("-" #number, -number); \ + } + +#define FROM_CHARS_TEST_FLOAT(number) \ + { \ + TestFloatParse(#number, number##f); \ + TestFloatParse("-" #number, -number##f); \ + } + +TEST(FromChars, NearRoundingCases) { + // Cases from "A Program for Testing IEEE Decimal-Binary Conversion" + // by Vern Paxson. + + // Forms that should round towards zero. (These are the hardest cases for + // each decimal mantissa size.) + FROM_CHARS_TEST_DOUBLE(5.e125); + FROM_CHARS_TEST_DOUBLE(69.e267); + FROM_CHARS_TEST_DOUBLE(999.e-026); + FROM_CHARS_TEST_DOUBLE(7861.e-034); + FROM_CHARS_TEST_DOUBLE(75569.e-254); + FROM_CHARS_TEST_DOUBLE(928609.e-261); + FROM_CHARS_TEST_DOUBLE(9210917.e080); + FROM_CHARS_TEST_DOUBLE(84863171.e114); + FROM_CHARS_TEST_DOUBLE(653777767.e273); + FROM_CHARS_TEST_DOUBLE(5232604057.e-298); + FROM_CHARS_TEST_DOUBLE(27235667517.e-109); + FROM_CHARS_TEST_DOUBLE(653532977297.e-123); + FROM_CHARS_TEST_DOUBLE(3142213164987.e-294); + FROM_CHARS_TEST_DOUBLE(46202199371337.e-072); + FROM_CHARS_TEST_DOUBLE(231010996856685.e-073); + FROM_CHARS_TEST_DOUBLE(9324754620109615.e212); + FROM_CHARS_TEST_DOUBLE(78459735791271921.e049); + FROM_CHARS_TEST_DOUBLE(272104041512242479.e200); + FROM_CHARS_TEST_DOUBLE(6802601037806061975.e198); + FROM_CHARS_TEST_DOUBLE(20505426358836677347.e-221); + FROM_CHARS_TEST_DOUBLE(836168422905420598437.e-234); + FROM_CHARS_TEST_DOUBLE(4891559871276714924261.e222); + FROM_CHARS_TEST_FLOAT(5.e-20); + FROM_CHARS_TEST_FLOAT(67.e14); + FROM_CHARS_TEST_FLOAT(985.e15); + FROM_CHARS_TEST_FLOAT(7693.e-42); + FROM_CHARS_TEST_FLOAT(55895.e-16); + FROM_CHARS_TEST_FLOAT(996622.e-44); + FROM_CHARS_TEST_FLOAT(7038531.e-32); + FROM_CHARS_TEST_FLOAT(60419369.e-46); + FROM_CHARS_TEST_FLOAT(702990899.e-20); + FROM_CHARS_TEST_FLOAT(6930161142.e-48); + FROM_CHARS_TEST_FLOAT(25933168707.e-13); + FROM_CHARS_TEST_FLOAT(596428896559.e20); + + // Similarly, forms that should round away from zero. + FROM_CHARS_TEST_DOUBLE(9.e-265); + FROM_CHARS_TEST_DOUBLE(85.e-037); + FROM_CHARS_TEST_DOUBLE(623.e100); + FROM_CHARS_TEST_DOUBLE(3571.e263); + FROM_CHARS_TEST_DOUBLE(81661.e153); + FROM_CHARS_TEST_DOUBLE(920657.e-023); + FROM_CHARS_TEST_DOUBLE(4603285.e-024); + FROM_CHARS_TEST_DOUBLE(87575437.e-309); + FROM_CHARS_TEST_DOUBLE(245540327.e122); + FROM_CHARS_TEST_DOUBLE(6138508175.e120); + FROM_CHARS_TEST_DOUBLE(83356057653.e193); + FROM_CHARS_TEST_DOUBLE(619534293513.e124); + FROM_CHARS_TEST_DOUBLE(2335141086879.e218); + FROM_CHARS_TEST_DOUBLE(36167929443327.e-159); + FROM_CHARS_TEST_DOUBLE(609610927149051.e-255); + FROM_CHARS_TEST_DOUBLE(3743626360493413.e-165); + FROM_CHARS_TEST_DOUBLE(94080055902682397.e-242); + FROM_CHARS_TEST_DOUBLE(899810892172646163.e283); + FROM_CHARS_TEST_DOUBLE(7120190517612959703.e120); + FROM_CHARS_TEST_DOUBLE(25188282901709339043.e-252); + FROM_CHARS_TEST_DOUBLE(308984926168550152811.e-052); + FROM_CHARS_TEST_DOUBLE(6372891218502368041059.e064); + FROM_CHARS_TEST_FLOAT(3.e-23); + FROM_CHARS_TEST_FLOAT(57.e18); + FROM_CHARS_TEST_FLOAT(789.e-35); + FROM_CHARS_TEST_FLOAT(2539.e-18); + FROM_CHARS_TEST_FLOAT(76173.e28); + FROM_CHARS_TEST_FLOAT(887745.e-11); + FROM_CHARS_TEST_FLOAT(5382571.e-37); + FROM_CHARS_TEST_FLOAT(82381273.e-35); + FROM_CHARS_TEST_FLOAT(750486563.e-38); + FROM_CHARS_TEST_FLOAT(3752432815.e-39); + FROM_CHARS_TEST_FLOAT(75224575729.e-45); + FROM_CHARS_TEST_FLOAT(459926601011.e15); +} + +#undef FROM_CHARS_TEST_DOUBLE +#undef FROM_CHARS_TEST_FLOAT +#endif + +float ToFloat(absl::string_view s) { + float f; + absl::from_chars(s.data(), s.data() + s.size(), f); + return f; +} + +double ToDouble(absl::string_view s) { + double d; + absl::from_chars(s.data(), s.data() + s.size(), d); + return d; +} + +// A duplication of the test cases in "NearRoundingCases" above, but with +// expected values expressed with integers, using ldexp/ldexpf. These test +// cases will work even on compilers that do not accurately round floating point +// literals. +TEST(FromChars, NearRoundingCasesExplicit) { + EXPECT_EQ(ToDouble("5.e125"), ldexp(6653062250012735, 365)); + EXPECT_EQ(ToDouble("69.e267"), ldexp(4705683757438170, 841)); + EXPECT_EQ(ToDouble("999.e-026"), ldexp(6798841691080350, -129)); + EXPECT_EQ(ToDouble("7861.e-034"), ldexp(8975675289889240, -153)); + EXPECT_EQ(ToDouble("75569.e-254"), ldexp(6091718967192243, -880)); + EXPECT_EQ(ToDouble("928609.e-261"), ldexp(7849264900213743, -900)); + EXPECT_EQ(ToDouble("9210917.e080"), ldexp(8341110837370930, 236)); + EXPECT_EQ(ToDouble("84863171.e114"), ldexp(4625202867375927, 353)); + EXPECT_EQ(ToDouble("653777767.e273"), ldexp(5068902999763073, 884)); + EXPECT_EQ(ToDouble("5232604057.e-298"), ldexp(5741343011915040, -1010)); + EXPECT_EQ(ToDouble("27235667517.e-109"), ldexp(6707124626673586, -380)); + EXPECT_EQ(ToDouble("653532977297.e-123"), ldexp(7078246407265384, -422)); + EXPECT_EQ(ToDouble("3142213164987.e-294"), ldexp(8219991337640559, -988)); + EXPECT_EQ(ToDouble("46202199371337.e-072"), ldexp(5224462102115359, -246)); + EXPECT_EQ(ToDouble("231010996856685.e-073"), ldexp(5224462102115359, -247)); + EXPECT_EQ(ToDouble("9324754620109615.e212"), ldexp(5539753864394442, 705)); + EXPECT_EQ(ToDouble("78459735791271921.e049"), ldexp(8388176519442766, 166)); + EXPECT_EQ(ToDouble("272104041512242479.e200"), ldexp(5554409530847367, 670)); + EXPECT_EQ(ToDouble("6802601037806061975.e198"), ldexp(5554409530847367, 668)); + EXPECT_EQ(ToDouble("20505426358836677347.e-221"), + ldexp(4524032052079546, -722)); + EXPECT_EQ(ToDouble("836168422905420598437.e-234"), + ldexp(5070963299887562, -760)); + EXPECT_EQ(ToDouble("4891559871276714924261.e222"), + ldexp(6452687840519111, 757)); + EXPECT_EQ(ToFloat("5.e-20"), ldexpf(15474250, -88)); + EXPECT_EQ(ToFloat("67.e14"), ldexpf(12479722, 29)); + EXPECT_EQ(ToFloat("985.e15"), ldexpf(14333636, 36)); + EXPECT_EQ(ToFloat("7693.e-42"), ldexpf(10979816, -150)); + EXPECT_EQ(ToFloat("55895.e-16"), ldexpf(12888509, -61)); + EXPECT_EQ(ToFloat("996622.e-44"), ldexpf(14224264, -150)); + EXPECT_EQ(ToFloat("7038531.e-32"), ldexpf(11420669, -107)); + EXPECT_EQ(ToFloat("60419369.e-46"), ldexpf(8623340, -150)); + EXPECT_EQ(ToFloat("702990899.e-20"), ldexpf(16209866, -61)); + EXPECT_EQ(ToFloat("6930161142.e-48"), ldexpf(9891056, -150)); + EXPECT_EQ(ToFloat("25933168707.e-13"), ldexpf(11138211, -32)); + EXPECT_EQ(ToFloat("596428896559.e20"), ldexpf(12333860, 82)); + + + EXPECT_EQ(ToDouble("9.e-265"), ldexp(8168427841980010, -930)); + EXPECT_EQ(ToDouble("85.e-037"), ldexp(6360455125664090, -169)); + EXPECT_EQ(ToDouble("623.e100"), ldexp(6263531988747231, 289)); + EXPECT_EQ(ToDouble("3571.e263"), ldexp(6234526311072170, 833)); + EXPECT_EQ(ToDouble("81661.e153"), ldexp(6696636728760206, 472)); + EXPECT_EQ(ToDouble("920657.e-023"), ldexp(5975405561110124, -109)); + EXPECT_EQ(ToDouble("4603285.e-024"), ldexp(5975405561110124, -110)); + EXPECT_EQ(ToDouble("87575437.e-309"), ldexp(8452160731874668, -1053)); + EXPECT_EQ(ToDouble("245540327.e122"), ldexp(4985336549131723, 381)); + EXPECT_EQ(ToDouble("6138508175.e120"), ldexp(4985336549131723, 379)); + EXPECT_EQ(ToDouble("83356057653.e193"), ldexp(5986732817132056, 625)); + EXPECT_EQ(ToDouble("619534293513.e124"), ldexp(4798406992060657, 399)); + EXPECT_EQ(ToDouble("2335141086879.e218"), ldexp(5419088166961646, 713)); + EXPECT_EQ(ToDouble("36167929443327.e-159"), ldexp(8135819834632444, -536)); + EXPECT_EQ(ToDouble("609610927149051.e-255"), ldexp(4576664294594737, -850)); + EXPECT_EQ(ToDouble("3743626360493413.e-165"), ldexp(6898586531774201, -549)); + EXPECT_EQ(ToDouble("94080055902682397.e-242"), ldexp(6273271706052298, -800)); + EXPECT_EQ(ToDouble("899810892172646163.e283"), ldexp(7563892574477827, 947)); + EXPECT_EQ(ToDouble("7120190517612959703.e120"), ldexp(5385467232557565, 409)); + EXPECT_EQ(ToDouble("25188282901709339043.e-252"), + ldexp(5635662608542340, -825)); + EXPECT_EQ(ToDouble("308984926168550152811.e-052"), + ldexp(5644774693823803, -157)); + EXPECT_EQ(ToDouble("6372891218502368041059.e064"), + ldexp(4616868614322430, 233)); + + EXPECT_EQ(ToFloat("3.e-23"), ldexpf(9507380, -98)); + EXPECT_EQ(ToFloat("57.e18"), ldexpf(12960300, 42)); + EXPECT_EQ(ToFloat("789.e-35"), ldexpf(10739312, -130)); + EXPECT_EQ(ToFloat("2539.e-18"), ldexpf(11990089, -72)); + EXPECT_EQ(ToFloat("76173.e28"), ldexpf(9845130, 86)); + EXPECT_EQ(ToFloat("887745.e-11"), ldexpf(9760860, -40)); + EXPECT_EQ(ToFloat("5382571.e-37"), ldexpf(11447463, -124)); + EXPECT_EQ(ToFloat("82381273.e-35"), ldexpf(8554961, -113)); + EXPECT_EQ(ToFloat("750486563.e-38"), ldexpf(9975678, -120)); + EXPECT_EQ(ToFloat("3752432815.e-39"), ldexpf(9975678, -121)); + EXPECT_EQ(ToFloat("75224575729.e-45"), ldexpf(13105970, -137)); + EXPECT_EQ(ToFloat("459926601011.e15"), ldexpf(12466336, 65)); +} + +// Common test logic for converting a std::string which lies exactly halfway between +// two target floats. +// +// mantissa and exponent represent the precise value between two floating point +// numbers, `expected_low` and `expected_high`. The floating point +// representation to parse in `StrCat(mantissa, "e", exponent)`. +// +// This function checks that an input just slightly less than the exact value +// is rounded down to `expected_low`, and an input just slightly greater than +// the exact value is rounded up to `expected_high`. +// +// The exact value should round to `expected_half`, which must be either +// `expected_low` or `expected_high`. +template <typename FloatType> +void TestHalfwayValue(const std::string& mantissa, int exponent, + FloatType expected_low, FloatType expected_high, + FloatType expected_half) { + std::string low_rep = mantissa; + low_rep[low_rep.size() - 1] -= 1; + absl::StrAppend(&low_rep, std::string(1000, '9'), "e", exponent); + + FloatType actual_low = 0; + absl::from_chars(low_rep.data(), low_rep.data() + low_rep.size(), actual_low); + EXPECT_EQ(expected_low, actual_low); + + std::string high_rep = absl::StrCat(mantissa, std::string(1000, '0'), "1e", exponent); + FloatType actual_high = 0; + absl::from_chars(high_rep.data(), high_rep.data() + high_rep.size(), + actual_high); + EXPECT_EQ(expected_high, actual_high); + + std::string halfway_rep = absl::StrCat(mantissa, "e", exponent); + FloatType actual_half = 0; + absl::from_chars(halfway_rep.data(), halfway_rep.data() + halfway_rep.size(), + actual_half); + EXPECT_EQ(expected_half, actual_half); +} + +TEST(FromChars, DoubleRounding) { + const double zero = 0.0; + const double first_subnormal = nextafter(zero, 1.0); + const double second_subnormal = nextafter(first_subnormal, 1.0); + + const double first_normal = DBL_MIN; + const double last_subnormal = nextafter(first_normal, 0.0); + const double second_normal = nextafter(first_normal, 1.0); + + const double last_normal = DBL_MAX; + const double penultimate_normal = nextafter(last_normal, 0.0); + + // Various test cases for numbers between two representable floats. Each + // call to TestHalfwayValue tests a number just below and just above the + // halfway point, as well as the number exactly between them. + + // Test between zero and first_subnormal. Round-to-even tie rounds down. + TestHalfwayValue( + "2." + "470328229206232720882843964341106861825299013071623822127928412503377536" + "351043759326499181808179961898982823477228588654633283551779698981993873" + "980053909390631503565951557022639229085839244910518443593180284993653615" + "250031937045767824921936562366986365848075700158576926990370631192827955" + "855133292783433840935197801553124659726357957462276646527282722005637400" + "648549997709659947045402082816622623785739345073633900796776193057750674" + "017632467360096895134053553745851666113422376667860416215968046191446729" + "184030053005753084904876539171138659164623952491262365388187963623937328" + "042389101867234849766823508986338858792562830275599565752445550725518931" + "369083625477918694866799496832404970582102851318545139621383772282614543" + "7693412532098591327667236328125", + -324, zero, first_subnormal, zero); + + // first_subnormal and second_subnormal. Round-to-even tie rounds up. + TestHalfwayValue( + "7." + "410984687618698162648531893023320585475897039214871466383785237510132609" + "053131277979497545424539885696948470431685765963899850655339096945981621" + "940161728171894510697854671067917687257517734731555330779540854980960845" + "750095811137303474765809687100959097544227100475730780971111893578483867" + "565399878350301522805593404659373979179073872386829939581848166016912201" + "945649993128979841136206248449867871357218035220901702390328579173252022" + "052897402080290685402160661237554998340267130003581248647904138574340187" + "552090159017259254714629617513415977493871857473787096164563890871811984" + "127167305601704549300470526959016576377688490826798697257336652176556794" + "107250876433756084600398490497214911746308553955635418864151316847843631" + "3080237596295773983001708984375", + -324, first_subnormal, second_subnormal, second_subnormal); + + // last_subnormal and first_normal. Round-to-even tie rounds up. + TestHalfwayValue( + "2." + "225073858507201136057409796709131975934819546351645648023426109724822222" + "021076945516529523908135087914149158913039621106870086438694594645527657" + "207407820621743379988141063267329253552286881372149012981122451451889849" + "057222307285255133155755015914397476397983411801999323962548289017107081" + "850690630666655994938275772572015763062690663332647565300009245888316433" + "037779791869612049497390377829704905051080609940730262937128958950003583" + "799967207254304360284078895771796150945516748243471030702609144621572289" + "880258182545180325707018860872113128079512233426288368622321503775666622" + "503982534335974568884423900265498198385487948292206894721689831099698365" + "846814022854243330660339850886445804001034933970427567186443383770486037" + "86162277173854562306587467901408672332763671875", + -308, last_subnormal, first_normal, first_normal); + + // first_normal and second_normal. Round-to-even tie rounds down. + TestHalfwayValue( + "2." + "225073858507201630123055637955676152503612414573018013083228724049586647" + "606759446192036794116886953213985520549032000903434781884412325572184367" + "563347617020518175998922941393629966742598285899994830148971433555578567" + "693279306015978183162142425067962460785295885199272493577688320732492479" + "924816869232247165964934329258783950102250973957579510571600738343645738" + "494324192997092179207389919761694314131497173265255020084997973676783743" + "155205818804439163810572367791175177756227497413804253387084478193655533" + "073867420834526162513029462022730109054820067654020201547112002028139700" + "141575259123440177362244273712468151750189745559978653234255886219611516" + "335924167958029604477064946470184777360934300451421683607013647479513962" + "13837722826145437693412532098591327667236328125", + -308, first_normal, second_normal, first_normal); + + // penultimate_normal and last_normal. Round-to-even rounds down. + TestHalfwayValue( + "1." + "797693134862315608353258760581052985162070023416521662616611746258695532" + "672923265745300992879465492467506314903358770175220871059269879629062776" + "047355692132901909191523941804762171253349609463563872612866401980290377" + "995141836029815117562837277714038305214839639239356331336428021390916694" + "57927874464075218944", + 308, penultimate_normal, last_normal, penultimate_normal); +} + +// Same test cases as DoubleRounding, now with new and improved Much Smaller +// Precision! +TEST(FromChars, FloatRounding) { + const float zero = 0.0; + const float first_subnormal = nextafterf(zero, 1.0); + const float second_subnormal = nextafterf(first_subnormal, 1.0); + + const float first_normal = FLT_MIN; + const float last_subnormal = nextafterf(first_normal, 0.0); + const float second_normal = nextafterf(first_normal, 1.0); + + const float last_normal = FLT_MAX; + const float penultimate_normal = nextafterf(last_normal, 0.0); + + // Test between zero and first_subnormal. Round-to-even tie rounds down. + TestHalfwayValue( + "7." + "006492321624085354618647916449580656401309709382578858785341419448955413" + "42930300743319094181060791015625", + -46, zero, first_subnormal, zero); + + // first_subnormal and second_subnormal. Round-to-even tie rounds up. + TestHalfwayValue( + "2." + "101947696487225606385594374934874196920392912814773657635602425834686624" + "028790902229957282543182373046875", + -45, first_subnormal, second_subnormal, second_subnormal); + + // last_subnormal and first_normal. Round-to-even tie rounds up. + TestHalfwayValue( + "1." + "175494280757364291727882991035766513322858992758990427682963118425003064" + "9651730385585324256680905818939208984375", + -38, last_subnormal, first_normal, first_normal); + + // first_normal and second_normal. Round-to-even tie rounds down. + TestHalfwayValue( + "1." + "175494420887210724209590083408724842314472120785184615334540294131831453" + "9442813071445925743319094181060791015625", + -38, first_normal, second_normal, first_normal); + + // penultimate_normal and last_normal. Round-to-even rounds down. + TestHalfwayValue("3.40282336497324057985868971510891282432", 38, + penultimate_normal, last_normal, penultimate_normal); +} + +TEST(FromChars, Underflow) { + // Check that underflow is handled correctly, according to the specification + // in DR 3081. + double d; + float f; + absl::from_chars_result result; + + std::string negative_underflow = "-1e-1000"; + const char* begin = negative_underflow.data(); + const char* end = begin + negative_underflow.size(); + d = 100.0; + result = absl::from_chars(begin, end, d); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_TRUE(std::signbit(d)); // negative + EXPECT_GE(d, -std::numeric_limits<double>::min()); + f = 100.0; + result = absl::from_chars(begin, end, f); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_TRUE(std::signbit(f)); // negative + EXPECT_GE(f, -std::numeric_limits<float>::min()); + + std::string positive_underflow = "1e-1000"; + begin = positive_underflow.data(); + end = begin + positive_underflow.size(); + d = -100.0; + result = absl::from_chars(begin, end, d); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_FALSE(std::signbit(d)); // positive + EXPECT_LE(d, std::numeric_limits<double>::min()); + f = -100.0; + result = absl::from_chars(begin, end, f); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_FALSE(std::signbit(f)); // positive + EXPECT_LE(f, std::numeric_limits<float>::min()); +} + +TEST(FromChars, Overflow) { + // Check that overflow is handled correctly, according to the specification + // in DR 3081. + double d; + float f; + absl::from_chars_result result; + + std::string negative_overflow = "-1e1000"; + const char* begin = negative_overflow.data(); + const char* end = begin + negative_overflow.size(); + d = 100.0; + result = absl::from_chars(begin, end, d); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_TRUE(std::signbit(d)); // negative + EXPECT_EQ(d, -std::numeric_limits<double>::max()); + f = 100.0; + result = absl::from_chars(begin, end, f); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_TRUE(std::signbit(f)); // negative + EXPECT_EQ(f, -std::numeric_limits<float>::max()); + + std::string positive_overflow = "1e1000"; + begin = positive_overflow.data(); + end = begin + positive_overflow.size(); + d = -100.0; + result = absl::from_chars(begin, end, d); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_FALSE(std::signbit(d)); // positive + EXPECT_EQ(d, std::numeric_limits<double>::max()); + f = -100.0; + result = absl::from_chars(begin, end, f); + EXPECT_EQ(result.ptr, end); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_FALSE(std::signbit(f)); // positive + EXPECT_EQ(f, std::numeric_limits<float>::max()); +} + +TEST(FromChars, ReturnValuePtr) { + // Check that `ptr` points one past the number scanned, even if that number + // is not representable. + double d; + absl::from_chars_result result; + + std::string normal = "3.14@#$%@#$%"; + result = absl::from_chars(normal.data(), normal.data() + normal.size(), d); + EXPECT_EQ(result.ec, std::errc()); + EXPECT_EQ(result.ptr - normal.data(), 4); + + std::string overflow = "1e1000@#$%@#$%"; + result = absl::from_chars(overflow.data(), + overflow.data() + overflow.size(), d); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_EQ(result.ptr - overflow.data(), 6); + + std::string garbage = "#$%@#$%"; + result = absl::from_chars(garbage.data(), + garbage.data() + garbage.size(), d); + EXPECT_EQ(result.ec, std::errc::invalid_argument); + EXPECT_EQ(result.ptr - garbage.data(), 0); +} + +// Check for a wide range of inputs that strtod() and absl::from_chars() exactly +// agree on the conversion amount. +// +// This test assumes the platform's strtod() uses perfect round_to_nearest +// rounding. +TEST(FromChars, TestVersusStrtod) { + for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) { + for (int exponent = -300; exponent < 300; ++exponent) { + std::string candidate = absl::StrCat(mantissa, "e", exponent); + double strtod_value = strtod(candidate.c_str(), nullptr); + double absl_value = 0; + absl::from_chars(candidate.data(), candidate.data() + candidate.size(), + absl_value); + ASSERT_EQ(strtod_value, absl_value) << candidate; + } + } +} + +// Check for a wide range of inputs that strtof() and absl::from_chars() exactly +// agree on the conversion amount. +// +// This test assumes the platform's strtof() uses perfect round_to_nearest +// rounding. +TEST(FromChars, TestVersusStrtof) { + for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) { + for (int exponent = -43; exponent < 32; ++exponent) { + std::string candidate = absl::StrCat(mantissa, "e", exponent); + float strtod_value = strtof(candidate.c_str(), nullptr); + float absl_value = 0; + absl::from_chars(candidate.data(), candidate.data() + candidate.size(), + absl_value); + ASSERT_EQ(strtod_value, absl_value) << candidate; + } + } +} + +// Tests if two floating point values have identical bit layouts. (EXPECT_EQ +// is not suitable for NaN testing, since NaNs are never equal.) +template <typename Float> +bool Identical(Float a, Float b) { + return 0 == memcmp(&a, &b, sizeof(Float)); +} + +// Check that NaNs are parsed correctly. The spec requires that +// std::from_chars on "NaN(123abc)" return the same value as std::nan("123abc"). +// How such an n-char-sequence affects the generated NaN is unspecified, so we +// just test for symmetry with std::nan and strtod here. +// +// (In Linux, this parses the value as a number and stuffs that number into the +// free bits of a quiet NaN.) +TEST(FromChars, NaNDoubles) { + for (std::string n_char_sequence : + {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000", + "8000000000000", "abc123", "legal_but_unexpected", + "99999999999999999999999", "_"}) { + std::string input = absl::StrCat("nan(", n_char_sequence, ")"); + SCOPED_TRACE(input); + double from_chars_double; + absl::from_chars(input.data(), input.data() + input.size(), + from_chars_double); + double std_nan_double = std::nan(n_char_sequence.c_str()); + EXPECT_TRUE(Identical(from_chars_double, std_nan_double)); + + // Also check that we match strtod()'s behavior. This test assumes that the + // platform has a compliant strtod(). +#if ABSL_STRTOD_HANDLES_NAN_CORRECTLY + double strtod_double = strtod(input.c_str(), nullptr); + EXPECT_TRUE(Identical(from_chars_double, strtod_double)); +#endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY + + // Check that we can parse a negative NaN + std::string negative_input = "-" + input; + double negative_from_chars_double; + absl::from_chars(negative_input.data(), + negative_input.data() + negative_input.size(), + negative_from_chars_double); + EXPECT_TRUE(std::signbit(negative_from_chars_double)); + EXPECT_FALSE(Identical(negative_from_chars_double, from_chars_double)); + from_chars_double = std::copysign(from_chars_double, -1.0); + EXPECT_TRUE(Identical(negative_from_chars_double, from_chars_double)); + } +} + +TEST(FromChars, NaNFloats) { + for (std::string n_char_sequence : + {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000", + "8000000000000", "abc123", "legal_but_unexpected", + "99999999999999999999999", "_"}) { + std::string input = absl::StrCat("nan(", n_char_sequence, ")"); + SCOPED_TRACE(input); + float from_chars_float; + absl::from_chars(input.data(), input.data() + input.size(), + from_chars_float); + float std_nan_float = std::nanf(n_char_sequence.c_str()); + EXPECT_TRUE(Identical(from_chars_float, std_nan_float)); + + // Also check that we match strtof()'s behavior. This test assumes that the + // platform has a compliant strtof(). +#if ABSL_STRTOD_HANDLES_NAN_CORRECTLY + float strtof_float = strtof(input.c_str(), nullptr); + EXPECT_TRUE(Identical(from_chars_float, strtof_float)); +#endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY + + // Check that we can parse a negative NaN + std::string negative_input = "-" + input; + float negative_from_chars_float; + absl::from_chars(negative_input.data(), + negative_input.data() + negative_input.size(), + negative_from_chars_float); + EXPECT_TRUE(std::signbit(negative_from_chars_float)); + EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float)); + from_chars_float = std::copysign(from_chars_float, -1.0); + EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float)); + } +} + +// Returns an integer larger than step. The values grow exponentially. +int NextStep(int step) { + return step + (step >> 2) + 1; +} + +// Test a conversion on a family of input strings, checking that the calculation +// is correct for in-bounds values, and that overflow and underflow are done +// correctly for out-of-bounds values. +// +// input_generator maps from an integer index to a std::string to test. +// expected_generator maps from an integer index to an expected Float value. +// from_chars conversion of input_generator(i) should result in +// expected_generator(i). +// +// lower_bound and upper_bound denote the smallest and largest values for which +// the conversion is expected to succeed. +template <typename Float> +void TestOverflowAndUnderflow( + const std::function<std::string(int)>& input_generator, + const std::function<Float(int)>& expected_generator, int lower_bound, + int upper_bound) { + // test legal values near lower_bound + int index, step; + for (index = lower_bound, step = 1; index < upper_bound; + index += step, step = NextStep(step)) { + std::string input = input_generator(index); + SCOPED_TRACE(input); + Float expected = expected_generator(index); + Float actual; + auto result = + absl::from_chars(input.data(), input.data() + input.size(), actual); + EXPECT_EQ(result.ec, std::errc()); + EXPECT_EQ(expected, actual); + } + // test legal values near upper_bound + for (index = upper_bound, step = 1; index > lower_bound; + index -= step, step = NextStep(step)) { + std::string input = input_generator(index); + SCOPED_TRACE(input); + Float expected = expected_generator(index); + Float actual; + auto result = + absl::from_chars(input.data(), input.data() + input.size(), actual); + EXPECT_EQ(result.ec, std::errc()); + EXPECT_EQ(expected, actual); + } + // Test underflow values below lower_bound + for (index = lower_bound - 1, step = 1; index > -1000000; + index -= step, step = NextStep(step)) { + std::string input = input_generator(index); + SCOPED_TRACE(input); + Float actual; + auto result = + absl::from_chars(input.data(), input.data() + input.size(), actual); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_LT(actual, 1.0); // check for underflow + } + // Test overflow values above upper_bound + for (index = upper_bound + 1, step = 1; index < 1000000; + index += step, step = NextStep(step)) { + std::string input = input_generator(index); + SCOPED_TRACE(input); + Float actual; + auto result = + absl::from_chars(input.data(), input.data() + input.size(), actual); + EXPECT_EQ(result.ec, std::errc::result_out_of_range); + EXPECT_GT(actual, 1.0); // check for overflow + } +} + +// Check that overflow and underflow are caught correctly for hex doubles. +// +// The largest representable double is 0x1.fffffffffffffp+1023, and the +// smallest representable subnormal is 0x0.0000000000001p-1022, which equals +// 0x1p-1074. Therefore 1023 and -1074 are the limits of acceptable exponents +// in this test. +TEST(FromChars, HexdecimalDoubleLimits) { + auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); }; + auto expected_gen = [](int index) { return std::ldexp(1.0, index); }; + TestOverflowAndUnderflow<double>(input_gen, expected_gen, -1074, 1023); +} + +// Check that overflow and underflow are caught correctly for hex floats. +// +// The largest representable float is 0x1.fffffep+127, and the smallest +// representable subnormal is 0x0.000002p-126, which equals 0x1p-149. +// Therefore 127 and -149 are the limits of acceptable exponents in this test. +TEST(FromChars, HexdecimalFloatLimits) { + auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); }; + auto expected_gen = [](int index) { return std::ldexp(1.0f, index); }; + TestOverflowAndUnderflow<float>(input_gen, expected_gen, -149, 127); +} + +// Check that overflow and underflow are caught correctly for decimal doubles. +// +// The largest representable double is about 1.8e308, and the smallest +// representable subnormal is about 5e-324. '1e-324' therefore rounds away from +// the smallest representable positive value. -323 and 308 are the limits of +// acceptable exponents in this test. +TEST(FromChars, DecimalDoubleLimits) { + auto input_gen = [](int index) { return absl::StrCat("1.0e", index); }; + auto expected_gen = [](int index) { return std::pow(10.0, index); }; + TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308); +} + +// Check that overflow and underflow are caught correctly for decimal floats. +// +// The largest representable float is about 3.4e38, and the smallest +// representable subnormal is about 1.45e-45. '1e-45' therefore rounds towards +// the smallest representable positive value. -45 and 38 are the limits of +// acceptable exponents in this test. +TEST(FromChars, DecimalFloatLimits) { + auto input_gen = [](int index) { return absl::StrCat("1.0e", index); }; + auto expected_gen = [](int index) { return std::pow(10.0, index); }; + TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38); +} + +} // namespace
diff --git a/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc b/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc new file mode 100644 index 0000000..3e7296e --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc
@@ -0,0 +1,357 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/charconv_bigint.h" + +#include <algorithm> +#include <cassert> +#include <string> + +namespace absl { +namespace strings_internal { + +namespace { + +// Table containing some large powers of 5, for fast computation. + +// Constant step size for entries in the kLargePowersOfFive table. Each entry +// is larger than the previous entry by a factor of 5**kLargePowerOfFiveStep +// (or 5**27). +// +// In other words, the Nth entry in the table is 5**(27*N). +// +// 5**27 is the largest power of 5 that fits in 64 bits. +constexpr int kLargePowerOfFiveStep = 27; + +// The largest legal index into the kLargePowersOfFive table. +// +// In other words, the largest precomputed power of 5 is 5**(27*20). +constexpr int kLargestPowerOfFiveIndex = 20; + +// Table of powers of (5**27), up to (5**27)**20 == 5**540. +// +// Used to generate large powers of 5 while limiting the number of repeated +// multiplications required. +// +// clang-format off +const uint32_t kLargePowersOfFive[] = { +// 5**27 (i=1), start=0, end=2 + 0xfa10079dU, 0x6765c793U, +// 5**54 (i=2), start=2, end=6 + 0x97d9f649U, 0x6664242dU, 0x29939b14U, 0x29c30f10U, +// 5**81 (i=3), start=6, end=12 + 0xc4f809c5U, 0x7bf3f22aU, 0x67bdae34U, 0xad340517U, 0x369d1b5fU, 0x10de1593U, +// 5**108 (i=4), start=12, end=20 + 0x92b260d1U, 0x9efff7c7U, 0x81de0ec6U, 0xaeba5d56U, 0x410664a4U, 0x4f40737aU, + 0x20d3846fU, 0x06d00f73U, +// 5**135 (i=5), start=20, end=30 + 0xff1b172dU, 0x13a1d71cU, 0xefa07617U, 0x7f682d3dU, 0xff8c90c0U, 0x3f0131e7U, + 0x3fdcb9feU, 0x917b0177U, 0x16c407a7U, 0x02c06b9dU, +// 5**162 (i=6), start=30, end=42 + 0x960f7199U, 0x056667ecU, 0xe07aefd8U, 0x80f2b9ccU, 0x8273f5e3U, 0xeb9a214aU, + 0x40b38005U, 0x0e477ad4U, 0x277d08e6U, 0xfa28b11eU, 0xd3f7d784U, 0x011c835bU, +// 5**189 (i=7), start=42, end=56 + 0xf723d9d5U, 0x3282d3f3U, 0xe00857d1U, 0x69659d25U, 0x2cf117cfU, 0x24da6d07U, + 0x954d1417U, 0x3e5d8cedU, 0x7a8bb766U, 0xfd785ae6U, 0x645436d2U, 0x40c78b34U, + 0x94151217U, 0x0072e9f7U, +// 5**216 (i=8), start=56, end=72 + 0x2b416aa1U, 0x7893c5a7U, 0xe37dc6d4U, 0x2bad2beaU, 0xf0fc846cU, 0x7575ae4bU, + 0x62587b14U, 0x83b67a34U, 0x02110cdbU, 0xf7992f55U, 0x00deb022U, 0xa4a23becU, + 0x8af5c5cdU, 0xb85b654fU, 0x818df38bU, 0x002e69d2U, +// 5**243 (i=9), start=72, end=90 + 0x3518cbbdU, 0x20b0c15fU, 0x38756c2fU, 0xfb5dc3ddU, 0x22ad2d94U, 0xbf35a952U, + 0xa699192aU, 0x9a613326U, 0xad2a9cedU, 0xd7f48968U, 0xe87dfb54U, 0xc8f05db6U, + 0x5ef67531U, 0x31c1ab49U, 0xe202ac9fU, 0x9b2957b5U, 0xa143f6d3U, 0x0012bf07U, +// 5**270 (i=10), start=90, end=110 + 0x8b971de9U, 0x21aba2e1U, 0x63944362U, 0x57172336U, 0xd9544225U, 0xfb534166U, + 0x08c563eeU, 0x14640ee2U, 0x24e40d31U, 0x02b06537U, 0x03887f14U, 0x0285e533U, + 0xb744ef26U, 0x8be3a6c4U, 0x266979b4U, 0x6761ece2U, 0xd9cb39e4U, 0xe67de319U, + 0x0d39e796U, 0x00079250U, +// 5**297 (i=11), start=110, end=132 + 0x260eb6e5U, 0xf414a796U, 0xee1a7491U, 0xdb9368ebU, 0xf50c105bU, 0x59157750U, + 0x9ed2fb5cU, 0xf6e56d8bU, 0xeaee8d23U, 0x0f319f75U, 0x2aa134d6U, 0xac2908e9U, + 0xd4413298U, 0x02f02a55U, 0x989d5a7aU, 0x70dde184U, 0xba8040a7U, 0x03200981U, + 0xbe03b11cU, 0x3c1c2a18U, 0xd60427a1U, 0x00030ee0U, +// 5**324 (i=12), start=132, end=156 + 0xce566d71U, 0xf1c4aa25U, 0x4e93ca53U, 0xa72283d0U, 0x551a73eaU, 0x3d0538e2U, + 0x8da4303fU, 0x6a58de60U, 0x0e660221U, 0x49cf61a6U, 0x8d058fc1U, 0xb9d1a14cU, + 0x4bab157dU, 0xc85c6932U, 0x518c8b9eU, 0x9b92b8d0U, 0x0d8a0e21U, 0xbd855df9U, + 0xb3ea59a1U, 0x8da29289U, 0x4584d506U, 0x3752d80fU, 0xb72569c6U, 0x00013c33U, +// 5**351 (i=13), start=156, end=182 + 0x190f354dU, 0x83695cfeU, 0xe5a4d0c7U, 0xb60fb7e8U, 0xee5bbcc4U, 0xb922054cU, + 0xbb4f0d85U, 0x48394028U, 0x1d8957dbU, 0x0d7edb14U, 0x4ecc7587U, 0x505e9e02U, + 0x4c87f36bU, 0x99e66bd6U, 0x44b9ed35U, 0x753037d4U, 0xe5fe5f27U, 0x2742c203U, + 0x13b2ed2bU, 0xdc525d2cU, 0xe6fde59aU, 0x77ffb18fU, 0x13c5752cU, 0x08a84bccU, + 0x859a4940U, 0x00007fb6U, +// 5**378 (i=14), start=182, end=210 + 0x4f98cb39U, 0xa60edbbcU, 0x83b5872eU, 0xa501acffU, 0x9cc76f78U, 0xbadd4c73U, + 0x43e989faU, 0xca7acf80U, 0x2e0c824fU, 0xb19f4ffcU, 0x092fd81cU, 0xe4eb645bU, + 0xa1ff84c2U, 0x8a5a83baU, 0xa8a1fae9U, 0x1db43609U, 0xb0fed50bU, 0x0dd7d2bdU, + 0x7d7accd8U, 0x91fa640fU, 0x37dcc6c5U, 0x1c417fd5U, 0xe4d462adU, 0xe8a43399U, + 0x131bf9a5U, 0x8df54d29U, 0x36547dc1U, 0x00003395U, +// 5**405 (i=15), start=210, end=240 + 0x5bd330f5U, 0x77d21967U, 0x1ac481b7U, 0x6be2f7ceU, 0x7f4792a9U, 0xe84c2c52U, + 0x84592228U, 0x9dcaf829U, 0xdab44ce1U, 0x3d0c311bU, 0x532e297dU, 0x4704e8b4U, + 0x9cdc32beU, 0x41e64d9dU, 0x7717bea1U, 0xa824c00dU, 0x08f50b27U, 0x0f198d77U, + 0x49bbfdf0U, 0x025c6c69U, 0xd4e55cd3U, 0xf083602bU, 0xb9f0fecdU, 0xc0864aeaU, + 0x9cb98681U, 0xaaf620e9U, 0xacb6df30U, 0x4faafe66U, 0x8af13c3bU, 0x000014d5U, +// 5**432 (i=16), start=240, end=272 + 0x682bb941U, 0x89a9f297U, 0xcba75d7bU, 0x404217b1U, 0xb4e519e9U, 0xa1bc162bU, + 0xf7f5910aU, 0x98715af5U, 0x2ff53e57U, 0xe3ef118cU, 0x490c4543U, 0xbc9b1734U, + 0x2affbe4dU, 0x4cedcb4cU, 0xfb14e99eU, 0x35e34212U, 0xece39c24U, 0x07673ab3U, + 0xe73115ddU, 0xd15d38e7U, 0x093eed3bU, 0xf8e7eac5U, 0x78a8cc80U, 0x25227aacU, + 0x3f590551U, 0x413da1cbU, 0xdf643a55U, 0xab65ad44U, 0xd70b23d7U, 0xc672cd76U, + 0x3364ea62U, 0x0000086aU, +// 5**459 (i=17), start=272, end=306 + 0x22f163ddU, 0x23cf07acU, 0xbe2af6c2U, 0xf412f6f6U, 0xc3ff541eU, 0x6eeaf7deU, + 0xa47047e0U, 0x408cda92U, 0x0f0eeb08U, 0x56deba9dU, 0xcfc6b090U, 0x8bbbdf04U, + 0x3933cdb3U, 0x9e7bb67dU, 0x9f297035U, 0x38946244U, 0xee1d37bbU, 0xde898174U, + 0x63f3559dU, 0x705b72fbU, 0x138d27d9U, 0xf8603a78U, 0x735eec44U, 0xe30987d5U, + 0xc6d38070U, 0x9cfe548eU, 0x9ff01422U, 0x7c564aa8U, 0x91cc60baU, 0xcbc3565dU, + 0x7550a50bU, 0x6909aeadU, 0x13234c45U, 0x00000366U, +// 5**486 (i=18), start=306, end=342 + 0x17954989U, 0x3a7d7709U, 0x98042de5U, 0xa9011443U, 0x45e723c2U, 0x269ffd6fU, + 0x58852a46U, 0xaaa1042aU, 0x2eee8153U, 0xb2b6c39eU, 0xaf845b65U, 0xf6c365d7U, + 0xe4cffb2bU, 0xc840e90cU, 0xabea8abbU, 0x5c58f8d2U, 0x5c19fa3aU, 0x4670910aU, + 0x4449f21cU, 0xefa645b3U, 0xcc427decU, 0x083c3d73U, 0x467cb413U, 0x6fe10ae4U, + 0x3caffc72U, 0x9f8da55eU, 0x5e5c8ea7U, 0x490594bbU, 0xf0871b0bU, 0xdd89816cU, + 0x8e931df8U, 0xe85ce1c9U, 0xcca090a5U, 0x575fa16bU, 0x6b9f106cU, 0x0000015fU, +// 5**513 (i=19), start=342, end=380 + 0xee20d805U, 0x57bc3c07U, 0xcdea624eU, 0xd3f0f52dU, 0x9924b4f4U, 0xcf968640U, + 0x61d41962U, 0xe87fb464U, 0xeaaf51c7U, 0x564c8b60U, 0xccda4028U, 0x529428bbU, + 0x313a1fa8U, 0x96bd0f94U, 0x7a82ebaaU, 0xad99e7e9U, 0xf2668cd4U, 0xbe33a45eU, + 0xfd0db669U, 0x87ee369fU, 0xd3ec20edU, 0x9c4d7db7U, 0xdedcf0d8U, 0x7cd2ca64U, + 0xe25a6577U, 0x61003fd4U, 0xe56f54ccU, 0x10b7c748U, 0x40526e5eU, 0x7300ae87U, + 0x5c439261U, 0x2c0ff469U, 0xbf723f12U, 0xb2379b61U, 0xbf59b4f5U, 0xc91b1c3fU, + 0xf0046d27U, 0x0000008dU, +// 5**540 (i=20), start=380, end=420 + 0x525c9e11U, 0xf4e0eb41U, 0xebb2895dU, 0x5da512f9U, 0x7d9b29d4U, 0x452f4edcU, + 0x0b90bc37U, 0x341777cbU, 0x63d269afU, 0x1da77929U, 0x0a5c1826U, 0x77991898U, + 0x5aeddf86U, 0xf853a877U, 0x538c31ccU, 0xe84896daU, 0xb7a0010bU, 0x17ef4de5U, + 0xa52a2adeU, 0x029fd81cU, 0x987ce701U, 0x27fefd77U, 0xdb46c66fU, 0x5d301900U, + 0x496998c0U, 0xbb6598b9U, 0x5eebb607U, 0xe547354aU, 0xdf4a2f7eU, 0xf06c4955U, + 0x96242ffaU, 0x1775fb27U, 0xbecc58ceU, 0xebf2a53bU, 0x3eaad82aU, 0xf41137baU, + 0x573e6fbaU, 0xfb4866b8U, 0x54002148U, 0x00000039U, +}; +// clang-format on + +// Returns a pointer to the big integer data for (5**27)**i. i must be +// between 1 and 20, inclusive. +const uint32_t* LargePowerOfFiveData(int i) { + return kLargePowersOfFive + i * (i - 1); +} + +// Returns the size of the big integer data for (5**27)**i, in words. i must be +// between 1 and 20, inclusive. +int LargePowerOfFiveSize(int i) { return 2 * i; } +} // namespace + +const uint32_t kFiveToNth[14] = { + 1, 5, 25, 125, 625, 3125, 15625, + 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125, +}; + +const uint32_t kTenToNth[10] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, +}; + +template <int max_words> +int BigUnsigned<max_words>::ReadFloatMantissa(const ParsedFloat& fp, + int significant_digits) { + SetToZero(); + assert(fp.type == FloatType::kNumber); + + if (fp.subrange_begin == nullptr) { + // We already exactly parsed the mantissa, so no more work is necessary. + words_[0] = fp.mantissa & 0xffffffffu; + words_[1] = fp.mantissa >> 32; + if (words_[1]) { + size_ = 2; + } else if (words_[0]) { + size_ = 1; + } + return fp.exponent; + } + int exponent_adjust = + ReadDigits(fp.subrange_begin, fp.subrange_end, significant_digits); + return fp.literal_exponent + exponent_adjust; +} + +template <int max_words> +int BigUnsigned<max_words>::ReadDigits(const char* begin, const char* end, + int significant_digits) { + assert(significant_digits <= Digits10() + 1); + SetToZero(); + + bool after_decimal_point = false; + // Discard any leading zeroes before the decimal point + while (begin < end && *begin == '0') { + ++begin; + } + int dropped_digits = 0; + // Discard any trailing zeroes. These may or may not be after the decimal + // point. + while (begin < end && *std::prev(end) == '0') { + --end; + ++dropped_digits; + } + if (begin < end && *std::prev(end) == '.') { + // If the std::string ends in '.', either before or after dropping zeroes, then + // drop the decimal point and look for more digits to drop. + dropped_digits = 0; + --end; + while (begin < end && *std::prev(end) == '0') { + --end; + ++dropped_digits; + } + } else if (dropped_digits) { + // We dropped digits, and aren't sure if they're before or after the decimal + // point. Figure that out now. + const char* dp = std::find(begin, end, '.'); + if (dp != end) { + // The dropped trailing digits were after the decimal point, so don't + // count them. + dropped_digits = 0; + } + } + // Any non-fraction digits we dropped need to be accounted for in our exponent + // adjustment. + int exponent_adjust = dropped_digits; + + uint32_t queued = 0; + int digits_queued = 0; + for (; begin != end && significant_digits > 0; ++begin) { + if (*begin == '.') { + after_decimal_point = true; + continue; + } + if (after_decimal_point) { + // For each fractional digit we emit in our parsed integer, adjust our + // decimal exponent to compensate. + --exponent_adjust; + } + int digit = (*begin - '0'); + --significant_digits; + if (significant_digits == 0 && std::next(begin) != end && + (digit == 0 || digit == 5)) { + // If this is the very last significant digit, but insignificant digits + // remain, we know that the last of those remaining significant digits is + // nonzero. (If it wasn't, we would have stripped it before we got here.) + // So if this final digit is a 0 or 5, adjust it upward by 1. + // + // This adjustment is what allows incredibly large mantissas ending in + // 500000...000000000001 to correctly round up, rather than to nearest. + ++digit; + } + queued = 10 * queued + digit; + ++digits_queued; + if (digits_queued == kMaxSmallPowerOfTen) { + MultiplyBy(kTenToNth[kMaxSmallPowerOfTen]); + AddWithCarry(0, queued); + queued = digits_queued = 0; + } + } + // Encode any remaining digits. + if (digits_queued) { + MultiplyBy(kTenToNth[digits_queued]); + AddWithCarry(0, queued); + } + + // If any insignificant digits remain, we will drop them. But if we have not + // yet read the decimal point, then we have to adjust the exponent to account + // for the dropped digits. + if (begin < end && !after_decimal_point) { + // This call to std::find will result in a pointer either to the decimal + // point, or to the end of our buffer if there was none. + // + // Either way, [begin, decimal_point) will contain the set of dropped digits + // that require an exponent adjustment. + const char* decimal_point = std::find(begin, end, '.'); + exponent_adjust += (decimal_point - begin); + } + return exponent_adjust; +} + +template <int max_words> +/* static */ BigUnsigned<max_words> BigUnsigned<max_words>::FiveToTheNth( + int n) { + BigUnsigned answer(1u); + + // Seed from the table of large powers, if possible. + bool first_pass = true; + while (n >= kLargePowerOfFiveStep) { + int big_power = + std::min(n / kLargePowerOfFiveStep, kLargestPowerOfFiveIndex); + if (first_pass) { + // just copy, rather than multiplying by 1 + std::copy( + LargePowerOfFiveData(big_power), + LargePowerOfFiveData(big_power) + LargePowerOfFiveSize(big_power), + answer.words_); + answer.size_ = LargePowerOfFiveSize(big_power); + first_pass = false; + } else { + answer.MultiplyBy(LargePowerOfFiveSize(big_power), + LargePowerOfFiveData(big_power)); + } + n -= kLargePowerOfFiveStep * big_power; + } + answer.MultiplyByFiveToTheNth(n); + return answer; +} + +template <int max_words> +void BigUnsigned<max_words>::MultiplyStep(int original_size, + const uint32_t* other_words, + int other_size, int step) { + int this_i = std::min(original_size - 1, step); + int other_i = step - this_i; + + uint64_t this_word = 0; + uint64_t carry = 0; + for (; this_i >= 0 && other_i < other_size; --this_i, ++other_i) { + uint64_t product = words_[this_i]; + product *= other_words[other_i]; + this_word += product; + carry += (this_word >> 32); + this_word &= 0xffffffff; + } + AddWithCarry(step + 1, carry); + words_[step] = this_word & 0xffffffff; + if (this_word > 0 && size_ <= step) { + size_ = step + 1; + } +} + +template <int max_words> +std::string BigUnsigned<max_words>::ToString() const { + BigUnsigned<max_words> copy = *this; + std::string result; + // Build result in reverse order + while (copy.size() > 0) { + int next_digit = copy.DivMod<10>(); + result.push_back('0' + next_digit); + } + if (result.empty()) { + result.push_back('0'); + } + std::reverse(result.begin(), result.end()); + return result; +} + +template class BigUnsigned<4>; +template class BigUnsigned<84>; + +} // namespace strings_internal +} // namespace absl
diff --git a/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h b/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h new file mode 100644 index 0000000..aa70af2 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h
@@ -0,0 +1,426 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ +#define ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ + +#include <algorithm> +#include <cstdint> +#include <iostream> +#include <string> + +#include "absl/strings/ascii.h" +#include "absl/strings/internal/charconv_parse.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace strings_internal { + +// The largest power that 5 that can be raised to, and still fit in a uint32_t. +constexpr int kMaxSmallPowerOfFive = 13; +// The largest power that 10 that can be raised to, and still fit in a uint32_t. +constexpr int kMaxSmallPowerOfTen = 9; + +extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1]; +extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; + +// Large, fixed-width unsigned integer. +// +// Exact rounding for decimal-to-binary floating point conversion requires very +// large integer math, but a design goal of absl::from_chars is to avoid +// allocating memory. The integer precision needed for decimal-to-binary +// conversions is large but bounded, so a huge fixed-width integer class +// suffices. +// +// This is an intentionally limited big integer class. Only needed operations +// are implemented. All storage lives in an array data member, and all +// arithmetic is done in-place, to avoid requiring separate storage for operand +// and result. +// +// This is an internal class. Some methods live in the .cc file, and are +// instantiated only for the values of max_words we need. +template <int max_words> +class BigUnsigned { + public: + static_assert(max_words == 4 || max_words == 84, + "unsupported max_words value"); + + BigUnsigned() : size_(0), words_{} {} + explicit BigUnsigned(uint32_t v) : size_(v > 0 ? 1 : 0), words_{v} {} + explicit BigUnsigned(uint64_t v) + : size_(0), + words_{static_cast<uint32_t>(v & 0xffffffff), + static_cast<uint32_t>(v >> 32)} { + if (words_[1]) { + size_ = 2; + } else if (words_[0]) { + size_ = 1; + } + } + + // Constructs a BigUnsigned from the given string_view containing a decimal + // value. If the input std::string is not a decimal integer, constructs a 0 + // instead. + explicit BigUnsigned(absl::string_view sv) : size_(0), words_{} { + // Check for valid input, returning a 0 otherwise. This is reasonable + // behavior only because this constructor is for unit tests. + if (std::find_if_not(sv.begin(), sv.end(), ascii_isdigit) != sv.end() || + sv.empty()) { + return; + } + int exponent_adjust = + ReadDigits(sv.data(), sv.data() + sv.size(), Digits10() + 1); + if (exponent_adjust > 0) { + MultiplyByTenToTheNth(exponent_adjust); + } + } + + // Loads the mantissa value of a previously-parsed float. + // + // Returns the associated decimal exponent. The value of the parsed float is + // exactly *this * 10**exponent. + int ReadFloatMantissa(const ParsedFloat& fp, int significant_digits); + + // Returns the number of decimal digits of precision this type provides. All + // numbers with this many decimal digits or fewer are representable by this + // type. + // + // Analagous to std::numeric_limits<BigUnsigned>::digits10. + static constexpr int Digits10() { + // 9975007/1035508 is very slightly less than log10(2**32). + return static_cast<uint64_t>(max_words) * 9975007 / 1035508; + } + + // Shifts left by the given number of bits. + void ShiftLeft(int count) { + if (count > 0) { + const int word_shift = count / 32; + if (word_shift >= max_words) { + SetToZero(); + return; + } + size_ = std::min(size_ + word_shift, max_words); + count %= 32; + if (count == 0) { + std::copy_backward(words_, words_ + size_ - word_shift, words_ + size_); + } else { + for (int i = std::min(size_, max_words - 1); i > word_shift; --i) { + words_[i] = (words_[i - word_shift] << count) | + (words_[i - word_shift - 1] >> (32 - count)); + } + words_[word_shift] = words_[0] << count; + // Grow size_ if necessary. + if (size_ < max_words && words_[size_]) { + ++size_; + } + } + std::fill(words_, words_ + word_shift, 0u); + } + } + + + // Multiplies by v in-place. + void MultiplyBy(uint32_t v) { + if (size_ == 0 || v == 1) { + return; + } + if (v == 0) { + SetToZero(); + return; + } + const uint64_t factor = v; + uint64_t window = 0; + for (int i = 0; i < size_; ++i) { + window += factor * words_[i]; + words_[i] = window & 0xffffffff; + window >>= 32; + } + // If carry bits remain and there's space for them, grow size_. + if (window && size_ < max_words) { + words_[size_] = window & 0xffffffff; + ++size_; + } + } + + void MultiplyBy(uint64_t v) { + uint32_t words[2]; + words[0] = static_cast<uint32_t>(v); + words[1] = static_cast<uint32_t>(v >> 32); + if (words[1] == 0) { + MultiplyBy(words[0]); + } else { + MultiplyBy(2, words); + } + } + + // Multiplies in place by 5 to the power of n. n must be non-negative. + void MultiplyByFiveToTheNth(int n) { + while (n >= kMaxSmallPowerOfFive) { + MultiplyBy(kFiveToNth[kMaxSmallPowerOfFive]); + n -= kMaxSmallPowerOfFive; + } + if (n > 0) { + MultiplyBy(kFiveToNth[n]); + } + } + + // Multiplies in place by 10 to the power of n. n must be non-negative. + void MultiplyByTenToTheNth(int n) { + if (n > kMaxSmallPowerOfTen) { + // For large n, raise to a power of 5, then shift left by the same amount. + // (10**n == 5**n * 2**n.) This requires fewer multiplications overall. + MultiplyByFiveToTheNth(n); + ShiftLeft(n); + } else if (n > 0) { + // We can do this more quickly for very small N by using a single + // multiplication. + MultiplyBy(kTenToNth[n]); + } + } + + // Returns the value of 5**n, for non-negative n. This implementation uses + // a lookup table, and is faster then seeding a BigUnsigned with 1 and calling + // MultiplyByFiveToTheNth(). + static BigUnsigned FiveToTheNth(int n); + + // Multiplies by another BigUnsigned, in-place. + template <int M> + void MultiplyBy(const BigUnsigned<M>& other) { + MultiplyBy(other.size(), other.words()); + } + + void SetToZero() { + std::fill(words_, words_ + size_, 0u); + size_ = 0; + } + + // Returns the value of the nth word of this BigUnsigned. This is + // range-checked, and returns 0 on out-of-bounds accesses. + uint32_t GetWord(int index) const { + if (index < 0 || index >= size_) { + return 0; + } + return words_[index]; + } + + // Returns this integer as a decimal std::string. This is not used in the decimal- + // to-binary conversion; it is intended to aid in testing. + std::string ToString() const; + + int size() const { return size_; } + const uint32_t* words() const { return words_; } + + private: + // Reads the number between [begin, end), possibly containing a decimal point, + // into this BigUnsigned. + // + // Callers are required to ensure [begin, end) contains a valid number, with + // one or more decimal digits and at most one decimal point. This routine + // will behave unpredictably if these preconditions are not met. + // + // Only the first `significant_digits` digits are read. Digits beyond this + // limit are "sticky": If the final significant digit is 0 or 5, and if any + // dropped digit is nonzero, then that final significant digit is adjusted up + // to 1 or 6. This adjustment allows for precise rounding. + // + // Returns `exponent_adjustment`, a power-of-ten exponent adjustment to + // account for the decimal point and for dropped significant digits. After + // this function returns, + // actual_value_of_parsed_string ~= *this * 10**exponent_adjustment. + int ReadDigits(const char* begin, const char* end, int significant_digits); + + // Performs a step of big integer multiplication. This computes the full + // (64-bit-wide) values that should be added at the given index (step), and + // adds to that location in-place. + // + // Because our math all occurs in place, we must multiply starting from the + // highest word working downward. (This is a bit more expensive due to the + // extra carries involved.) + // + // This must be called in steps, for each word to be calculated, starting from + // the high end and working down to 0. The first value of `step` should be + // `std::min(original_size + other.size_ - 2, max_words - 1)`. + // The reason for this expression is that multiplying the i'th word from one + // multiplicand and the j'th word of another multiplicand creates a + // two-word-wide value to be stored at the (i+j)'th element. The highest + // word indices we will access are `original_size - 1` from this object, and + // `other.size_ - 1` from our operand. Therefore, + // `original_size + other.size_ - 2` is the first step we should calculate, + // but limited on an upper bound by max_words. + + // Working from high-to-low ensures that we do not overwrite the portions of + // the initial value of *this which are still needed for later steps. + // + // Once called with step == 0, *this contains the result of the + // multiplication. + // + // `original_size` is the size_ of *this before the first call to + // MultiplyStep(). `other_words` and `other_size` are the contents of our + // operand. `step` is the step to perform, as described above. + void MultiplyStep(int original_size, const uint32_t* other_words, + int other_size, int step); + + void MultiplyBy(int other_size, const uint32_t* other_words) { + const int original_size = size_; + const int first_step = + std::min(original_size + other_size - 2, max_words - 1); + for (int step = first_step; step >= 0; --step) { + MultiplyStep(original_size, other_words, other_size, step); + } + } + + // Adds a 32-bit value to the index'th word, with carry. + void AddWithCarry(int index, uint32_t value) { + if (value) { + while (index < max_words && value > 0) { + words_[index] += value; + // carry if we overflowed in this word: + if (value > words_[index]) { + value = 1; + ++index; + } else { + value = 0; + } + } + size_ = std::min(max_words, std::max(index + 1, size_)); + } + } + + void AddWithCarry(int index, uint64_t value) { + if (value && index < max_words) { + uint32_t high = value >> 32; + uint32_t low = value & 0xffffffff; + words_[index] += low; + if (words_[index] < low) { + ++high; + if (high == 0) { + // Carry from the low word caused our high word to overflow. + // Short circuit here to do the right thing. + AddWithCarry(index + 2, static_cast<uint32_t>(1)); + return; + } + } + if (high > 0) { + AddWithCarry(index + 1, high); + } else { + // Normally 32-bit AddWithCarry() sets size_, but since we don't call + // it when `high` is 0, do it ourselves here. + size_ = std::min(max_words, std::max(index + 1, size_)); + } + } + } + + // Divide this in place by a constant divisor. Returns the remainder of the + // division. + template <uint32_t divisor> + uint32_t DivMod() { + uint64_t accumulator = 0; + for (int i = size_ - 1; i >= 0; --i) { + accumulator <<= 32; + accumulator += words_[i]; + // accumulator / divisor will never overflow an int32_t in this loop + words_[i] = static_cast<uint32_t>(accumulator / divisor); + accumulator = accumulator % divisor; + } + while (size_ > 0 && words_[size_ - 1] == 0) { + --size_; + } + return static_cast<uint32_t>(accumulator); + } + + // The number of elements in words_ that may carry significant values. + // All elements beyond this point are 0. + // + // When size_ is 0, this BigUnsigned stores the value 0. + // When size_ is nonzero, is *not* guaranteed that words_[size_ - 1] is + // nonzero. This can occur due to overflow truncation. + // In particular, x.size_ != y.size_ does *not* imply x != y. + int size_; + uint32_t words_[max_words]; +}; + +// Compares two big integer instances. +// +// Returns -1 if lhs < rhs, 0 if lhs == rhs, and 1 if lhs > rhs. +template <int N, int M> +int Compare(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { + int limit = std::max(lhs.size(), rhs.size()); + for (int i = limit - 1; i >= 0; --i) { + const uint32_t lhs_word = lhs.GetWord(i); + const uint32_t rhs_word = rhs.GetWord(i); + if (lhs_word < rhs_word) { + return -1; + } else if (lhs_word > rhs_word) { + return 1; + } + } + return 0; +} + +template <int N, int M> +bool operator==(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { + int limit = std::max(lhs.size(), rhs.size()); + for (int i = 0; i < limit; ++i) { + if (lhs.GetWord(i) != rhs.GetWord(i)) { + return false; + } + } + return true; +} + +template <int N, int M> +bool operator!=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { + return !(lhs == rhs); +} + +template <int N, int M> +bool operator<(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { + return Compare(lhs, rhs) == -1; +} + +template <int N, int M> +bool operator>(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { + return rhs < lhs; +} +template <int N, int M> +bool operator<=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { + return !(rhs < lhs); +} +template <int N, int M> +bool operator>=(const BigUnsigned<N>& lhs, const BigUnsigned<M>& rhs) { + return !(lhs < rhs); +} + +// Output operator for BigUnsigned, for testing purposes only. +template <int N> +std::ostream& operator<<(std::ostream& os, const BigUnsigned<N>& num) { + return os << num.ToString(); +} + +// Explicit instantiation declarations for the sizes of BigUnsigned that we +// are using. +// +// For now, the choices of 4 and 84 are arbitrary; 4 is a small value that is +// still bigger than an int128, and 84 is a large value we will want to use +// in the from_chars implementation. +// +// Comments justifying the use of 84 belong in the from_chars implementation, +// and will be added in a follow-up CL. +extern template class BigUnsigned<4>; +extern template class BigUnsigned<84>; + +} // namespace strings_internal +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_
diff --git a/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc b/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc new file mode 100644 index 0000000..9b63578 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc
@@ -0,0 +1,203 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/charconv_bigint.h" + +#include <string> + +#include "gtest/gtest.h" + +namespace absl { +namespace strings_internal { + +TEST(BigUnsigned, ShiftLeft) { + { + // Check that 3 * 2**100 is calculated correctly + BigUnsigned<4> num(3u); + num.ShiftLeft(100); + EXPECT_EQ(num, BigUnsigned<4>("3802951800684688204490109616128")); + } + { + // Test that overflow is truncated properly. + // 15 is 4 bits long, and BigUnsigned<4> is a 128-bit bigint. + // Shifting left by 125 bits should truncate off the high bit, so that + // 15 << 125 == 7 << 125 + // after truncation. + BigUnsigned<4> a(15u); + BigUnsigned<4> b(7u); + BigUnsigned<4> c(3u); + a.ShiftLeft(125); + b.ShiftLeft(125); + c.ShiftLeft(125); + EXPECT_EQ(a, b); + EXPECT_NE(a, c); + } + { + // Same test, larger bigint: + BigUnsigned<84> a(15u); + BigUnsigned<84> b(7u); + BigUnsigned<84> c(3u); + a.ShiftLeft(84 * 32 - 3); + b.ShiftLeft(84 * 32 - 3); + c.ShiftLeft(84 * 32 - 3); + EXPECT_EQ(a, b); + EXPECT_NE(a, c); + } + { + // Check that incrementally shifting has the same result as doing it all at + // once (attempting to capture corner cases.) + const std::string seed = "1234567890123456789012345678901234567890"; + BigUnsigned<84> a(seed); + for (int i = 1; i <= 84 * 32; ++i) { + a.ShiftLeft(1); + BigUnsigned<84> b(seed); + b.ShiftLeft(i); + EXPECT_EQ(a, b); + } + // And we should have fully rotated all bits off by now: + EXPECT_EQ(a, BigUnsigned<84>(0u)); + } +} + +TEST(BigUnsigned, MultiplyByUint32) { + const BigUnsigned<84> factorial_100( + "933262154439441526816992388562667004907159682643816214685929638952175999" + "932299156089414639761565182862536979208272237582511852109168640000000000" + "00000000000000"); + BigUnsigned<84> a(1u); + for (uint32_t i = 1; i <= 100; ++i) { + a.MultiplyBy(i); + } + EXPECT_EQ(a, BigUnsigned<84>(factorial_100)); +} + +TEST(BigUnsigned, MultiplyByBigUnsigned) { + { + // Put the terms of factorial_200 into two bigints, and multiply them + // together. + const BigUnsigned<84> factorial_200( + "7886578673647905035523632139321850622951359776871732632947425332443594" + "4996340334292030428401198462390417721213891963883025764279024263710506" + "1926624952829931113462857270763317237396988943922445621451664240254033" + "2918641312274282948532775242424075739032403212574055795686602260319041" + "7032406235170085879617892222278962370389737472000000000000000000000000" + "0000000000000000000000000"); + BigUnsigned<84> evens(1u); + BigUnsigned<84> odds(1u); + for (uint32_t i = 1; i < 200; i += 2) { + odds.MultiplyBy(i); + evens.MultiplyBy(i + 1); + } + evens.MultiplyBy(odds); + EXPECT_EQ(evens, factorial_200); + } + { + // Multiply various powers of 10 together. + for (int a = 0 ; a < 700; a += 25) { + SCOPED_TRACE(a); + BigUnsigned<84> a_value("3" + std::string(a, '0')); + for (int b = 0; b < (700 - a); b += 25) { + SCOPED_TRACE(b); + BigUnsigned<84> b_value("2" + std::string(b, '0')); + BigUnsigned<84> expected_product("6" + std::string(a + b, '0')); + b_value.MultiplyBy(a_value); + EXPECT_EQ(b_value, expected_product); + } + } + } +} + +TEST(BigUnsigned, MultiplyByOverflow) { + { + // Check that multiplcation overflow predictably truncates. + + // A big int with all bits on. + BigUnsigned<4> all_bits_on("340282366920938463463374607431768211455"); + // Modulo 2**128, this is equal to -1. Therefore the square of this, + // modulo 2**128, should be 1. + all_bits_on.MultiplyBy(all_bits_on); + EXPECT_EQ(all_bits_on, BigUnsigned<4>(1u)); + } + { + // Try multiplying a large bigint by 2**50, and compare the result to + // shifting. + BigUnsigned<4> value_1("12345678901234567890123456789012345678"); + BigUnsigned<4> value_2("12345678901234567890123456789012345678"); + BigUnsigned<4> two_to_fiftieth(1u); + two_to_fiftieth.ShiftLeft(50); + + value_1.ShiftLeft(50); + value_2.MultiplyBy(two_to_fiftieth); + EXPECT_EQ(value_1, value_2); + } +} + +TEST(BigUnsigned, FiveToTheNth) { + { + // Sanity check that MultiplyByFiveToTheNth gives consistent answers, up to + // and including overflow. + for (int i = 0; i < 1160; ++i) { + SCOPED_TRACE(i); + BigUnsigned<84> value_1(123u); + BigUnsigned<84> value_2(123u); + value_1.MultiplyByFiveToTheNth(i); + for (int j = 0; j < i; j++) { + value_2.MultiplyBy(5u); + } + EXPECT_EQ(value_1, value_2); + } + } + { + // Check that the faster, table-lookup-based static method returns the same + // result that multiplying in-place would return, up to and including + // overflow. + for (int i = 0; i < 1160; ++i) { + SCOPED_TRACE(i); + BigUnsigned<84> value_1(1u); + value_1.MultiplyByFiveToTheNth(i); + BigUnsigned<84> value_2 = BigUnsigned<84>::FiveToTheNth(i); + EXPECT_EQ(value_1, value_2); + } + } +} + +TEST(BigUnsigned, TenToTheNth) { + { + // Sanity check MultiplyByTenToTheNth. + for (int i = 0; i < 800; ++i) { + SCOPED_TRACE(i); + BigUnsigned<84> value_1(123u); + BigUnsigned<84> value_2(123u); + value_1.MultiplyByTenToTheNth(i); + for (int j = 0; j < i; j++) { + value_2.MultiplyBy(10u); + } + EXPECT_EQ(value_1, value_2); + } + } + { + // Alternate testing approach, taking advantage of the decimal parser. + for (int i = 0; i < 200; ++i) { + SCOPED_TRACE(i); + BigUnsigned<84> value_1(135u); + value_1.MultiplyByTenToTheNth(i); + BigUnsigned<84> value_2("135" + std::string(i, '0')); + EXPECT_EQ(value_1, value_2); + } + } +} + + +} // namespace strings_internal +} // namespace absl
diff --git a/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc b/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc new file mode 100644 index 0000000..a04cc676 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc
@@ -0,0 +1,496 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/charconv_parse.h" +#include "absl/strings/charconv.h" + +#include <cassert> +#include <cstdint> +#include <limits> + +#include "absl/strings/internal/memutil.h" + +namespace absl { +namespace { + +// ParseFloat<10> will read the first 19 significant digits of the mantissa. +// This number was chosen for multiple reasons. +// +// (a) First, for whatever integer type we choose to represent the mantissa, we +// want to choose the largest possible number of decimal digits for that integer +// type. We are using uint64_t, which can express any 19-digit unsigned +// integer. +// +// (b) Second, we need to parse enough digits that the binary value of any +// mantissa we capture has more bits of resolution than the mantissa +// representation in the target float. Our algorithm requires at least 3 bits +// of headway, but 19 decimal digits give a little more than that. +// +// The following static assertions verify the above comments: +constexpr int kDecimalMantissaDigitsMax = 19; + +static_assert(std::numeric_limits<uint64_t>::digits10 == + kDecimalMantissaDigitsMax, + "(a) above"); + +// IEEE doubles, which we assume in Abseil, have 53 binary bits of mantissa. +static_assert(std::numeric_limits<double>::is_iec559, "IEEE double assumed"); +static_assert(std::numeric_limits<double>::radix == 2, "IEEE double fact"); +static_assert(std::numeric_limits<double>::digits == 53, "IEEE double fact"); + +// The lowest valued 19-digit decimal mantissa we can read still contains +// sufficient information to reconstruct a binary mantissa. +static_assert(1000000000000000000u > (uint64_t(1) << (53 + 3)), "(b) above"); + +// ParseFloat<16> will read the first 15 significant digits of the mantissa. +// +// Because a base-16-to-base-2 conversion can be done exactly, we do not need +// to maximize the number of scanned hex digits to improve our conversion. What +// is required is to scan two more bits than the mantissa can represent, so that +// we always round correctly. +// +// (One extra bit does not suffice to perform correct rounding, since a number +// exactly halfway between two representable floats has unique rounding rules, +// so we need to differentiate between a "halfway between" number and a "closer +// to the larger value" number.) +constexpr int kHexadecimalMantissaDigitsMax = 15; + +// The minimum number of significant bits that will be read from +// kHexadecimalMantissaDigitsMax hex digits. We must subtract by three, since +// the most significant digit can be a "1", which only contributes a single +// significant bit. +constexpr int kGuaranteedHexadecimalMantissaBitPrecision = + 4 * kHexadecimalMantissaDigitsMax - 3; + +static_assert(kGuaranteedHexadecimalMantissaBitPrecision > + std::numeric_limits<double>::digits + 2, + "kHexadecimalMantissaDigitsMax too small"); + +// We also impose a limit on the number of significant digits we will read from +// an exponent, to avoid having to deal with integer overflow. We use 9 for +// this purpose. +// +// If we read a 9 digit exponent, the end result of the conversion will +// necessarily be infinity or zero, depending on the sign of the exponent. +// Therefore we can just drop extra digits on the floor without any extra +// logic. +constexpr int kDecimalExponentDigitsMax = 9; +static_assert(std::numeric_limits<int>::digits10 >= kDecimalExponentDigitsMax, + "int type too small"); + +// To avoid incredibly large inputs causing integer overflow for our exponent, +// we impose an arbitrary but very large limit on the number of significant +// digits we will accept. The implementation refuses to match a std::string with +// more consecutive significant mantissa digits than this. +constexpr int kDecimalDigitLimit = 50000000; + +// Corresponding limit for hexadecimal digit inputs. This is one fourth the +// amount of kDecimalDigitLimit, since each dropped hexadecimal digit requires +// a binary exponent adjustment of 4. +constexpr int kHexadecimalDigitLimit = kDecimalDigitLimit / 4; + +// The largest exponent we can read is 999999999 (per +// kDecimalExponentDigitsMax), and the largest exponent adjustment we can get +// from dropped mantissa digits is 2 * kDecimalDigitLimit, and the sum of these +// comfortably fits in an integer. +// +// We count kDecimalDigitLimit twice because there are independent limits for +// numbers before and after the decimal point. (In the case where there are no +// significant digits before the decimal point, there are independent limits for +// post-decimal-point leading zeroes and for significant digits.) +static_assert(999999999 + 2 * kDecimalDigitLimit < + std::numeric_limits<int>::max(), + "int type too small"); +static_assert(999999999 + 2 * (4 * kHexadecimalDigitLimit) < + std::numeric_limits<int>::max(), + "int type too small"); + +// Returns true if the provided bitfield allows parsing an exponent value +// (e.g., "1.5e100"). +bool AllowExponent(chars_format flags) { + bool fixed = (flags & chars_format::fixed) == chars_format::fixed; + bool scientific = + (flags & chars_format::scientific) == chars_format::scientific; + return scientific || !fixed; +} + +// Returns true if the provided bitfield requires an exponent value be present. +bool RequireExponent(chars_format flags) { + bool fixed = (flags & chars_format::fixed) == chars_format::fixed; + bool scientific = + (flags & chars_format::scientific) == chars_format::scientific; + return scientific && !fixed; +} + +const int8_t kAsciiToInt[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +// Returns true if `ch` is a digit in the given base +template <int base> +bool IsDigit(char ch); + +// Converts a valid `ch` to its digit value in the given base. +template <int base> +unsigned ToDigit(char ch); + +// Returns true if `ch` is the exponent delimiter for the given base. +template <int base> +bool IsExponentCharacter(char ch); + +// Returns the maximum number of significant digits we will read for a float +// in the given base. +template <int base> +constexpr int MantissaDigitsMax(); + +// Returns the largest consecutive run of digits we will accept when parsing a +// number in the given base. +template <int base> +constexpr int DigitLimit(); + +// Returns the amount the exponent must be adjusted by for each dropped digit. +// (For decimal this is 1, since the digits are in base 10 and the exponent base +// is also 10, but for hexadecimal this is 4, since the digits are base 16 but +// the exponent base is 2.) +template <int base> +constexpr int DigitMagnitude(); + +template <> +bool IsDigit<10>(char ch) { + return ch >= '0' && ch <= '9'; +} +template <> +bool IsDigit<16>(char ch) { + return kAsciiToInt[static_cast<unsigned char>(ch)] >= 0; +} + +template <> +unsigned ToDigit<10>(char ch) { + return ch - '0'; +} +template <> +unsigned ToDigit<16>(char ch) { + return kAsciiToInt[static_cast<unsigned char>(ch)]; +} + +template <> +bool IsExponentCharacter<10>(char ch) { + return ch == 'e' || ch == 'E'; +} + +template <> +bool IsExponentCharacter<16>(char ch) { + return ch == 'p' || ch == 'P'; +} + +template <> +constexpr int MantissaDigitsMax<10>() { + return kDecimalMantissaDigitsMax; +} +template <> +constexpr int MantissaDigitsMax<16>() { + return kHexadecimalMantissaDigitsMax; +} + +template <> +constexpr int DigitLimit<10>() { + return kDecimalDigitLimit; +} +template <> +constexpr int DigitLimit<16>() { + return kHexadecimalDigitLimit; +} + +template <> +constexpr int DigitMagnitude<10>() { + return 1; +} +template <> +constexpr int DigitMagnitude<16>() { + return 4; +} + +// Reads decimal digits from [begin, end) into *out. Returns the number of +// digits consumed. +// +// After max_digits has been read, keeps consuming characters, but no longer +// adjusts *out. If a nonzero digit is dropped this way, *dropped_nonzero_digit +// is set; otherwise, it is left unmodified. +// +// If no digits are matched, returns 0 and leaves *out unchanged. +// +// ConsumeDigits does not protect against overflow on *out; max_digits must +// be chosen with respect to type T to avoid the possibility of overflow. +template <int base, typename T> +std::size_t ConsumeDigits(const char* begin, const char* end, int max_digits, + T* out, bool* dropped_nonzero_digit) { + if (base == 10) { + assert(max_digits <= std::numeric_limits<T>::digits10); + } else if (base == 16) { + assert(max_digits * 4 <= std::numeric_limits<T>::digits); + } + const char* const original_begin = begin; + T accumulator = *out; + const char* significant_digits_end = + (end - begin > max_digits) ? begin + max_digits : end; + while (begin < significant_digits_end && IsDigit<base>(*begin)) { + // Do not guard against *out overflow; max_digits was chosen to avoid this. + // Do assert against it, to detect problems in debug builds. + auto digit = static_cast<T>(ToDigit<base>(*begin)); + assert(accumulator * base >= accumulator); + accumulator *= base; + assert(accumulator + digit >= accumulator); + accumulator += digit; + ++begin; + } + bool dropped_nonzero = false; + while (begin < end && IsDigit<base>(*begin)) { + dropped_nonzero = dropped_nonzero || (*begin != '0'); + ++begin; + } + if (dropped_nonzero && dropped_nonzero_digit != nullptr) { + *dropped_nonzero_digit = true; + } + *out = accumulator; + return begin - original_begin; +} + +// Returns true if `v` is one of the chars allowed inside parentheses following +// a NaN. +bool IsNanChar(char v) { + return (v == '_') || (v >= '0' && v <= '9') || (v >= 'a' && v <= 'z') || + (v >= 'A' && v <= 'Z'); +} + +// Checks the range [begin, end) for a strtod()-formatted infinity or NaN. If +// one is found, sets `out` appropriately and returns true. +bool ParseInfinityOrNan(const char* begin, const char* end, + strings_internal::ParsedFloat* out) { + if (end - begin < 3) { + return false; + } + switch (*begin) { + case 'i': + case 'I': { + // An infinity std::string consists of the characters "inf" or "infinity", + // case insensitive. + if (strings_internal::memcasecmp(begin + 1, "nf", 2) != 0) { + return false; + } + out->type = strings_internal::FloatType::kInfinity; + if (end - begin >= 8 && + strings_internal::memcasecmp(begin + 3, "inity", 5) == 0) { + out->end = begin + 8; + } else { + out->end = begin + 3; + } + return true; + } + case 'n': + case 'N': { + // A NaN consists of the characters "nan", case insensitive, optionally + // followed by a parenthesized sequence of zero or more alphanumeric + // characters and/or underscores. + if (strings_internal::memcasecmp(begin + 1, "an", 2) != 0) { + return false; + } + out->type = strings_internal::FloatType::kNan; + out->end = begin + 3; + // NaN is allowed to be followed by a parenthesized std::string, consisting of + // only the characters [a-zA-Z0-9_]. Match that if it's present. + begin += 3; + if (begin < end && *begin == '(') { + const char* nan_begin = begin + 1; + while (nan_begin < end && IsNanChar(*nan_begin)) { + ++nan_begin; + } + if (nan_begin < end && *nan_begin == ')') { + // We found an extra NaN specifier range + out->subrange_begin = begin + 1; + out->subrange_end = nan_begin; + out->end = nan_begin + 1; + } + } + return true; + } + default: + return false; + } +} +} // namespace + +namespace strings_internal { + +template <int base> +strings_internal::ParsedFloat ParseFloat(const char* begin, const char* end, + chars_format format_flags) { + strings_internal::ParsedFloat result; + + // Exit early if we're given an empty range. + if (begin == end) return result; + + // Handle the infinity and NaN cases. + if (ParseInfinityOrNan(begin, end, &result)) { + return result; + } + + const char* const mantissa_begin = begin; + while (begin < end && *begin == '0') { + ++begin; // skip leading zeros + } + uint64_t mantissa = 0; + + int exponent_adjustment = 0; + bool mantissa_is_inexact = false; + std::size_t pre_decimal_digits = ConsumeDigits<base>( + begin, end, MantissaDigitsMax<base>(), &mantissa, &mantissa_is_inexact); + begin += pre_decimal_digits; + int digits_left; + if (pre_decimal_digits >= DigitLimit<base>()) { + // refuse to parse pathological inputs + return result; + } else if (pre_decimal_digits > MantissaDigitsMax<base>()) { + // We dropped some non-fraction digits on the floor. Adjust our exponent + // to compensate. + exponent_adjustment = + static_cast<int>(pre_decimal_digits - MantissaDigitsMax<base>()); + digits_left = 0; + } else { + digits_left = + static_cast<int>(MantissaDigitsMax<base>() - pre_decimal_digits); + } + if (begin < end && *begin == '.') { + ++begin; + if (mantissa == 0) { + // If we haven't seen any nonzero digits yet, keep skipping zeros. We + // have to adjust the exponent to reflect the changed place value. + const char* begin_zeros = begin; + while (begin < end && *begin == '0') { + ++begin; + } + std::size_t zeros_skipped = begin - begin_zeros; + if (zeros_skipped >= DigitLimit<base>()) { + // refuse to parse pathological inputs + return result; + } + exponent_adjustment -= static_cast<int>(zeros_skipped); + } + std::size_t post_decimal_digits = ConsumeDigits<base>( + begin, end, digits_left, &mantissa, &mantissa_is_inexact); + begin += post_decimal_digits; + + // Since `mantissa` is an integer, each significant digit we read after + // the decimal point requires an adjustment to the exponent. "1.23e0" will + // be stored as `mantissa` == 123 and `exponent` == -2 (that is, + // "123e-2"). + if (post_decimal_digits >= DigitLimit<base>()) { + // refuse to parse pathological inputs + return result; + } else if (post_decimal_digits > digits_left) { + exponent_adjustment -= digits_left; + } else { + exponent_adjustment -= post_decimal_digits; + } + } + // If we've found no mantissa whatsoever, this isn't a number. + if (mantissa_begin == begin) { + return result; + } + // A bare "." doesn't count as a mantissa either. + if (begin - mantissa_begin == 1 && *mantissa_begin == '.') { + return result; + } + + if (mantissa_is_inexact) { + // We dropped significant digits on the floor. Handle this appropriately. + if (base == 10) { + // If we truncated significant decimal digits, store the full range of the + // mantissa for future big integer math for exact rounding. + result.subrange_begin = mantissa_begin; + result.subrange_end = begin; + } else if (base == 16) { + // If we truncated hex digits, reflect this fact by setting the low + // ("sticky") bit. This allows for correct rounding in all cases. + mantissa |= 1; + } + } + result.mantissa = mantissa; + + const char* const exponent_begin = begin; + result.literal_exponent = 0; + bool found_exponent = false; + if (AllowExponent(format_flags) && begin < end && + IsExponentCharacter<base>(*begin)) { + bool negative_exponent = false; + ++begin; + if (begin < end && *begin == '-') { + negative_exponent = true; + ++begin; + } else if (begin < end && *begin == '+') { + ++begin; + } + const char* const exponent_digits_begin = begin; + // Exponent is always expressed in decimal, even for hexadecimal floats. + begin += ConsumeDigits<10>(begin, end, kDecimalExponentDigitsMax, + &result.literal_exponent, nullptr); + if (begin == exponent_digits_begin) { + // there were no digits where we expected an exponent. We failed to read + // an exponent and should not consume the 'e' after all. Rewind 'begin'. + found_exponent = false; + begin = exponent_begin; + } else { + found_exponent = true; + if (negative_exponent) { + result.literal_exponent = -result.literal_exponent; + } + } + } + + if (!found_exponent && RequireExponent(format_flags)) { + // Provided flags required an exponent, but none was found. This results + // in a failure to scan. + return result; + } + + // Success! + result.type = strings_internal::FloatType::kNumber; + if (result.mantissa > 0) { + result.exponent = result.literal_exponent + + (DigitMagnitude<base>() * exponent_adjustment); + } else { + result.exponent = 0; + } + result.end = begin; + return result; +} + +template ParsedFloat ParseFloat<10>(const char* begin, const char* end, + chars_format format_flags); +template ParsedFloat ParseFloat<16>(const char* begin, const char* end, + chars_format format_flags); + +} // namespace strings_internal +} // namespace absl
diff --git a/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h b/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h new file mode 100644 index 0000000..7a5c087 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h
@@ -0,0 +1,96 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ +#define ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ + +#include <cstdint> + +#include "absl/strings/charconv.h" + +namespace absl { +namespace strings_internal { + +// Enum indicating whether a parsed float is a number or special value. +enum class FloatType { kNumber, kInfinity, kNan }; + +// The decomposed parts of a parsed `float` or `double`. +struct ParsedFloat { + // Representation of the parsed mantissa, with the decimal point adjusted to + // make it an integer. + // + // During decimal scanning, this contains 19 significant digits worth of + // mantissa value. If digits beyond this point are found, they + // are truncated, and if any of these dropped digits are nonzero, then + // `mantissa` is inexact, and the full mantissa is stored in [subrange_begin, + // subrange_end). + // + // During hexadecimal scanning, this contains 15 significant hex digits worth + // of mantissa value. Digits beyond this point are sticky -- they are + // truncated, but if any dropped digits are nonzero, the low bit of mantissa + // will be set. (This allows for precise rounding, and avoids the need + // to store the full mantissa in [subrange_begin, subrange_end).) + uint64_t mantissa = 0; + + // Floating point expontent. This reflects any decimal point adjustments and + // any truncated digits from the mantissa. The absolute value of the parsed + // number is represented by mantissa * (base ** exponent), where base==10 for + // decimal floats, and base==2 for hexadecimal floats. + int exponent = 0; + + // The literal exponent value scanned from the input, or 0 if none was + // present. This does not reflect any adjustments applied to mantissa. + int literal_exponent = 0; + + // The type of number scanned. + FloatType type = FloatType::kNumber; + + // When non-null, [subrange_begin, subrange_end) marks a range of characters + // that require further processing. The meaning is dependent on float type. + // If type == kNumber and this is set, this is a "wide input": the input + // mantissa contained more than 19 digits. The range contains the full + // mantissa. It plus `literal_exponent` need to be examined to find the best + // floating point match. + // If type == kNan and this is set, the range marks the contents of a + // matched parenthesized character region after the NaN. + const char* subrange_begin = nullptr; + const char* subrange_end = nullptr; + + // One-past-the-end of the successfully parsed region, or nullptr if no + // matching pattern was found. + const char* end = nullptr; +}; + +// Read the floating point number in the provided range, and populate +// ParsedFloat accordingly. +// +// format_flags is a bitmask value specifying what patterns this API will match. +// `scientific` and `fixed` are honored per std::from_chars rules +// ([utility.from.chars], C++17): if exactly one of these bits is set, then an +// exponent is required, or dislallowed, respectively. +// +// Template parameter `base` must be either 10 or 16. For base 16, a "0x" is +// *not* consumed. The `hex` bit from format_flags is ignored by ParseFloat. +template <int base> +ParsedFloat ParseFloat(const char* begin, const char* end, + absl::chars_format format_flags); + +extern template ParsedFloat ParseFloat<10>(const char* begin, const char* end, + absl::chars_format format_flags); +extern template ParsedFloat ParseFloat<16>(const char* begin, const char* end, + absl::chars_format format_flags); + +} // namespace strings_internal +} // namespace absl +#endif // ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_
diff --git a/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc b/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc new file mode 100644 index 0000000..1ff8600 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc
@@ -0,0 +1,357 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/internal/charconv_parse.h" + +#include <string> +#include <utility> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/strings/str_cat.h" + +using absl::chars_format; +using absl::strings_internal::FloatType; +using absl::strings_internal::ParsedFloat; +using absl::strings_internal::ParseFloat; + +namespace { + +// Check that a given std::string input is parsed to the expected mantissa and +// exponent. +// +// Input std::string `s` must contain a '$' character. It marks the end of the +// characters that should be consumed by the match. It is stripped from the +// input to ParseFloat. +// +// If input std::string `s` contains '[' and ']' characters, these mark the region +// of characters that should be marked as the "subrange". For NaNs, this is +// the location of the extended NaN std::string. For numbers, this is the location +// of the full, over-large mantissa. +template <int base> +void ExpectParsedFloat(std::string s, absl::chars_format format_flags, + FloatType expected_type, uint64_t expected_mantissa, + int expected_exponent, + int expected_literal_exponent = -999) { + SCOPED_TRACE(s); + + int begin_subrange = -1; + int end_subrange = -1; + // If s contains '[' and ']', then strip these characters and set the subrange + // indices appropriately. + std::string::size_type open_bracket_pos = s.find('['); + if (open_bracket_pos != std::string::npos) { + begin_subrange = static_cast<int>(open_bracket_pos); + s.replace(open_bracket_pos, 1, ""); + std::string::size_type close_bracket_pos = s.find(']'); + ABSL_RAW_CHECK(close_bracket_pos != absl::string_view::npos, + "Test input contains [ without matching ]"); + end_subrange = static_cast<int>(close_bracket_pos); + s.replace(close_bracket_pos, 1, ""); + } + const std::string::size_type expected_characters_matched = s.find('$'); + ABSL_RAW_CHECK(expected_characters_matched != std::string::npos, + "Input std::string must contain $"); + s.replace(expected_characters_matched, 1, ""); + + ParsedFloat parsed = + ParseFloat<base>(s.data(), s.data() + s.size(), format_flags); + + EXPECT_NE(parsed.end, nullptr); + if (parsed.end == nullptr) { + return; // The following tests are not useful if we fully failed to parse + } + EXPECT_EQ(parsed.type, expected_type); + if (begin_subrange == -1) { + EXPECT_EQ(parsed.subrange_begin, nullptr); + EXPECT_EQ(parsed.subrange_end, nullptr); + } else { + EXPECT_EQ(parsed.subrange_begin, s.data() + begin_subrange); + EXPECT_EQ(parsed.subrange_end, s.data() + end_subrange); + } + if (parsed.type == FloatType::kNumber) { + EXPECT_EQ(parsed.mantissa, expected_mantissa); + EXPECT_EQ(parsed.exponent, expected_exponent); + if (expected_literal_exponent != -999) { + EXPECT_EQ(parsed.literal_exponent, expected_literal_exponent); + } + } + auto characters_matched = static_cast<int>(parsed.end - s.data()); + EXPECT_EQ(characters_matched, expected_characters_matched); +} + +// Check that a given std::string input is parsed to the expected mantissa and +// exponent. +// +// Input std::string `s` must contain a '$' character. It marks the end of the +// characters that were consumed by the match. +template <int base> +void ExpectNumber(std::string s, absl::chars_format format_flags, + uint64_t expected_mantissa, int expected_exponent, + int expected_literal_exponent = -999) { + ExpectParsedFloat<base>(std::move(s), format_flags, FloatType::kNumber, + expected_mantissa, expected_exponent, + expected_literal_exponent); +} + +// Check that a given std::string input is parsed to the given special value. +// +// This tests against both number bases, since infinities and NaNs have +// identical representations in both modes. +void ExpectSpecial(const std::string& s, absl::chars_format format_flags, + FloatType type) { + ExpectParsedFloat<10>(s, format_flags, type, 0, 0); + ExpectParsedFloat<16>(s, format_flags, type, 0, 0); +} + +// Check that a given input std::string is not matched by Float. +template <int base> +void ExpectFailedParse(absl::string_view s, absl::chars_format format_flags) { + ParsedFloat parsed = + ParseFloat<base>(s.data(), s.data() + s.size(), format_flags); + EXPECT_EQ(parsed.end, nullptr); +} + +TEST(ParseFloat, SimpleValue) { + // Test that various forms of floating point numbers all parse correctly. + ExpectNumber<10>("1.23456789e5$", chars_format::general, 123456789, -3); + ExpectNumber<10>("1.23456789e+5$", chars_format::general, 123456789, -3); + ExpectNumber<10>("1.23456789E5$", chars_format::general, 123456789, -3); + ExpectNumber<10>("1.23456789e05$", chars_format::general, 123456789, -3); + ExpectNumber<10>("123.456789e3$", chars_format::general, 123456789, -3); + ExpectNumber<10>("0.000123456789e9$", chars_format::general, 123456789, -3); + ExpectNumber<10>("123456.789$", chars_format::general, 123456789, -3); + ExpectNumber<10>("123456789e-3$", chars_format::general, 123456789, -3); + + ExpectNumber<16>("1.234abcdefp28$", chars_format::general, 0x1234abcdef, -8); + ExpectNumber<16>("1.234abcdefp+28$", chars_format::general, 0x1234abcdef, -8); + ExpectNumber<16>("1.234ABCDEFp28$", chars_format::general, 0x1234abcdef, -8); + ExpectNumber<16>("1.234AbCdEfP0028$", chars_format::general, 0x1234abcdef, + -8); + ExpectNumber<16>("123.4abcdefp20$", chars_format::general, 0x1234abcdef, -8); + ExpectNumber<16>("0.0001234abcdefp44$", chars_format::general, 0x1234abcdef, + -8); + ExpectNumber<16>("1234abcd.ef$", chars_format::general, 0x1234abcdef, -8); + ExpectNumber<16>("1234abcdefp-8$", chars_format::general, 0x1234abcdef, -8); + + // ExpectNumber does not attempt to drop trailing zeroes. + ExpectNumber<10>("0001.2345678900e005$", chars_format::general, 12345678900, + -5); + ExpectNumber<16>("0001.234abcdef000p28$", chars_format::general, + 0x1234abcdef000, -20); + + // Ensure non-matching characters after a number are ignored, even when they + // look like potentially matching characters. + ExpectNumber<10>("1.23456789e5$ ", chars_format::general, 123456789, -3); + ExpectNumber<10>("1.23456789e5$e5e5", chars_format::general, 123456789, -3); + ExpectNumber<10>("1.23456789e5$.25", chars_format::general, 123456789, -3); + ExpectNumber<10>("1.23456789e5$-", chars_format::general, 123456789, -3); + ExpectNumber<10>("1.23456789e5$PUPPERS!!!", chars_format::general, 123456789, + -3); + ExpectNumber<10>("123456.789$efghij", chars_format::general, 123456789, -3); + ExpectNumber<10>("123456.789$e", chars_format::general, 123456789, -3); + ExpectNumber<10>("123456.789$p5", chars_format::general, 123456789, -3); + ExpectNumber<10>("123456.789$.10", chars_format::general, 123456789, -3); + + ExpectNumber<16>("1.234abcdefp28$ ", chars_format::general, 0x1234abcdef, + -8); + ExpectNumber<16>("1.234abcdefp28$p28", chars_format::general, 0x1234abcdef, + -8); + ExpectNumber<16>("1.234abcdefp28$.125", chars_format::general, 0x1234abcdef, + -8); + ExpectNumber<16>("1.234abcdefp28$-", chars_format::general, 0x1234abcdef, -8); + ExpectNumber<16>("1.234abcdefp28$KITTEHS!!!", chars_format::general, + 0x1234abcdef, -8); + ExpectNumber<16>("1234abcd.ef$ghijk", chars_format::general, 0x1234abcdef, + -8); + ExpectNumber<16>("1234abcd.ef$p", chars_format::general, 0x1234abcdef, -8); + ExpectNumber<16>("1234abcd.ef$.10", chars_format::general, 0x1234abcdef, -8); + + // Ensure we can read a full resolution mantissa without overflow. + ExpectNumber<10>("9999999999999999999$", chars_format::general, + 9999999999999999999u, 0); + ExpectNumber<16>("fffffffffffffff$", chars_format::general, + 0xfffffffffffffffu, 0); + + // Check that zero is consistently read. + ExpectNumber<10>("0$", chars_format::general, 0, 0); + ExpectNumber<16>("0$", chars_format::general, 0, 0); + ExpectNumber<10>("000000000000000000000000000000000000000$", + chars_format::general, 0, 0); + ExpectNumber<16>("000000000000000000000000000000000000000$", + chars_format::general, 0, 0); + ExpectNumber<10>("0000000000000000000000.000000000000000000$", + chars_format::general, 0, 0); + ExpectNumber<16>("0000000000000000000000.000000000000000000$", + chars_format::general, 0, 0); + ExpectNumber<10>("0.00000000000000000000000000000000e123456$", + chars_format::general, 0, 0); + ExpectNumber<16>("0.00000000000000000000000000000000p123456$", + chars_format::general, 0, 0); +} + +TEST(ParseFloat, LargeDecimalMantissa) { + // After 19 significant decimal digits in the mantissa, ParsedFloat will + // truncate additional digits. We need to test that: + // 1) the truncation to 19 digits happens + // 2) the returned exponent reflects the dropped significant digits + // 3) a correct literal_exponent is set + // + // If and only if a significant digit is found after 19 digits, then the + // entirety of the mantissa in case the exact value is needed to make a + // rounding decision. The [ and ] characters below denote where such a + // subregion was marked by by ParseFloat. They are not part of the input. + + // Mark a capture group only if a dropped digit is significant (nonzero). + ExpectNumber<10>("100000000000000000000000000$", chars_format::general, + 1000000000000000000, + /* adjusted exponent */ 8); + + ExpectNumber<10>("123456789123456789100000000$", chars_format::general, + 1234567891234567891, + /* adjusted exponent */ 8); + + ExpectNumber<10>("[123456789123456789123456789]$", chars_format::general, + 1234567891234567891, + /* adjusted exponent */ 8, + /* literal exponent */ 0); + + ExpectNumber<10>("[123456789123456789100000009]$", chars_format::general, + 1234567891234567891, + /* adjusted exponent */ 8, + /* literal exponent */ 0); + + ExpectNumber<10>("[123456789123456789120000000]$", chars_format::general, + 1234567891234567891, + /* adjusted exponent */ 8, + /* literal exponent */ 0); + + // Leading zeroes should not count towards the 19 significant digit limit + ExpectNumber<10>("[00000000123456789123456789123456789]$", + chars_format::general, 1234567891234567891, + /* adjusted exponent */ 8, + /* literal exponent */ 0); + + ExpectNumber<10>("00000000123456789123456789100000000$", + chars_format::general, 1234567891234567891, + /* adjusted exponent */ 8); + + // Truncated digits after the decimal point should not cause a further + // exponent adjustment. + ExpectNumber<10>("1.234567891234567891e123$", chars_format::general, + 1234567891234567891, 105); + ExpectNumber<10>("[1.23456789123456789123456789]e123$", chars_format::general, + 1234567891234567891, + /* adjusted exponent */ 105, + /* literal exponent */ 123); + + // Ensure we truncate, and not round. (The from_chars algorithm we use + // depends on our guess missing low, if it misses, so we need the rounding + // error to be downward.) + ExpectNumber<10>("[1999999999999999999999]$", chars_format::general, + 1999999999999999999, + /* adjusted exponent */ 3, + /* literal exponent */ 0); +} + +TEST(ParseFloat, LargeHexadecimalMantissa) { + // After 15 significant hex digits in the mantissa, ParsedFloat will treat + // additional digits as sticky, We need to test that: + // 1) The truncation to 15 digits happens + // 2) The returned exponent reflects the dropped significant digits + // 3) If a nonzero digit is dropped, the low bit of mantissa is set. + + ExpectNumber<16>("123456789abcdef123456789abcdef$", chars_format::general, + 0x123456789abcdef, 60); + + // Leading zeroes should not count towards the 15 significant digit limit + ExpectNumber<16>("000000123456789abcdef123456789abcdef$", + chars_format::general, 0x123456789abcdef, 60); + + // Truncated digits after the radix point should not cause a further + // exponent adjustment. + ExpectNumber<16>("1.23456789abcdefp100$", chars_format::general, + 0x123456789abcdef, 44); + ExpectNumber<16>("1.23456789abcdef123456789abcdefp100$", + chars_format::general, 0x123456789abcdef, 44); + + // test sticky digit behavior. The low bit should be set iff any dropped + // digit is nonzero. + ExpectNumber<16>("123456789abcdee123456789abcdee$", chars_format::general, + 0x123456789abcdef, 60); + ExpectNumber<16>("123456789abcdee000000000000001$", chars_format::general, + 0x123456789abcdef, 60); + ExpectNumber<16>("123456789abcdee000000000000000$", chars_format::general, + 0x123456789abcdee, 60); +} + +TEST(ParseFloat, ScientificVsFixed) { + // In fixed mode, an exponent is never matched (but the remainder of the + // number will be matched.) + ExpectNumber<10>("1.23456789$e5", chars_format::fixed, 123456789, -8); + ExpectNumber<10>("123456.789$", chars_format::fixed, 123456789, -3); + ExpectNumber<16>("1.234abcdef$p28", chars_format::fixed, 0x1234abcdef, -36); + ExpectNumber<16>("1234abcd.ef$", chars_format::fixed, 0x1234abcdef, -8); + + // In scientific mode, numbers don't match *unless* they have an exponent. + ExpectNumber<10>("1.23456789e5$", chars_format::scientific, 123456789, -3); + ExpectFailedParse<10>("-123456.789$", chars_format::scientific); + ExpectNumber<16>("1.234abcdefp28$", chars_format::scientific, 0x1234abcdef, + -8); + ExpectFailedParse<16>("1234abcd.ef$", chars_format::scientific); +} + +TEST(ParseFloat, Infinity) { + ExpectFailedParse<10>("in", chars_format::general); + ExpectFailedParse<16>("in", chars_format::general); + ExpectFailedParse<10>("inx", chars_format::general); + ExpectFailedParse<16>("inx", chars_format::general); + ExpectSpecial("inf$", chars_format::general, FloatType::kInfinity); + ExpectSpecial("Inf$", chars_format::general, FloatType::kInfinity); + ExpectSpecial("INF$", chars_format::general, FloatType::kInfinity); + ExpectSpecial("inf$inite", chars_format::general, FloatType::kInfinity); + ExpectSpecial("iNfInItY$", chars_format::general, FloatType::kInfinity); + ExpectSpecial("infinity$!!!", chars_format::general, FloatType::kInfinity); +} + +TEST(ParseFloat, NaN) { + ExpectFailedParse<10>("na", chars_format::general); + ExpectFailedParse<16>("na", chars_format::general); + ExpectFailedParse<10>("nah", chars_format::general); + ExpectFailedParse<16>("nah", chars_format::general); + ExpectSpecial("nan$", chars_format::general, FloatType::kNan); + ExpectSpecial("NaN$", chars_format::general, FloatType::kNan); + ExpectSpecial("nAn$", chars_format::general, FloatType::kNan); + ExpectSpecial("NAN$", chars_format::general, FloatType::kNan); + ExpectSpecial("NaN$aNaNaNaNaBatman!", chars_format::general, FloatType::kNan); + + // A parenthesized sequence of the characters [a-zA-Z0-9_] is allowed to + // appear after an NaN. Check that this is allowed, and that the correct + // characters are grouped. + // + // (The characters [ and ] in the pattern below delimit the expected matched + // subgroup; they are not part of the input passed to ParseFloat.) + ExpectSpecial("nan([0xabcdef])$", chars_format::general, FloatType::kNan); + ExpectSpecial("nan([0xabcdef])$...", chars_format::general, FloatType::kNan); + ExpectSpecial("nan([0xabcdef])$)...", chars_format::general, FloatType::kNan); + ExpectSpecial("nan([])$", chars_format::general, FloatType::kNan); + ExpectSpecial("nan([aAzZ09_])$", chars_format::general, FloatType::kNan); + // If the subgroup contains illegal characters, don't match it at all. + ExpectSpecial("nan$(bad-char)", chars_format::general, FloatType::kNan); + // Also cope with a missing close paren. + ExpectSpecial("nan$(0xabcdef", chars_format::general, FloatType::kNan); +} + +} // namespace
diff --git a/third_party/abseil-cpp/absl/strings/numbers.cc b/third_party/abseil-cpp/absl/strings/numbers.cc index 68ef799..f842ed8 100644 --- a/third_party/abseil-cpp/absl/strings/numbers.cc +++ b/third_party/abseil-cpp/absl/strings/numbers.cc
@@ -32,6 +32,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/strings/ascii.h" +#include "absl/strings/charconv.h" #include "absl/strings/internal/bits.h" #include "absl/strings/internal/memutil.h" #include "absl/strings/str_cat.h" @@ -40,51 +41,54 @@ bool SimpleAtof(absl::string_view str, float* value) { *value = 0.0; - if (str.empty()) return false; - char buf[32]; - std::unique_ptr<char[]> bigbuf; - char* ptr = buf; - if (str.size() > sizeof(buf) - 1) { - bigbuf.reset(new char[str.size() + 1]); - ptr = bigbuf.get(); + str = StripAsciiWhitespace(str); + if (!str.empty() && str[0] == '+') { + str.remove_prefix(1); } - memcpy(ptr, str.data(), str.size()); - ptr[str.size()] = '\0'; - - char* endptr; - *value = strtof(ptr, &endptr); - if (endptr != ptr) { - while (absl::ascii_isspace(*endptr)) ++endptr; + auto result = absl::from_chars(str.data(), str.data() + str.size(), *value); + if (result.ec == std::errc::invalid_argument) { + return false; } - // Ignore range errors from strtod/strtof. - // The values it returns on underflow and - // overflow are the right fallback in a - // robust setting. - return *ptr != '\0' && *endptr == '\0'; + if (result.ptr != str.data() + str.size()) { + // not all non-whitespace characters consumed + return false; + } + // from_chars() with DR 3801's current wording will return max() on + // overflow. SimpleAtof returns infinity instead. + if (result.ec == std::errc::result_out_of_range) { + if (*value > 1.0) { + *value = std::numeric_limits<float>::infinity(); + } else if (*value < -1.0) { + *value = -std::numeric_limits<float>::infinity(); + } + } + return true; } bool SimpleAtod(absl::string_view str, double* value) { *value = 0.0; - if (str.empty()) return false; - char buf[32]; - std::unique_ptr<char[]> bigbuf; - char* ptr = buf; - if (str.size() > sizeof(buf) - 1) { - bigbuf.reset(new char[str.size() + 1]); - ptr = bigbuf.get(); + str = StripAsciiWhitespace(str); + if (!str.empty() && str[0] == '+') { + str.remove_prefix(1); } - memcpy(ptr, str.data(), str.size()); - ptr[str.size()] = '\0'; - - char* endptr; - *value = strtod(ptr, &endptr); - if (endptr != ptr) { - while (absl::ascii_isspace(*endptr)) ++endptr; + auto result = absl::from_chars(str.data(), str.data() + str.size(), *value); + if (result.ec == std::errc::invalid_argument) { + return false; } - // Ignore range errors from strtod. The values it - // returns on underflow and overflow are the right - // fallback in a robust setting. - return *ptr != '\0' && *endptr == '\0'; + if (result.ptr != str.data() + str.size()) { + // not all non-whitespace characters consumed + return false; + } + // from_chars() with DR 3801's current wording will return max() on + // overflow. SimpleAtod returns infinity instead. + if (result.ec == std::errc::result_out_of_range) { + if (*value > 1.0) { + *value = std::numeric_limits<double>::infinity(); + } else if (*value < -1.0) { + *value = -std::numeric_limits<double>::infinity(); + } + } + return true; } namespace {
diff --git a/third_party/abseil-cpp/absl/synchronization/BUILD.bazel b/third_party/abseil-cpp/absl/synchronization/BUILD.bazel index 123536e..372874e 100644 --- a/third_party/abseil-cpp/absl/synchronization/BUILD.bazel +++ b/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
@@ -149,12 +149,6 @@ size = "large", srcs = ["mutex_test.cc"], copts = ABSL_TEST_COPTS, - tags = [ - "no_test_android_arm", - "no_test_android_arm64", - "no_test_android_x86", - "no_test_loonix", # Too slow. - ], deps = [ ":synchronization", ":thread_pool",
diff --git a/third_party/abseil-cpp/absl/time/BUILD.bazel b/third_party/abseil-cpp/absl/time/BUILD.bazel index fe55fe1..e793da8 100644 --- a/third_party/abseil-cpp/absl/time/BUILD.bazel +++ b/third_party/abseil-cpp/absl/time/BUILD.bazel
@@ -44,6 +44,7 @@ "//absl/base", "//absl/base:core_headers", "//absl/numeric:int128", + "//absl/strings", "//absl/time/internal/cctz:civil_time", "//absl/time/internal/cctz:time_zone", ], @@ -80,9 +81,6 @@ "time_zone_test.cc", ], copts = ABSL_TEST_COPTS, - tags = [ - "no_test_loonix", - ], deps = [ ":test_util", ":time",
diff --git a/third_party/abseil-cpp/absl/time/BUILD.gn b/third_party/abseil-cpp/absl/time/BUILD.gn index 1cc3276..3ed4655b 100644 --- a/third_party/abseil-cpp/absl/time/BUILD.gn +++ b/third_party/abseil-cpp/absl/time/BUILD.gn
@@ -37,6 +37,7 @@ "../base", "../base:core_headers", "../numeric:int128", + "../strings", "../time/internal/cctz:civil_time", "../time/internal/cctz:time_zone", ]
diff --git a/third_party/abseil-cpp/absl/time/CMakeLists.txt b/third_party/abseil-cpp/absl/time/CMakeLists.txt index 72bb4d25..06272364 100644 --- a/third_party/abseil-cpp/absl/time/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/time/CMakeLists.txt
@@ -53,7 +53,7 @@ ${TIME_PUBLIC_HEADERS} ${TIME_INTERNAL_HEADERS} ) -set(TIME_PUBLIC_LIBRARIES absl::base absl::stacktrace absl::int128) +set(TIME_PUBLIC_LIBRARIES absl::base absl::stacktrace absl::int128 absl::strings) absl_library( TARGET
diff --git a/third_party/abseil-cpp/absl/time/duration.cc b/third_party/abseil-cpp/absl/time/duration.cc index 82b4d98..c13fa79 100644 --- a/third_party/abseil-cpp/absl/time/duration.cc +++ b/third_party/abseil-cpp/absl/time/duration.cc
@@ -896,8 +896,7 @@ return true; } -// TODO(absl-team): Remove once dependencies are removed. -bool ParseFlag(const std::string& text, Duration* dst, std::string* /* err */) { +bool ParseFlag(const std::string& text, Duration* dst, std::string* ) { return ParseDuration(text, dst); }
diff --git a/third_party/abseil-cpp/absl/time/format.cc b/third_party/abseil-cpp/absl/time/format.cc index 5dc01bda..6edf2b5 100644 --- a/third_party/abseil-cpp/absl/time/format.cc +++ b/third_party/abseil-cpp/absl/time/format.cc
@@ -129,7 +129,6 @@ return b; } -// TODO(absl-team): Remove once dependencies are removed. // Functions required to support absl::Time flags. bool ParseFlag(const std::string& text, absl::Time* t, std::string* error) { return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error);
diff --git a/third_party/abseil-cpp/absl/time/time.h b/third_party/abseil-cpp/absl/time/time.h index 99c12bbd..ceec2de 100644 --- a/third_party/abseil-cpp/absl/time/time.h +++ b/third_party/abseil-cpp/absl/time/time.h
@@ -64,6 +64,7 @@ #include <utility> #include "absl/base/port.h" // Needed for string vs std::string +#include "absl/strings/string_view.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { @@ -491,9 +492,6 @@ // `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. bool ParseDuration(const std::string& dur_string, Duration* d); -// Flag Support -// TODO(absl-team): Remove once dependencies are removed. - // ParseFlag() // bool ParseFlag(const std::string& text, Duration* dst, std::string* error); @@ -993,8 +991,6 @@ bool ParseTime(const std::string& format, const std::string& input, TimeZone tz, Time* time, std::string* err); -// TODO(absl-team): Remove once dependencies are removed. - // ParseFlag() // UnparseFlag() //
diff --git a/third_party/abseil-cpp/absl/types/BUILD.bazel b/third_party/abseil-cpp/absl/types/BUILD.bazel index 1fc4c09..c50ec425 100644 --- a/third_party/abseil-cpp/absl/types/BUILD.bazel +++ b/third_party/abseil-cpp/absl/types/BUILD.bazel
@@ -248,6 +248,19 @@ ) cc_test( + name = "variant_benchmark", + srcs = [ + "variant_benchmark.cc", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":variant", + "//absl/utility", + "@com_github_google_benchmark//:benchmark_main", + ], +) + +cc_test( name = "variant_exception_safety_test", size = "small", srcs = [
diff --git a/third_party/abseil-cpp/absl/types/internal/variant.h b/third_party/abseil-cpp/absl/types/internal/variant.h index 61c56ddf..94c2dda 100644 --- a/third_party/abseil-cpp/absl/types/internal/variant.h +++ b/third_party/abseil-cpp/absl/types/internal/variant.h
@@ -19,15 +19,19 @@ #ifndef ABSL_TYPES_variant_internal_H_ #define ABSL_TYPES_variant_internal_H_ +#include <cassert> #include <cstddef> +#include <cstdlib> #include <memory> #include <stdexcept> #include <tuple> #include <type_traits> +#include "absl/base/config.h" #include "absl/base/internal/identity.h" #include "absl/base/internal/inline_variable.h" #include "absl/base/internal/invoke.h" +#include "absl/base/macros.h" #include "absl/base/optimization.h" #include "absl/meta/type_traits.h" #include "absl/types/bad_variant_access.h" @@ -119,6 +123,8 @@ template <std::size_t I> using SizeT = std::integral_constant<std::size_t, I>; +using NPos = SizeT<variant_npos>; + template <class Variant, class T, class = void> struct IndexOfConstructedType {}; @@ -248,19 +254,270 @@ ReturnType, FunctionObject, index_sequence<TailEndIndices...>, absl::make_index_sequence<HeadEndIndex>, BoundIndices...> {}; -template <std::size_t... EndIndices, class Op, class... SizeT> -VisitIndicesResultT<Op, SizeT...> visit_indices(Op&& op, SizeT... indices) { - return AccessSimpleArray( - MakeVisitationMatrix<VisitIndicesResultT<Op, SizeT...>, Op, - index_sequence<(EndIndices + 1)...>>::Run(), - (indices + 1)...)(absl::forward<Op>(op)); -} +struct UnreachableSwitchCase { + template <class Op> + [[noreturn]] static VisitIndicesResultT<Op, std::size_t> Run( + Op&& /*ignored*/) { +#if ABSL_HAVE_BUILTIN(__builtin_unreachable) || \ + (defined(__GNUC__) && !defined(__clang__)) + __builtin_unreachable(); +#elif defined(_MSC_VER) + __assume(false); +#else + // Try to use assert of false being identified as an unreachable intrinsic. + // NOTE: We use assert directly to increase chances of exploiting an assume + // intrinsic. + assert(false); // NOLINT + + // Hack to silence potential no return warning -- cause an infinite loop. + return Run(absl::forward<Op>(op)); +#endif // Checks for __builtin_unreachable + } +}; + +template <class Op, std::size_t I> +struct ReachableSwitchCase { + static VisitIndicesResultT<Op, std::size_t> Run(Op&& op) { + return absl::base_internal::Invoke(absl::forward<Op>(op), SizeT<I>()); + } +}; + +// The number 33 is just a guess at a reasonable maximum to our switch. It is +// not based on any analysis. The reason it is a power of 2 plus 1 instead of a +// power of 2 is because the number was picked to correspond to a power of 2 +// amount of "normal" alternatives, plus one for the possibility of the user +// providing "monostate" in addition to the more natural alternatives. +ABSL_INTERNAL_INLINE_CONSTEXPR(std::size_t, MaxUnrolledVisitCases, 33); + +// Note: The default-definition is for unreachable cases. +template <bool IsReachable> +struct PickCaseImpl { + template <class Op, std::size_t I> + using Apply = UnreachableSwitchCase; +}; + +template <> +struct PickCaseImpl</*IsReachable =*/true> { + template <class Op, std::size_t I> + using Apply = ReachableSwitchCase<Op, I>; +}; + +// Note: This form of dance with template aliases is to make sure that we +// instantiate a number of templates proportional to the number of variant +// alternatives rather than a number of templates proportional to our +// maximum unrolled amount of visitation cases (aliases are effectively +// "free" whereas other template instantiations are costly). +template <class Op, std::size_t I, std::size_t EndIndex> +using PickCase = typename PickCaseImpl<(I < EndIndex)>::template Apply<Op, I>; template <class ReturnType> [[noreturn]] ReturnType TypedThrowBadVariantAccess() { absl::variant_internal::ThrowBadVariantAccess(); } +// Given N variant sizes, determine the number of cases there would need to be +// in a single switch-statement that would cover every possibility in the +// corresponding N-ary visit operation. +template <std::size_t... NumAlternatives> +struct NumCasesOfSwitch; + +template <std::size_t HeadNumAlternatives, std::size_t... TailNumAlternatives> +struct NumCasesOfSwitch<HeadNumAlternatives, TailNumAlternatives...> { + static constexpr std::size_t value = + (HeadNumAlternatives + 1) * + NumCasesOfSwitch<TailNumAlternatives...>::value; +}; + +template <> +struct NumCasesOfSwitch<> { + static constexpr std::size_t value = 1; +}; + +// A switch statement optimizes better than the table of function pointers. +template <std::size_t EndIndex> +struct VisitIndicesSwitch { + static_assert(EndIndex <= MaxUnrolledVisitCases, + "Maximum unrolled switch size exceeded."); + + template <class Op> + static VisitIndicesResultT<Op, std::size_t> Run(Op&& op, std::size_t i) { + switch (i) { + case 0: + return PickCase<Op, 0, EndIndex>::Run(absl::forward<Op>(op)); + case 1: + return PickCase<Op, 1, EndIndex>::Run(absl::forward<Op>(op)); + case 2: + return PickCase<Op, 2, EndIndex>::Run(absl::forward<Op>(op)); + case 3: + return PickCase<Op, 3, EndIndex>::Run(absl::forward<Op>(op)); + case 4: + return PickCase<Op, 4, EndIndex>::Run(absl::forward<Op>(op)); + case 5: + return PickCase<Op, 5, EndIndex>::Run(absl::forward<Op>(op)); + case 6: + return PickCase<Op, 6, EndIndex>::Run(absl::forward<Op>(op)); + case 7: + return PickCase<Op, 7, EndIndex>::Run(absl::forward<Op>(op)); + case 8: + return PickCase<Op, 8, EndIndex>::Run(absl::forward<Op>(op)); + case 9: + return PickCase<Op, 9, EndIndex>::Run(absl::forward<Op>(op)); + case 10: + return PickCase<Op, 10, EndIndex>::Run(absl::forward<Op>(op)); + case 11: + return PickCase<Op, 11, EndIndex>::Run(absl::forward<Op>(op)); + case 12: + return PickCase<Op, 12, EndIndex>::Run(absl::forward<Op>(op)); + case 13: + return PickCase<Op, 13, EndIndex>::Run(absl::forward<Op>(op)); + case 14: + return PickCase<Op, 14, EndIndex>::Run(absl::forward<Op>(op)); + case 15: + return PickCase<Op, 15, EndIndex>::Run(absl::forward<Op>(op)); + case 16: + return PickCase<Op, 16, EndIndex>::Run(absl::forward<Op>(op)); + case 17: + return PickCase<Op, 17, EndIndex>::Run(absl::forward<Op>(op)); + case 18: + return PickCase<Op, 18, EndIndex>::Run(absl::forward<Op>(op)); + case 19: + return PickCase<Op, 19, EndIndex>::Run(absl::forward<Op>(op)); + case 20: + return PickCase<Op, 20, EndIndex>::Run(absl::forward<Op>(op)); + case 21: + return PickCase<Op, 21, EndIndex>::Run(absl::forward<Op>(op)); + case 22: + return PickCase<Op, 22, EndIndex>::Run(absl::forward<Op>(op)); + case 23: + return PickCase<Op, 23, EndIndex>::Run(absl::forward<Op>(op)); + case 24: + return PickCase<Op, 24, EndIndex>::Run(absl::forward<Op>(op)); + case 25: + return PickCase<Op, 25, EndIndex>::Run(absl::forward<Op>(op)); + case 26: + return PickCase<Op, 26, EndIndex>::Run(absl::forward<Op>(op)); + case 27: + return PickCase<Op, 27, EndIndex>::Run(absl::forward<Op>(op)); + case 28: + return PickCase<Op, 28, EndIndex>::Run(absl::forward<Op>(op)); + case 29: + return PickCase<Op, 29, EndIndex>::Run(absl::forward<Op>(op)); + case 30: + return PickCase<Op, 30, EndIndex>::Run(absl::forward<Op>(op)); + case 31: + return PickCase<Op, 31, EndIndex>::Run(absl::forward<Op>(op)); + case 32: + return PickCase<Op, 32, EndIndex>::Run(absl::forward<Op>(op)); + default: + ABSL_ASSERT(i == variant_npos); + return absl::base_internal::Invoke(absl::forward<Op>(op), NPos()); + } + } +}; + +template <std::size_t... EndIndices> +struct VisitIndicesFallback { + template <class Op, class... SizeT> + static VisitIndicesResultT<Op, SizeT...> Run(Op&& op, SizeT... indices) { + return AccessSimpleArray( + MakeVisitationMatrix<VisitIndicesResultT<Op, SizeT...>, Op, + index_sequence<(EndIndices + 1)...>>::Run(), + (indices + 1)...)(absl::forward<Op>(op)); + } +}; + +// Take an N-dimensional series of indices and convert them into a single index +// without loss of information. The purpose of this is to be able to convert an +// N-ary visit operation into a single switch statement. +template <std::size_t...> +struct FlattenIndices; + +template <std::size_t HeadSize, std::size_t... TailSize> +struct FlattenIndices<HeadSize, TailSize...> { + template<class... SizeType> + static constexpr std::size_t Run(std::size_t head, SizeType... tail) { + return head + HeadSize * FlattenIndices<TailSize...>::Run(tail...); + } +}; + +template <> +struct FlattenIndices<> { + static constexpr std::size_t Run() { return 0; } +}; + +// Take a single "flattened" index (flattened by FlattenIndices) and determine +// the value of the index of one of the logically represented dimensions. +template <std::size_t I, std::size_t IndexToGet, std::size_t HeadSize, + std::size_t... TailSize> +struct UnflattenIndex { + static constexpr std::size_t value = + UnflattenIndex<I / HeadSize, IndexToGet - 1, TailSize...>::value; +}; + +template <std::size_t I, std::size_t HeadSize, std::size_t... TailSize> +struct UnflattenIndex<I, 0, HeadSize, TailSize...> { + static constexpr std::size_t value = (I % HeadSize); +}; + +// The backend for converting an N-ary visit operation into a unary visit. +template <class IndexSequence, std::size_t... EndIndices> +struct VisitIndicesVariadicImpl; + +template <std::size_t... N, std::size_t... EndIndices> +struct VisitIndicesVariadicImpl<absl::index_sequence<N...>, EndIndices...> { + // A type that can take an N-ary function object and converts it to a unary + // function object that takes a single, flattened index, and "unflattens" it + // into its individual dimensions when forwarding to the wrapped object. + template <class Op> + struct FlattenedOp { + template <std::size_t I> + VisitIndicesResultT<Op, decltype(EndIndices)...> operator()( + SizeT<I> /*index*/) && { + return base_internal::Invoke( + absl::forward<Op>(op), + SizeT<UnflattenIndex<I, N, (EndIndices + 1)...>::value - + std::size_t{1}>()...); + } + + Op&& op; + }; + + template <class Op, class... SizeType> + static VisitIndicesResultT<Op, decltype(EndIndices)...> Run( + Op&& op, SizeType... i) { + return VisitIndicesSwitch<NumCasesOfSwitch<EndIndices...>::value>::Run( + FlattenedOp<Op>{absl::forward<Op>(op)}, + FlattenIndices<(EndIndices + std::size_t{1})...>::Run( + (i + std::size_t{1})...)); + } +}; + +template <std::size_t... EndIndices> +struct VisitIndicesVariadic + : VisitIndicesVariadicImpl<absl::make_index_sequence<sizeof...(EndIndices)>, + EndIndices...> {}; + +// This implementation will flatten N-ary visit operations into a single switch +// statement when the number of cases would be less than our maximum specified +// switch-statement size. +// TODO(calabrese) +// Based on benchmarks, determine whether the function table approach actually +// does optimize better than a chain of switch statements and possibly update +// the implementation accordingly. Also consider increasing the maximum switch +// size. +template <std::size_t... EndIndices> +struct VisitIndices + : absl::conditional_t<(NumCasesOfSwitch<EndIndices...>::value <= + MaxUnrolledVisitCases), + VisitIndicesVariadic<EndIndices...>, + VisitIndicesFallback<EndIndices...>> {}; + +template <std::size_t EndIndex> +struct VisitIndices<EndIndex> + : absl::conditional_t<(EndIndex <= MaxUnrolledVisitCases), + VisitIndicesSwitch<EndIndex>, + VisitIndicesFallback<EndIndex>> {}; + // Suppress bogus warning on MSVC: MSVC complains that the `reinterpret_cast` // below is returning the address of a temporary or local object. #ifdef _MSC_VER @@ -270,8 +527,10 @@ // TODO(calabrese) std::launder // TODO(calabrese) constexpr +// NOTE: DO NOT REMOVE the `inline` keyword as it is necessary to work around a +// MSVC bug. See https://github.com/abseil/abseil-cpp/issues/129 for details. template <class Self, std::size_t I> -VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> /*i*/) { +inline VariantAccessResult<I, Self> AccessUnion(Self&& self, SizeT<I> /*i*/) { return reinterpret_cast<VariantAccessResult<I, Self>>(self); } @@ -313,7 +572,7 @@ template <class Variant> static void InitFrom(Variant& self, Variant&& other) { // NOLINT - variant_internal::visit_indices<absl::variant_size<Variant>::value>( + VisitIndices<absl::variant_size<Variant>::value>::Run( InitFromVisitor<Variant, Variant&&>{&self, std::forward<Variant>(other)}, other.index()); @@ -1049,9 +1308,7 @@ VariantStateBaseDestructorNontrivial* self; }; - void destroy() { - variant_internal::visit_indices<sizeof...(T)>(Destroyer{this}, index_); - } + void destroy() { VisitIndices<sizeof...(T)>::Run(Destroyer{this}, index_); } ~VariantStateBaseDestructorNontrivial() { destroy(); } @@ -1087,8 +1344,7 @@ VariantMoveBaseNontrivial(VariantMoveBaseNontrivial&& other) noexcept( absl::conjunction<std::is_nothrow_move_constructible<T>...>::value) : Base(NoopConstructorTag()) { - variant_internal::visit_indices<sizeof...(T)>(Construct{this, &other}, - other.index_); + VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_); index_ = other.index_; } @@ -1131,8 +1387,7 @@ VariantCopyBaseNontrivial(VariantCopyBaseNontrivial const& other) : Base(NoopConstructorTag()) { - variant_internal::visit_indices<sizeof...(T)>(Construct{this, &other}, - other.index_); + VisitIndices<sizeof...(T)>::Run(Construct{this, &other}, other.index_); index_ = other.index_; } @@ -1166,7 +1421,7 @@ operator=(VariantMoveAssignBaseNontrivial&& other) noexcept( absl::conjunction<std::is_nothrow_move_constructible<T>..., std::is_nothrow_move_assignable<T>...>::value) { - variant_internal::visit_indices<sizeof...(T)>( + VisitIndices<sizeof...(T)>::Run( VariantCoreAccess::MakeMoveAssignVisitor(this, &other), other.index_); return *this; } @@ -1195,7 +1450,7 @@ VariantCopyAssignBaseNontrivial& operator=( const VariantCopyAssignBaseNontrivial& other) { - variant_internal::visit_indices<sizeof...(T)>( + VisitIndices<sizeof...(T)>::Run( VariantCoreAccess::MakeCopyAssignVisitor(this, other), other.index_); return *this; } @@ -1336,7 +1591,7 @@ template <std::size_t Wi> void operator()(SizeT<Wi> /*w_i*/) { if (v->index() == Wi) { - visit_indices<sizeof...(Types)>(SwapSameIndex<Types...>{v, w}, Wi); + VisitIndices<sizeof...(Types)>::Run(SwapSameIndex<Types...>{v, w}, Wi); } else { generic_swap(); } @@ -1370,11 +1625,10 @@ if (var.valueless_by_exception()) { return 239799884; } - size_t result = - variant_internal::visit_indices<variant_size<Variant>::value>( - PerformVisitation<VariantHashVisitor, const Variant&>{ - std::forward_as_tuple(var), VariantHashVisitor{}}, - var.index()); + size_t result = VisitIndices<variant_size<Variant>::value>::Run( + PerformVisitation<VariantHashVisitor, const Variant&>{ + std::forward_as_tuple(var), VariantHashVisitor{}}, + var.index()); // Combine the index and the hash result in order to distinguish // std::variant<int, int> holding the same value as different alternative. return result ^ var.index();
diff --git a/third_party/abseil-cpp/absl/types/optional.h b/third_party/abseil-cpp/absl/types/optional.h index 80a2d14..c837cdd 100644 --- a/third_party/abseil-cpp/absl/types/optional.h +++ b/third_party/abseil-cpp/absl/types/optional.h
@@ -48,7 +48,7 @@ using std::make_optional; using std::nullopt_t; using std::nullopt; -} +} // namespace absl #else // ABSL_HAVE_STD_OPTIONAL
diff --git a/third_party/abseil-cpp/absl/types/variant.h b/third_party/abseil-cpp/absl/types/variant.h index 7ae65ab..5837a1b 100644 --- a/third_party/abseil-cpp/absl/types/variant.h +++ b/third_party/abseil-cpp/absl/types/variant.h
@@ -416,12 +416,12 @@ template <typename Visitor, typename... Variants> variant_internal::VisitResult<Visitor, Variants...> visit(Visitor&& vis, Variants&&... vars) { - return variant_internal::visit_indices< - variant_size<absl::decay_t<Variants>>::value...>( - variant_internal::PerformVisitation<Visitor, Variants...>{ - std::forward_as_tuple(absl::forward<Variants>(vars)...), - absl::forward<Visitor>(vis)}, - vars.index()...); + return variant_internal:: + VisitIndices<variant_size<absl::decay_t<Variants> >::value...>::Run( + variant_internal::PerformVisitation<Visitor, Variants...>{ + std::forward_as_tuple(absl::forward<Variants>(vars)...), + absl::forward<Visitor>(vis)}, + vars.index()...); } // monostate @@ -573,7 +573,7 @@ variant& operator=(T&& t) noexcept( std::is_nothrow_assignable<Tj&, T>::value&& std::is_nothrow_constructible<Tj, T>::value) { - variant_internal::visit_indices<sizeof...(Tn) + 1>( + variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run( variant_internal::VariantCoreAccess::MakeConversionAssignVisitor( this, absl::forward<T>(t)), index()); @@ -682,7 +682,7 @@ // true and `is_nothrow_swappable()` is same as `std::is_trivial()`. void swap(variant& rhs) noexcept( absl::conjunction<std::is_trivial<T0>, std::is_trivial<Tn>...>::value) { - return variant_internal::visit_indices<sizeof...(Tn) + 1>( + return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run( variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index()); } }; @@ -722,7 +722,7 @@ constexpr variant_internal::RequireAllHaveEqualT<Types...> operator==( const variant<Types...>& a, const variant<Types...>& b) { return (a.index() == b.index()) && - variant_internal::visit_indices<sizeof...(Types)>( + variant_internal::VisitIndices<sizeof...(Types)>::Run( variant_internal::EqualsOp<Types...>{&a, &b}, a.index()); } @@ -731,7 +731,7 @@ constexpr variant_internal::RequireAllHaveNotEqualT<Types...> operator!=( const variant<Types...>& a, const variant<Types...>& b) { return (a.index() != b.index()) || - variant_internal::visit_indices<sizeof...(Types)>( + variant_internal::VisitIndices<sizeof...(Types)>::Run( variant_internal::NotEqualsOp<Types...>{&a, &b}, a.index()); } @@ -741,7 +741,7 @@ const variant<Types...>& a, const variant<Types...>& b) { return (a.index() != b.index()) ? (a.index() + 1) < (b.index() + 1) - : variant_internal::visit_indices<sizeof...(Types)>( + : variant_internal::VisitIndices<sizeof...(Types)>::Run( variant_internal::LessThanOp<Types...>{&a, &b}, a.index()); } @@ -751,7 +751,7 @@ const variant<Types...>& a, const variant<Types...>& b) { return (a.index() != b.index()) ? (a.index() + 1) > (b.index() + 1) - : variant_internal::visit_indices<sizeof...(Types)>( + : variant_internal::VisitIndices<sizeof...(Types)>::Run( variant_internal::GreaterThanOp<Types...>{&a, &b}, a.index()); } @@ -762,7 +762,7 @@ const variant<Types...>& a, const variant<Types...>& b) { return (a.index() != b.index()) ? (a.index() + 1) < (b.index() + 1) - : variant_internal::visit_indices<sizeof...(Types)>( + : variant_internal::VisitIndices<sizeof...(Types)>::Run( variant_internal::LessThanOrEqualsOp<Types...>{&a, &b}, a.index()); } @@ -773,7 +773,7 @@ operator>=(const variant<Types...>& a, const variant<Types...>& b) { return (a.index() != b.index()) ? (a.index() + 1) > (b.index() + 1) - : variant_internal::visit_indices<sizeof...(Types)>( + : variant_internal::VisitIndices<sizeof...(Types)>::Run( variant_internal::GreaterThanOrEqualsOp<Types...>{&a, &b}, a.index()); }
diff --git a/third_party/abseil-cpp/absl/types/variant_benchmark.cc b/third_party/abseil-cpp/absl/types/variant_benchmark.cc new file mode 100644 index 0000000..99658ac --- /dev/null +++ b/third_party/abseil-cpp/absl/types/variant_benchmark.cc
@@ -0,0 +1,220 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Unit tests for the variant template. The 'is' and 'IsEmpty' methods +// of variant are not explicitly tested because they are used repeatedly +// in building other tests. All other public variant methods should have +// explicit tests. + +#include "absl/types/variant.h" + +#include <cstddef> +#include <cstdlib> +#include <string> +#include <tuple> + +#include "benchmark/benchmark.h" +#include "absl/utility/utility.h" + +namespace absl { +namespace { + +template <std::size_t I> +struct VariantAlternative { + char member; +}; + +template <class Indices> +struct VariantOfAlternativesImpl; + +template <std::size_t... Indices> +struct VariantOfAlternativesImpl<absl::index_sequence<Indices...>> { + using type = absl::variant<VariantAlternative<Indices>...>; +}; + +template <std::size_t NumAlternatives> +using VariantOfAlternatives = typename VariantOfAlternativesImpl< + absl::make_index_sequence<NumAlternatives>>::type; + +struct Empty {}; + +template <class... T> +void Ignore(T...) noexcept {} + +template <class T> +Empty DoNotOptimizeAndReturnEmpty(T&& arg) noexcept { + benchmark::DoNotOptimize(arg); + return {}; +} + +struct VisitorApplier { + struct Visitor { + template <class... T> + void operator()(T&&... args) const noexcept { + Ignore(DoNotOptimizeAndReturnEmpty(args)...); + } + }; + + template <class... Vars> + void operator()(const Vars&... vars) const noexcept { + absl::visit(Visitor(), vars...); + } +}; + +template <std::size_t NumIndices, std::size_t CurrIndex = NumIndices - 1> +struct MakeWithIndex { + using Variant = VariantOfAlternatives<NumIndices>; + + static Variant Run(std::size_t index) { + return index == CurrIndex + ? Variant(absl::in_place_index_t<CurrIndex>()) + : MakeWithIndex<NumIndices, CurrIndex - 1>::Run(index); + } +}; + +template <std::size_t NumIndices> +struct MakeWithIndex<NumIndices, 0> { + using Variant = VariantOfAlternatives<NumIndices>; + + static Variant Run(std::size_t /*index*/) { return Variant(); } +}; + +template <std::size_t NumIndices, class Dimensions> +struct MakeVariantTuple; + +template <class T, std::size_t /*I*/> +using always_t = T; + +template <std::size_t NumIndices> +VariantOfAlternatives<NumIndices> MakeVariant(std::size_t dimension, + std::size_t index) { + return dimension == 0 + ? MakeWithIndex<NumIndices>::Run(index % NumIndices) + : MakeVariant<NumIndices>(dimension - 1, index / NumIndices); +} + +template <std::size_t NumIndices, std::size_t... Dimensions> +struct MakeVariantTuple<NumIndices, absl::index_sequence<Dimensions...>> { + using VariantTuple = + std::tuple<always_t<VariantOfAlternatives<NumIndices>, Dimensions>...>; + + static VariantTuple Run(int index) { + return std::make_tuple(MakeVariant<NumIndices>(Dimensions, index)...); + } +}; + +constexpr std::size_t integral_pow(std::size_t base, std::size_t power) { + return power == 0 ? 1 : base * integral_pow(base, power - 1); +} + +template <std::size_t End, std::size_t I = 0> +struct VisitTestBody { + template <class Vars, class State> + static bool Run(Vars& vars, State& state) { + if (state.KeepRunning()) { + absl::apply(VisitorApplier(), vars[I]); + return VisitTestBody<End, I + 1>::Run(vars, state); + } + return false; + } +}; + +template <std::size_t End> +struct VisitTestBody<End, End> { + template <class Vars, class State> + static bool Run(Vars& /*vars*/, State& /*state*/) { + return true; + } +}; + +// Visit operations where branch prediction is likely to give a boost. +template <std::size_t NumIndices, std::size_t NumDimensions = 1> +void BM_RedundantVisit(benchmark::State& state) { + auto vars = + MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>:: + Run(static_cast<std::size_t>(state.range(0))); + + for (auto _ : state) { // NOLINT + benchmark::DoNotOptimize(vars); + absl::apply(VisitorApplier(), vars); + } +} + +// Visit operations where branch prediction is unlikely to give a boost. +template <std::size_t NumIndices, std::size_t NumDimensions = 1> +void BM_Visit(benchmark::State& state) { + constexpr std::size_t num_possibilities = + integral_pow(NumIndices, NumDimensions); + + using VariantTupleMaker = + MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>; + using Tuple = typename VariantTupleMaker::VariantTuple; + + Tuple vars[num_possibilities]; + for (std::size_t i = 0; i < num_possibilities; ++i) + vars[i] = VariantTupleMaker::Run(i); + + while (VisitTestBody<num_possibilities>::Run(vars, state)) { + } +} + +// Visitation +// Each visit is on a different variant with a different active alternative) + +// Unary visit +BENCHMARK_TEMPLATE(BM_Visit, 1); +BENCHMARK_TEMPLATE(BM_Visit, 2); +BENCHMARK_TEMPLATE(BM_Visit, 3); +BENCHMARK_TEMPLATE(BM_Visit, 4); +BENCHMARK_TEMPLATE(BM_Visit, 5); +BENCHMARK_TEMPLATE(BM_Visit, 6); +BENCHMARK_TEMPLATE(BM_Visit, 7); +BENCHMARK_TEMPLATE(BM_Visit, 8); +BENCHMARK_TEMPLATE(BM_Visit, 16); +BENCHMARK_TEMPLATE(BM_Visit, 32); +BENCHMARK_TEMPLATE(BM_Visit, 64); + +// Binary visit +BENCHMARK_TEMPLATE(BM_Visit, 1, 2); +BENCHMARK_TEMPLATE(BM_Visit, 2, 2); +BENCHMARK_TEMPLATE(BM_Visit, 3, 2); +BENCHMARK_TEMPLATE(BM_Visit, 4, 2); +BENCHMARK_TEMPLATE(BM_Visit, 5, 2); + +// Ternary visit +BENCHMARK_TEMPLATE(BM_Visit, 1, 3); +BENCHMARK_TEMPLATE(BM_Visit, 2, 3); +BENCHMARK_TEMPLATE(BM_Visit, 3, 3); + +// Quaternary visit +BENCHMARK_TEMPLATE(BM_Visit, 1, 4); +BENCHMARK_TEMPLATE(BM_Visit, 2, 4); + +// Redundant Visitation +// Each visit consistently has the same alternative active + +// Unary visit +BENCHMARK_TEMPLATE(BM_RedundantVisit, 1)->Arg(0); +BENCHMARK_TEMPLATE(BM_RedundantVisit, 2)->DenseRange(0, 1); +BENCHMARK_TEMPLATE(BM_RedundantVisit, 8)->DenseRange(0, 7); + +// Binary visit +BENCHMARK_TEMPLATE(BM_RedundantVisit, 1, 2)->Arg(0); +BENCHMARK_TEMPLATE(BM_RedundantVisit, 2, 2) + ->DenseRange(0, integral_pow(2, 2) - 1); +BENCHMARK_TEMPLATE(BM_RedundantVisit, 4, 2) + ->DenseRange(0, integral_pow(4, 2) - 1); + +} // namespace +} // namespace absl
diff --git a/third_party/blink/public/platform/modules/payments/web_payment_details_modifier.h b/third_party/blink/public/platform/modules/payments/web_payment_details_modifier.h index 3320720..0c1bf2b 100644 --- a/third_party/blink/public/platform/modules/payments/web_payment_details_modifier.h +++ b/third_party/blink/public/platform/modules/payments/web_payment_details_modifier.h
@@ -13,7 +13,7 @@ // https://w3c.github.io/browser-payment-api/#paymentdetailsmodifier-dictionary struct WebPaymentDetailsModifier { - WebVector<WebString> supported_methods; + WebString supported_method; WebPaymentItem total; WebVector<WebPaymentItem> additional_display_items; WebString stringified_data;
diff --git a/third_party/blink/public/platform/modules/payments/web_payment_method_data.h b/third_party/blink/public/platform/modules/payments/web_payment_method_data.h index 9134273..bdd1821 100644 --- a/third_party/blink/public/platform/modules/payments/web_payment_method_data.h +++ b/third_party/blink/public/platform/modules/payments/web_payment_method_data.h
@@ -15,7 +15,7 @@ // https://w3c.github.io/browser-payment-api/#paymentmethoddata-dictionary struct WebPaymentMethodData { - WebVector<WebString> supported_methods; + WebString supported_method; WebString stringified_data; };
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index 5e4ce08..01f4b37 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -626,6 +626,12 @@ virtual bool AllowScriptExtensionForServiceWorker(const WebURL& script_url) { return false; } + // Whether the new service worker glue for NetworkService is enabled (i.e., + // the NetworkService or ServiceWorkerServicification feature is enabled). + // TODO(falken): Make ServiceWorkerServicification a base::Feature inside + // the blink namespace, then this function can move out of platform.h and be + // implemented directly in blink. + virtual bool IsServiceWorkerNetServicificationEnabled() { return false; } // WebCrypto ----------------------------------------------------------
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom index eb09bb3e..d13f8c2 100644 --- a/third_party/blink/public/platform/web_feature.mojom +++ b/third_party/blink/public/platform/web_feature.mojom
@@ -1598,7 +1598,6 @@ kARIAValueNowAttribute = 2117, kARIAValueTextAttribute = 2118, kV8LabeledExpressionStatement = 2119, - kPaymentRequestSupportedMethodsArray = 2120, kNavigatorDeviceMemory = 2121, kFixedWidthTableDistributionChanged = 2122, kWebkitBoxLayout = 2123,
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h index b0ac714..8dd63af 100644 --- a/third_party/blink/public/platform/web_url_request.h +++ b/third_party/blink/public/platform/web_url_request.h
@@ -133,7 +133,7 @@ // the resource. Server transformations may // still happen if the page is heavy. kNoScriptOn = 1 << 6, // Request that script be disabled for page load. - kPreviewsStateLast = kPreviewsOff + kPreviewsStateLast = kNoScriptOn }; class ExtraData {
diff --git a/third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h b/third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h index 70c82df..77c4f83 100644 --- a/third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h +++ b/third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h
@@ -35,6 +35,7 @@ #include "third_party/blink/public/common/message_port/transferable_message.h" #include "third_party/blink/public/platform/modules/serviceworker/web_service_worker.h" #include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_registration.h" +#include "third_party/blink/public/platform/web_canonical_cookie.h" #include <memory> @@ -87,12 +88,10 @@ const WebString& developer_id, const WebString& unique_id, const WebVector<WebBackgroundFetchSettledFetch>& fetches) = 0; - // TODO(pwnall): Use blink::CanonicalCookie, after https://crrev.com/c/991196 - // lands. - virtual void DispatchCookieChangeEvent(int event_id, - const WebString& cookie_name, - const WebString& cookie_value, - bool is_cookie_delete) = 0; + virtual void DispatchCookieChangeEvent( + int event_id, + const WebCanonicalCookie& cookie, + network::mojom::CookieChangeCause change_cause) = 0; virtual void DispatchExtendableMessageEvent( int event_id, TransferableMessage,
diff --git a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc index 7135792..b341b43 100644 --- a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc +++ b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc
@@ -32,13 +32,35 @@ } bool IsCallbackFunctionRunnable( - const ScriptState* callback_relevant_script_state) { + const ScriptState* callback_relevant_script_state, + ScriptState* incumbent_script_state) { if (!callback_relevant_script_state->ContextIsValid()) return false; - const ExecutionContext* execution_context = + const ExecutionContext* relevant_execution_context = ExecutionContext::From(callback_relevant_script_state); - return execution_context && !execution_context->IsContextPaused() && - !execution_context->IsContextDestroyed(); + if (!relevant_execution_context || + relevant_execution_context->IsContextPaused() || + relevant_execution_context->IsContextDestroyed()) { + return false; + } + + // TODO(yukishiino): Callback function type value must make the incumbent + // environment alive, i.e. the reference to v8::Context must be strong. + v8::HandleScope handle_scope(incumbent_script_state->GetIsolate()); + v8::Local<v8::Context> incumbent_context = + incumbent_script_state->GetContext(); + ExecutionContext* incumbent_execution_context = + incumbent_context.IsEmpty() ? nullptr + : ToExecutionContext(incumbent_context); + // The incumbent realm schedules the currently-running callback although it + // may not correspond to the currently-running function object. So we check + // the incumbent context which originally schedules the currently-running + // callback to see whether the script setting is disabled before invoking + // the callback. + return incumbent_execution_context && + !incumbent_execution_context->IsContextPaused() && + !incumbent_execution_context->IsContextDestroyed() && + incumbent_execution_context->CanExecuteScripts(kAboutToExecuteScript); } } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h index 87f137c..806710d2 100644 --- a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h +++ b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h
@@ -61,7 +61,8 @@ }; CORE_EXPORT bool IsCallbackFunctionRunnable( - const ScriptState* callback_relevant_script_state); + const ScriptState* callback_relevant_script_state, + ScriptState* incumbent_script_state); using InstallTemplateFunction = void (*)(v8::Isolate* isolate,
diff --git a/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl b/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl index d1bf4ca..2997528 100644 --- a/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl +++ b/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl
@@ -24,7 +24,8 @@ promise type, in which case this function needs to convert any exception into a rejected promise. See also step 14.4. to 14.6. #} - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -55,17 +56,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - {# TODO(yukishiino): Callback function type value must make the incumbent - environment alive, i.e. the reference to v8::Context must be strong. #} - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "{{callback_function_name}}", - "The provided callback is no longer runnable.")); - return v8::Nothing<{{return_cpp_type}}>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl b/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl index b2f87f8..088e0346 100644 --- a/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl +++ b/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl
@@ -73,7 +73,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -93,17 +94,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - {# TODO(yukishiino): Callback interface type value must make the incumbent - environment alive, i.e. the reference to v8::Context must be strong. #} - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "{{method.name}}", - "{{cpp_class}}", - "The provided callback is no longer runnable.")); - return v8::Nothing<{{method.cpp_type}}>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc index 36554cd..379fb37 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc
@@ -31,7 +31,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -62,15 +63,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "AnyCallbackFunctionOptionalAnyArg", - "The provided callback is no longer runnable.")); - return v8::Nothing<ScriptValue>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc index f9a95ed4..09bb8f7f 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc
@@ -31,7 +31,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -62,15 +63,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "LongCallbackFunction", - "The provided callback is no longer runnable.")); - return v8::Nothing<int32_t>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc index 3893d9aa..327e370 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc
@@ -31,7 +31,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -62,15 +63,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "StringSequenceCallbackFunctionLongSequenceArg", - "The provided callback is no longer runnable.")); - return v8::Nothing<Vector<String>>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc index 834fa925..5ef981a 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc
@@ -29,7 +29,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -49,15 +50,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "voidMethod", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -133,7 +125,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -153,15 +146,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "booleanMethod", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<bool>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -249,7 +233,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -269,15 +254,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "voidMethodBooleanArg", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -357,7 +333,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -377,15 +354,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "voidMethodSequenceArg", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -465,7 +433,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -485,15 +454,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "voidMethodFloatArg", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -573,7 +533,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -593,15 +554,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "voidMethodTestInterfaceEmptyArg", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -681,7 +633,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -701,15 +654,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "voidMethodTestInterfaceEmptyStringArg", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -790,7 +734,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -810,15 +755,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "callbackWithThisValueVoidMethodStringArg", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext()); @@ -898,7 +834,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -918,15 +855,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "customVoidMethodTestInterfaceEmptyArg", - "TestCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc index 0cc493af..491b86f 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc
@@ -85,7 +85,8 @@ // This function implements "call a user object's operation". // https://heycam.github.io/webidl/#call-a-user-objects-operation - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -105,15 +106,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 8. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "acceptNode", - "TestLegacyCallbackInterface", - "The provided callback is no longer runnable.")); - return v8::Nothing<uint16_t>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc index 867ce98..fa19a8da 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc
@@ -30,7 +30,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -61,15 +62,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "VoidCallbackFunction", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc index 240261dd..5cb3829 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc
@@ -31,7 +31,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -62,15 +63,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "VoidCallbackFunctionDictionaryArg", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc index 7ebedc61..e59fd62 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc
@@ -31,7 +31,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -62,15 +63,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "VoidCallbackFunctionEnumArg", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc index 9f9f3e6..e643754 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc
@@ -31,7 +31,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -62,15 +63,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "VoidCallbackFunctionInterfaceArg", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc index 657e044..b27efc3 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc
@@ -32,7 +32,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -63,15 +64,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "VoidCallbackFunctionTestInterfaceSequenceArg", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc index eb20bbf5..2e6f7b1 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc
@@ -31,7 +31,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -62,15 +63,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "VoidCallbackFunctionTypedef", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc index ed9a974..55344d3d 100644 --- a/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc +++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc
@@ -30,7 +30,8 @@ // "3.10. Invoking callback functions". // https://heycam.github.io/webidl/#es-invoking-callback-functions - if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState())) { + if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(), + IncumbentScriptState())) { // Wrapper-tracing for the callback function makes the function object and // its creation context alive. Thus it's safe to use the creation context // of the callback function here. @@ -61,15 +62,6 @@ ScriptState::Scope callback_relevant_context_scope( CallbackRelevantScriptState()); // step 9. Prepare to run a callback with stored settings. - if (IncumbentScriptState()->GetContext().IsEmpty()) { - V8ThrowException::ThrowError( - GetIsolate(), - ExceptionMessages::FailedToExecute( - "invoke", - "VoidCallbackFunctionModules", - "The provided callback is no longer runnable.")); - return v8::Nothing<void>(); - } v8::Context::BackupIncumbentScope backup_incumbent_scope( IncumbentScriptState()->GetContext());
diff --git a/third_party/blink/renderer/controller/bloated_renderer_detector.cc b/third_party/blink/renderer/controller/bloated_renderer_detector.cc index 6544d7f2..c17f99b 100644 --- a/third_party/blink/renderer/controller/bloated_renderer_detector.cc +++ b/third_party/blink/renderer/controller/bloated_renderer_detector.cc
@@ -23,9 +23,12 @@ NearV8HeapLimitHandling BloatedRendererDetector::OnNearV8HeapLimitOnMainThreadImpl() { - WTF::TimeDelta uptime = (WTF::CurrentTimeTicks() - startup_time_); - if (uptime.InMinutes() < kMinimumUptimeInMinutes) { - return NearV8HeapLimitHandling::kIgnoredDueToSmallUptime; + if (!RuntimeEnabledFeatures:: + BloatedRendererDetectionSkipUptimeCheckEnabled()) { + WTF::TimeDelta uptime = (WTF::CurrentTimeTicks() - startup_time_); + if (uptime.InMinutes() < kMinimumUptimeInMinutes) { + return NearV8HeapLimitHandling::kIgnoredDueToSmallUptime; + } } RendererResourceCoordinator::Get().OnRendererIsBloated(); return NearV8HeapLimitHandling::kForwardedToBrowser;
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_selector.cc b/third_party/blink/renderer/core/css/parser/css_parser_selector.cc index 5895646..de16b87 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_selector.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_selector.cc
@@ -39,16 +39,10 @@ : selector_(std::make_unique<CSSSelector>(tag_q_name, is_implicit)) {} CSSParserSelector::~CSSParserSelector() { - if (!tag_history_) - return; - Vector<std::unique_ptr<CSSParserSelector>, 16> to_delete; - std::unique_ptr<CSSParserSelector> selector = std::move(tag_history_); - while (true) { - std::unique_ptr<CSSParserSelector> next = std::move(selector->tag_history_); - to_delete.push_back(std::move(selector)); - if (!next) - break; - selector = std::move(next); + while (tag_history_) { + std::unique_ptr<CSSParserSelector> next = + std::move(tag_history_->tag_history_); + tag_history_ = std::move(next); } }
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn index c41f552..d8f6ddf 100644 --- a/third_party/blink/renderer/core/dom/BUILD.gn +++ b/third_party/blink/renderer/core/dom/BUILD.gn
@@ -129,9 +129,8 @@ "events/event_listener_map.h", "events/event_path.cc", "events/event_path.h", + "events/event_queue.cc", "events/event_queue.h", - "events/event_queue_impl.cc", - "events/event_queue_impl.h", "events/event_target.cc", "events/event_target.h", "events/event_target_impl.cc",
diff --git a/third_party/blink/renderer/core/dom/events/event_queue_impl.cc b/third_party/blink/renderer/core/dom/events/event_queue.cc similarity index 77% rename from third_party/blink/renderer/core/dom/events/event_queue_impl.cc rename to third_party/blink/renderer/core/dom/events/event_queue.cc index 7c4ab23..5600b6e 100644 --- a/third_party/blink/renderer/core/dom/events/event_queue_impl.cc +++ b/third_party/blink/renderer/core/dom/events/event_queue.cc
@@ -24,7 +24,7 @@ * */ -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "base/macros.h" #include "third_party/blink/public/platform/task_type.h" @@ -34,26 +34,23 @@ namespace blink { -EventQueueImpl* EventQueueImpl::Create(ExecutionContext* context, - TaskType task_type) { - return new EventQueueImpl(context, task_type); +EventQueue* EventQueue::Create(ExecutionContext* context, TaskType task_type) { + return new EventQueue(context, task_type); } -EventQueueImpl::EventQueueImpl(ExecutionContext* context, TaskType task_type) +EventQueue::EventQueue(ExecutionContext* context, TaskType task_type) : ContextLifecycleObserver(context), task_type_(task_type), is_closed_(false) {} -EventQueueImpl::~EventQueueImpl() = default; +EventQueue::~EventQueue() = default; -void EventQueueImpl::Trace(blink::Visitor* visitor) { +void EventQueue::Trace(blink::Visitor* visitor) { visitor->Trace(queued_events_); - EventQueue::Trace(visitor); ContextLifecycleObserver::Trace(visitor); } -bool EventQueueImpl::EnqueueEvent(const base::Location& from_here, - Event* event) { +bool EventQueue::EnqueueEvent(const base::Location& from_here, Event* event) { if (is_closed_) return false; @@ -70,13 +67,13 @@ // Pass the event as a weak persistent so that GC can collect an event-related // object like IDBTransaction as soon as possible. task_runner->PostTask( - FROM_HERE, WTF::Bind(&EventQueueImpl::DispatchEvent, WrapPersistent(this), + FROM_HERE, WTF::Bind(&EventQueue::DispatchEvent, WrapPersistent(this), WrapWeakPersistent(event))); return true; } -void EventQueueImpl::CancelAllEvents() { +void EventQueue::CancelAllEvents() { if (!GetExecutionContext()) { DCHECK(!queued_events_.size()); return; @@ -84,7 +81,7 @@ DoCancelAllEvents(GetExecutionContext()); } -bool EventQueueImpl::RemoveEvent(Event* event) { +bool EventQueue::RemoveEvent(Event* event) { auto found = queued_events_.find(event); if (found == queued_events_.end()) return false; @@ -92,7 +89,7 @@ return true; } -void EventQueueImpl::DispatchEvent(Event* event) { +void EventQueue::DispatchEvent(Event* event) { if (!event || !RemoveEvent(event)) return; @@ -106,22 +103,22 @@ target->DispatchEvent(event); } -void EventQueueImpl::ContextDestroyed(ExecutionContext* context) { +void EventQueue::ContextDestroyed(ExecutionContext* context) { Close(context); } -void EventQueueImpl::Close(ExecutionContext* context) { +void EventQueue::Close(ExecutionContext* context) { is_closed_ = true; DoCancelAllEvents(context); } -void EventQueueImpl::DoCancelAllEvents(ExecutionContext* context) { +void EventQueue::DoCancelAllEvents(ExecutionContext* context) { for (const auto& queued_event : queued_events_) probe::AsyncTaskCanceled(context, queued_event); queued_events_.clear(); } -bool EventQueueImpl::HasPendingEvents() const { +bool EventQueue::HasPendingEvents() const { return queued_events_.size() > 0; }
diff --git a/third_party/blink/renderer/core/dom/events/event_queue.h b/third_party/blink/renderer/core/dom/events/event_queue.h index 1abbf56..bd547a6 100644 --- a/third_party/blink/renderer/core/dom/events/event_queue.h +++ b/third_party/blink/renderer/core/dom/events/event_queue.h
@@ -27,23 +27,44 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_H_ -#include "base/location.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/hash_set.h" +#include "third_party/blink/public/platform/task_type.h" +#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" +#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" namespace blink { class Event; +class ExecutionContext; -class CORE_EXPORT EventQueue : public GarbageCollectedFinalized<EventQueue> { +class CORE_EXPORT EventQueue final + : public GarbageCollectedFinalized<EventQueue>, + public ContextLifecycleObserver { + USING_GARBAGE_COLLECTED_MIXIN(EventQueue); + public: - virtual ~EventQueue() = default; - virtual void Trace(blink::Visitor* visitor) {} - virtual bool EnqueueEvent(const base::Location&, Event*) = 0; - virtual void CancelAllEvents() = 0; - virtual bool HasPendingEvents() const = 0; + // TODO(hajimehoshi): TaskType should be determined based on an event instead + // of specifying here. + static EventQueue* Create(ExecutionContext*, TaskType); + ~EventQueue(); + + void Trace(blink::Visitor*) override; + bool EnqueueEvent(const base::Location&, Event*); + void CancelAllEvents(); + bool HasPendingEvents() const; + + private: + EventQueue(ExecutionContext*, TaskType); + + bool RemoveEvent(Event*); + void DispatchEvent(Event*); + + void ContextDestroyed(ExecutionContext*) override; + void Close(ExecutionContext*); + void DoCancelAllEvents(ExecutionContext*); + + const TaskType task_type_; + HeapLinkedHashSet<Member<Event>> queued_events_; + bool is_closed_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/events/event_queue_impl.h b/third_party/blink/renderer/core/dom/events/event_queue_impl.h deleted file mode 100644 index 7ecfaee0..0000000 --- a/third_party/blink/renderer/core/dom/events/event_queue_impl.h +++ /dev/null
@@ -1,73 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_IMPL_H_ - -#include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" -#include "third_party/blink/renderer/core/dom/events/event_queue.h" -#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" - -namespace blink { - -class Event; -class ExecutionContext; - -class CORE_EXPORT EventQueueImpl final : public EventQueue, - public ContextLifecycleObserver { - USING_GARBAGE_COLLECTED_MIXIN(EventQueueImpl); - - public: - // TODO(hajimehoshi): TaskType should be determined based on an event instead - // of specifying here. - static EventQueueImpl* Create(ExecutionContext*, TaskType); - ~EventQueueImpl() override; - - // EventQueue - void Trace(blink::Visitor*) override; - bool EnqueueEvent(const base::Location&, Event*) override; - void CancelAllEvents() override; - bool HasPendingEvents() const override; - - private: - EventQueueImpl(ExecutionContext*, TaskType); - - bool RemoveEvent(Event*); - void DispatchEvent(Event*); - - void ContextDestroyed(ExecutionContext*) override; - void Close(ExecutionContext*); - void DoCancelAllEvents(ExecutionContext*); - - const TaskType task_type_; - HeapLinkedHashSet<Member<Event>> queued_events_; - bool is_closed_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_IMPL_H_
diff --git a/third_party/blink/renderer/core/dom/mutation_observer.cc b/third_party/blink/renderer/core/dom/mutation_observer.cc index d43a0ab0..a330c7b 100644 --- a/third_party/blink/renderer/core/dom/mutation_observer.cc +++ b/third_party/blink/renderer/core/dom/mutation_observer.cc
@@ -287,13 +287,8 @@ } bool MutationObserver::ShouldBeSuspended() const { - ExecutionContext* execution_context = delegate_->GetExecutionContext(); - if (!execution_context) - return false; - Document* document = ToDocument(execution_context); - DCHECK(document); - return !document->CanExecuteScripts(kAboutToExecuteScript) || - execution_context->IsContextPaused(); + const ExecutionContext* execution_context = delegate_->GetExecutionContext(); + return execution_context && execution_context->IsContextPaused(); } void MutationObserver::CancelInspectorAsyncTasks() {
diff --git a/third_party/blink/renderer/core/editing/layout_selection.cc b/third_party/blink/renderer/core/editing/layout_selection.cc index 16f8e01..a9f9bd8 100644 --- a/third_party/blink/renderer/core/editing/layout_selection.cc +++ b/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -76,13 +76,49 @@ return end_offset_; } +static LayoutTextFragment* FirstLetterPartFor( + const LayoutObject* layout_object) { + if (!layout_object->IsText()) + return nullptr; + if (!ToLayoutText(layout_object)->IsTextFragment()) + return nullptr; + return ToLayoutTextFragment(const_cast<LayoutObject*>( + AssociatedLayoutObjectOf(*layout_object->GetNode(), 0))); +} + +static LayoutObject* NextLayoutObjectOnFlatTree( + const LayoutObject& layout_object) { + // If |layout_object| is a first letter part, return remaining part. + if (layout_object.IsText() && ToLayoutText(layout_object).IsTextFragment() && + !ToLayoutTextFragment(layout_object).IsRemainingTextLayoutObject()) { + const Node* associated_node = + ToLayoutTextFragment(layout_object).AssociatedTextNode(); + if (!associated_node) + return nullptr; + return associated_node->GetLayoutObject(); + } + // Otherwise, find the first layouted object of following nodes. + const Node* node = layout_object.GetNode(); + DCHECK(node); + for (const Node* next = FlatTreeTraversal::Next(*node); next; + next = FlatTreeTraversal::Next(*next)) { + LayoutObject* layout_object = next->GetLayoutObject(); + if (!layout_object) + continue; + if (LayoutObject* first_letter = FirstLetterPartFor(layout_object)) + return first_letter; + return layout_object; + } + return nullptr; +} + SelectionPaintRange::Iterator::Iterator(const SelectionPaintRange* range) { if (!range || range->IsNull()) { current_ = nullptr; return; } current_ = range->StartLayoutObject(); - stop_ = range->EndLayoutObject()->NextInPreOrder(); + stop_ = NextLayoutObjectOnFlatTree(*range->EndLayoutObject()); } LayoutObject* SelectionPaintRange::Iterator::operator*() const { @@ -92,7 +128,7 @@ SelectionPaintRange::Iterator& SelectionPaintRange::Iterator::operator++() { DCHECK(current_); - current_ = current_->NextInPreOrder(); + current_ = NextLayoutObjectOnFlatTree(*current_); if (current_ && current_ != stop_) return *this; @@ -425,15 +461,6 @@ return ToText(layout_node)->length(); } -static LayoutTextFragment* FirstLetterPartFor(LayoutObject* layout_object) { - if (!layout_object->IsText()) - return nullptr; - if (!ToLayoutText(layout_object)->IsTextFragment()) - return nullptr; - return ToLayoutTextFragment(const_cast<LayoutObject*>( - AssociatedLayoutObjectOf(*layout_object->GetNode(), 0))); -} - static void MarkSelected(SelectedLayoutObjects* selected_objects, LayoutObject* layout_object, SelectionState state) {
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc index fbae23c..e871bd56 100644 --- a/third_party/blink/renderer/core/editing/layout_selection_test.cc +++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -76,18 +76,20 @@ return layout_object.member_func(); \ } +USING_LAYOUTOBJECT_FUNC(IsBR); USING_LAYOUTOBJECT_FUNC(IsLayoutBlock); USING_LAYOUTOBJECT_FUNC(IsLayoutBlockFlow); -USING_LAYOUTOBJECT_FUNC(IsLayoutNGBlockFlow); +USING_LAYOUTOBJECT_FUNC(IsLayoutButton); +USING_LAYOUTOBJECT_FUNC(IsLayoutEmbeddedContent); +USING_LAYOUTOBJECT_FUNC(IsLayoutImage); USING_LAYOUTOBJECT_FUNC(IsLayoutInline); -USING_LAYOUTOBJECT_FUNC(IsBR); +USING_LAYOUTOBJECT_FUNC(IsLayoutNGBlockFlow); USING_LAYOUTOBJECT_FUNC(IsListItem); USING_LAYOUTOBJECT_FUNC(IsListMarker); -USING_LAYOUTOBJECT_FUNC(IsLayoutImage); -USING_LAYOUTOBJECT_FUNC(IsLayoutButton); +USING_LAYOUTOBJECT_FUNC(IsRuby); +USING_LAYOUTOBJECT_FUNC(IsRubyText); USING_LAYOUTOBJECT_FUNC(IsSVGRoot); USING_LAYOUTOBJECT_FUNC(IsSVGText); -USING_LAYOUTOBJECT_FUNC(IsLayoutEmbeddedContent); static IsTypeOf IsLayoutTextFragmentOf(const String& text) { return WTF::BindRepeating( @@ -686,6 +688,41 @@ TEST_NO_NEXT_LAYOUT_OBJECT(); } +// http:/crbug.com/843144 +TEST_F(LayoutSelectionTest, Ruby) { + Selection().SetSelectionAndEndTyping( + SetSelectionTextToBody("^<ruby>foo<rt>bar</rt></ruby>|")); + Selection().CommitAppearanceIfNeeded(); + TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate); + TEST_NEXT(IsRuby, kNone, NotInvalidate); + TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate); + TEST_NEXT(IsRubyText, kContain, NotInvalidate); + TEST_NEXT("bar", kEnd, ShouldInvalidate); + TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate); + TEST_NEXT("foo", kStart, ShouldInvalidate); + TEST_NO_NEXT_LAYOUT_OBJECT(); + + UpdateAllLifecyclePhases(); + TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate); + TEST_NEXT(IsRuby, kNone, NotInvalidate); + TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate); + TEST_NEXT(IsRubyText, kContain, NotInvalidate); + TEST_NEXT("bar", kEnd, NotInvalidate); + TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate); + TEST_NEXT("foo", kStart, NotInvalidate); + TEST_NO_NEXT_LAYOUT_OBJECT(); + + Selection().ClearLayoutSelection(); + TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate); + TEST_NEXT(IsRuby, kNone, NotInvalidate); + TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate); + TEST_NEXT(IsRubyText, kNone, NotInvalidate); + TEST_NEXT("bar", kNone, ShouldInvalidate); + TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate); + TEST_NEXT("foo", kNone, ShouldInvalidate); + TEST_NO_NEXT_LAYOUT_OBJECT(); +} + static const NGPaintFragment* FindNGPaintFragmentInternal( const NGPaintFragment* paint, const LayoutObject* layout_object) {
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index 81e65b97..0868b42 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -58,7 +58,7 @@ #include "third_party/blink/renderer/core/clipboard/data_object.h" #include "third_party/blink/renderer/core/clipboard/data_transfer.h" #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/events/drag_event.h" #include "third_party/blink/renderer/core/events/gesture_event.h" @@ -738,8 +738,8 @@ : ContextClient(element.GetDocument().GetFrame()), element_(element), event_queue_( - EventQueueImpl::Create(element.GetDocument().GetExecutionContext(), - TaskType::kInternalDefault)), + EventQueue::Create(element.GetDocument().GetExecutionContext(), + TaskType::kInternalDefault)), web_plugin_(web_plugin), layer_(nullptr), touch_event_request_type_(kTouchEventRequestTypeNone),
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc index f59deb0..7ee5229 100644 --- a/third_party/blink/renderer/core/frame/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -511,12 +511,6 @@ "HTTPS. See " "https://goo.gl/rStTGz for more details.")}; - case WebFeature::kPaymentRequestSupportedMethodsArray: - return {"PaymentRequestSupportedMethodsArray", kM64, - ReplacedWillBeRemoved( - "PaymentRequest's supportedMethods taking an array", - "a single string", kM64, "5177301645918208")}; - case WebFeature::kLocalCSSFileExtensionRejected: return {"LocalCSSFileExtensionRejected", kM64, String("CSS cannot be loaded from `file:` URLs unless they end "
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 7efcbef..d97a10b 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -3000,7 +3000,7 @@ layer->CcLayer()->RemoveAllChildren(); RecordForeignLayer(context, *layer, DisplayItem::kForeignLayerWrapper, layer->CcLayer(), layer->GetOffsetFromTransformNode(), - RoundedIntSize(layer->Size())); + layer->Size()); } if (contents_layer) { auto position = contents_layer->position(); @@ -3081,8 +3081,10 @@ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { GraphicsContext context(*paint_controller_); // Note: Some blink unit tests run without turning on compositing which - // means we don't create viewport layers. - if (GetLayoutView()->Compositor()->InCompositingMode()) { + // means we don't create viewport layers. OOPIFs also don't have their own + // viewport layers. + if (GetLayoutView()->Compositor()->InCompositingMode() && + GetFrame() == GetPage()->MainFrame()) { // TODO(bokan): We should eventually stop creating layers for the visual // viewport. At that point, we can remove this. However, for now, CC // still has some dependencies on the viewport scale and scroll layers. @@ -3946,10 +3948,12 @@ VisibleContentSize(scrollbar_inclusion)); } -LayoutRect LocalFrameView::VisibleScrollSnapportRect() const { +LayoutRect LocalFrameView::VisibleScrollSnapportRect( + IncludeScrollbarsInRect scrollbar_inclusion) const { const ComputedStyle* style = GetLayoutBox()->Style(); - LayoutRect visible_content_rect = LayoutRect( - FloatPoint(scroll_offset_), VisibleContentSize(kExcludeScrollbars)); + LayoutRect visible_content_rect = + LayoutRect(LayoutPoint(DoublePoint(scroll_offset_)), + LayoutSize(VisibleContentSize(scrollbar_inclusion))); LayoutRectOutsets padding( MinimumValueForLength(style->ScrollPaddingTop(), visible_content_rect.Height()), @@ -4559,20 +4563,17 @@ return; } - IntRect parent_rect = parent->FrameRect(); + IntSize parent_size(parent->Size()); // First clause: for this rough data collection we assume the user never // scrolls right. - if (frame_rect.X() >= parent_rect.Width() || parent_rect.Height() <= 0) + if (frame_rect.X() >= parent_size.Width() || parent_size.Height() <= 0) return; int this_frame_screens_away = 0; // If an frame is created above the current scoll position, this logic counts // it as visible. - if (frame_rect.Y() > parent->GetScrollOffset().Height()) { - this_frame_screens_away = - (frame_rect.Y() - parent->GetScrollOffset().Height()) / - parent_rect.Height(); - } + if (frame_rect.Y() > 0) + this_frame_screens_away = frame_rect.Y() / parent_size.Height(); DCHECK_GE(this_frame_screens_away, 0); int parent_screens_away = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index 83e418ce..aa812e3 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -530,7 +530,8 @@ // The visible scroll snapport rect is contracted from the visible content // rect, by the amount of the document's scroll-padding. - LayoutRect VisibleScrollSnapportRect() const override; + LayoutRect VisibleScrollSnapportRect( + IncludeScrollbarsInRect = kExcludeScrollbars) const override; // Clips the provided rect to the visible content area. For this purpose, we // also query the chrome client for any active overrides to the visible area
diff --git a/third_party/blink/renderer/core/frame/reporting_observer.cc b/third_party/blink/renderer/core/frame/reporting_observer.cc index 1caf300..b5d24d1 100644 --- a/third_party/blink/renderer/core/frame/reporting_observer.cc +++ b/third_party/blink/renderer/core/frame/reporting_observer.cc
@@ -37,6 +37,9 @@ } void ReportingObserver::QueueReport(Report* report) { + if (!ObservedType(report->type())) + return; + report_queue_.push_back(report); // When the first report of a batch is queued, make a task to report the whole @@ -48,8 +51,13 @@ } } +bool ReportingObserver::ObservedType(const String& type) { + return !options_.hasTypes() || options_.types().IsEmpty() || + options_.types().Find(type) != kNotFound; +} + bool ReportingObserver::Buffered() { - return options_.buffered(); + return options_.hasBuffered() && options_.buffered(); } void ReportingObserver::ClearBuffered() { @@ -64,6 +72,12 @@ ReportingContext::From(execution_context_)->UnregisterObserver(this); } +HeapVector<Member<Report>> ReportingObserver::takeRecords() { + auto reports = report_queue_; + report_queue_.clear(); + return reports; +} + void ReportingObserver::Trace(blink::Visitor* visitor) { visitor->Trace(execution_context_); visitor->Trace(callback_);
diff --git a/third_party/blink/renderer/core/frame/reporting_observer.h b/third_party/blink/renderer/core/frame/reporting_observer.h index 4c282d62..da46280a 100644 --- a/third_party/blink/renderer/core/frame/reporting_observer.h +++ b/third_party/blink/renderer/core/frame/reporting_observer.h
@@ -31,6 +31,10 @@ // Queues a report to be reported via callback soon (possibly in a batch). void QueueReport(Report* report); + // Returns whether this ReportingObserver observes reports of the type |type|, + // based on the |types| option. + bool ObservedType(const String& type); + // Returns the state of the |buffered| option. bool Buffered(); @@ -40,6 +44,7 @@ void observe(); void disconnect(); + HeapVector<Member<Report>> takeRecords(); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/frame/reporting_observer.idl b/third_party/blink/renderer/core/frame/reporting_observer.idl index ef1a601c..9675882 100644 --- a/third_party/blink/renderer/core/frame/reporting_observer.idl +++ b/third_party/blink/renderer/core/frame/reporting_observer.idl
@@ -13,4 +13,7 @@ ] interface ReportingObserver { void observe(); void disconnect(); + ReportList takeRecords(); }; + +typedef sequence<Report> ReportList;
diff --git a/third_party/blink/renderer/core/frame/reporting_observer_options.idl b/third_party/blink/renderer/core/frame/reporting_observer_options.idl index daa436e..8a1ada9 100644 --- a/third_party/blink/renderer/core/frame/reporting_observer_options.idl +++ b/third_party/blink/renderer/core/frame/reporting_observer_options.idl
@@ -5,5 +5,6 @@ // https://wicg.github.io/reporting/#dictdef-reportingobserveroptions dictionary ReportingObserverOptions { + sequence<DOMString>? types; boolean buffered = false; };
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc index bddc080..e2e538a 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -176,21 +176,21 @@ VisualViewport().VisibleContentRect(scrollbar_inclusion).Size()); } -LayoutRect RootFrameViewport::VisibleScrollSnapportRect() const { - // The current viewport is the one that excludes the scrollbars so - // we intersect the visual viewport with the scrollbar-excluded frameView - // content rect. However, we don't use visibleContentRect directly since it +LayoutRect RootFrameViewport::VisibleScrollSnapportRect( + IncludeScrollbarsInRect scrollbar_inclusion) const { + // The effective viewport is the intersection of the visual viewport with the + // layout viewport. However, we don't use visibleContentRect directly since it // floors the scroll offset. Instead, we use ScrollAnimatorBase::currentOffset // and construct a LayoutRect from that. LayoutRect frame_rect_in_content = LayoutRect( FloatPoint(LayoutViewport().GetScrollAnimator().CurrentOffset()), - FloatSize(LayoutViewport().VisibleContentRect().Size())); - LayoutRect visual_rect_in_content = - LayoutRect(FloatPoint(ScrollOffsetFromScrollAnimators()), - FloatSize(VisualViewport().VisibleContentRect().Size())); + FloatSize( + LayoutViewport().VisibleContentRect(scrollbar_inclusion).Size())); + LayoutRect visual_rect_in_content = LayoutRect( + FloatPoint(ScrollOffsetFromScrollAnimators()), + FloatSize( + VisualViewport().VisibleContentRect(scrollbar_inclusion).Size())); - // Intersect layout and visual rects to exclude the scrollbar from the view - // rect. LayoutRect visible_scroll_snapport = Intersection(visual_rect_in_content, frame_rect_in_content); if (!LayoutViewport().GetLayoutBox())
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.h b/third_party/blink/renderer/core/frame/root_frame_viewport.h index f6b00c09..a5a8e89 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.h +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -64,7 +64,8 @@ const WebScrollIntoViewParams&) override; IntRect VisibleContentRect( IncludeScrollbarsInRect = kExcludeScrollbars) const override; - LayoutRect VisibleScrollSnapportRect() const override; + LayoutRect VisibleScrollSnapportRect( + IncludeScrollbarsInRect = kExcludeScrollbars) const override; bool ShouldUseIntegerScrollOffset() const override; bool IsActive() const override; int ScrollSize(ScrollbarOrientation) const override;
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc b/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc index 1a2a256..18a95dc 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
@@ -464,14 +464,14 @@ EXPECT_EQ(IntPoint(100, 75), root_frame_viewport->VisibleContentRect().Location()); EXPECT_EQ(ScrollOffset(500, 401), - root_frame_viewport->VisibleContentRect().Size()); + DoubleSize(root_frame_viewport->VisibleContentRect().Size())); visual_viewport->SetScale(2); EXPECT_EQ(IntPoint(100, 75), root_frame_viewport->VisibleContentRect().Location()); EXPECT_EQ(ScrollOffset(250, 201), - root_frame_viewport->VisibleContentRect().Size()); + DoubleSize(root_frame_viewport->VisibleContentRect().Size())); } // Tests that scrolls on the root frame scroll the visual viewport before
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 ebe3ab6..1df74e600 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -737,7 +737,7 @@ NavigateTo(base_url_ + "viewport-device-width.html"); // Ensure the scroll layer matches the frame view's size. - EXPECT_EQ(FloatSize(320, 240), visual_viewport.ScrollLayer()->Size()); + EXPECT_EQ(IntSize(320, 240), visual_viewport.ScrollLayer()->Size()); // Ensure the location and scale were reset. EXPECT_EQ(FloatSize(), visual_viewport.GetScrollOffset()); @@ -1195,13 +1195,13 @@ LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView(); visual_viewport.SetScale(1); - EXPECT_EQ(IntSize(500, 450), visual_viewport.VisibleRect().Size()); + EXPECT_EQ(FloatSize(500, 450), visual_viewport.VisibleRect().Size()); EXPECT_EQ(IntSize(1000, 900), frame_view.FrameRect().Size()); // Simulate bringing down the browser controls by 20px. WebView()->ApplyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1, 1); - EXPECT_EQ(IntSize(500, 430), visual_viewport.VisibleRect().Size()); + EXPECT_EQ(FloatSize(500, 430), visual_viewport.VisibleRect().Size()); // Test that the scroll bounds are adjusted appropriately: the visual viewport // should be shrunk by 20px to 430px. The outer viewport was shrunk to @@ -1246,7 +1246,7 @@ LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView(); visual_viewport.SetScale(2); - EXPECT_EQ(IntSize(250, 225), visual_viewport.VisibleRect().Size()); + EXPECT_EQ(FloatSize(250, 225), visual_viewport.VisibleRect().Size()); EXPECT_EQ(IntSize(1000, 900), frame_view.FrameRect().Size()); // Simulate bringing down the browser controls by 20px. Since we're zoomed in, @@ -1254,7 +1254,7 @@ // they do at an unzoomed level. WebView()->ApplyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1, 1); - EXPECT_EQ(IntSize(250, 215), visual_viewport.VisibleRect().Size()); + EXPECT_EQ(FloatSize(250, 215), visual_viewport.VisibleRect().Size()); // Test that the scroll bounds are adjusted appropriately. visual_viewport.Move(ScrollOffset(10000, 10000)); @@ -1328,8 +1328,8 @@ LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView(); visual_viewport.SetScale(page_scale); - EXPECT_EQ(IntSize(250, (visual_viewport_height - browser_controls_height) / - page_scale), + EXPECT_EQ(FloatSize(250, (visual_viewport_height - browser_controls_height) / + page_scale), visual_viewport.VisibleRect().Size()); EXPECT_EQ(IntSize(1000, layout_viewport_height - browser_controls_height / min_page_scale), @@ -1344,7 +1344,7 @@ kUserScroll); WebView()->GetBrowserControls().SetShownRatio(0); - EXPECT_EQ(IntSize(250, visual_viewport_height / page_scale), + EXPECT_EQ(FloatSize(250, visual_viewport_height / page_scale), visual_viewport.VisibleRect().Size()); ScrollOffset frame_view_expected = @@ -1365,7 +1365,7 @@ 0, false); EXPECT_EQ(IntSize(500, visual_viewport_height), visual_viewport.Size()); - EXPECT_EQ(IntSize(250, visual_viewport_height / page_scale), + EXPECT_EQ(FloatSize(250, visual_viewport_height / page_scale), visual_viewport.VisibleRect().Size()); EXPECT_EQ(IntSize(1000, layout_viewport_height), frame_view.FrameRect().Size()); @@ -1399,7 +1399,7 @@ LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView(); visual_viewport.SetScale(page_scale); - EXPECT_EQ(IntSize(250, visual_viewport_height / page_scale), + EXPECT_EQ(FloatSize(250, visual_viewport_height / page_scale), visual_viewport.VisibleRect().Size()); EXPECT_EQ(IntSize(1000, layout_viewport_height), frame_view.FrameRect().Size()); @@ -1413,8 +1413,8 @@ frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000), kUserScroll); - EXPECT_EQ(IntSize(250, (visual_viewport_height - browser_controls_height) / - page_scale), + EXPECT_EQ(FloatSize(250, (visual_viewport_height - browser_controls_height) / + page_scale), visual_viewport.VisibleRect().Size()); ScrollOffset frame_view_expected( @@ -1439,8 +1439,8 @@ EXPECT_EQ(IntSize(500, visual_viewport_height - browser_controls_height), visual_viewport.Size()); - EXPECT_EQ(IntSize(250, (visual_viewport_height - browser_controls_height) / - page_scale), + EXPECT_EQ(FloatSize(250, (visual_viewport_height - browser_controls_height) / + page_scale), visual_viewport.VisibleRect().Size()); EXPECT_EQ(IntSize(1000, layout_viewport_height - browser_controls_height / min_page_scale),
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc index b19e282..4c4f9b2a 100644 --- a/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc +++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc
@@ -84,6 +84,7 @@ const ResourceRequest& resource_request, WebFrameLoadType frame_load_type) { DCHECK(!lazy_load_intersection_observer_); + was_recorded_as_deferred_ = false; lazy_load_intersection_observer_ = IntersectionObserver::Create( {Length(GetLazyFrameLoadingViewportDistanceThresholdPx( @@ -111,11 +112,28 @@ DCHECK(!entries.IsEmpty()); DCHECK_EQ(element_, entries.back()->target()); - if (!entries.back()->isIntersecting() && - !IsFrameProbablyHidden(*entries.back()->boundingClientRect())) { + if (entries.back()->isIntersecting()) { + RecordInitialDeferralAction( + FrameInitialDeferralAction::kLoadedNearOrInViewport); + } else if (IsFrameProbablyHidden(*entries.back()->boundingClientRect())) { + RecordInitialDeferralAction(FrameInitialDeferralAction::kLoadedHidden); + } else { + RecordInitialDeferralAction(FrameInitialDeferralAction::kDeferred); return; } + if (was_recorded_as_deferred_) { + DCHECK(element_->GetDocument().GetFrame()); + DCHECK(element_->GetDocument().GetFrame()->Client()); + + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", + element_->GetDocument() + .GetFrame() + ->Client() + ->GetEffectiveConnectionType()); + } + // The content frame of the element should not have changed, since any // pending lazy load should have been already been cancelled in // DisconnectContentFrame() if the content frame changes. @@ -166,6 +184,17 @@ time_when_first_visible_ = CurrentTimeTicks(); RecordVisibilityMetricsIfLoadedAndVisible(); + visibility_metrics_observer_->disconnect(); + visibility_metrics_observer_.Clear(); + + // The below metrics require getting the effective connection type from the + // parent frame, so return early here if there's no parent frame to get the + // effective connection type from. + if (!element_->GetDocument().GetFrame()) + return; + + DCHECK(element_->GetDocument().GetFrame()->Client()); + // On slow networks, iframes might not finish loading by the time the user // leaves the page, so the visible load time metrics samples won't represent // the slowest frames. To remedy this, record how often below the fold @@ -173,7 +202,7 @@ // This isn't recorded for above the fold frames since basically every above // the fold frame would be visible before they finish loading. if (time_when_first_load_finished_.is_null() && - !is_initially_above_the_fold_ && element_->GetDocument().GetFrame()) { + !is_initially_above_the_fold_) { // Note: If the WebEffectiveConnectionType enum ever gets out of sync with // net::EffectiveConnectionType, then this will have to be updated to record // the sample in terms of net::EffectiveConnectionType instead of @@ -186,8 +215,14 @@ ->GetEffectiveConnectionType()); } - visibility_metrics_observer_->disconnect(); - visibility_metrics_observer_.Clear(); + if (was_recorded_as_deferred_) { + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", + element_->GetDocument() + .GetFrame() + ->Client() + ->GetEffectiveConnectionType()); + } } void LazyLoadFrameObserver::RecordMetricsOnLoadFinished() { @@ -271,6 +306,51 @@ } } +void LazyLoadFrameObserver::RecordInitialDeferralAction( + FrameInitialDeferralAction action) { + if (was_recorded_as_deferred_) + return; + + DCHECK(element_->GetDocument().GetFrame()); + DCHECK(element_->GetDocument().GetFrame()->Client()); + + switch (element_->GetDocument() + .GetFrame() + ->Client() + ->GetEffectiveConnectionType()) { + case WebEffectiveConnectionType::kTypeUnknown: + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Unknown", + action); + break; + case WebEffectiveConnectionType::kTypeOffline: + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Offline", + action); + break; + case WebEffectiveConnectionType::kTypeSlow2G: + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Slow2G", + action); + break; + case WebEffectiveConnectionType::kType2G: + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.2G", action); + break; + case WebEffectiveConnectionType::kType3G: + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.3G", action); + break; + case WebEffectiveConnectionType::kType4G: + UMA_HISTOGRAM_ENUMERATION( + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.4G", action); + break; + } + + if (action == FrameInitialDeferralAction::kDeferred) + was_recorded_as_deferred_ = true; +} + void LazyLoadFrameObserver::Trace(blink::Visitor* visitor) { visitor->Trace(element_); visitor->Trace(lazy_load_intersection_observer_);
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer.h b/third_party/blink/renderer/core/html/lazy_load_frame_observer.h index 36a2baee..248e38f 100644 --- a/third_party/blink/renderer/core/html/lazy_load_frame_observer.h +++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer.h
@@ -21,6 +21,24 @@ class LazyLoadFrameObserver : public GarbageCollected<LazyLoadFrameObserver> { public: + // This enum is logged to histograms, so values should not be reordered or + // reused, and it must match the corresponding enum + // "LazyLoad.FrameInitialDeferralAction" in + // tools/metrics/histograms/enums.xml. + enum class FrameInitialDeferralAction { + // The frame was not loaded immediately, and the load continued to be + // deferred. + kDeferred = 0, + // The frame was either visible or near enough to the viewport that it was + // loaded immediately. + kLoadedNearOrInViewport = 1, + // The frame was determined to likely be a hidden frame (e.g. analytics or + // communication iframes), so it was loaded immediately. + kLoadedHidden = 2, + + kMaxValue = kLoadedHidden + }; + explicit LazyLoadFrameObserver(HTMLFrameOwnerElement&); void DeferLoadUntilNearViewport(const ResourceRequest&, WebFrameLoadType); @@ -42,6 +60,7 @@ const HeapVector<Member<IntersectionObserverEntry>>&); void RecordVisibilityMetricsIfLoadedAndVisible(); + void RecordInitialDeferralAction(FrameInitialDeferralAction); const Member<HTMLFrameOwnerElement> element_; @@ -62,6 +81,11 @@ TimeTicks time_when_first_visible_; // Set when the first load event is dispatched for the frame. TimeTicks time_when_first_load_finished_; + + // Keeps track of whether the frame was initially recorded as having been + // deferred, so that the appropriate histograms can be recorded if the frame + // later gets loaded in for some reason. + bool was_recorded_as_deferred_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc index 73822c9..f987c93 100644 --- a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
@@ -51,6 +51,22 @@ "Blink.VisibleLoadTime.LazyLoadEligibleFrames.BelowTheFold.4G"}, }; +constexpr std::pair<WebEffectiveConnectionType, const char*> + kInitialDeferralActionHistogramNames[] = { + {WebEffectiveConnectionType::kTypeUnknown, + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Unknown"}, + {WebEffectiveConnectionType::kTypeOffline, + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Offline"}, + {WebEffectiveConnectionType::kTypeSlow2G, + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.Slow2G"}, + {WebEffectiveConnectionType::kType2G, + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.2G"}, + {WebEffectiveConnectionType::kType3G, + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.3G"}, + {WebEffectiveConnectionType::kType4G, + "Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.4G"}, +}; + // Convenience enums to make it easy to access the appropriate value of the // tuple parameters in the parameterized tests below, e.g. so that // std::get<LazyFrameLoadingFeatureStatus>(GetParam()) can be used instead of @@ -94,11 +110,17 @@ settings.SetLazyFrameLoadingDistanceThresholdPx4G(700); } + int GetLoadingDistanceThreshold() const { + static constexpr int kDistanceThresholdByEffectiveConnectionType[] = { + 200, 300, 400, 500, 600, 700}; + return kDistanceThresholdByEffectiveConnectionType[static_cast<int>( + std::get<WebEffectiveConnectionType>(GetParam()))]; + } + void ExpectVisibleLoadTimeHistogramSamplesIfApplicable( int expected_above_the_fold_count, int expected_below_the_fold_count) { - if (std::get<LazyFrameVisibleLoadTimeFeatureStatus>(GetParam()) != - LazyFrameVisibleLoadTimeFeatureStatus::kEnabled) { + if (!RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled()) { // Expect zero samples if the visible load time metrics feature is // disabled. expected_above_the_fold_count = 0; @@ -121,15 +143,47 @@ } } - HistogramTester* histogram_tester() { return &histogram_tester_; } - - int GetLoadingDistanceThreshold() const { - static constexpr int kDistanceThresholdByEffectiveConnectionType[] = { - 200, 300, 400, 500, 600, 700}; - return kDistanceThresholdByEffectiveConnectionType[static_cast<int>( - std::get<WebEffectiveConnectionType>(GetParam()))]; + void ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction action, + int expected_count) { + for (const auto& pair : kInitialDeferralActionHistogramNames) { + if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled() && + std::get<WebEffectiveConnectionType>(GetParam()) == pair.first) { + histogram_tester()->ExpectUniqueSample( + pair.second, static_cast<int>(action), expected_count); + } else { + histogram_tester()->ExpectTotalCount(pair.second, 0); + } + } } + void ExpectLoadStartedAfterDeferredSamplesIfApplicable(int expected_count) { + if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) { + histogram_tester()->ExpectUniqueSample( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", + static_cast<int>(std::get<WebEffectiveConnectionType>(GetParam())), + expected_count); + } else { + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + } + } + + void ExpectVisibleAfterDeferredSamplesIfApplicable(int expected_count) { + if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled() && + RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled()) { + histogram_tester()->ExpectUniqueSample( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", + static_cast<int>(std::get<WebEffectiveConnectionType>(GetParam())), + expected_count); + } else { + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); + } + } + + HistogramTester* histogram_tester() { return &histogram_tester_; } + // Convenience function to load a page with a cross origin frame far down the // page such that it's not near the viewport. std::unique_ptr<SimRequest> LoadPageWithCrossOriginFrameFarFromViewport() { @@ -167,6 +221,13 @@ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); + if (!child_frame_resource) { child_frame_resource.reset( new SimRequest("https://crossorigin.com/subframe.html", "text/html")); @@ -214,6 +275,13 @@ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + for (const auto& pair : kInitialDeferralActionHistogramNames) + histogram_tester()->ExpectTotalCount(pair.second, 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); } TEST_P(LazyLoadFramesTest, AboveTheFoldFrame) { @@ -250,6 +318,15 @@ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(1, 0); histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction:: + kLoadedNearOrInViewport, + 1); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); } TEST_P(LazyLoadFramesTest, BelowTheFoldButNearViewportFrame) { @@ -298,6 +375,15 @@ // samples in the VisibleBeforeLoaded histogram. histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction:: + kLoadedNearOrInViewport, + 1); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); } TEST_P(LazyLoadFramesTest, HiddenAndTinyFrames) { @@ -387,6 +473,13 @@ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction::kLoadedHidden, 6); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); } TEST_P(LazyLoadFramesTest, LoadCrossOriginFrameFarFromViewport) { @@ -406,6 +499,12 @@ EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload")); ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1); + ExpectLoadStartedAfterDeferredSamplesIfApplicable(1); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); + child_frame_resource->Complete(""); Compositor().BeginFrame(); @@ -429,6 +528,11 @@ histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1); + ExpectLoadStartedAfterDeferredSamplesIfApplicable(1); + ExpectVisibleAfterDeferredSamplesIfApplicable(1); } TEST_P(LazyLoadFramesTest, @@ -458,6 +562,11 @@ "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); } + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1); + ExpectLoadStartedAfterDeferredSamplesIfApplicable(1); + ExpectVisibleAfterDeferredSamplesIfApplicable(1); + child_frame_resource->Complete(""); Compositor().BeginFrame(); @@ -471,6 +580,11 @@ histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled() ? 1 : 0); + + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1); + ExpectLoadStartedAfterDeferredSamplesIfApplicable(1); + ExpectVisibleAfterDeferredSamplesIfApplicable(1); } TEST_P(LazyLoadFramesTest, NestedFrameInCrossOriginFrameFarFromViewport) { @@ -511,6 +625,12 @@ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + ExpectInitialDeferralActionHistogramSamplesIfApplicable( + LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1); + ExpectLoadStartedAfterDeferredSamplesIfApplicable(1); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); } TEST_P(LazyLoadFramesTest, AboutBlankChildFrameNavigation) { @@ -558,6 +678,13 @@ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + for (const auto& pair : kInitialDeferralActionHistogramNames) + histogram_tester()->ExpectTotalCount(pair.second, 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); } TEST_P(LazyLoadFramesTest, JavascriptStringFrameUrl) { @@ -583,6 +710,13 @@ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0); histogram_tester()->ExpectTotalCount( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0); + + for (const auto& pair : kInitialDeferralActionHistogramNames) + histogram_tester()->ExpectTotalCount(pair.second, 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0); + histogram_tester()->ExpectTotalCount( + "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0); } INSTANTIATE_TEST_CASE_P(
diff --git a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc index 83b395e0..55cd545 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc +++ b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc
@@ -18,7 +18,6 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/network/network_state_notifier.h" -#include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -59,11 +58,8 @@ ContextLifecycleObserver(nullptr), element_(element), muted_video_play_method_visibility_observer_(nullptr), - muted_video_autoplay_offscreen_start_time_ms_(0), - muted_video_autoplay_offscreen_duration_ms_(0), is_visible_(false), - muted_video_offscreen_duration_visibility_observer_(nullptr), - load_start_time_ms_(0.0) { + muted_video_offscreen_duration_visibility_observer_(nullptr) { element->addEventListener(EventTypeNames::loadstart, this, false); } @@ -75,14 +71,14 @@ void AutoplayUmaHelper::OnLoadStarted() { if (element_->GetLoadType() == WebMediaPlayer::kLoadTypeURL) - load_start_time_ms_ = CurrentTimeTicksInMilliseconds(); + load_start_time_ = CurrentTimeTicks(); } void AutoplayUmaHelper::OnAutoplayInitiated(AutoplaySource source) { int32_t autoplay_wait_time_ms = -1; - if (load_start_time_ms_ != 0.0) { + if (!load_start_time_.is_null()) { autoplay_wait_time_ms = static_cast<int32_t>(std::min<int64_t>( - CurrentTimeTicksInMilliseconds() - load_start_time_ms_, + (CurrentTimeTicks() - load_start_time_).InMilliseconds(), std::numeric_limits<int32_t>::max())); } DEFINE_STATIC_LOCAL(EnumerationHistogram, video_histogram, @@ -352,12 +348,10 @@ return; if (is_visible) { - muted_video_autoplay_offscreen_duration_ms_ += - static_cast<int64_t>(CurrentTimeTicksInMilliseconds()) - - muted_video_autoplay_offscreen_start_time_ms_; + muted_video_autoplay_offscreen_duration_ += + CurrentTimeTicks() - muted_video_autoplay_offscreen_start_time_; } else { - muted_video_autoplay_offscreen_start_time_ms_ = - static_cast<int64_t>(CurrentTimeTicksInMilliseconds()); + muted_video_autoplay_offscreen_start_time_ = CurrentTimeTicks(); } is_visible_ = is_visible; @@ -430,8 +424,7 @@ return; // Start recording muted video playing offscreen duration. - muted_video_autoplay_offscreen_start_time_ms_ = - static_cast<int64_t>(CurrentTimeTicksInMilliseconds()); + muted_video_autoplay_offscreen_start_time_ = CurrentTimeTicks(); is_visible_ = false; muted_video_offscreen_duration_visibility_observer_ = new ElementVisibilityObserver( @@ -449,16 +442,15 @@ return; if (!is_visible_) { - muted_video_autoplay_offscreen_duration_ms_ += - static_cast<int64_t>(CurrentTimeTicksInMilliseconds()) - - muted_video_autoplay_offscreen_start_time_ms_; + muted_video_autoplay_offscreen_duration_ += + CurrentTimeTicks() - muted_video_autoplay_offscreen_start_time_; } // Since histograms uses int32_t, the duration needs to be limited to // std::numeric_limits<int32_t>::max(). - int32_t bounded_time = static_cast<int32_t>( - std::min<int64_t>(muted_video_autoplay_offscreen_duration_ms_, - std::numeric_limits<int32_t>::max())); + int32_t bounded_time = static_cast<int32_t>(std::min<int64_t>( + muted_video_autoplay_offscreen_duration_.InMilliseconds(), + std::numeric_limits<int32_t>::max())); DCHECK(sources_.count(AutoplaySource::kMethod)); @@ -470,7 +462,7 @@ muted_video_offscreen_duration_visibility_observer_->Stop(); muted_video_offscreen_duration_visibility_observer_ = nullptr; - muted_video_autoplay_offscreen_duration_ms_ = 0; + muted_video_autoplay_offscreen_duration_ = TimeDelta(); MaybeUnregisterMediaElementPauseListener(); MaybeUnregisterContextDestroyedObserver(); }
diff --git a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h index defb52e..ce9bdd9a 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h +++ b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/dom/events/event_listener.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/wtf/time.h" #include <set> @@ -133,10 +134,10 @@ // The recording stops whenever the playback pauses or the page is unloaded. // The starting time of autoplaying muted video. - int64_t muted_video_autoplay_offscreen_start_time_ms_; + TimeTicks muted_video_autoplay_offscreen_start_time_; // The duration an autoplaying muted video has been in offscreen. - int64_t muted_video_autoplay_offscreen_duration_ms_; + TimeDelta muted_video_autoplay_offscreen_duration_; // Whether an autoplaying muted video is visible. bool is_visible_; @@ -149,7 +150,7 @@ Member<ElementVisibilityObserver> muted_video_offscreen_duration_visibility_observer_; - double load_start_time_ms_; + TimeTicks load_start_time_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index 65b1b65..60e732cc 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -52,7 +52,7 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -465,8 +465,8 @@ this, &HTMLMediaElement::CheckViewportIntersectionTimerFired), played_time_ranges_(), - async_event_queue_(EventQueueImpl::Create(GetExecutionContext(), - TaskType::kMediaElementEvent)), + async_event_queue_(EventQueue::Create(GetExecutionContext(), + TaskType::kMediaElementEvent)), playback_rate_(1.0f), default_playback_rate_(1.0f), network_state_(kNetworkEmpty),
diff --git a/third_party/blink/renderer/core/html/track/text_track_list.cc b/third_party/blink/renderer/core/html/track/text_track_list.cc index 9bf1c29..40ee5455 100644 --- a/third_party/blink/renderer/core/html/track/text_track_list.cc +++ b/third_party/blink/renderer/core/html/track/text_track_list.cc
@@ -25,7 +25,7 @@ #include "third_party/blink/renderer/core/html/track/text_track_list.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/track/inband_text_track.h" #include "third_party/blink/renderer/core/html/track/loadable_text_track.h" @@ -37,9 +37,8 @@ TextTrackList::TextTrackList(HTMLMediaElement* owner) : owner_(owner), - async_event_queue_(EventQueueImpl::Create(GetExecutionContext(), - TaskType::kMediaElementEvent)) { -} + async_event_queue_(EventQueue::Create(GetExecutionContext(), + TaskType::kMediaElementEvent)) {} TextTrackList::~TextTrackList() = default;
diff --git a/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc b/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc index a0fd177..52f1cf8 100644 --- a/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc
@@ -433,8 +433,7 @@ if (!layer->DrawsContent()) return Response::Error("Layer does not draw content"); - IntSize size = ExpandedIntSize(layer->Size()); - IntRect interest_rect(IntPoint(0, 0), size); + IntRect interest_rect(IntPoint(), layer->Size()); suppress_layer_paint_events_ = true; // If we hit a devtool break point in the middle of document lifecycle, for @@ -522,14 +521,15 @@ Response response = GetSnapshotById(snapshot_id, snapshot); if (!response.isSuccess()) return response; - std::unique_ptr<Vector<char>> base64_data = snapshot->Replay( + Vector<char> base64_data = snapshot->Replay( from_step.fromMaybe(0), to_step.fromMaybe(0), scale.fromMaybe(1.0)); - if (!base64_data) + if (base64_data.IsEmpty()) return Response::Error("Image encoding failed"); + static constexpr char kUrlPrefix[] = "data:image/png;base64,"; StringBuilder url; - url.Append("data:image/png;base64,"); - url.ReserveCapacity(url.length() + base64_data->size()); - url.Append(base64_data->begin(), base64_data->size()); + url.ReserveCapacity(sizeof(kUrlPrefix) + base64_data.size()); + url.Append(kUrlPrefix); + url.Append(base64_data.begin(), base64_data.size()); *data_url = url.ToString(); return Response::OK(); }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc index ca585fa..0eb45386 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -215,6 +215,13 @@ if (position_pending == kPositionNotPending && box != stack_.begin()) { box[-1].metrics.Unite(box->metrics); } + + // Create box fragments for parent if the current box has properties (e.g., + // margin) that make it tricky to compute the parent's rects. + if (box != stack_.begin() && box[-1].item) { + if (box->ParentNeedsBoxFragment()) + box[-1].SetNeedsBoxFragment(); + } } void NGInlineBoxState::SetNeedsBoxFragment() { @@ -237,6 +244,15 @@ } } +bool NGInlineBoxState::ParentNeedsBoxFragment() const { + if (margin_inline_start || margin_inline_end) + return true; + // TODO(xiaochengh): Include other cases: + // - current box has a different font-size + // - current box is an atomic inline + return false; +} + // Crete a placeholder for a box fragment. // We keep a flat list of fragments because it is more suitable for operations // such as ApplyBaselineShift. Later, CreateBoxFragments() creates box fragments @@ -397,27 +413,12 @@ if (box_data_list_.IsEmpty()) return position; - // Compute inline positions of inline boxes. + // Adjust child offsets for margin/border/padding of inline boxes. for (auto& box_data : box_data_list_) { unsigned start = box_data.fragment_start; unsigned end = box_data.fragment_end; DCHECK_GT(end, start); - NGLineBoxFragmentBuilder::Child& start_child = (*line_box)[start]; - // Clamping left offset is not defined, match to the existing behavior. - LayoutUnit line_left_offset = - start_child.offset.inline_offset.ClampNegativeToZero(); - LayoutUnit line_right_offset = end < line_box->size() - ? (*line_box)[end].offset.inline_offset - : position; - box_data.offset.inline_offset = - line_left_offset + box_data.margin_line_left; - box_data.size.inline_size = - line_right_offset - line_left_offset + - box_data.margin_border_padding_line_left - box_data.margin_line_left + - box_data.margin_border_padding_line_right - box_data.margin_line_right; - - // Adjust child offsets for margin/border/padding. if (box_data.margin_border_padding_line_left) { line_box->MoveInInlineDirection(box_data.margin_border_padding_line_left, start, line_box->size()); @@ -431,6 +432,39 @@ } } + // Compute positions and sizes of inline boxes. + // + // Accumulate margin/border/padding of boxes for each child, to place nested + // parent boxes relative to the leaf (text or atomic inline) child. + struct LinePadding { + LayoutUnit line_left; + LayoutUnit line_right; + }; + Vector<LinePadding, 32> accumulated_padding(line_box->size()); + for (auto& box_data : box_data_list_) { + // Compute line-left and line-right edge of this box by accomodating + // border/padding of this box and margin/border/padding of descendants + // boxes, while accumulating its margin/border/padding. + unsigned start = box_data.fragment_start; + NGLineBoxFragmentBuilder::Child& start_child = (*line_box)[start]; + LayoutUnit line_left_offset = start_child.offset.inline_offset; + LinePadding& start_padding = accumulated_padding[start]; + start_padding.line_left += box_data.margin_border_padding_line_left; + line_left_offset -= start_padding.line_left - box_data.margin_line_left; + + DCHECK_GT(box_data.fragment_end, start); + unsigned last = box_data.fragment_end - 1; + NGLineBoxFragmentBuilder::Child& last_child = (*line_box)[last]; + LayoutUnit line_right_offset = + last_child.offset.inline_offset + last_child.inline_size; + LinePadding& last_padding = accumulated_padding[last]; + last_padding.line_right += box_data.margin_border_padding_line_right; + line_right_offset += last_padding.line_right - box_data.margin_line_right; + + box_data.offset.inline_offset = line_left_offset; + box_data.size.inline_size = line_right_offset - line_left_offset; + } + return position; }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h index 7e0f488e..5af2672 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -91,6 +91,12 @@ void SetLineRightForBoxFragment(const NGInlineItem&, const NGInlineItemResult&); + // In certain circumstances, the parent's rects is not a simple union of its + // children fragments' rects, e.g., when children have margin. In such cases, + // we should create box fragments for the parent to avoid hacky fixup when + // computing its rects. + bool ParentNeedsBoxFragment() const; + // Returns if the text style can be added without open-tag. // Text with different font or vertical-align needs to be wrapped with an // inline box.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc index a157f2f..190fc9a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -516,8 +516,16 @@ shape_result->StartIndexForResult()); item_result.inline_size = shape_result->SnappedWidth(); item_result.shape_result = std::move(shape_result); - } else { - // TODO(kojii): Implement atomic inline. + } else if (item_result.item->Type() == NGInlineItem::kAtomicInline) { + float offset = 0.f; + DCHECK_LE(line_info->StartOffset(), item_result.start_offset); + unsigned line_text_offset = + item_result.start_offset - line_info->StartOffset(); + DCHECK_EQ(kObjectReplacementCharacter, line_text[line_text_offset]); + float space = spacing.ComputeSpacing(line_text_offset, offset); + item_result.inline_size += space; + // |offset| is non-zero only before CJK characters. + DCHECK_EQ(offset, 0.f); } } return true;
diff --git a/third_party/blink/renderer/core/loader/document_threadable_loader.cc b/third_party/blink/renderer/core/loader/document_threadable_loader.cc index 727fdf6..1990bb81 100644 --- a/third_party/blink/renderer/core/loader/document_threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/document_threadable_loader.cc
@@ -337,6 +337,33 @@ if (should_bypass_service_worker) new_request.SetSkipServiceWorker(true); + // In S13nServiceWorker, if the controller service worker has no fetch event + // handler, it's skipped entirely, so we should treat that case the same as + // having no controller. In non-S13nServiceWorker, we can't do that since we + // don't know which service worker will handle the request since it's + // determined on the browser process and skipWaiting() can happen in the + // meantime. + // + // TODO(crbug.com/715640): When non-S13nServiceWorker is removed, + // is_controlled_by_service_worker is the same as + // ControllerServiceWorkerMode::kControlled, so this code can be simplified. + bool is_controlled_by_service_worker = false; + switch ( + loading_context_->GetResourceFetcher()->IsControlledByServiceWorker()) { + case blink::mojom::ControllerServiceWorkerMode::kControlled: + is_controlled_by_service_worker = true; + break; + case blink::mojom::ControllerServiceWorkerMode::kNoFetchEventHandler: + if (Platform::Current()->IsServiceWorkerNetServicificationEnabled()) + is_controlled_by_service_worker = false; + else + is_controlled_by_service_worker = true; + break; + case blink::mojom::ControllerServiceWorkerMode::kNoController: + is_controlled_by_service_worker = false; + break; + } + // Process the CORS protocol inside the DocumentThreadableLoader for the // following cases: // @@ -360,8 +387,7 @@ if (!async_ || new_request.GetSkipServiceWorker() || !SchemeRegistry::ShouldTreatURLSchemeAsAllowingServiceWorkers( new_request.Url().Protocol()) || - loading_context_->GetResourceFetcher()->IsControlledByServiceWorker() == - blink::mojom::ControllerServiceWorkerMode::kNoController) { + !is_controlled_by_service_worker) { DispatchInitialRequest(new_request); return; }
diff --git a/third_party/blink/renderer/core/page/page_overlay.cc b/third_party/blink/renderer/core/page/page_overlay.cc index a29b3df..a4b09ee 100644 --- a/third_party/blink/renderer/core/page/page_overlay.cc +++ b/third_party/blink/renderer/core/page/page_overlay.cc
@@ -105,12 +105,12 @@ LayoutRect PageOverlay::VisualRect() const { DCHECK(layer_.get()); - return LayoutRect(FloatPoint(), layer_->Size()); + return LayoutRect(IntPoint(), layer_->Size()); } IntRect PageOverlay::ComputeInterestRect(const GraphicsLayer* graphics_layer, const IntRect&) const { - return IntRect(IntPoint(), ExpandedIntSize(layer_->Size())); + return IntRect(IntPoint(), layer_->Size()); } void PageOverlay::PaintContents(const GraphicsLayer* graphics_layer,
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc index ab4de0a..0938ab658 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.cc +++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -525,9 +525,7 @@ LayoutRectOutsets BackgroundImageGeometry::ComputeDestRectAdjustment( const FillLayer& fill_layer, - PaintPhase paint_phase, - LayoutRect& positioning_rect, - LayoutRect& dest_rect) const { + PaintPhase paint_phase) const { LayoutRectOutsets dest_adjust; // Attempt to shrink the destination rect if possible while also ensuring that @@ -558,23 +556,9 @@ switch (fill_layer.Clip()) { case EFillBox::kContent: dest_adjust += positioning_box_.PaddingOutsets(); - dest_adjust += positioning_box_.BorderBoxOutsets(); - break; + FALLTHROUGH; case EFillBox::kPadding: - if (disallow_border_derived_adjustment) { - dest_adjust = positioning_box_.BorderBoxOutsets(); - } else { - FloatRect inner_border_rect = - positioning_box_.StyleRef() - .GetRoundedInnerBorderFor(positioning_rect) - .Rect(); - dest_adjust.SetLeft(LayoutUnit(inner_border_rect.X()) - dest_rect.X()); - dest_adjust.SetTop(LayoutUnit(inner_border_rect.Y()) - dest_rect.Y()); - dest_adjust.SetRight(dest_rect.MaxX() - - LayoutUnit(inner_border_rect.MaxX())); - dest_adjust.SetBottom(dest_rect.MaxY() - - LayoutUnit(inner_border_rect.MaxY())); - } + dest_adjust += positioning_box_.BorderBoxOutsets(); break; case EFillBox::kBorder: { if (disallow_border_derived_adjustment) @@ -582,24 +566,15 @@ BorderEdge edges[4]; positioning_box_.StyleRef().GetBorderEdgeInfo(edges); - FloatRect inner_border_rect = - positioning_box_.StyleRef() - .GetRoundedInnerBorderFor(positioning_rect) - .Rect(); - if (edges[static_cast<unsigned>(BoxSide::kTop)].ObscuresBackground()) { - dest_adjust.SetTop(LayoutUnit(inner_border_rect.Y()) - dest_rect.Y()); - } - if (edges[static_cast<unsigned>(BoxSide::kRight)].ObscuresBackground()) { - dest_adjust.SetRight(dest_rect.MaxX() - - LayoutUnit(inner_border_rect.MaxX())); - } - if (edges[static_cast<unsigned>(BoxSide::kBottom)].ObscuresBackground()) { - dest_adjust.SetBottom(dest_rect.MaxY() - - LayoutUnit(inner_border_rect.MaxY())); - } - if (edges[static_cast<unsigned>(BoxSide::kLeft)].ObscuresBackground()) { - dest_adjust.SetLeft(LayoutUnit(inner_border_rect.X()) - dest_rect.X()); - } + const auto border_outsets = positioning_box_.BorderBoxOutsets(); + if (edges[static_cast<unsigned>(BoxSide::kTop)].ObscuresBackground()) + dest_adjust.SetTop(border_outsets.Top()); + if (edges[static_cast<unsigned>(BoxSide::kRight)].ObscuresBackground()) + dest_adjust.SetRight(border_outsets.Right()); + if (edges[static_cast<unsigned>(BoxSide::kBottom)].ObscuresBackground()) + dest_adjust.SetBottom(border_outsets.Bottom()); + if (edges[static_cast<unsigned>(BoxSide::kLeft)].ObscuresBackground()) + dest_adjust.SetLeft(border_outsets.Left()); } break; case EFillBox::kText: break; @@ -622,17 +597,10 @@ positioning_area = FixedAttachmentPositioningArea(box_, container, flags); SetDestRect(positioning_area); } else { - auto dest_rect = LayoutRect(PixelSnappedIntRect(paint_rect)); - if (painting_view_ || cell_using_container_background_) positioning_area.SetSize(positioning_size_override_); else - positioning_area = dest_rect; - - auto dest_adjust = ComputeDestRectAdjustment(fill_layer, paint_phase, - positioning_area, dest_rect); - dest_rect.Contract(dest_adjust); - SetDestRect(dest_rect); + positioning_area = paint_rect; LayoutRectOutsets box_outset; if (fill_layer.Origin() != EFillBox::kBorder) { @@ -642,6 +610,11 @@ } positioning_area.Contract(box_outset); + auto dest_rect = paint_rect; + auto dest_adjust = ComputeDestRectAdjustment(fill_layer, paint_phase); + dest_rect.Contract(dest_adjust); + SetDestRect(dest_rect); + box_offset = LayoutPoint(box_outset.Left() - dest_adjust.Left(), box_outset.Top() - dest_adjust.Top()); @@ -793,7 +766,10 @@ UseFixedAttachment(paint_rect.Location()); // Clip the final output rect to the paint rect - dest_rect_.Intersect(LayoutRect(PixelSnappedIntRect(paint_rect))); + dest_rect_.Intersect(paint_rect); + + // Snap as-yet unsnapped values. + SetDestRect(LayoutRect(PixelSnappedIntRect(dest_rect_))); } const ImageResourceObserver& BackgroundImageGeometry::ImageClient() const {
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.h b/third_party/blink/renderer/core/paint/background_image_geometry.h index 76d5006..27a595f 100644 --- a/third_party/blink/renderer/core/paint/background_image_geometry.h +++ b/third_party/blink/renderer/core/paint/background_image_geometry.h
@@ -109,9 +109,7 @@ const LayoutBox&); LayoutRectOutsets ComputeDestRectAdjustment(const FillLayer&, - PaintPhase, - LayoutRect&, - LayoutRect&) const; + PaintPhase) const; void ComputePositioningArea(const LayoutBoxModelObject*, PaintPhase, GlobalPaintFlags,
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 95f8ca35..5b78051a 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -1673,7 +1673,8 @@ overflow_clip_rect.Location()); scrolling_contents_layer_->SetOffsetDoubleFromLayoutObject( - ToIntSize(scrolling_contents_layer_offset_from_layout_object), + DoubleSize(scrolling_contents_layer_offset_from_layout_object.X(), + scrolling_contents_layer_offset_from_layout_object.Y()), GraphicsLayer::kDontSetNeedsDisplay); } @@ -1700,13 +1701,13 @@ // Should be equivalent to local_compositing_bounds. IntRect compositing_bounds( IntPoint(graphics_layer_->OffsetFromLayoutObject()), - FlooredIntSize(graphics_layer_->Size())); + graphics_layer_->Size()); if (scrolling_layer_) { // Override compositing bounds to include full overflow if composited // scrolling is used. compositing_bounds = IntRect(IntPoint(scrolling_contents_layer_->OffsetFromLayoutObject()), - FlooredIntSize(scrolling_contents_layer_->Size())); + scrolling_contents_layer_->Size()); } else if (child_containment_layer_) { // If we have a clipping layer, shrink compositing bounds to the clip rect. // Note: this is technically incorrect because non-composited positive @@ -1715,13 +1716,13 @@ // escape clips, thus shrinking the layer won't cause bug. IntRect clipping_box( IntPoint(child_containment_layer_->OffsetFromLayoutObject()), - FlooredIntSize(child_containment_layer_->Size())); + child_containment_layer_->Size()); compositing_bounds.Intersect(clipping_box); } IntRect old_compositing_bounds( IntPoint(foreground_layer_->OffsetFromLayoutObject()), - FlooredIntSize(foreground_layer_->Size())); + foreground_layer_->Size()); if (compositing_bounds != old_compositing_bounds) { foreground_layer_->SetOffsetFromLayoutObject( ToIntSize(compositing_bounds.Location())); @@ -3369,8 +3370,7 @@ const GraphicsLayer* graphics_layer, const IntRect& previous_interest_rect) const { // Use the previous interest rect if it covers the whole layer. - IntRect whole_layer_rect = - IntRect(IntPoint(), ExpandedIntSize(graphics_layer->Size())); + IntRect whole_layer_rect = IntRect(IntPoint(), graphics_layer->Size()); if (!NeedsRepaint(*graphics_layer) && previous_interest_rect == whole_layer_rect) return previous_interest_rect; @@ -3383,8 +3383,7 @@ IntRect new_interest_rect = RecomputeInterestRect(graphics_layer); if (NeedsRepaint(*graphics_layer) || InterestRectChangedEnoughToRepaint( - previous_interest_rect, new_interest_rect, - ExpandedIntSize(graphics_layer->Size()))) + previous_interest_rect, new_interest_rect, graphics_layer->Size())) return new_interest_rect; return previous_interest_rect; }
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc index 59ce908..0eb6def 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
@@ -2559,13 +2559,13 @@ ->Layer() ->GetCompositedLayerMapping(); ASSERT_TRUE(mapping); - EXPECT_EQ(FloatSize(120, 120), mapping->MainGraphicsLayer()->Size()); + EXPECT_EQ(IntSize(120, 120), mapping->MainGraphicsLayer()->Size()); ASSERT_TRUE(mapping->ClippingLayer()); EXPECT_EQ(FloatPoint(10, 10), mapping->ClippingLayer()->GetPosition()); - EXPECT_EQ(FloatSize(100, 100), mapping->ClippingLayer()->Size()); + EXPECT_EQ(IntSize(100, 100), mapping->ClippingLayer()->Size()); ASSERT_TRUE(mapping->ForegroundLayer()); EXPECT_EQ(FloatPoint(0, 0), mapping->ForegroundLayer()->GetPosition()); - EXPECT_EQ(FloatSize(100, 100), mapping->ForegroundLayer()->Size()); + EXPECT_EQ(IntSize(100, 100), mapping->ForegroundLayer()->Size()); } TEST_F(CompositedLayerMappingTest, ScrollLayerSizingSubpixelAccumulation) {
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc index 60f0aa6..93c4b73 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
@@ -73,6 +73,11 @@ Node* const node = paint_fragment.GetNode(); if (!node) return DocumentMarkerVector(); + // We don't paint any marker on ellipsis. + if (paint_fragment.PhysicalFragment().StyleVariant() == + NGStyleVariant::kEllipsis) + return DocumentMarkerVector(); + DocumentMarkerController& document_marker_controller = node->GetDocument().Markers(); return document_marker_controller.ComputeMarkersToPaint(*node);
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 0dccbd6..0a75d2e6 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
@@ -682,9 +682,10 @@ GetLayoutBox()->Location())); } -LayoutRect PaintLayerScrollableArea::VisibleScrollSnapportRect() const { +LayoutRect PaintLayerScrollableArea::VisibleScrollSnapportRect( + IncludeScrollbarsInRect scrollbar_inclusion) const { const ComputedStyle* style = GetLayoutBox()->Style(); - LayoutRect layout_content_rect(LayoutContentRect(kExcludeScrollbars)); + LayoutRect layout_content_rect(LayoutContentRect(scrollbar_inclusion)); layout_content_rect.MoveBy(LayoutPoint(-ScrollOrigin())); LayoutRectOutsets padding(MinimumValueForLength(style->ScrollPaddingTop(), layout_content_rect.Height()), @@ -824,12 +825,16 @@ } int PaintLayerScrollableArea::PageStep(ScrollbarOrientation orientation) const { - int length = - (orientation == kHorizontalScrollbar) ? VisibleWidth() : VisibleHeight(); + // Paging scroll operations should take scroll-padding into account [1]. So we + // use the snapport rect to calculate the page step instead of the visible + // rect. + // [1] https://drafts.csswg.org/css-scroll-snap/#scroll-padding + IntSize snapport_size = VisibleScrollSnapportRect().PixelSnappedSize(); + int length = (orientation == kHorizontalScrollbar) ? snapport_size.Width() + : snapport_size.Height(); int min_page_step = static_cast<float>(length) * ScrollableArea::MinFractionToStepWhenPaging(); int page_step = max(min_page_step, length - MaxOverlapBetweenPages()); - return max(page_step, 1); }
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 57e6e5c..ec713777 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
@@ -286,7 +286,8 @@ IntSize MaximumScrollOffsetInt() const override; IntRect VisibleContentRect( IncludeScrollbarsInRect = kExcludeScrollbars) const override; - LayoutRect VisibleScrollSnapportRect() const override; + LayoutRect VisibleScrollSnapportRect( + IncludeScrollbarsInRect = kExcludeScrollbars) const override; IntSize ContentsSize() const override; void ContentsResized() override; bool IsScrollable() const override;
diff --git a/third_party/blink/renderer/core/testing/null_execution_context.h b/third_party/blink/renderer/core/testing/null_execution_context.h index d1036c4..d642abe 100644 --- a/third_party/blink/renderer/core/testing/null_execution_context.h +++ b/third_party/blink/renderer/core/testing/null_execution_context.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" -#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/execution_context/security_context.h" #include "third_party/blink/renderer/core/inspector/console_message.h"
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc index df6a7d1..0792fb4 100644 --- a/third_party/blink/renderer/core/timing/performance.cc +++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -135,6 +135,8 @@ entries.AppendVector(resource_timing_buffer_); entries.AppendVector(event_timing_buffer_); + if (first_input_timing_) + entries.push_back(first_input_timing_); if (!navigation_timing_) navigation_timing_ = CreateNavigationTimingInstance(); // This extra checking is needed when WorkerPerformance @@ -172,6 +174,10 @@ for (const auto& event : event_timing_buffer_) entries.push_back(event); break; + case PerformanceEntry::kFirstInput: + if (first_input_timing_) + entries.push_back(first_input_timing_); + break; case PerformanceEntry::kNavigation: if (!navigation_timing_) navigation_timing_ = CreateNavigationTimingInstance(); @@ -241,6 +247,11 @@ } } + if (entry_type.IsNull() || type == PerformanceEntry::kFirstInput) { + if (first_input_timing_ && first_input_timing_->name() == name) + entries.push_back(first_input_timing_); + } + if (entry_type.IsNull() || type == PerformanceEntry::kNavigation) { if (!navigation_timing_) navigation_timing_ = CreateNavigationTimingInstance(); @@ -870,6 +881,7 @@ visitor->Trace(user_timing_); visitor->Trace(first_paint_timing_); visitor->Trace(first_contentful_paint_timing_); + visitor->Trace(first_input_timing_); visitor->Trace(observers_); visitor->Trace(active_observers_); visitor->Trace(suspended_observers_);
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h index a87a9539..1b61ccd 100644 --- a/third_party/blink/renderer/core/timing/performance.h +++ b/third_party/blink/renderer/core/timing/performance.h
@@ -258,6 +258,7 @@ Member<UserTiming> user_timing_; Member<PerformanceEntry> first_paint_timing_; Member<PerformanceEntry> first_contentful_paint_timing_; + Member<PerformanceEventTiming> first_input_timing_; TimeTicks time_origin_;
diff --git a/third_party/blink/renderer/core/timing/performance_entry.cc b/third_party/blink/renderer/core/timing/performance_entry.cc index 78034d7..8d867d3 100644 --- a/third_party/blink/renderer/core/timing/performance_entry.cc +++ b/third_party/blink/renderer/core/timing/performance_entry.cc
@@ -91,6 +91,8 @@ return kPaint; if (entry_type == "event") return kEvent; + if (entry_type == "firstInput") + return kFirstInput; return kInvalid; }
diff --git a/third_party/blink/renderer/core/timing/performance_entry.h b/third_party/blink/renderer/core/timing/performance_entry.h index 2a4f904..6641341 100644 --- a/third_party/blink/renderer/core/timing/performance_entry.h +++ b/third_party/blink/renderer/core/timing/performance_entry.h
@@ -64,7 +64,8 @@ kLongTask = 1 << 6, kTaskAttribution = 1 << 7, kPaint = 1 << 8, - kEvent = 1 << 9 + kEvent = 1 << 9, + kFirstInput = 1 << 10, }; String name() const;
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 f8db19b..be23bd0 100644 --- a/third_party/blink/renderer/core/timing/performance_event_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_event_timing.cc
@@ -10,7 +10,7 @@ // static PerformanceEventTiming* PerformanceEventTiming::Create( - const String& type, + const String& event_type, DOMHighResTimeStamp start_time, DOMHighResTimeStamp processing_start, DOMHighResTimeStamp processing_end, @@ -18,17 +18,29 @@ // 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(type, start_time, processing_start, - processing_end, cancelable); + return new PerformanceEventTiming(event_type, "event", start_time, + processing_start, processing_end, + cancelable); +} + +// static +PerformanceEventTiming* PerformanceEventTiming::CreateFirstInputTiming( + PerformanceEventTiming* entry) { + PerformanceEventTiming* first_input = new PerformanceEventTiming( + entry->name(), "firstInput", entry->startTime(), entry->processingStart(), + entry->processingEnd(), entry->cancelable()); + first_input->SetDuration(entry->duration()); + return first_input; } PerformanceEventTiming::PerformanceEventTiming( - const String& type, + const String& event_type, + const String& entry_type, DOMHighResTimeStamp start_time, DOMHighResTimeStamp processing_start, DOMHighResTimeStamp processing_end, bool cancelable) - : PerformanceEntry(type, "event", start_time, 0.0), + : PerformanceEntry(event_type, entry_type, start_time, 0.0), processing_start_(processing_start), processing_end_(processing_end), cancelable_(cancelable) {} @@ -44,7 +56,8 @@ } void PerformanceEventTiming::SetDuration(double duration) { - DCHECK_LE(0, duration); + // TODO(npm): enable this DCHECK once https://crbug.com/852846 is fixed. + // DCHECK_LE(0, duration); duration_ = duration; }
diff --git a/third_party/blink/renderer/core/timing/performance_event_timing.h b/third_party/blink/renderer/core/timing/performance_event_timing.h index 15b4f5d..2386f04 100644 --- a/third_party/blink/renderer/core/timing/performance_event_timing.h +++ b/third_party/blink/renderer/core/timing/performance_event_timing.h
@@ -16,12 +16,15 @@ DEFINE_WRAPPERTYPEINFO(); public: - static PerformanceEventTiming* Create(const String& type, + static PerformanceEventTiming* Create(const String& event_type, DOMHighResTimeStamp start_time, DOMHighResTimeStamp processing_start, DOMHighResTimeStamp processing_end, bool cancelable); + static PerformanceEventTiming* CreateFirstInputTiming( + PerformanceEventTiming* entry); + ~PerformanceEventTiming() override; bool cancelable() const { return cancelable_; } @@ -36,7 +39,8 @@ void Trace(blink::Visitor*) override; private: - PerformanceEventTiming(const String& type, + PerformanceEventTiming(const String& event_type, + const String& entry_type, DOMHighResTimeStamp start_time, DOMHighResTimeStamp processing_start, DOMHighResTimeStamp processing_end,
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc index 2e68db0..53c1ad0 100644 --- a/third_party/blink/renderer/core/timing/window_performance.cc +++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -207,6 +207,7 @@ void WindowPerformance::Trace(blink::Visitor* visitor) { visitor->Trace(event_timings_); + visitor->Trace(first_pointer_down_event_timing_); visitor->Trace(navigation_); visitor->Trace(timing_); Performance::Trace(visitor); @@ -349,13 +350,27 @@ void WindowPerformance::ReportEventTimings(WebLayerTreeView::SwapResult result, TimeTicks timestamp) { + DCHECK(OriginTrials::eventTimingEnabled(GetExecutionContext())); + DOMHighResTimeStamp end_time = MonotonicTimeToDOMHighResTimeStamp(timestamp); for (const auto& entry : event_timings_) { int duration_in_ms = std::ceil((end_time - entry->startTime()) / 8) * 8; + entry->SetDuration(duration_in_ms); + if (!first_input_timing_) { + if (entry->name() == "pointerdown") { + first_pointer_down_event_timing_ = + PerformanceEventTiming::CreateFirstInputTiming(entry); + } else if (entry->name() == "pointerup") { + DispatchFirstInputTiming(first_pointer_down_event_timing_); + } else if (entry->name() == "click" || entry->name() == "keydown" || + entry->name() == "mousedown") { + DispatchFirstInputTiming( + PerformanceEventTiming::CreateFirstInputTiming(entry)); + } + } if (duration_in_ms <= kEventTimingDurationThresholdInMs) continue; - entry->SetDuration(duration_in_ms); if (ObservingEventTimingEntries()) NotifyObserversOfEntry(*entry); @@ -365,4 +380,19 @@ event_timings_.clear(); } +void WindowPerformance::DispatchFirstInputTiming( + PerformanceEventTiming* entry) { + DCHECK(OriginTrials::eventTimingEnabled(GetExecutionContext())); + + if (!entry) + return; + DCHECK_EQ("firstInput", entry->entryType()); + if (HasObserverFor(PerformanceEntry::kFirstInput)) + NotifyObserversOfEntry(*entry); + + DCHECK(!first_input_timing_); + if (ShouldBufferEventTiming()) + first_input_timing_ = entry; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/window_performance.h b/third_party/blink/renderer/core/timing/window_performance.h index 2466df70..fbaab69 100644 --- a/third_party/blink/renderer/core/timing/window_performance.h +++ b/third_party/blink/renderer/core/timing/window_performance.h
@@ -105,10 +105,13 @@ void ReportEventTimings(WebLayerTreeView::SwapResult result, TimeTicks timestamp); + void DispatchFirstInputTiming(PerformanceEventTiming* entry); + // PerformanceEventTiming entries that have not been added yet: the event // dispatch has been completed but the swap promise used to determine // |duration| has not been resolved. HeapVector<Member<PerformanceEventTiming>> event_timings_; + Member<PerformanceEventTiming> first_pointer_down_event_timing_; mutable Member<PerformanceNavigation> navigation_; mutable Member<PerformanceTiming> timing_; };
diff --git a/third_party/blink/renderer/core/timing/window_performance_test.cc b/third_party/blink/renderer/core/timing/window_performance_test.cc index 81e2077..a24145c 100644 --- a/third_party/blink/renderer/core/timing/window_performance_test.cc +++ b/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -31,11 +31,7 @@ class WindowPerformanceTest : public testing::Test { protected: void SetUp() override { - page_holder_ = DummyPageHolder::Create(IntSize(800, 600)); - page_holder_->GetDocument().SetURL(KURL("https://example.com")); - performance_ = - WindowPerformance::Create(page_holder_->GetDocument().domWindow()); - performance_->time_origin_ = GetTimeOrigin(); + ResetPerformance(); // Create another dummy page holder and pretend this is the iframe. another_page_holder_ = DummyPageHolder::Create(IntSize(400, 300)); @@ -88,6 +84,14 @@ .first; } + void ResetPerformance() { + page_holder_ = DummyPageHolder::Create(IntSize(800, 600)); + page_holder_->GetDocument().SetURL(KURL("https://example.com")); + performance_ = + WindowPerformance::Create(page_holder_->GetDocument().domWindow()); + performance_->time_origin_ = GetTimeOrigin(); + } + Persistent<WindowPerformance> performance_; std::unique_ptr<DummyPageHolder> page_holder_; std::unique_ptr<DummyPageHolder> another_page_holder_; @@ -296,4 +300,63 @@ performance_->getEntriesByName("click", "event").size()); } +// Test for existence of 'firstInput' given different types of first events. +TEST_F(WindowPerformanceTest, FirstInput) { + struct { + String event_type; + bool should_report; + } inputs[] = {{"click", true}, {"keydown", true}, + {"keypress", false}, {"pointerdown", false}, + {"mousedown", true}, {"mousemove", false}, + {"mouseover", false}}; + for (const auto& input : inputs) { + // firstInput does not have a |duration| threshold so use close values. + performance_->RegisterEventTiming( + input.event_type, GetTimeOrigin(), + GetTimeOrigin() + TimeDelta::FromMilliseconds(1), + GetTimeOrigin() + TimeDelta::FromMilliseconds(2), false); + SimulateSwapPromise(GetTimeOrigin() + TimeDelta::FromMilliseconds(3)); + PerformanceEntryVector firstInputs = + performance_->getEntriesByType("firstInput"); + EXPECT_GE(1u, firstInputs.size()); + EXPECT_EQ(input.should_report, firstInputs.size() == 1u); + ResetPerformance(); + } +} + +// Test that the 'firstInput' is populated after some irrelevant events are +// ignored. +TEST_F(WindowPerformanceTest, FirstInputAfterIgnored) { + String several_events[] = {"mousemove", "mouseover", "mousedown"}; + for (const auto& event : several_events) { + performance_->RegisterEventTiming( + event, GetTimeOrigin(), + GetTimeOrigin() + TimeDelta::FromMilliseconds(1), + GetTimeOrigin() + TimeDelta::FromMilliseconds(2), false); + } + SimulateSwapPromise(GetTimeOrigin() + TimeDelta::FromMilliseconds(3)); + ASSERT_EQ(1u, performance_->getEntriesByType("firstInput").size()); + EXPECT_EQ("mousedown", + performance_->getEntriesByType("firstInput")[0]->name()); +} + +// Test that pointerdown followed by pointerup works as a 'firstInput'. +TEST_F(WindowPerformanceTest, FirstPointerUp) { + TimeTicks start_time = GetTimeOrigin(); + TimeTicks processing_start = GetTimeOrigin() + TimeDelta::FromMilliseconds(1); + TimeTicks processing_end = GetTimeOrigin() + TimeDelta::FromMilliseconds(2); + TimeTicks swap_time = GetTimeOrigin() + TimeDelta::FromMilliseconds(3); + performance_->RegisterEventTiming("pointerdown", start_time, processing_start, + processing_end, false); + SimulateSwapPromise(swap_time); + EXPECT_EQ(0u, performance_->getEntriesByType("firstInput").size()); + performance_->RegisterEventTiming("pointerup", start_time, processing_start, + processing_end, false); + SimulateSwapPromise(swap_time); + EXPECT_EQ(1u, performance_->getEntriesByType("firstInput").size()); + // The name of the entry should be "pointerdown". + EXPECT_EQ(1u, + performance_->getEntriesByName("pointerdown", "firstInput").size()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc index d88f026..e7bb578 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h" #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
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 9744de3..d0539f6 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
@@ -28,6 +28,10 @@ #include <libxml/parser.h> #include <libxml/parserInternals.h> +#include <libxml/xmlversion.h> +#if defined(LIBXML_CATALOG_ENABLED) +#include <libxml/catalog.h> +#endif #include <libxslt/xslt.h> #include <memory> @@ -648,6 +652,9 @@ if (did_init) return; +#if defined(LIBXML_CATALOG_ENABLED) + xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE); +#endif xmlInitParser(); xmlRegisterInputCallbacks(MatchFunc, OpenFunc, ReadFunc, CloseFunc); xmlRegisterOutputCallbacks(MatchFunc, OpenFunc, WriteFunc, CloseFunc);
diff --git a/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js b/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js index 866c93e..6108fd70 100644 --- a/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js +++ b/third_party/blink/renderer/devtools/front_end/network/RequestHTMLView.js
@@ -64,6 +64,7 @@ iframe.className = 'html-preview-frame'; iframe.setAttribute('sandbox', ''); // Forbid to run JavaScript and set unique origin. iframe.setAttribute('src', this._dataURL); + iframe.setAttribute('tabIndex', -1); this.contentElement.appendChild(iframe); } };
diff --git a/third_party/blink/renderer/devtools/front_end/network/requestHTMLView.css b/third_party/blink/renderer/devtools/front_end/network/requestHTMLView.css index dac6625..a71ebee 100644 --- a/third_party/blink/renderer/devtools/front_end/network/requestHTMLView.css +++ b/third_party/blink/renderer/devtools/front_end/network/requestHTMLView.css
@@ -7,5 +7,4 @@ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); flex-grow: 1; margin: 20px; - pointer-events: none; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 33b98bf..759ff2f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/dom/accessible_node.h" #include "third_party/blink/renderer/core/dom/accessible_node_list.h" +#include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/editing/editing_utilities.h" #include "third_party/blink/renderer/core/editing/visible_position.h" @@ -474,6 +475,8 @@ cached_has_inherited_presentational_role_(false), cached_is_editable_root_(false), cached_live_region_root_(nullptr), + cached_aria_column_index_(0), + cached_aria_row_index_(0), ax_object_cache_(&ax_object_cache) { ++number_of_live_ax_objects_; } @@ -869,6 +872,8 @@ ? const_cast<AXObject*>(this) : (ParentObjectIfExists() ? ParentObjectIfExists()->LiveRegionRoot() : nullptr); + cached_aria_column_index_ = ComputeAriaColumnIndex(); + cached_aria_row_index_ = ComputeAriaRowIndex(); // TODO(dmazzoni): remove this const_cast. if (cached_is_ignored_ != LastKnownIsIgnoredValue()) { const_cast<AXObject*>(this)->ChildrenChanged(); @@ -2503,71 +2508,94 @@ } unsigned AXObject::AriaColumnIndex() const { + UpdateCachedAttributeValuesIfNeeded(); + return cached_aria_column_index_; +} + +unsigned AXObject::AriaRowIndex() const { + UpdateCachedAttributeValuesIfNeeded(); + return cached_aria_row_index_; +} + +unsigned AXObject::ComputeAriaColumnIndex() const { if (!IsTableCellLikeRole()) return 0; + // First see if it has an ARIA column index explicitly set. uint32_t col_index; if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, col_index) && col_index >= 1) { return col_index; } + // Get the previous sibling. + // TODO(dmazzoni): this code depends on the DOM; move this code out of Blink + // and make it more general. + AXObject* previous = nullptr; + if (GetNode()) { + Node* previousNode = ElementTraversal::PreviousSibling(*GetNode()); + previous = AXObjectCache().GetOrCreate(previousNode); + } + + // It has a previous sibling, so if that cell has a column index, this one's + // index is one greater. + if (previous) { + col_index = previous->AriaColumnIndex(); + if (col_index) + return col_index + 1; + return 0; + } + + // No previous cell, so check the row to see if it sets a column index. const AXObject* row = TableRowParent(); if (!row) return 0; - - if (!row->HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, - col_index)) - col_index = 0; - for (const auto& child : row->TableCellChildren()) { - if (child == this) - break; - unsigned child_aria_column_index = child->AriaColumnIndex(); - if (child_aria_column_index) - col_index = child_aria_column_index; - if (col_index > 0) - col_index++; + if (row->HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, + col_index)) { + return col_index; } - return col_index; + + // Otherwise there's no ARIA column index. + return 0; } -unsigned AXObject::AriaRowIndex() const { - const AXObject* row; - if (IsTableCellLikeRole()) - row = TableRowParent(); - else if (IsTableRowLikeRole()) - row = this; - else +unsigned AXObject::ComputeAriaRowIndex() const { + if (!IsTableCellLikeRole() && !IsTableRowLikeRole()) return 0; + // First check if there's an ARIA row index explicitly set. uint32_t row_index; if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kRowIndex, row_index) && row_index >= 1) { return row_index; } - if (row != this && - row->HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kRowIndex, - row_index) && - row_index >= 1) { - return row_index; + // If this is a cell, return the ARIA row index of the containing row. + if (IsTableCellLikeRole()) { + const AXObject* row = TableRowParent(); + if (row) + return row->AriaRowIndex(); + return 0; } - const AXObject* table = row->TableParent(); - if (!table) + // Otherwise, this is a row. Find the previous sibling row. + // TODO(dmazzoni): this code depends on the DOM; move this code out of Blink + // and make it more general. + if (!GetNode()) + return 0; + Node* previousNode = ElementTraversal::PreviousSibling(*GetNode()); + AXObject* previous = AXObjectCache().GetOrCreate(previousNode); + if (!previous || !previous->IsTableRowLikeRole()) return 0; - row_index = 0; - for (const auto& child : table->TableRowChildren()) { - if (child == row) - break; - unsigned child_aria_row_index = child->AriaRowIndex(); - if (child_aria_row_index) - row_index = child_aria_row_index; - if (row_index > 0) - row_index++; - } - return row_index; + // If the previous row has an ARIA row index, this one is the same index + // plus one. + row_index = previous->AriaRowIndex(); + if (row_index) + return row_index + 1; + + // Otherwise there's no ARIA row index. + return 0; } AXObject::AXObjectVector AXObject::TableRowChildren() const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index d2d09ca..1d43fd9a 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -1054,6 +1054,8 @@ mutable bool cached_has_inherited_presentational_role_ : 1; mutable bool cached_is_editable_root_; mutable Member<AXObject> cached_live_region_root_; + mutable int cached_aria_column_index_; + mutable int cached_aria_row_index_; Member<AXObjectCacheImpl> ax_object_cache_; @@ -1070,6 +1072,8 @@ static bool IncludesARIAWidgetRole(const String&); static bool HasInteractiveARIAAttribute(const Element&); AccessibilityRole RemapAriaRoleDueToParent(AccessibilityRole) const; + unsigned ComputeAriaColumnIndex() const; + unsigned ComputeAriaRowIndex() const; static unsigned number_of_live_ax_objects_;
diff --git a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc index d401c15..8bd0f35 100644 --- a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc +++ b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/events/message_event.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -116,7 +116,7 @@ : ContextLifecycleObserver(execution_context), origin_(execution_context->GetSecurityOrigin()), event_queue_( - EventQueueImpl::Create(execution_context, TaskType::kInternalMedia)), + EventQueue::Create(execution_context, TaskType::kInternalMedia)), name_(name), binding_(this) { mojom::blink::BroadcastChannelProviderPtr& provider =
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc b/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc index 24f86d7..18cbec9a 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc +++ b/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/cookie_store/cookie_change_event.h" +#include "third_party/blink/renderer/core/dom/dom_time_stamp.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_change_event_init.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h" #include "third_party/blink/renderer/modules/event_modules.h" @@ -42,4 +43,56 @@ deleted_ = initializer.deleted(); } +// static +void CookieChangeEvent::ToCookieListItem( + const WebCanonicalCookie& canonical_cookie, + bool is_deleted, // True for the information from a cookie deletion event. + CookieListItem& list_item) { + list_item.setName(canonical_cookie.Name()); + list_item.setPath(canonical_cookie.Path()); + list_item.setSecure(canonical_cookie.IsSecure()); + + // The domain of host-only cookies is the host name, without a dot (.) prefix. + String cookie_domain = canonical_cookie.Domain(); + if (cookie_domain.StartsWith(".")) + list_item.setDomain(cookie_domain.Substring(1)); + + if (!is_deleted) { + list_item.setValue(canonical_cookie.Value()); + if (!canonical_cookie.ExpiryDate().is_null()) { + list_item.setExpires(ConvertSecondsToDOMTimeStamp( + canonical_cookie.ExpiryDate().ToDoubleT())); + } + } +} + +// static +void CookieChangeEvent::ToEventInfo( + const WebCanonicalCookie& backend_cookie, + ::network::mojom::CookieChangeCause change_cause, + HeapVector<CookieListItem>& changed, + HeapVector<CookieListItem>& deleted) { + switch (change_cause) { + case ::network::mojom::CookieChangeCause::INSERTED: + case ::network::mojom::CookieChangeCause::EXPLICIT: { + CookieListItem& cookie = changed.emplace_back(); + ToCookieListItem(backend_cookie, false /* is_deleted */, cookie); + break; + } + case ::network::mojom::CookieChangeCause::UNKNOWN_DELETION: + case ::network::mojom::CookieChangeCause::EXPIRED: + case ::network::mojom::CookieChangeCause::EVICTED: + case ::network::mojom::CookieChangeCause::EXPIRED_OVERWRITE: { + CookieListItem& cookie = deleted.emplace_back(); + ToCookieListItem(backend_cookie, true /* is_deleted */, cookie); + break; + } + + case ::network::mojom::CookieChangeCause::OVERWRITE: + // A cookie overwrite causes an OVERWRITE (meaning the old cookie was + // deleted) and an INSERTED. + break; + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h b/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h index 9784240..0778a30 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h +++ b/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_CHANGE_EVENT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_CHANGE_EVENT_H_ +#include "third_party/blink/public/platform/web_canonical_cookie.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -48,6 +49,17 @@ // GarbageCollected void Trace(blink::Visitor*) override; + static void ToCookieListItem( + const WebCanonicalCookie& canonical_cookie, + bool is_deleted, // True for information from a cookie deletion event. + CookieListItem& cookie); + + // Helper for converting backend event information into a CookieChangeEvent. + static void ToEventInfo(const WebCanonicalCookie& cookie, + ::network::mojom::CookieChangeCause cause, + HeapVector<CookieListItem>& changed, + HeapVector<CookieListItem>& deleted); + private: CookieChangeEvent(); CookieChangeEvent(const AtomicString& type,
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl b/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl index e9d0618..17c9128 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl +++ b/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl
@@ -7,6 +7,10 @@ dictionary CookieListItem { USVString name; USVString value; + USVString? domain; + USVString path; + DOMTimeStamp? expires; + boolean secure; }; typedef sequence<CookieListItem> CookieList;
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc index 41bbdf3..3fd1c87 100644 --- a/third_party/blink/renderer/modules/cookie_store/cookie_store.cc +++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.cc
@@ -130,7 +130,7 @@ if (name.IsEmpty() && value.Contains('=')) { exception_state.ThrowTypeError( - "Cookie value cannot contain '=' if the name is empty."); + "Cookie value cannot contain '=' if the name is empty"); return base::nullopt; } @@ -141,13 +141,27 @@ } } + String cookie_url_host = cookie_url.Host(); String domain; if (options.hasDomain()) { - // TODO(crbug.com/729800): Checks and exception throwing. - domain = options.domain(); + // The leading dot (".") from the domain attribute is stripped in the + // Set-Cookie header, for compatibility. This API doesn't have compatibility + // constraints, so reject the edge case outright. + if (options.domain().StartsWith(".")) { + exception_state.ThrowTypeError("Cookie domain cannot start with \".\""); + return base::nullopt; + } + + domain = String(".") + options.domain(); + if (!cookie_url_host.EndsWith(domain) && + cookie_url_host != options.domain()) { + exception_state.ThrowTypeError( + "Cookie domain must domain-match current host"); + return base::nullopt; + } } else { - // TODO(crbug.com/729800): Correct value? - domain = cookie_url.Host(); + // The absence of "domain" implies a host-only cookie. + domain = cookie_url_host; } const String path = options.hasPath() ? options.path() : String("/"); @@ -213,15 +227,6 @@ return backend_subscription; } -void ToCookieListItem( - const WebCanonicalCookie& canonical_cookie, - bool is_deleted, // True for the information from a cookie deletion event. - CookieListItem& cookie) { - cookie.setName(canonical_cookie.Name()); - if (!is_deleted) - cookie.setValue(canonical_cookie.Value()); -} - void ToCookieChangeSubscription( const blink::mojom::blink::CookieChangeSubscription& backend_subscription, CookieStoreGetOptions& subscription) { @@ -439,34 +444,12 @@ const WebCanonicalCookie& backend_cookie, network::mojom::blink::CookieChangeCause change_cause) { HeapVector<CookieListItem> changed, deleted; - - switch (change_cause) { - case ::network::mojom::blink::CookieChangeCause::INSERTED: - case ::network::mojom::blink::CookieChangeCause::EXPLICIT: { - CookieListItem& cookie = changed.emplace_back(); - ToCookieListItem(backend_cookie, false /* is_deleted */, cookie); - break; - } - case ::network::mojom::blink::CookieChangeCause::UNKNOWN_DELETION: - case ::network::mojom::blink::CookieChangeCause::EXPIRED: - case ::network::mojom::blink::CookieChangeCause::EVICTED: - case ::network::mojom::blink::CookieChangeCause::EXPIRED_OVERWRITE: { - CookieListItem& cookie = deleted.emplace_back(); - ToCookieListItem(backend_cookie, true /* is_deleted */, cookie); - break; - } - - case ::network::mojom::blink::CookieChangeCause::OVERWRITE: - // A cookie overwrite causes an OVERWRITE (meaning the old cookie was - // deleted) and an INSERTED. - break; - } - + CookieChangeEvent::ToEventInfo(backend_cookie, change_cause, changed, + deleted); if (changed.IsEmpty() && deleted.IsEmpty()) { // The backend only reported OVERWRITE events, which are dropped. return; } - DispatchEvent(CookieChangeEvent::Create( EventTypeNames::change, std::move(changed), std::move(deleted))); } @@ -538,9 +521,10 @@ HeapVector<CookieListItem> cookies; cookies.ReserveInitialCapacity(backend_cookies.size()); - for (const auto& canonical_cookie : backend_cookies) { + for (const auto& backend_cookie : backend_cookies) { CookieListItem& cookie = cookies.emplace_back(); - ToCookieListItem(canonical_cookie, false /* is_deleted */, cookie); + CookieChangeEvent::ToCookieListItem(backend_cookie, false /* is_deleted */, + cookie); } resolver->Resolve(std::move(cookies)); @@ -559,9 +543,10 @@ return; } - const auto& canonical_cookie = backend_cookies.front(); + const auto& backend_cookie = backend_cookies.front(); CookieListItem cookie; - ToCookieListItem(canonical_cookie, false /* is_deleted */, cookie); + CookieChangeEvent::ToCookieListItem(backend_cookie, false /* is_deleted */, + cookie); resolver->Resolve(cookie); }
diff --git a/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc b/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc index 6de8c05..f0480ad3 100644 --- a/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc +++ b/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc
@@ -45,21 +45,4 @@ deleted_ = initializer.deleted(); } -// static -void ExtendableCookieChangeEvent::ToCookieChangeListItem( - const WebString& cookie_name, - const WebString& cookie_value, - bool is_cookie_delete, - HeapVector<CookieListItem>& changed, - HeapVector<CookieListItem>& deleted) { - if (is_cookie_delete) { - CookieListItem& cookie = deleted.emplace_back(); - cookie.setName(cookie_name); - } else { - CookieListItem& cookie = changed.emplace_back(); - cookie.setName(cookie_name); - cookie.setValue(cookie_value); - } -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h b/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h index af810bf..121efdaf 100644 --- a/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h +++ b/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h
@@ -16,7 +16,6 @@ class ExtendableCookieChangeEventInit; class WaitUntilObserver; -class WebString; class ExtendableCookieChangeEvent final : public ExtendableEvent { DEFINE_WRAPPERTYPEINFO(); @@ -53,16 +52,6 @@ // GarbageCollected void Trace(blink::Visitor*) override; - // Helper for converting backend event information into a CookieChangeEvent. - // - // TODO(pwnall): Switch to blink::CanonicalCookie when - // https://crrev.com/c/991196 lands. - static void ToCookieChangeListItem(const WebString& cookie_name, - const WebString& cookie_value, - bool is_cookie_delete, - HeapVector<CookieListItem>& changed, - HeapVector<CookieListItem>& deleted); - private: ExtendableCookieChangeEvent(const AtomicString& type, HeapVector<CookieListItem> changed,
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc index 142009f..9b6209e3 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc
@@ -38,7 +38,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h" @@ -329,8 +329,8 @@ MediaKeys* media_keys, WebEncryptedMediaSessionType session_type) : ContextLifecycleObserver(ExecutionContext::From(script_state)), - async_event_queue_(EventQueueImpl::Create(GetExecutionContext(), - TaskType::kMediaElementEvent)), + async_event_queue_(EventQueue::Create(GetExecutionContext(), + TaskType::kMediaElementEvent)), media_keys_(media_keys), session_type_(session_type), expiration_(std::numeric_limits<double>::quiet_NaN()),
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/third_party/blink/renderer/modules/indexeddb/idb_database.cc index f9288a0..75ccc9d 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_database.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -35,7 +35,7 @@ #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_callback.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/indexeddb/idb_any.h" #include "third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.h" @@ -108,8 +108,7 @@ v8::Isolate* isolate) : ContextLifecycleObserver(context), backend_(std::move(backend)), - event_queue_( - EventQueueImpl::Create(context, TaskType::kInternalIndexedDB)), + event_queue_(EventQueue::Create(context, TaskType::kInternalIndexedDB)), database_callbacks_(callbacks), isolate_(isolate) { database_callbacks_->Connect(this);
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc index 9ea7f8b..49cdcc0 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -38,7 +38,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" #include "third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h" @@ -138,8 +138,8 @@ isolate_(script_state->GetIsolate()), metrics_(std::move(metrics)), source_(source), - event_queue_(EventQueueImpl::Create(ExecutionContext::From(script_state), - TaskType::kInternalIndexedDB)) {} + event_queue_(EventQueue::Create(ExecutionContext::From(script_state), + TaskType::kInternalIndexedDB)) {} IDBRequest::~IDBRequest() { DCHECK((ready_state_ == DONE && metrics_.IsEmpty()) ||
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc b/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc index 1211545..68b3d5d5 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
@@ -26,7 +26,7 @@ #include "third_party/blink/renderer/modules/indexeddb/idb_transaction.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database.h" @@ -90,8 +90,8 @@ mode_(kWebIDBTransactionModeReadOnly), scope_(scope), state_(kActive), - event_queue_(EventQueueImpl::Create(execution_context, - TaskType::kInternalIndexedDB)) { + event_queue_( + EventQueue::Create(execution_context, TaskType::kInternalIndexedDB)) { DCHECK(database_); DCHECK(!scope_.IsEmpty()) << "Observer transactions must operate " "on a well-defined set of stores"; @@ -108,8 +108,8 @@ database_(db), mode_(mode), scope_(scope), - event_queue_(EventQueueImpl::Create(ExecutionContext::From(script_state), - TaskType::kInternalIndexedDB)) { + event_queue_(EventQueue::Create(ExecutionContext::From(script_state), + TaskType::kInternalIndexedDB)) { DCHECK(database_); DCHECK(!scope_.IsEmpty()) << "Non-versionchange transactions must operate " "on a well-defined set of stores"; @@ -137,8 +137,8 @@ mode_(kWebIDBTransactionModeVersionChange), state_(kInactive), old_database_metadata_(old_metadata), - event_queue_(EventQueueImpl::Create(execution_context, - TaskType::kInternalIndexedDB)) { + event_queue_( + EventQueue::Create(execution_context, TaskType::kInternalIndexedDB)) { DCHECK(database_); DCHECK(open_db_request_); DCHECK(scope_.IsEmpty());
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc index 64a0cf4..71df829 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -135,7 +135,7 @@ const char kSizingLargeCSSClass[] = "sizing-large"; // The minimum width in pixels to reach a given size. -constexpr int kSizingMediumThreshold = 641; +constexpr int kSizingMediumThreshold = 741; constexpr int kSizingLargeThreshold = 1441; // Used for setting overlay play button width CSS variable. @@ -1354,8 +1354,8 @@ int width = size_.Width(); int height = size_.Height(); - double play_button_width = - std::max(kMinOverlayPlayButtonWidth, std::min(width * 0.3, height * 0.3)); + double play_button_width = std::max(kMinOverlayPlayButtonWidth, + std::min(width * 0.25, height * 0.25)); WTF::String play_button_css_value = WTF::String::Number(play_button_width); play_button_css_value.append("px");
diff --git a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css index 1bec0051..fbeed38 100644 --- a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css +++ b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
@@ -215,10 +215,10 @@ video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-mute-button" i], video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-fullscreen-button" i], video::-webkit-media-controls.sizing-medium input[pseudo="-internal-media-controls-overflow-button" i] { - width: 96px; - height: 96px; - min-width: 96px; - background-size: 48px; + width: 64px; + height: 64px; + min-width: 64px; + background-size: 32px; } video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-play-button" i], @@ -238,8 +238,8 @@ } video::-webkit-media-controls.sizing-medium div[pseudo="-internal-media-controls-button-panel" i] { - height: 96px; - line-height: 96px; + height: 64px; + line-height: 64px; padding: 0 32px 0 64px; } @@ -408,7 +408,7 @@ } video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-overlay-play-button" i] { - margin-bottom: -96px; + margin-bottom: -64px; } video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-overlay-play-button" i] {
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc index 376cadc..f3a1152 100644 --- a/third_party/blink/renderer/modules/mediasource/media_source.cc +++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -36,7 +36,7 @@ #include "third_party/blink/public/platform/web_media_source.h" #include "third_party/blink/public/platform/web_source_buffer.h" #include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" @@ -114,7 +114,7 @@ : ContextLifecycleObserver(context), ready_state_(ClosedKeyword()), async_event_queue_( - EventQueueImpl::Create(context, TaskType::kMediaElementEvent)), + EventQueue::Create(context, TaskType::kMediaElementEvent)), attached_element_(nullptr), source_buffers_(SourceBufferList::Create(GetExecutionContext(), async_event_queue_.Get())),
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/third_party/blink/renderer/modules/mediasource/source_buffer.cc index 5fe52c2..aac2e732 100644 --- a/third_party/blink/renderer/modules/mediasource/source_buffer.cc +++ b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -37,7 +37,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_source_buffer.h" #include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h" +#include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/use_counter.h"
diff --git a/third_party/blink/renderer/modules/payments/basic_card_helper.cc b/third_party/blink/renderer/modules/payments/basic_card_helper.cc index e0a7d16..3d3511a 100644 --- a/third_party/blink/renderer/modules/payments/basic_card_helper.cc +++ b/third_party/blink/renderer/modules/payments/basic_card_helper.cc
@@ -84,9 +84,9 @@ } } -bool BasicCardHelper::ContainsNetworkNames(const Vector<String>& input) { +bool BasicCardHelper::IsNetworkName(const String& input) { for (size_t i = 0; i < arraysize(kBasicCardNetworks); ++i) { - if (input.Contains(kBasicCardNetworks[i].name)) { + if (input == kBasicCardNetworks[i].name) { return true; } }
diff --git a/third_party/blink/renderer/modules/payments/basic_card_helper.h b/third_party/blink/renderer/modules/payments/basic_card_helper.h index 92ed712..48d7418 100644 --- a/third_party/blink/renderer/modules/payments/basic_card_helper.h +++ b/third_party/blink/renderer/modules/payments/basic_card_helper.h
@@ -27,8 +27,8 @@ Vector<::payments::mojom::blink::BasicCardType>& supported_types_output, ExceptionState&); - // Check whether |input| contains 'basic-card' network names. - static bool ContainsNetworkNames(const Vector<String>& input); + // Check whether |input| is 'basic-card' network name. + static bool IsNetworkName(const String& input); }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_details_modifier.idl b/third_party/blink/renderer/modules/payments/payment_details_modifier.idl index 0da69ce..9eb9208 100644 --- a/third_party/blink/renderer/modules/payments/payment_details_modifier.idl +++ b/third_party/blink/renderer/modules/payments/payment_details_modifier.idl
@@ -5,15 +5,7 @@ // https://w3c.github.io/browser-payment-api/#idl-def-paymentdetailsmodifier dictionary PaymentDetailsModifier { - // TODO(zino): The supportedMethods's type was changed from - // sequence<DOMString> to DOMString[1][2]. But we are not sure if we can - // remove them now. So, we will define it as union type of DOMString and - // sequence<DOMString> temporarily for now. - // Please see: https://crbug.com/754779 - // - // [1] https://github.com/w3c/browser-payment-api/pull/551 - // [2] https://w3c.github.io/browser-payment-api/#paymentdetailsmodifier-dictionary - required (DOMString or sequence<DOMString>) supportedMethods; + [ImplementedAs=supportedMethod] required DOMString supportedMethods; PaymentItem total; sequence<PaymentItem> additionalDisplayItems; [RuntimeEnabled=PaymentDetailsModifierData] object data;
diff --git a/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc b/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc index 0e02dcf..f966452 100644 --- a/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc +++ b/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc
@@ -37,12 +37,7 @@ ScriptState* script_state, const WebPaymentDetailsModifier& web_modifier) { PaymentDetailsModifier modifier; - Vector<String> supported_methods; - for (const auto& web_method : web_modifier.supported_methods) { - supported_methods.push_back(web_method); - } - modifier.setSupportedMethods( - StringOrStringSequence::FromStringSequence(supported_methods)); + modifier.setSupportedMethod(web_modifier.supported_method); modifier.setTotal(ToPaymentItem(web_modifier.total)); HeapVector<PaymentItem> additional_display_items; for (const auto& web_item : web_modifier.additional_display_items) { @@ -71,12 +66,7 @@ ScriptState* script_state, const WebPaymentMethodData& web_method_data) { PaymentMethodData method_data; - Vector<String> supported_methods; - for (const auto& method : web_method_data.supported_methods) { - supported_methods.push_back(method); - } - method_data.setSupportedMethods( - StringOrStringSequence::FromStringSequence(supported_methods)); + method_data.setSupportedMethod(web_method_data.supported_method); method_data.setData( StringDataToScriptValue(script_state, web_method_data.stringified_data)); return method_data;
diff --git a/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc b/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc index c541cc8..3f0109f 100644 --- a/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc +++ b/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc
@@ -24,8 +24,7 @@ static WebPaymentMethodData CreateWebPaymentMethodDataForTest() { WebPaymentMethodData web_method_data; - WebString method = WebString::FromUTF8("foo"); - web_method_data.supported_methods = WebVector<WebString>(&method, 1); + web_method_data.supported_method = "foo"; web_method_data.stringified_data = "{\"merchantId\":\"12345\"}"; return web_method_data; } @@ -69,17 +68,8 @@ ASSERT_TRUE(data.hasMethodData()); ASSERT_EQ(1UL, data.methodData().size()); - ASSERT_TRUE(data.methodData().front().hasSupportedMethods()); - ASSERT_EQ(1UL, data.methodData() - .front() - .supportedMethods() - .GetAsStringSequence() - .size()); - ASSERT_EQ("foo", data.methodData() - .front() - .supportedMethods() - .GetAsStringSequence() - .front()); + ASSERT_TRUE(data.methodData().front().hasSupportedMethod()); + ASSERT_EQ("foo", data.methodData().front().supportedMethod()); ASSERT_TRUE(data.methodData().front().hasData()); ASSERT_TRUE(data.methodData().front().data().IsObject()); String stringified_data = ToBlinkString<String>( @@ -110,17 +100,8 @@ ASSERT_TRUE(data.hasMethodData()); ASSERT_EQ(1UL, data.methodData().size()); - ASSERT_TRUE(data.methodData().front().hasSupportedMethods()); - ASSERT_EQ(1UL, data.methodData() - .front() - .supportedMethods() - .GetAsStringSequence() - .size()); - ASSERT_EQ("foo", data.methodData() - .front() - .supportedMethods() - .GetAsStringSequence() - .front()); + ASSERT_TRUE(data.methodData().front().hasSupportedMethod()); + ASSERT_EQ("foo", data.methodData().front().supportedMethod()); ASSERT_TRUE(data.methodData().front().hasData()); ASSERT_TRUE(data.methodData().front().data().IsObject()); String stringified_data = ToBlinkString<String>(
diff --git a/third_party/blink/renderer/modules/payments/payment_method_data.idl b/third_party/blink/renderer/modules/payments/payment_method_data.idl index 4cd8cfc..be09a4c 100644 --- a/third_party/blink/renderer/modules/payments/payment_method_data.idl +++ b/third_party/blink/renderer/modules/payments/payment_method_data.idl
@@ -5,14 +5,6 @@ // https://w3c.github.io/browser-payment-api/#idl-def-paymentmethoddata dictionary PaymentMethodData { - // TODO(zino): The supportedMethods's type was changed from - // sequence<DOMString> to DOMString[1][2]. But we are not sure if we can - // remove them now. So, we will define it as union type of DOMString and - // sequence<DOMString> temporarily for now. - // Please see: https://crbug.com/754779 - // - // [1] https://github.com/w3c/browser-payment-api/pull/551 - // [2] https://w3c.github.io/browser-payment-api/#paymentdetailsmodifier-dictionary - required (DOMString or sequence<DOMString>) supportedMethods; + [ImplementedAs=supportedMethod] required DOMString supportedMethods; object data; };
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc index cd98927..19bcf6e 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -417,11 +417,10 @@ output->supported_types, exception_state); } -void StringifyAndParseMethodSpecificData( - const Vector<String>& supported_methods, - const ScriptValue& input, - PaymentMethodDataPtr& output, - ExceptionState& exception_state) { +void StringifyAndParseMethodSpecificData(const String& supported_method, + const ScriptValue& input, + PaymentMethodDataPtr& output, + ExceptionState& exception_state) { DCHECK(!input.IsEmpty()); v8::Local<v8::String> value; if (!input.V8Value()->IsObject() || @@ -445,24 +444,24 @@ // Serialize payment method specific data to be sent to the payment apps. The // payment apps are responsible for validating and processing their method // data asynchronously. Do not throw exceptions here. - if (supported_methods.Contains("https://android.com/pay") || - supported_methods.Contains("https://google.com/pay")) { + if (supported_method == "https://android.com/pay" || + supported_method == "https://google.com/pay") { SetAndroidPayMethodData(input, output, exception_state); if (exception_state.HadException()) exception_state.ClearException(); } if (RuntimeEnabledFeatures::PaymentRequestBasicCardEnabled() && - supported_methods.Contains("basic-card")) { + supported_method == "basic-card") { SetBasicCardMethodData(input, output, exception_state); if (exception_state.HadException()) exception_state.ClearException(); } } -void CountPaymentRequestNetworkNameInSupportedMethods( - const Vector<String>& supported_methods, +void CountPaymentRequestNetworkNameInSupportedMethod( + const String& supported_method, ExecutionContext& execution_context) { - if (BasicCardHelper::ContainsNetworkNames(supported_methods)) { + if (BasicCardHelper::IsNetworkName(supported_method)) { Deprecation::CountDeprecation( &execution_context, WebFeature::kPaymentRequestNetworkNameInSupportedMethods); @@ -516,54 +515,28 @@ return; } - Vector<String> supported_methods; - if (modifier.supportedMethods().IsString()) { - supported_methods.push_back(modifier.supportedMethods().GetAsString()); - } - if (modifier.supportedMethods().IsStringSequence()) { - supported_methods = modifier.supportedMethods().GetAsStringSequence(); - if (supported_methods.size() > 1) { - Deprecation::CountDeprecation( - &execution_context, - WebFeature::kPaymentRequestSupportedMethodsArray); - } - } - if (supported_methods.IsEmpty()) { - exception_state.ThrowTypeError( - "Must specify at least one payment method identifier"); + if (!IsValidMethodFormat(modifier.supportedMethod())) { + exception_state.ThrowRangeError( + "Invalid payment method identifier format"); return; } - if (supported_methods.size() > PaymentRequest::kMaxListSize) { - exception_state.ThrowTypeError( - "At most 1024 supportedMethods allowed for modifier"); - return; - } - - for (const String& method : supported_methods) { - if (method.length() > PaymentRequest::kMaxStringLength) { - exception_state.ThrowTypeError( - "Supported method name for identifier cannot be longer than 1024 " - "characters"); - return; - } - if (!IsValidMethodFormat(method)) { - exception_state.ThrowRangeError( - "Invalid payment method identifier format"); - return; - } - } - CountPaymentRequestNetworkNameInSupportedMethods(supported_methods, - execution_context); + CountPaymentRequestNetworkNameInSupportedMethod(modifier.supportedMethod(), + execution_context); output.back()->method_data = payments::mojom::blink::PaymentMethodData::New(); - output.back()->method_data->supported_methods = supported_methods; + + // TODO(zino): We should replace supported_methods with supported_method in + // mojom and browser side (including a bunch of tests). + // Please see https://crbug.com/754779 + output.back()->method_data->supported_methods = { + modifier.supportedMethod()}; if (modifier.hasData() && !modifier.data().IsEmpty()) { - StringifyAndParseMethodSpecificData(supported_methods, modifier.data(), - output.back()->method_data, - exception_state); + StringifyAndParseMethodSpecificData( + modifier.supportedMethod(), modifier.data(), + output.back()->method_data, exception_state); } else { output.back()->method_data->stringified_data = ""; } @@ -670,57 +643,26 @@ } for (const PaymentMethodData payment_method_data : input) { - Vector<String> supported_methods; - if (payment_method_data.supportedMethods().IsString()) { - supported_methods.push_back( - payment_method_data.supportedMethods().GetAsString()); - } - if (payment_method_data.supportedMethods().IsStringSequence()) { - supported_methods = - payment_method_data.supportedMethods().GetAsStringSequence(); - if (supported_methods.size() > 1) { - Deprecation::CountDeprecation( - &execution_context, - WebFeature::kPaymentRequestSupportedMethodsArray); - } - } - if (supported_methods.IsEmpty()) { - exception_state.ThrowTypeError( - "Each payment method needs to include at least one payment method " - "identifier"); + if (!IsValidMethodFormat(payment_method_data.supportedMethod())) { + exception_state.ThrowRangeError( + "Invalid payment method identifier format"); return; } + method_names.insert(payment_method_data.supportedMethod()); - if (supported_methods.size() > PaymentRequest::kMaxListSize) { - exception_state.ThrowTypeError( - "At most 1024 payment method identifiers are supported"); - return; - } - - for (const String identifier : supported_methods) { - if (identifier.length() > PaymentRequest::kMaxStringLength) { - exception_state.ThrowTypeError( - "A payment method identifier cannot be longer than 1024 " - "characters"); - return; - } - if (!IsValidMethodFormat(identifier)) { - exception_state.ThrowRangeError( - "Invalid payment method identifier format"); - return; - } - method_names.insert(identifier); - } - - CountPaymentRequestNetworkNameInSupportedMethods(supported_methods, - execution_context); + CountPaymentRequestNetworkNameInSupportedMethod( + payment_method_data.supportedMethod(), execution_context); output.push_back(payments::mojom::blink::PaymentMethodData::New()); - output.back()->supported_methods = supported_methods; + + // TODO(zino): We should replace supported_methods with supported_method in + // mojom and browser side (including a bunch of tests). + // Please see https://crbug.com/754779 + output.back()->supported_methods = {payment_method_data.supportedMethod()}; if (payment_method_data.hasData() && !payment_method_data.data().IsEmpty()) { - StringifyAndParseMethodSpecificData(supported_methods, + StringifyAndParseMethodSpecificData(payment_method_data.supportedMethod(), payment_method_data.data(), output.back(), exception_state); } else {
diff --git a/third_party/blink/renderer/modules/payments/payment_test_helper.cc b/third_party/blink/renderer/modules/payments/payment_test_helper.cc index d778b2c5..6c6b4d3 100644 --- a/third_party/blink/renderer/modules/payments/payment_test_helper.cc +++ b/third_party/blink/renderer/modules/payments/payment_test_helper.cc
@@ -127,9 +127,7 @@ item = BuildPaymentItemForTest(); PaymentDetailsModifier modifier; - StringOrStringSequence supportedMethods; - supportedMethods.SetStringSequence(Vector<String>(1, "foo")); - modifier.setSupportedMethods(supportedMethods); + modifier.setSupportedMethod("foo"); modifier.setTotal(total); modifier.setAdditionalDisplayItems(HeapVector<PaymentItem>(1, item)); return modifier; @@ -185,9 +183,7 @@ HeapVector<PaymentMethodData> BuildPaymentMethodDataForTest() { HeapVector<PaymentMethodData> method_data(1, PaymentMethodData()); - StringOrStringSequence supportedMethods; - supportedMethods.SetStringSequence(Vector<String>(1, "foo")); - method_data[0].setSupportedMethods(supportedMethods); + method_data[0].setSupportedMethod("foo"); return method_data; }
diff --git a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.cc b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.cc index 0e12ad4..8e50f97 100644 --- a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.cc
@@ -61,6 +61,7 @@ #include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event_init.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h" #include "third_party/blink/renderer/modules/background_sync/sync_event.h" +#include "third_party/blink/renderer/modules/cookie_store/cookie_change_event.h" #include "third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h" #include "third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h" #include "third_party/blink/renderer/modules/notifications/notification.h" @@ -258,23 +259,21 @@ void ServiceWorkerGlobalScopeProxy::DispatchCookieChangeEvent( int event_id, - const WebString& cookie_name, - const WebString& cookie_value, - bool is_cookie_delete) { + const WebCanonicalCookie& cookie, + network::mojom::CookieChangeCause change_cause) { DCHECK(WorkerGlobalScope()->IsContextThread()); WaitUntilObserver* observer = WaitUntilObserver::Create( WorkerGlobalScope(), WaitUntilObserver::kCookieChange, event_id); HeapVector<CookieListItem> changed; HeapVector<CookieListItem> deleted; - ExtendableCookieChangeEvent::ToCookieChangeListItem( - cookie_name, cookie_value, is_cookie_delete, changed, deleted); + CookieChangeEvent::ToEventInfo(cookie, change_cause, changed, deleted); Event* event = ExtendableCookieChangeEvent::Create( EventTypeNames::cookiechange, std::move(changed), std::move(deleted), observer); - // TODO(pwnall): When switching to blink::CanonicalCookie, handle the case - // when (changed.IsEmpty() && deleted.IsEmpty()). + // TODO(pwnall): Handle handle the case when + // (changed.IsEmpty() && deleted.IsEmpty()). // TODO(pwnall): Investigate dispatching this on cookieStore. WorkerGlobalScope()->DispatchExtendableEvent(event, observer);
diff --git a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.h b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.h index a012b73a..220b1a5c 100644 --- a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.h +++ b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope_proxy.h
@@ -99,10 +99,10 @@ const WebString& developer_id, const WebString& unique_id, const WebVector<WebBackgroundFetchSettledFetch>& fetches) override; - void DispatchCookieChangeEvent(int event_id, - const WebString& cookie_name, - const WebString& cookie_value, - bool is_cookie_delete) override; + void DispatchCookieChangeEvent( + int event_id, + const WebCanonicalCookie& cookie, + network::mojom::CookieChangeCause change_cause) override; void DispatchExtendableMessageEvent( int event_id, TransferableMessage,
diff --git a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc index d10ae49..2ee1c2ec 100644 --- a/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc +++ b/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
@@ -70,9 +70,9 @@ } detected_barcodes.push_back(DetectedBarcode::Create( barcode->raw_value, - DOMRect::Create(barcode->bounding_box.x, barcode->bounding_box.y, - barcode->bounding_box.width, - barcode->bounding_box.height), + DOMRectReadOnly::Create( + barcode->bounding_box.x, barcode->bounding_box.y, + barcode->bounding_box.width, barcode->bounding_box.height), corner_points)); }
diff --git a/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc b/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc index 5da23bd..402e2f6 100644 --- a/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc +++ b/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc
@@ -10,12 +10,12 @@ DetectedBarcode* DetectedBarcode::Create() { HeapVector<Point2D> empty_list; - return new DetectedBarcode(g_empty_string, DOMRect::Create(0, 0, 0, 0), - empty_list); + return new DetectedBarcode(g_empty_string, + DOMRectReadOnly::Create(0, 0, 0, 0), empty_list); } DetectedBarcode* DetectedBarcode::Create(String raw_value, - DOMRect* bounding_box, + DOMRectReadOnly* bounding_box, HeapVector<Point2D> corner_points) { return new DetectedBarcode(raw_value, bounding_box, corner_points); } @@ -24,7 +24,7 @@ return raw_value_; } -DOMRect* DetectedBarcode::boundingBox() const { +DOMRectReadOnly* DetectedBarcode::boundingBox() const { return bounding_box_.Get(); } @@ -33,7 +33,7 @@ } DetectedBarcode::DetectedBarcode(String raw_value, - DOMRect* bounding_box, + DOMRectReadOnly* bounding_box, HeapVector<Point2D> corner_points) : raw_value_(raw_value), bounding_box_(bounding_box),
diff --git a/third_party/blink/renderer/modules/shapedetection/detected_barcode.h b/third_party/blink/renderer/modules/shapedetection/detected_barcode.h index 18e4575c..69dcfd9 100644 --- a/third_party/blink/renderer/modules/shapedetection/detected_barcode.h +++ b/third_party/blink/renderer/modules/shapedetection/detected_barcode.h
@@ -12,25 +12,25 @@ namespace blink { -class DOMRect; +class DOMRectReadOnly; class MODULES_EXPORT DetectedBarcode final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: static DetectedBarcode* Create(); - static DetectedBarcode* Create(String, DOMRect*, HeapVector<Point2D>); + static DetectedBarcode* Create(String, DOMRectReadOnly*, HeapVector<Point2D>); const String& rawValue() const; - DOMRect* boundingBox() const; + DOMRectReadOnly* boundingBox() const; const HeapVector<Point2D>& cornerPoints() const; void Trace(blink::Visitor*) override; private: - DetectedBarcode(String, DOMRect*, HeapVector<Point2D>); + DetectedBarcode(String, DOMRectReadOnly*, HeapVector<Point2D>); const String raw_value_; - const Member<DOMRect> bounding_box_; + const Member<DOMRectReadOnly> bounding_box_; const HeapVector<Point2D> corner_points_; };
diff --git a/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl b/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl index 6bd2f7b..56951d2c 100644 --- a/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl +++ b/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
@@ -10,7 +10,7 @@ ] interface DetectedBarcode { // TODO(mcasas): Implement missing fields. https://crbug.com/646083 [SameObject] readonly attribute DOMString rawValue; - [SameObject] readonly attribute DOMRect boundingBox; + [SameObject] readonly attribute DOMRectReadOnly boundingBox; // 4 corner points in clockwise direction starting with top-left. Due to // possible perspective distortions, this is not necessarily a rectangle. [SameObject, SaveSameObject] readonly attribute FrozenArray<Point2D> cornerPoints;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/audio_destination_node.cc index d3d89db4..89b4932 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_destination_node.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_destination_node.cc
@@ -43,8 +43,7 @@ DCHECK(!IsInitialized()); } -void AudioDestinationHandler::Render(AudioBus* source_bus, - AudioBus* destination_bus, +void AudioDestinationHandler::Render(AudioBus* destination_bus, size_t number_of_frames, const AudioIOPosition& output_position) { TRACE_EVENT0("webaudio", "AudioDestinationHandler::Render"); @@ -78,10 +77,6 @@ // quantum. Context()->HandlePreRenderTasks(output_position); - // Prepare the local audio input provider for this render quantum. - if (source_bus) - local_audio_input_provider_.Set(source_bus); - DCHECK_GE(NumberOfInputs(), 1u); if (NumberOfInputs() < 1) { destination_bus->Zero();
diff --git a/third_party/blink/renderer/modules/webaudio/audio_destination_node.h b/third_party/blink/renderer/modules/webaudio/audio_destination_node.h index 120edf8..d521c86 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_destination_node.h +++ b/third_party/blink/renderer/modules/webaudio/audio_destination_node.h
@@ -30,7 +30,6 @@ #include "third_party/blink/renderer/modules/webaudio/audio_node.h" #include "third_party/blink/renderer/platform/audio/audio_bus.h" #include "third_party/blink/renderer/platform/audio/audio_io_callback.h" -#include "third_party/blink/renderer/platform/audio/audio_source_provider.h" namespace blink { @@ -46,11 +45,9 @@ void Process(size_t) final { } // we're pulled by hardware so this is never called - // The audio hardware calls render() to get the next render quantum of audio - // into destinationBus. It will optionally give us local/live audio input in - // sourceBus (if it's not 0). - void Render(AudioBus* source_bus, - AudioBus* destination_bus, + // Invoked by the AudioDestination to get the next render quantum into + // |destination_bus|. + void Render(AudioBus* destination_bus, size_t number_of_frames, const AudioIOPosition& output_position) final; @@ -79,42 +76,8 @@ virtual int FramesPerBuffer() const = 0; protected: - // LocalAudioInputProvider allows us to expose an AudioSourceProvider for - // local/live audio input. If there is local/live audio input, we call set() - // with the audio input data every render quantum. - class LocalAudioInputProvider final : public AudioSourceProvider { - public: - LocalAudioInputProvider() - : source_bus_(AudioBus::Create( - 2, - AudioUtilities::kRenderQuantumFrames)) // FIXME: handle - // non-stereo local input. - {} - - void Set(AudioBus* bus) { - if (bus) - source_bus_->CopyFrom(*bus); - } - - // AudioSourceProvider. - void ProvideInput(AudioBus* destination_bus, - size_t number_of_frames) override { - bool is_good = destination_bus && - destination_bus->length() == number_of_frames && - source_bus_->length() == number_of_frames; - DCHECK(is_good); - if (is_good) - destination_bus->CopyFrom(*source_bus_); - } - - private: - scoped_refptr<AudioBus> source_bus_; - }; - // Counts the number of sample-frames processed by the destination. size_t current_sample_frame_; - - LocalAudioInputProvider local_audio_input_provider_; }; class AudioDestinationNode : public AudioNode {
diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc index dc9595e..1719e329 100644 --- a/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc
@@ -314,10 +314,6 @@ return true; } - // Prepare the local audio input provider for this render quantum. - if (source_bus) - local_audio_input_provider_.Set(source_bus); - DCHECK_GE(NumberOfInputs(), 1u); if (NumberOfInputs() < 1) { destination_bus->Zero();
diff --git a/third_party/blink/renderer/modules/xr/xr_device.cc b/third_party/blink/renderer/modules/xr/xr_device.cc index 51ef912..7af71ec 100644 --- a/third_party/blink/renderer/modules/xr/xr_device.cc +++ b/third_party/blink/renderer/modules/xr/xr_device.cc
@@ -228,7 +228,14 @@ output_context = options.outputContext(); } - XRSession* session = new XRSession(this, options.exclusive(), output_context); + XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque; + // TODO(https://crbug.com/828321): Use session options instead of the flag. + if (RuntimeEnabledFeatures::WebXRHitTestEnabled()) { + blend_mode = XRSession::kBlendModeAlphaBlend; + } + + XRSession* session = + new XRSession(this, options.exclusive(), output_context, blend_mode); sessions_.insert(session); if (options.exclusive()) {
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index bb8669f..efeb80e 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -91,7 +91,8 @@ XRSession::XRSession(XRDevice* device, bool exclusive, - XRPresentationContext* output_context) + XRPresentationContext* output_context, + EnvironmentBlendMode environment_blend_mode) : device_(device), exclusive_(exclusive), output_context_(output_context), @@ -115,6 +116,21 @@ UpdateCanvasDimensions(canvas); } } + + switch (environment_blend_mode) { + case kBlendModeOpaque: + blend_mode_string_ = "opaque"; + break; + case kBlendModeAdditive: + blend_mode_string_ = "additive"; + break; + case kBlendModeAlphaBlend: + blend_mode_string_ = "alpha-blend"; + break; + default: + NOTREACHED() << "Unknown environment blend mode: " + << environment_blend_mode; + } } void XRSession::setDepthNear(double value) {
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h index 79e2ae6..e28369d 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.h +++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -38,12 +38,22 @@ DEFINE_WRAPPERTYPEINFO(); public: - XRSession(XRDevice*, bool exclusive, XRPresentationContext* output_context); + enum EnvironmentBlendMode { + kBlendModeOpaque = 1, + kBlendModeAdditive = 2, + kBlendModeAlphaBlend = 3 + }; + + XRSession(XRDevice*, + bool exclusive, + XRPresentationContext* output_context, + EnvironmentBlendMode environment_blend_mode); ~XRSession() override = default; XRDevice* device() const { return device_; } bool exclusive() const { return exclusive_; } XRPresentationContext* outputContext() const { return output_context_; } + const String& environmentBlendMode() const { return blend_mode_string_; } // Near and far depths are used when computing projection matrices for this // Session's views. Changes will propegate to the appropriate matrices on the @@ -158,6 +168,7 @@ const Member<XRDevice> device_; const bool exclusive_; const Member<XRPresentationContext> output_context_; + String blend_mode_string_; Member<XRLayer> base_layer_; HeapVector<Member<XRView>> views_; InputSourceMap input_sources_;
diff --git a/third_party/blink/renderer/modules/xr/xr_session.idl b/third_party/blink/renderer/modules/xr/xr_session.idl index c1ddfbd..365f18e 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.idl +++ b/third_party/blink/renderer/modules/xr/xr_session.idl
@@ -3,6 +3,12 @@ // found in the LICENSE file. // https://immersive-web.github.io/webxr/#xrsession-interface +enum XREnvironmentBlendMode { + "opaque", + "additive", + "alpha-blend", +}; + [ SecureContext, OriginTrialEnabled=WebXR @@ -10,6 +16,7 @@ readonly attribute XRDevice device; readonly attribute boolean exclusive; readonly attribute XRPresentationContext outputContext; + readonly attribute XREnvironmentBlendMode environmentBlendMode; attribute double depthNear; attribute double depthFar;
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.cc b/third_party/blink/renderer/platform/audio/audio_destination.cc index 24e122b..fe73447 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination.cc +++ b/third_party/blink/renderer/platform/audio/audio_destination.cc
@@ -183,7 +183,7 @@ output_position.position = 0.0; // Process WebAudio graph and push the rendered output to FIFO. - callback_.Render(nullptr, render_bus_.get(), + callback_.Render(render_bus_.get(), AudioUtilities::kRenderQuantumFrames, output_position); fifo_->Push(render_bus_.get()); }
diff --git a/third_party/blink/renderer/platform/audio/audio_io_callback.h b/third_party/blink/renderer/platform/audio/audio_io_callback.h index 079bb19..e97f83a8 100644 --- a/third_party/blink/renderer/platform/audio/audio_io_callback.h +++ b/third_party/blink/renderer/platform/audio/audio_io_callback.h
@@ -46,11 +46,9 @@ // Abstract base-class for isochronous audio I/O client. class AudioIOCallback { public: - // render() is called periodically to get the next render quantum of audio - // into destinationBus. Optional audio input is given in sourceBus (if it's - // not 0). - virtual void Render(AudioBus* source_bus, - AudioBus* destination_bus, + // Called periodically to get the next render quantum of audio into + // |destination_bus|. + virtual void Render(AudioBus* destination_bus, size_t frames_to_process, const AudioIOPosition& output_position) = 0;
diff --git a/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc b/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc index 57966613..6c8efc8 100644 --- a/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc +++ b/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc
@@ -35,8 +35,8 @@ #include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" #include "third_party/blink/renderer/platform/language.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkTypeface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/fonts/font_cache.h b/third_party/blink/renderer/platform/fonts/font_cache.h index 3327374..81020921 100644 --- a/third_party/blink/renderer/platform/fonts/font_cache.h +++ b/third_party/blink/renderer/platform/fonts/font_cache.h
@@ -53,10 +53,9 @@ #include "third_party/blink/renderer/platform/wtf/text/cstring.h" #include "third_party/blink/renderer/platform/wtf/text/unicode.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkRefCnt.h" -#include "SkFontMgr.h" - class SkString; class SkTypeface;
diff --git a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc index 9b6f99c..5781caf 100644 --- a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc +++ b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
@@ -34,10 +34,6 @@ #include <memory> #include <utility> -#include "SkFontMgr.h" -#include "SkStream.h" -#include "SkTypeface.h" - #include "build/build_config.h" #include "third_party/blink/public/platform/linux/web_sandbox_support.h" #include "third_party/blink/public/platform/platform.h" @@ -53,6 +49,9 @@ #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" +#include "third_party/skia/include/core/SkFontMgr.h" +#include "third_party/skia/include/core/SkStream.h" +#include "third_party/skia/include/core/SkTypeface.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h b/third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h index bd2854a..89aac4d 100644 --- a/third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h +++ b/third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h
@@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WEB_FONT_TYPEFACE_FACTORY_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WEB_FONT_TYPEFACE_FACTORY_H_ -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "build/build_config.h" #if defined(OS_WIN) || defined(OS_MACOSX)
diff --git a/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc b/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc index 03dad0c..539575b 100644 --- a/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc +++ b/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc
@@ -34,8 +34,6 @@ #include <memory> #include <utility> -#include "SkFontMgr.h" -#include "SkTypeface_win.h" #include "base/debug/alias.h" #include "third_party/blink/renderer/platform/fonts/bitmap_glyphs_blacklist.h" #include "third_party/blink/renderer/platform/fonts/font_description.h" @@ -44,6 +42,8 @@ #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" #include "third_party/blink/renderer/platform/fonts/win/font_fallback_win.h" #include "third_party/blink/renderer/platform/language.h" +#include "third_party/skia/include/core/SkFontMgr.h" +#include "third_party/skia/include/ports/SkTypeface_win.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc b/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc index 319f729..ecb970b 100644 --- a/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc +++ b/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
@@ -33,13 +33,14 @@ #include <unicode/uchar.h> #include <limits> -#include "SkFontMgr.h" -#include "SkTypeface.h" + #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/text/icu_error.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/skia/include/core/SkFontMgr.h" +#include "third_party/skia/include/core/SkTypeface.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/geometry/double_size.h b/third_party/blink/renderer/platform/geometry/double_size.h index 273c50e..081ef03 100644 --- a/third_party/blink/renderer/platform/geometry/double_size.h +++ b/third_party/blink/renderer/platform/geometry/double_size.h
@@ -21,7 +21,8 @@ public: DoubleSize() : width_(0), height_(0) {} DoubleSize(double width, double height) : width_(width), height_(height) {} - DoubleSize(const IntSize& p) : width_(p.Width()), height_(p.Height()) {} + explicit DoubleSize(const IntSize& p) + : width_(p.Width()), height_(p.Height()) {} DoubleSize(const FloatSize& s) : width_(s.Width()), height_(s.Height()) {} explicit DoubleSize(const LayoutSize&);
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 d6993e6..1864cf1 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
@@ -525,7 +525,10 @@ // Rastering the recording would have locked images, since we've flushed // all recorded ops, we should relase all locked images as well. - GetOrCreateResourceProvider()->ReleaseLockedImages(); + // A new null check on the resource provider is necessary just in case + // the playback crashed the context. + if (GetOrCreateResourceProvider()) + GetOrCreateResourceProvider()->ReleaseLockedImages(); if (is_deferral_enabled_) StartRecording();
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc index 6bf85c5..f96a3401 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -136,7 +136,7 @@ } LayoutRect GraphicsLayer::VisualRect() const { - LayoutRect bounds = LayoutRect(FloatPoint(), Size()); + LayoutRect bounds = LayoutRect(LayoutPoint(), LayoutSize(Size())); if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { DCHECK(layer_state_); bounds.MoveBy(layer_state_->offset); @@ -267,7 +267,7 @@ void GraphicsLayer::SetOffsetFromLayoutObject( const IntSize& offset, ShouldSetNeedsDisplay should_set_needs_display) { - SetOffsetDoubleFromLayoutObject(offset); + SetOffsetDoubleFromLayoutObject(DoubleSize(offset)); } void GraphicsLayer::SetOffsetDoubleFromLayoutObject( @@ -359,7 +359,7 @@ if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { DCHECK(layer_state_) << "No layer state for GraphicsLayer: " << DebugName(); // Generate raster invalidations for SPv175 (but not SPv2). - IntRect layer_bounds(layer_state_->offset, ExpandedIntSize(Size())); + IntRect layer_bounds(layer_state_->offset, Size()); EnsureRasterInvalidator().Generate(GetPaintController().GetPaintArtifact(), layer_bounds, layer_state_->state, VisualRectSubpixelOffset()); @@ -1372,7 +1372,7 @@ if (client_.ShouldThrottleRendering()) return sk_sp<PaintRecord>(new PaintRecord); - FloatRect bounds(IntRect(IntPoint(0, 0), ExpandedIntSize(Size()))); + FloatRect bounds(IntRect(IntPoint(), Size())); GraphicsContext graphics_context(GetPaintController()); graphics_context.BeginRecording(bounds); if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
diff --git a/third_party/blink/renderer/platform/graphics/picture_snapshot.cc b/third_party/blink/renderer/platform/graphics/picture_snapshot.cc index a01d0e6d..9773f501 100644 --- a/third_party/blink/renderer/platform/graphics/picture_snapshot.cc +++ b/third_party/blink/renderer/platform/graphics/picture_snapshot.cc
@@ -88,9 +88,9 @@ return picture_->cullRect().isEmpty(); } -std::unique_ptr<Vector<char>> PictureSnapshot::Replay(unsigned from_step, - unsigned to_step, - double scale) const { +Vector<char> PictureSnapshot::Replay(unsigned from_step, + unsigned to_step, + double scale) const { const SkIRect bounds = picture_->cullRect().roundOut(); int width = ceil(scale * bounds.width()); int height = ceil(scale * bounds.height()); @@ -113,7 +113,7 @@ canvas.ResetStepCount(); picture_->playback(&canvas, &canvas); } - std::unique_ptr<Vector<char>> base64_data = std::make_unique<Vector<char>>(); + Vector<char> base64_data; Vector<char> encoded_image; SkPixmap src; @@ -127,10 +127,10 @@ if (!ImageEncoder::Encode( reinterpret_cast<Vector<unsigned char>*>(&encoded_image), src, options)) { - return nullptr; + return Vector<char>(); } - Base64Encode(encoded_image, *base64_data); + Base64Encode(encoded_image, base64_data); return base64_data; }
diff --git a/third_party/blink/renderer/platform/graphics/picture_snapshot.h b/third_party/blink/renderer/platform/graphics/picture_snapshot.h index 8d20983..aa9cbb1 100644 --- a/third_party/blink/renderer/platform/graphics/picture_snapshot.h +++ b/third_party/blink/renderer/platform/graphics/picture_snapshot.h
@@ -60,9 +60,9 @@ PictureSnapshot(sk_sp<const SkPicture>); - std::unique_ptr<Vector<char>> Replay(unsigned from_step = 0, - unsigned to_step = 0, - double scale = 1.0) const; + Vector<char> Replay(unsigned from_step = 0, + unsigned to_step = 0, + double scale = 1.0) const; Vector<Vector<TimeDelta>> Profile(unsigned min_iterations, TimeDelta min_duration, const FloatRect* clip_rect) const;
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index b40282f..908ca10 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -728,27 +728,11 @@ void ThreadState::ScheduleIncrementalMarkingStep() { CHECK(!IsSweepingInProgress()); - - // BlinkGC::kTesting incremental marking tasks are executed by - // RunScheduledGC(). - if (current_gc_data_.reason != BlinkGC::kTesting) { - Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask( - FROM_HERE, WTF::Bind(&ThreadState::RunIncrementalMarkingStepTask, - WTF::Unretained(this))); - } SetGCState(kIncrementalMarkingStepScheduled); } void ThreadState::ScheduleIncrementalMarkingFinalize() { CHECK(!IsSweepingInProgress()); - - // BlinkGC::kTesting incremental marking tasks are executed by - // RunScheduledGC(). - if (current_gc_data_.reason != BlinkGC::kTesting) { - Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask( - FROM_HERE, WTF::Bind(&ThreadState::RunIncrementalMarkingFinalizeTask, - WTF::Unretained(this))); - } SetGCState(kIncrementalMarkingFinalizeScheduled); } @@ -930,12 +914,10 @@ // Idle time GC will be scheduled by Blink Scheduler. break; case kIncrementalMarkingStepScheduled: - if (current_gc_data_.reason == BlinkGC::kTesting) - RunIncrementalMarkingStepTask(); + IncrementalMarkingStep(); break; case kIncrementalMarkingFinalizeScheduled: - if (current_gc_data_.reason == BlinkGC::kTesting) - RunIncrementalMarkingFinalizeTask(); + IncrementalMarkingFinalize(); break; case kIncrementalGCScheduled: IncrementalMarkingStart(reason_for_scheduled_gc_); @@ -1457,18 +1439,6 @@ SetWrapperTracing(false); } -void ThreadState::RunIncrementalMarkingStepTask() { - if (GetGCState() != kIncrementalMarkingStepScheduled) - return; - IncrementalMarkingStep(); -} - -void ThreadState::RunIncrementalMarkingFinalizeTask() { - if (GetGCState() != kIncrementalMarkingFinalizeScheduled) - return; - IncrementalMarkingFinalize(); -} - void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) { VLOG(2) << "[state:" << this << "] " << "IncrementalMarking: Start";
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index fe254c8..6f256a1 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -293,9 +293,6 @@ void ScheduleIncrementalMarkingStep(); void ScheduleIncrementalMarkingFinalize(); - void RunIncrementalMarkingStepTask(); - void RunIncrementalMarkingFinalizeTask(); - void IncrementalMarkingStart(BlinkGC::GCReason); void IncrementalMarkingStep(); void IncrementalMarkingFinalize();
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_client.h b/third_party/blink/renderer/platform/loader/fetch/resource_client.h index f4476b6..932aeb8 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_client.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_client.h
@@ -81,11 +81,6 @@ // non-null Resource*. ResourceClient subclasses are responsible for calling // ClearResource(). friend class ResourceFetcher; - // TODO(japhet): There isn't a clean way for SVGResourceClients to determine - // whether SVGElementProxy is holding a Resource that it should register with, - // so SVGElementProxy handles it for those clients. SVGResourceClients should - // have a better way to register themselves as clients. crbug.com/789198 - friend class SVGElementProxy; // CSSFontFaceSrcValue only ever requests a Resource once, and acts as an // intermediate caching layer of sorts. It needs to be able to register // additional clients.
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index e945696..f432a5e 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -139,6 +139,11 @@ status: "experimental", }, { + // Detects bloated renderers even if the uptime is small. + // Useful for local testing, not intended for production. + name: "BloatedRendererDetectionSkipUptimeCheck", + }, + { name: "BlockCredentialedSubresources", status: "stable", }, @@ -430,7 +435,7 @@ }, { name: "ExperimentalHardwareEchoCancellation", - origin_trial_feature_name: "ExperimentalHardwareEchoCancellation", + origin_trial_feature_name: "ExperimentalHardwareEchoCancellation2", status: "experimental", }, // Enables a set of features intended to help improve web developer
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn index 8b36810..f382a727 100644 --- a/third_party/blink/renderer/platform/scheduler/BUILD.gn +++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -12,7 +12,7 @@ "base/graceful_queue_shutdown_helper.h", "base/real_time_domain.cc", "base/real_time_domain.h", - "base/sequence_manager.h", + "base/sequence_manager_forward.h", "base/task_queue.cc", "base/task_queue_forward.h", "base/task_queue_impl.cc",
diff --git a/third_party/blink/renderer/platform/scheduler/base/proto/task_queue_manager_test_description.proto b/third_party/blink/renderer/platform/scheduler/base/proto/task_queue_manager_test_description.proto index 4eb18780..969940a 100644 --- a/third_party/blink/renderer/platform/scheduler/base/proto/task_queue_manager_test_description.proto +++ b/third_party/blink/renderer/platform/scheduler/base/proto/task_queue_manager_test_description.proto
@@ -21,27 +21,23 @@ // Describes interfaces that can be tested by the fuzzer. // TODO(farahcharab) Add more interfaces here. message Action { - // NEXT ID = 5 + // NEXT ID = 3 - // The number of milliseconds after which an action should be executed - // relative to the start of the program. - optional uint64 delay_ms = 1; - - required PostDelayedTaskAction default_action_desc = 2; - - oneof description { - CreateTaskQueueAction create_task_queue_desc = 3; - PostDelayedTaskAction post_delayed_task_desc = 4; + oneof action { + CreateTaskQueueAction create_task_queue = 1; + PostDelayedTaskAction post_delayed_task = 2; } } message Task { - // NEXT ID = 3 + // NEXT ID = 4 - // If not set, then this is a no-op task. - repeated Action actions = 1; + required uint64 task_id = 1; optional uint64 duration_ms = 2; + + // If not set, then this is a no-op task. + repeated Action action = 3; } // Describes the grammar of TaskQueueManager::CreateTaskQueue. @@ -56,14 +52,14 @@ // NEXT ID = 4 // Used to identify the queue to post to. - required uint64 task_queue_id = 1; + optional uint64 task_queue_id = 1; - required Task task = 2; + optional Task task = 2; // Delay parameter passed to TaskQueue::PostDelayedTask i.e. the delay is // measured after executing the PostDelayedTaskAction. optional uint64 delay_ms = 3; } - repeated Action actions = 1; + repeated PostDelayedTaskAction initial_task = 1; }
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h new file mode 100644 index 0000000..3019bbe --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h
@@ -0,0 +1,32 @@ +// 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_BASE_SEQUENCE_MANAGER_FORWARD_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_FORWARD_H_ + +// TODO(kraynov): Remove this header after the move. + +// Must be included first. +#include "third_party/blink/renderer/platform/platform_export.h" + +#define HACKDEF_INCLUDED_FROM_BLINK +// It also includes task_queue_impl.h which has PLATFORM_EXPORT macros. +#include "base/task/sequence_manager/sequence_manager.h" +#undef HACKDEF_INCLUDED_FROM_BLINK + +namespace base { +namespace sequence_manager { + +// Create SequenceManager using MessageLoop on the current thread. +// implementation is located in task_queue_manager_impl.cc. +// TODO(kraynov): Move to SequenceManager class. +// TODO(scheduler-dev): Rename to TakeOverCurrentThread when we'll stop using +// MessageLoop and will actually take over a thread. +PLATFORM_EXPORT std::unique_ptr<SequenceManager> +CreateSequenceManagerOnCurrentThread(); + +} // namespace sequence_manager +} // namespace base + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_FORWARD_H_
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc index 0ecdba2..cc00c19 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc
@@ -50,8 +50,7 @@ } // namespace -// static -std::unique_ptr<SequenceManager> SequenceManager::CreateOnCurrentThread() { +std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread() { return TaskQueueManagerImpl::CreateOnCurrentThread(); }
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h index 0ca2909..b97e8bd 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h
@@ -30,7 +30,7 @@ #include "base/task/sequence_manager/thread_controller.h" #include "base/threading/thread_checker.h" #include "third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h"
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc index fcbd4e18..62cfd8c0 100644 --- a/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc +++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include <stddef.h> #include <memory>
diff --git a/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc b/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc index 08b9ad1c..f0a1ed7 100644 --- a/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc
@@ -9,7 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/test/simple_test_tick_clock.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h"
diff --git a/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc b/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc index 25511bd..b70de85c 100644 --- a/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc +++ b/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc
@@ -107,7 +107,7 @@ CreateNonMainThreadScheduler() override { return std::make_unique<CompositorThreadScheduler>( GetThread(), - base::sequence_manager::SequenceManager::CreateOnCurrentThread()); + base::sequence_manager::CreateSequenceManagerOnCurrentThread()); } DISALLOW_COPY_AND_ASSIGN(WebThreadForCompositor);
diff --git a/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc b/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc index 31691c6..b2d91b4 100644 --- a/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
@@ -7,8 +7,9 @@ #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" +#include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" #include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc index 7e59731..49a550c 100644 --- a/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
@@ -15,9 +15,10 @@ #include "components/viz/test/ordered_simple_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" #include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h index 5bede6a..053434c 100644 --- a/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h +++ b/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
@@ -12,7 +12,7 @@ #include "base/message_loop/message_loop.h" #include "base/time/tick_clock.h" #include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc index 0d3254a..d40869e 100644 --- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
@@ -15,7 +15,7 @@ #include "components/viz/test/ordered_simple_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc index 7e2335f..7aafd2c 100644 --- a/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
@@ -28,7 +28,7 @@ std::unique_ptr<MainThreadSchedulerImpl> scheduler( new MainThreadSchedulerImpl( - base::sequence_manager::SequenceManager::CreateOnCurrentThread(), + base::sequence_manager::CreateSequenceManagerOnCurrentThread(), initial_virtual_time)); return std::move(scheduler); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc index cb735f2d..e17188d 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc
@@ -9,7 +9,7 @@ #include "base/test/test_mock_time_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/test/test_task_time_observer.h"
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc index d35ad78..a9cc668 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
@@ -10,7 +10,7 @@ #include "base/test/scoped_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h"
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc index 411bf302..462e2ae 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc
@@ -25,7 +25,7 @@ WorkerSchedulerProxy* proxy) { return std::make_unique<WorkerThreadScheduler>( thread_type, - base::sequence_manager::SequenceManager::CreateOnCurrentThread(), proxy); + base::sequence_manager::CreateSequenceManagerOnCurrentThread(), proxy); } void NonMainThreadSchedulerImpl::Init() {
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc index 71ca7fc..b349af11 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
@@ -78,7 +78,7 @@ std::unique_ptr<NonMainThreadSchedulerImpl> CreateNonMainThreadScheduler() override { auto scheduler = std::make_unique<WorkerThreadSchedulerForTest>( - base::sequence_manager::SequenceManager::CreateOnCurrentThread(), + base::sequence_manager::CreateSequenceManagerOnCurrentThread(), worker_scheduler_proxy(), throtting_state_changed_); scheduler_ = scheduler.get(); worker_scheduler_ = std::make_unique<scheduler::WorkerScheduler>(
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc index 002715d..cf11320 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -14,7 +14,7 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "third_party/blink/renderer/platform/histogram.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_forward.h" #include "third_party/blink/renderer/platform/scheduler/child/features.h" #include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
diff --git a/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc b/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc index f228ae0..639eaf1 100644 --- a/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc +++ b/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc
@@ -622,7 +622,7 @@ animator->AdjustImplOnlyScrollOffsetAnimation(IntSize(10, -10)); EXPECT_TRUE(animator->HasAnimationThatRequiresService()); - EXPECT_EQ(FloatSize(110, 90), + EXPECT_EQ(IntSize(110, 90), animator->ImplOnlyAnimationAdjustmentForTesting()); animator->UpdateCompositorAnimations();
diff --git a/third_party/blink/renderer/platform/scroll/scrollable_area.cc b/third_party/blink/renderer/platform/scroll/scrollable_area.cc index bee196b..db673dc 100644 --- a/third_party/blink/renderer/platform/scroll/scrollable_area.cc +++ b/third_party/blink/renderer/platform/scroll/scrollable_area.cc
@@ -663,9 +663,14 @@ } int ScrollableArea::PageStep(ScrollbarOrientation orientation) const { - IntRect visible_rect = VisibleContentRect(kIncludeScrollbars); - int length = (orientation == kHorizontalScrollbar) ? visible_rect.Width() - : visible_rect.Height(); + // Paging scroll operations should take scroll-padding into account [1]. So we + // use the snapport rect to calculate the page step instead of the visible + // rect. + // [1] https://drafts.csswg.org/css-scroll-snap/#scroll-padding + IntSize snapport_size = + VisibleScrollSnapportRect(kIncludeScrollbars).PixelSnappedSize(); + int length = (orientation == kHorizontalScrollbar) ? snapport_size.Width() + : snapport_size.Height(); int min_page_step = static_cast<float>(length) * MinFractionToStepWhenPaging(); int page_step = std::max(min_page_step, length - MaxOverlapBetweenPages());
diff --git a/third_party/blink/renderer/platform/scroll/scrollable_area.h b/third_party/blink/renderer/platform/scroll/scrollable_area.h index af849e5..e971220 100644 --- a/third_party/blink/renderer/platform/scroll/scrollable_area.h +++ b/third_party/blink/renderer/platform/scroll/scrollable_area.h
@@ -249,8 +249,9 @@ // container for the scroll snap areas when calculating snap positions. It's // the box's scrollport contracted by its scroll-padding. // https://drafts.csswg.org/css-scroll-snap-1/#scroll-padding - virtual LayoutRect VisibleScrollSnapportRect() const { - return LayoutRect(VisibleContentRect()); + virtual LayoutRect VisibleScrollSnapportRect( + IncludeScrollbarsInRect scrollbar_inclusion = kExcludeScrollbars) const { + return LayoutRect(VisibleContentRect(scrollbar_inclusion)); } virtual IntPoint LastKnownMousePosition() const { return IntPoint(); }
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support.cc b/third_party/blink/renderer/platform/testing/testing_platform_support.cc index cc83810..9e98ff0 100644 --- a/third_party/blink/renderer/platform/testing/testing_platform_support.cc +++ b/third_party/blink/renderer/platform/testing/testing_platform_support.cc
@@ -49,7 +49,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/mime/mock_mime_registry.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_forward.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" #include "third_party/blink/renderer/platform/wtf/wtf.h"
diff --git a/third_party/closure_compiler/externs/bluetooth_private.js b/third_party/closure_compiler/externs/bluetooth_private.js index 76ef861..cfcfbbc 100644 --- a/third_party/closure_compiler/externs/bluetooth_private.js +++ b/third_party/closure_compiler/externs/bluetooth_private.js
@@ -21,7 +21,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingEventType */ chrome.bluetoothPrivate.PairingEventType = { REQUEST_PINCODE: 'requestPincode', @@ -36,7 +35,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-ConnectResultType */ chrome.bluetoothPrivate.ConnectResultType = { ALREADY_CONNECTED: 'alreadyConnected', @@ -53,7 +51,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingResponse */ chrome.bluetoothPrivate.PairingResponse = { CONFIRM: 'confirm', @@ -63,7 +60,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-TransportType */ chrome.bluetoothPrivate.TransportType = { LE: 'le', @@ -79,7 +75,6 @@ * passkey: (number|undefined), * enteredKey: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-PairingEvent */ chrome.bluetoothPrivate.PairingEvent; @@ -89,7 +84,6 @@ * powered: (boolean|undefined), * discoverable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-NewAdapterState */ chrome.bluetoothPrivate.NewAdapterState; @@ -100,7 +94,6 @@ * pincode: (string|undefined), * passkey: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-SetPairingResponseOptions */ chrome.bluetoothPrivate.SetPairingResponseOptions; @@ -111,7 +104,6 @@ * rssi: (number|undefined), * pathloss: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#type-DiscoveryFilter */ chrome.bluetoothPrivate.DiscoveryFilter; @@ -119,14 +111,12 @@ * Changes the state of the Bluetooth adapter. * @param {!chrome.bluetoothPrivate.NewAdapterState} adapterState * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/bluetoothPrivate#method-setAdapterState */ chrome.bluetoothPrivate.setAdapterState = function(adapterState, callback) {}; /** * @param {!chrome.bluetoothPrivate.SetPairingResponseOptions} options * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/bluetoothPrivate#method-setPairingResponse */ chrome.bluetoothPrivate.setPairingResponse = function(options, callback) {}; @@ -134,7 +124,6 @@ * Tears down all connections to the given device. * @param {string} deviceAddress * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/bluetoothPrivate#method-disconnectAll */ chrome.bluetoothPrivate.disconnectAll = function(deviceAddress, callback) {}; @@ -142,7 +131,6 @@ * Forgets the given device. * @param {string} deviceAddress * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/bluetoothPrivate#method-forgetDevice */ chrome.bluetoothPrivate.forgetDevice = function(deviceAddress, callback) {}; @@ -150,7 +138,6 @@ * Set or clear discovery filter. * @param {!chrome.bluetoothPrivate.DiscoveryFilter} discoveryFilter * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/bluetoothPrivate#method-setDiscoveryFilter */ chrome.bluetoothPrivate.setDiscoveryFilter = function(discoveryFilter, callback) {}; @@ -160,7 +147,6 @@ * succeed and invoke |callback| with ConnectResultType. * @param {string} deviceAddress * @param {function(!chrome.bluetoothPrivate.ConnectResultType):void=} callback - * @see https://developer.chrome.com/extensions/bluetoothPrivate#method-connect */ chrome.bluetoothPrivate.connect = function(deviceAddress, callback) {}; @@ -168,13 +154,11 @@ * Pairs the given device. * @param {string} deviceAddress * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/bluetoothPrivate#method-pair */ chrome.bluetoothPrivate.pair = function(deviceAddress, callback) {}; /** * Fired when a pairing event occurs. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/bluetoothPrivate#event-onPairing */ chrome.bluetoothPrivate.onPairing;
diff --git a/third_party/closure_compiler/externs/developer_private.js b/third_party/closure_compiler/externs/developer_private.js index a4b21dc..212e30c3 100644 --- a/third_party/closure_compiler/externs/developer_private.js +++ b/third_party/closure_compiler/externs/developer_private.js
@@ -18,7 +18,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ItemType */ chrome.developerPrivate.ItemType = { HOSTED_APP: 'hosted_app', @@ -36,7 +35,6 @@ * incognito: boolean, * generatedBackgroundPage: boolean * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ItemInspectView */ chrome.developerPrivate.ItemInspectView; @@ -47,7 +45,6 @@ * render_view_id: (string|number), * incognito: boolean * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-InspectOptions */ chrome.developerPrivate.InspectOptions; @@ -55,13 +52,11 @@ * @typedef {{ * message: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-InstallWarning */ chrome.developerPrivate.InstallWarning; /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionType */ chrome.developerPrivate.ExtensionType = { HOSTED_APP: 'HOSTED_APP', @@ -74,7 +69,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-Location */ chrome.developerPrivate.Location = { FROM_STORE: 'FROM_STORE', @@ -85,7 +79,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ViewType */ chrome.developerPrivate.ViewType = { APP_WINDOW: 'APP_WINDOW', @@ -100,7 +93,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ErrorType */ chrome.developerPrivate.ErrorType = { MANIFEST: 'MANIFEST', @@ -109,7 +101,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ErrorLevel */ chrome.developerPrivate.ErrorLevel = { LOG: 'LOG', @@ -119,7 +110,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionState */ chrome.developerPrivate.ExtensionState = { ENABLED: 'ENABLED', @@ -130,7 +120,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-CommandScope */ chrome.developerPrivate.CommandScope = { GLOBAL: 'GLOBAL', @@ -142,7 +131,6 @@ * isEnabled: boolean, * isActive: boolean * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-AccessModifier */ chrome.developerPrivate.AccessModifier; @@ -153,7 +141,6 @@ * url: string, * functionName: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-StackFrame */ chrome.developerPrivate.StackFrame; @@ -168,7 +155,6 @@ * manifestKey: string, * manifestSpecific: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ManifestError */ chrome.developerPrivate.ManifestError; @@ -188,7 +174,6 @@ * canInspect: boolean, * stackTrace: !Array<!chrome.developerPrivate.StackFrame> * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-RuntimeError */ chrome.developerPrivate.RuntimeError; @@ -198,7 +183,6 @@ * corruptInstall: boolean, * updateRequired: boolean * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-DisableReasons */ chrome.developerPrivate.DisableReasons; @@ -207,7 +191,6 @@ * openInTab: boolean, * url: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-OptionsPage */ chrome.developerPrivate.OptionsPage; @@ -216,7 +199,6 @@ * url: string, * specified: boolean * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-HomePage */ chrome.developerPrivate.HomePage; @@ -229,13 +211,11 @@ * isIframe: boolean, * type: !chrome.developerPrivate.ViewType * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionView */ chrome.developerPrivate.ExtensionView; /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ControllerType */ chrome.developerPrivate.ControllerType = { POLICY: 'POLICY', @@ -248,7 +228,6 @@ * type: !chrome.developerPrivate.ControllerType, * text: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ControlledInfo */ chrome.developerPrivate.ControlledInfo; @@ -261,7 +240,6 @@ * scope: !chrome.developerPrivate.CommandScope, * isExtensionAction: boolean * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-Command */ chrome.developerPrivate.Command; @@ -270,7 +248,6 @@ * id: string, * name: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-DependentExtension */ chrome.developerPrivate.DependentExtension; @@ -279,7 +256,6 @@ * message: string, * submessages: !Array<string> * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-Permission */ chrome.developerPrivate.Permission; @@ -321,7 +297,6 @@ * views: !Array<!chrome.developerPrivate.ExtensionView>, * webStoreUrl: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionInfo */ chrome.developerPrivate.ExtensionInfo; @@ -334,7 +309,6 @@ * isIncognitoAvailable: boolean, * isSupervised: boolean * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ProfileInfo */ chrome.developerPrivate.ProfileInfo; @@ -368,7 +342,6 @@ * offline_enabled: boolean, * views: !Array<!chrome.developerPrivate.ItemInspectView> * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ItemInfo */ chrome.developerPrivate.ItemInfo; @@ -377,7 +350,6 @@ * includeDisabled: (boolean|undefined), * includeTerminated: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-GetExtensionsInfoOptions */ chrome.developerPrivate.GetExtensionsInfoOptions; @@ -389,7 +361,6 @@ * errorCollection: (boolean|undefined), * runOnAllUrls: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionConfigurationUpdate */ chrome.developerPrivate.ExtensionConfigurationUpdate; @@ -397,7 +368,6 @@ * @typedef {{ * inDeveloperMode: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ProfileConfigurationUpdate */ chrome.developerPrivate.ProfileConfigurationUpdate; @@ -408,7 +378,6 @@ * scope: (!chrome.developerPrivate.CommandScope|undefined), * keybinding: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ExtensionCommandUpdate */ chrome.developerPrivate.ExtensionCommandUpdate; @@ -417,7 +386,6 @@ * failQuietly: (boolean|undefined), * populateErrorForUnpacked: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ReloadOptions */ chrome.developerPrivate.ReloadOptions; @@ -428,13 +396,11 @@ * retryGuid: (string|undefined), * useDraggedPath: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-LoadUnpackedOptions */ chrome.developerPrivate.LoadUnpackedOptions; /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-PackStatus */ chrome.developerPrivate.PackStatus = { SUCCESS: 'SUCCESS', @@ -444,7 +410,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-FileType */ chrome.developerPrivate.FileType = { LOAD: 'LOAD', @@ -453,7 +418,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-SelectType */ chrome.developerPrivate.SelectType = { FILE: 'FILE', @@ -462,7 +426,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/developerPrivate#type-EventType */ chrome.developerPrivate.EventType = { INSTALLED: 'INSTALLED', @@ -487,7 +450,6 @@ * override_flags: number, * status: !chrome.developerPrivate.PackStatus * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-PackDirectoryResponse */ chrome.developerPrivate.PackDirectoryResponse; @@ -495,7 +457,6 @@ * @typedef {{ * name: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ProjectInfo */ chrome.developerPrivate.ProjectInfo; @@ -505,7 +466,6 @@ * item_id: string, * extensionInfo: (!chrome.developerPrivate.ExtensionInfo|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-EventData */ chrome.developerPrivate.EventData; @@ -515,7 +475,6 @@ * highlight: string, * afterHighlight: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-ErrorFileSource */ chrome.developerPrivate.ErrorFileSource; @@ -526,7 +485,6 @@ * source: (!chrome.developerPrivate.ErrorFileSource|undefined), * retryGuid: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-LoadError */ chrome.developerPrivate.LoadError; @@ -539,7 +497,6 @@ * manifestSpecific: (string|undefined), * lineNumber: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-RequestFileSourceProperties */ chrome.developerPrivate.RequestFileSourceProperties; @@ -551,7 +508,6 @@ * title: string, * message: string * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-RequestFileSourceResponse */ chrome.developerPrivate.RequestFileSourceResponse; @@ -565,7 +521,6 @@ * lineNumber: (number|undefined), * columnNumber: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-OpenDevToolsProperties */ chrome.developerPrivate.OpenDevToolsProperties; @@ -575,14 +530,12 @@ * errorIds: (!Array<number>|undefined), * type: (!chrome.developerPrivate.ErrorType|undefined) * }} - * @see https://developer.chrome.com/extensions/developerPrivate#type-DeleteExtensionErrorsProperties */ chrome.developerPrivate.DeleteExtensionErrorsProperties; /** * Runs auto update for extensions and apps immediately. * @param {function():void=} callback Called after update check completes. - * @see https://developer.chrome.com/extensions/developerPrivate#method-autoUpdate */ chrome.developerPrivate.autoUpdate = function(callback) {}; @@ -592,7 +545,6 @@ * to restrict the items returned. * @param {function(!Array<!chrome.developerPrivate.ExtensionInfo>):void=} * callback Called with extensions info. - * @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionsInfo */ chrome.developerPrivate.getExtensionsInfo = function(options, callback) {}; @@ -601,7 +553,6 @@ * @param {string} id The id of the extension. * @param {function(!chrome.developerPrivate.ExtensionInfo):void=} callback * Called with the result. - * @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionInfo */ chrome.developerPrivate.getExtensionInfo = function(id, callback) {}; @@ -609,7 +560,6 @@ * Returns the size of a particular extension on disk (already formatted). * @param {string} id The id of the extension. * @param {function(string):void} callback Called with the result. - * @see https://developer.chrome.com/extensions/developerPrivate#method-getExtensionSize */ chrome.developerPrivate.getExtensionSize = function(id, callback) {}; @@ -620,14 +570,12 @@ * @param {function(!Array<!chrome.developerPrivate.ItemInfo>):void} callback * Called with items info. * @deprecated Use getExtensionsInfo - * @see https://developer.chrome.com/extensions/developerPrivate#method-getItemsInfo */ chrome.developerPrivate.getItemsInfo = function(includeDisabled, includeTerminated, callback) {}; /** * Returns the current profile's configuration. * @param {function(!chrome.developerPrivate.ProfileInfo):void} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-getProfileConfiguration */ chrome.developerPrivate.getProfileConfiguration = function(callback) {}; @@ -637,7 +585,6 @@ * parameters for updating the profile's configuration. Any properties * omitted from |update| will not be changed. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-updateProfileConfiguration */ chrome.developerPrivate.updateProfileConfiguration = function(update, callback) {}; @@ -645,7 +592,6 @@ * Opens a permissions dialog. * @param {string} extensionId The id of the extension to show permissions for. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-showPermissionsDialog */ chrome.developerPrivate.showPermissionsDialog = function(extensionId, callback) {}; @@ -656,7 +602,6 @@ * configuration parameters. * @param {function((!chrome.developerPrivate.LoadError|undefined)):void=} * callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-reload */ chrome.developerPrivate.reload = function(extensionId, options, callback) {}; @@ -666,7 +611,6 @@ * parameters for updating the extension's configuration. Any properties * omitted from |update| will not be changed. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-updateExtensionConfiguration */ chrome.developerPrivate.updateExtensionConfiguration = function(update, callback) {}; @@ -676,21 +620,18 @@ * configuration parameters. * @param {function((!chrome.developerPrivate.LoadError|undefined)):void=} * callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-loadUnpacked */ chrome.developerPrivate.loadUnpacked = function(options, callback) {}; /** * Installs the file that was dragged and dropped onto the associated page. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-installDroppedFile */ chrome.developerPrivate.installDroppedFile = function(callback) {}; /** * Notifies the browser that a user began a drag in order to install an * extension. - * @see https://developer.chrome.com/extensions/developerPrivate#method-notifyDragInstallInProgress */ chrome.developerPrivate.notifyDragInstallInProgress = function() {}; @@ -698,7 +639,6 @@ * Loads an extension / app. * @param {Object} directory The directory to load the extension from. * @param {function(string):void} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-loadDirectory */ chrome.developerPrivate.loadDirectory = function(directory, callback) {}; @@ -710,7 +650,6 @@ * example, pem type is for private key and load type is for an unpacked * item. * @param {function(string):void} callback called with selected item's path. - * @see https://developer.chrome.com/extensions/developerPrivate#method-choosePath */ chrome.developerPrivate.choosePath = function(selectType, fileType, callback) {}; @@ -721,14 +660,12 @@ * @param {number=} flags Special flags to apply to the loading process, if any. * @param {function(!chrome.developerPrivate.PackDirectoryResponse):void=} * callback called with the success result string. - * @see https://developer.chrome.com/extensions/developerPrivate#method-packDirectory */ chrome.developerPrivate.packDirectory = function(path, privateKeyPath, flags, callback) {}; /** * Returns true if the profile is managed. * @param {function(boolean):void} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-isProfileManaged */ chrome.developerPrivate.isProfileManaged = function(callback) {}; @@ -738,7 +675,6 @@ * @param {!chrome.developerPrivate.RequestFileSourceProperties} properties * @param {function(!chrome.developerPrivate.RequestFileSourceResponse):void} * callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-requestFileSource */ chrome.developerPrivate.requestFileSource = function(properties, callback) {}; @@ -746,7 +682,6 @@ * Open the developer tools to focus on a particular error. * @param {!chrome.developerPrivate.OpenDevToolsProperties} properties * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-openDevTools */ chrome.developerPrivate.openDevTools = function(properties, callback) {}; @@ -755,7 +690,6 @@ * @param {!chrome.developerPrivate.DeleteExtensionErrorsProperties} properties * The properties specifying the errors to remove. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-deleteExtensionErrors */ chrome.developerPrivate.deleteExtensionErrors = function(properties, callback) {}; @@ -763,7 +697,6 @@ * Repairs the extension specified. * @param {string} extensionId The id of the extension to repair. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-repairExtension */ chrome.developerPrivate.repairExtension = function(extensionId, callback) {}; @@ -772,7 +705,6 @@ * @param {string} extensionId The id of the extension to show the options page * for. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-showOptions */ chrome.developerPrivate.showOptions = function(extensionId, callback) {}; @@ -780,7 +712,6 @@ * Shows the path of the extension specified. * @param {string} extensionId The id of the extension to show the path for. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-showPath */ chrome.developerPrivate.showPath = function(extensionId, callback) {}; @@ -789,7 +720,6 @@ * @param {boolean} isSuspended Whether or not shortcut handling should be * suspended. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-setShortcutHandlingSuspended */ chrome.developerPrivate.setShortcutHandlingSuspended = function(isSuspended, callback) {}; @@ -798,7 +728,6 @@ * @param {!chrome.developerPrivate.ExtensionCommandUpdate} update The * parameters for updating the extension command. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-updateExtensionCommand */ chrome.developerPrivate.updateExtensionCommand = function(update, callback) {}; @@ -808,7 +737,6 @@ * @param {string} extensionId The id of the extension to modify. * @param {string} host The host to add. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-addHostPermission */ chrome.developerPrivate.addHostPermission = function(extensionId, host, callback) {}; @@ -818,7 +746,6 @@ * @param {string} extensionId The id of the extension to modify. * @param {string} host The host to remove. * @param {function():void=} callback - * @see https://developer.chrome.com/extensions/developerPrivate#method-removeHostPermission */ chrome.developerPrivate.removeHostPermission = function(extensionId, host, callback) {}; @@ -827,7 +754,6 @@ * @param {boolean} enabled * @param {function():void=} callback * @deprecated Use management.setEnabled - * @see https://developer.chrome.com/extensions/developerPrivate#method-enable */ chrome.developerPrivate.enable = function(id, enabled, callback) {}; @@ -836,7 +762,6 @@ * @param {boolean} allow * @param {function():void=} callback * @deprecated Use updateExtensionConfiguration - * @see https://developer.chrome.com/extensions/developerPrivate#method-allowIncognito */ chrome.developerPrivate.allowIncognito = function(extensionId, allow, callback) {}; @@ -845,7 +770,6 @@ * @param {boolean} allow * @param {function():void=} callback * @deprecated Use updateExtensionConfiguration - * @see https://developer.chrome.com/extensions/developerPrivate#method-allowFileAccess */ chrome.developerPrivate.allowFileAccess = function(extensionId, allow, callback) {}; @@ -853,20 +777,17 @@ * @param {!chrome.developerPrivate.InspectOptions} options * @param {function():void=} callback * @deprecated Use openDevTools - * @see https://developer.chrome.com/extensions/developerPrivate#method-inspect */ chrome.developerPrivate.inspect = function(options, callback) {}; /** * Fired when a item state is changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/developerPrivate#event-onItemStateChanged */ chrome.developerPrivate.onItemStateChanged; /** * Fired when the profile's state has changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/developerPrivate#event-onProfileStateChanged */ chrome.developerPrivate.onProfileStateChanged;
diff --git a/third_party/closure_compiler/externs/input_method_private.js b/third_party/closure_compiler/externs/input_method_private.js index 2e810a8..b34f21a 100644 --- a/third_party/closure_compiler/externs/input_method_private.js +++ b/third_party/closure_compiler/externs/input_method_private.js
@@ -22,7 +22,6 @@ * isPhysicalKeyboardAutocorrectEnabled: boolean, * isImeMenuActivated: boolean * }):void} callback Callback which is called with the config object. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getInputMethodConfig */ chrome.inputMethodPrivate.getInputMethodConfig = function(callback) {}; @@ -33,7 +32,6 @@ * name: string, * indicator: string * }>):void} callback Callback which is called with the input method objects. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getInputMethods */ chrome.inputMethodPrivate.getInputMethods = function(callback) {}; @@ -41,7 +39,6 @@ * Gets the current input method. * @param {function(string):void} callback Callback which is called with the * current input method. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getCurrentInputMethod */ chrome.inputMethodPrivate.getCurrentInputMethod = function(callback) {}; @@ -51,7 +48,6 @@ * method. * @param {function():void=} callback Callback which is called once the current * input method is set. If unsuccessful $(ref:runtime.lastError) is set. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-setCurrentInputMethod */ chrome.inputMethodPrivate.setCurrentInputMethod = function(inputMethodId, callback) {}; @@ -59,7 +55,6 @@ * Fetches a list of all the words currently in the dictionary. * @param {function(!Array<string>):void} callback Callback which is called once * the list of dictionary words are ready. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-fetchAllDictionaryWords */ chrome.inputMethodPrivate.fetchAllDictionaryWords = function(callback) {}; @@ -68,7 +63,6 @@ * @param {string} word A new word to add to the dictionary. * @param {function():void=} callback Callback which is called once the word is * added. If unsuccessful $(ref:runtime.lastError) is set. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-addWordToDictionary */ chrome.inputMethodPrivate.addWordToDictionary = function(word, callback) {}; @@ -76,7 +70,6 @@ * Gets whether the encrypt sync is enabled. * @param {function(boolean):void=} callback Callback which is called to provide * the result. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-getEncryptSyncEnabled */ chrome.inputMethodPrivate.getEncryptSyncEnabled = function(callback) {}; @@ -85,41 +78,35 @@ * @param {string} xkb_name The XKB layout name. * @param {function():void=} callback Callback which is called when the layout * is set. - * @see https://developer.chrome.com/extensions/inputMethodPrivate#method-setXkbLayout */ chrome.inputMethodPrivate.setXkbLayout = function(xkb_name, callback) {}; /** * Fired when the input method is changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onChanged */ chrome.inputMethodPrivate.onChanged; /** * Fired when the composition bounds or cursor bounds are changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onCompositionBoundsChanged */ chrome.inputMethodPrivate.onCompositionBoundsChanged; /** * Fired when the custom spelling dictionary is loaded. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onDictionaryLoaded */ chrome.inputMethodPrivate.onDictionaryLoaded; /** * Fired when words are added or removed from the custom spelling dictionary. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onDictionaryChanged */ chrome.inputMethodPrivate.onDictionaryChanged; /** * Fired when the IME menu is activated or deactivated. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/inputMethodPrivate#event-onImeMenuActivationChanged */ chrome.inputMethodPrivate.onImeMenuActivationChanged;
diff --git a/third_party/closure_compiler/externs/language_settings_private.js b/third_party/closure_compiler/externs/language_settings_private.js index 2b041bf..2618a53 100644 --- a/third_party/closure_compiler/externs/language_settings_private.js +++ b/third_party/closure_compiler/externs/language_settings_private.js
@@ -18,7 +18,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-MoveType */ chrome.languageSettingsPrivate.MoveType = { TOP: 'TOP', @@ -37,7 +36,6 @@ * supportsTranslate: (boolean|undefined), * isAllowedUILocale: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-Language */ chrome.languageSettingsPrivate.Language; @@ -48,7 +46,6 @@ * isDownloading: (boolean|undefined), * downloadFailed: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-SpellcheckDictionaryStatus */ chrome.languageSettingsPrivate.SpellcheckDictionaryStatus; @@ -60,7 +57,6 @@ * enabled: (boolean|undefined), * hasOptionsPage: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-InputMethod */ chrome.languageSettingsPrivate.InputMethod; @@ -69,7 +65,6 @@ * componentExtensionImes: !Array<!chrome.languageSettingsPrivate.InputMethod>, * thirdPartyExtensionImes: !Array<!chrome.languageSettingsPrivate.InputMethod> * }} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#type-InputMethodLists */ chrome.languageSettingsPrivate.InputMethodLists; @@ -77,7 +72,6 @@ * Gets languages available for translate, spell checking, input and locale. * @param {function(!Array<!chrome.languageSettingsPrivate.Language>):void} * callback - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getLanguageList */ chrome.languageSettingsPrivate.getLanguageList = function(callback) {}; @@ -85,14 +79,12 @@ * Enables a language, adding it to the Accept-Language list (used to decide * which languages to translate, generate the Accept-Language header, etc.). * @param {string} languageCode - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-enableLanguage */ chrome.languageSettingsPrivate.enableLanguage = function(languageCode) {}; /** * Disables a language, removing it from the Accept-Language list. * @param {string} languageCode - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-disableLanguage */ chrome.languageSettingsPrivate.disableLanguage = function(languageCode) {}; @@ -100,7 +92,6 @@ * Enables or disables translation for a given language. * @param {string} languageCode * @param {boolean} enable - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-setEnableTranslationForLanguage */ chrome.languageSettingsPrivate.setEnableTranslationForLanguage = function(languageCode, enable) {}; @@ -108,7 +99,6 @@ * Moves a language inside the language list. * @param {string} languageCode * @param {!chrome.languageSettingsPrivate.MoveType} moveType - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-moveLanguage */ chrome.languageSettingsPrivate.moveLanguage = function(languageCode, moveType) {}; @@ -116,35 +106,30 @@ * Gets the current status of the chosen spell check dictionaries. * @param {function(!Array<!chrome.languageSettingsPrivate.SpellcheckDictionaryStatus>):void} * callback - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getSpellcheckDictionaryStatuses */ chrome.languageSettingsPrivate.getSpellcheckDictionaryStatuses = function(callback) {}; /** * Gets the custom spell check words, in sorted order. * @param {function(!Array<string>):void} callback - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getSpellcheckWords */ chrome.languageSettingsPrivate.getSpellcheckWords = function(callback) {}; /** * Adds a word to the custom dictionary. * @param {string} word - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-addSpellcheckWord */ chrome.languageSettingsPrivate.addSpellcheckWord = function(word) {}; /** * Removes a word from the custom dictionary. * @param {string} word - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-removeSpellcheckWord */ chrome.languageSettingsPrivate.removeSpellcheckWord = function(word) {}; /** * Gets the translate target language (in most cases, the display locale). * @param {function(string):void} callback - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getTranslateTargetLanguage */ chrome.languageSettingsPrivate.getTranslateTargetLanguage = function(callback) {}; @@ -152,7 +137,6 @@ * Gets all supported input methods, including third-party IMEs. Chrome OS only. * @param {function(!chrome.languageSettingsPrivate.InputMethodLists):void} * callback - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-getInputMethodLists */ chrome.languageSettingsPrivate.getInputMethodLists = function(callback) {}; @@ -160,7 +144,6 @@ * Adds the input method to the current user's list of enabled input methods, * enabling the input method for the current user. Chrome OS only. * @param {string} inputMethodId - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-addInputMethod */ chrome.languageSettingsPrivate.addInputMethod = function(inputMethodId) {}; @@ -168,14 +151,12 @@ * Removes the input method from the current user's list of enabled input * methods, disabling the input method for the current user. Chrome OS only. * @param {string} inputMethodId - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-removeInputMethod */ chrome.languageSettingsPrivate.removeInputMethod = function(inputMethodId) {}; /** * Tries to download the dictionary after a failed download. * @param {string} languageCode - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#method-retryDownloadDictionary */ chrome.languageSettingsPrivate.retryDownloadDictionary = function(languageCode) {}; @@ -183,7 +164,6 @@ * Called when the pref for the dictionaries used for spell checking changes or * the status of one of the spell check dictionaries changes. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onSpellcheckDictionariesChanged */ chrome.languageSettingsPrivate.onSpellcheckDictionariesChanged; @@ -191,20 +171,17 @@ * Called when words are added to and/or removed from the custom spell check * dictionary. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onCustomDictionaryChanged */ chrome.languageSettingsPrivate.onCustomDictionaryChanged; /** * Called when an input method is added. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onInputMethodAdded */ chrome.languageSettingsPrivate.onInputMethodAdded; /** * Called when an input method is removed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/languageSettingsPrivate#event-onInputMethodRemoved */ -chrome.languageSettingsPrivate.onInputMethodRemoved; \ No newline at end of file +chrome.languageSettingsPrivate.onInputMethodRemoved;
diff --git a/third_party/closure_compiler/externs/metrics_private.js b/third_party/closure_compiler/externs/metrics_private.js index 0eb03486..f1acebef 100644 --- a/third_party/closure_compiler/externs/metrics_private.js +++ b/third_party/closure_compiler/externs/metrics_private.js
@@ -18,7 +18,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/metricsPrivate#type-MetricTypeType */ chrome.metricsPrivate.MetricTypeType = { HISTOGRAM_LOG: 'histogram-log', @@ -34,14 +33,12 @@ * max: number, * buckets: number * }} - * @see https://developer.chrome.com/extensions/metricsPrivate#type-MetricType */ chrome.metricsPrivate.MetricType; /** * Returns true if the user opted in to sending crash reports. * @param {function(boolean):void} callback - * @see https://developer.chrome.com/extensions/metricsPrivate#method-getIsCrashReportingEnabled */ chrome.metricsPrivate.getIsCrashReportingEnabled = function(callback) {}; @@ -50,7 +47,6 @@ * trial does not exist or is not enabled. * @param {string} name * @param {function(string):void} callback - * @see https://developer.chrome.com/extensions/metricsPrivate#method-getFieldTrial */ chrome.metricsPrivate.getFieldTrial = function(name, callback) {}; @@ -59,14 +55,12 @@ * otherwise. * @param {string} name * @param {function((Object|undefined)):void} callback - * @see https://developer.chrome.com/extensions/metricsPrivate#method-getVariationParams */ chrome.metricsPrivate.getVariationParams = function(name, callback) {}; /** * Records an action performed by the user. * @param {string} name - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordUserAction */ chrome.metricsPrivate.recordUserAction = function(name) {}; @@ -74,7 +68,6 @@ * Records a percentage value from 1 to 100. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordPercentage */ chrome.metricsPrivate.recordPercentage = function(metricName, value) {}; @@ -82,7 +75,6 @@ * Records a value than can range from 1 to 1,000,000. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordCount */ chrome.metricsPrivate.recordCount = function(metricName, value) {}; @@ -90,7 +82,6 @@ * Records a value than can range from 1 to 100. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordSmallCount */ chrome.metricsPrivate.recordSmallCount = function(metricName, value) {}; @@ -98,7 +89,6 @@ * Records a value than can range from 1 to 10,000. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordMediumCount */ chrome.metricsPrivate.recordMediumCount = function(metricName, value) {}; @@ -107,7 +97,6 @@ * specified in milliseconds. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordTime */ chrome.metricsPrivate.recordTime = function(metricName, value) {}; @@ -116,7 +105,6 @@ * specified in milliseconds. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordMediumTime */ chrome.metricsPrivate.recordMediumTime = function(metricName, value) {}; @@ -125,7 +113,6 @@ * specified in milliseconds. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordLongTime */ chrome.metricsPrivate.recordLongTime = function(metricName, value) {}; @@ -134,7 +121,6 @@ * histogram defined by the |metricName|. * @param {string} metricName * @param {string} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordSparseHashable */ chrome.metricsPrivate.recordSparseHashable = function(metricName, value) {}; @@ -143,7 +129,6 @@ * by the |metricName|. * @param {string} metricName * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordSparseValue */ chrome.metricsPrivate.recordSparseValue = function(metricName, value) {}; @@ -151,7 +136,6 @@ * Adds a value to the given metric. * @param {!chrome.metricsPrivate.MetricType} metric * @param {number} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordValue */ chrome.metricsPrivate.recordValue = function(metric, value) {}; @@ -160,7 +144,6 @@ * base::UmaHistogramBoolean(). * @param {string} metricName * @param {boolean} value - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordBoolean */ chrome.metricsPrivate.recordBoolean = function(metricName, value) {}; @@ -171,6 +154,5 @@ * @param {string} metricName * @param {number} value * @param {number} enumSize - * @see https://developer.chrome.com/extensions/metricsPrivate#method-recordEnumerationValue */ chrome.metricsPrivate.recordEnumerationValue = function(metricName, value, enumSize) {};
diff --git a/third_party/closure_compiler/externs/networking_private.js b/third_party/closure_compiler/externs/networking_private.js index 0688878..87ac9e1 100644 --- a/third_party/closure_compiler/externs/networking_private.js +++ b/third_party/closure_compiler/externs/networking_private.js
@@ -18,7 +18,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ActivationStateType */ chrome.networkingPrivate.ActivationStateType = { ACTIVATED: 'Activated', @@ -29,7 +28,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-CaptivePortalStatus */ chrome.networkingPrivate.CaptivePortalStatus = { UNKNOWN: 'Unknown', @@ -41,7 +39,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ConnectionStateType */ chrome.networkingPrivate.ConnectionStateType = { CONNECTED: 'Connected', @@ -51,7 +48,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-DeviceStateType */ chrome.networkingPrivate.DeviceStateType = { UNINITIALIZED: 'Uninitialized', @@ -63,7 +59,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-IPConfigType */ chrome.networkingPrivate.IPConfigType = { DHCP: 'DHCP', @@ -72,7 +67,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkType */ chrome.networkingPrivate.NetworkType = { ALL: 'All', @@ -87,7 +81,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ProxySettingsType */ chrome.networkingPrivate.ProxySettingsType = { DIRECT: 'Direct', @@ -107,7 +100,6 @@ * UserEditable: (boolean|undefined), * DeviceEditable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedBoolean */ chrome.networkingPrivate.ManagedBoolean; @@ -122,7 +114,6 @@ * UserEditable: (boolean|undefined), * DeviceEditable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedLong */ chrome.networkingPrivate.ManagedLong; @@ -137,7 +128,6 @@ * UserEditable: (boolean|undefined), * DeviceEditable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedDOMString */ chrome.networkingPrivate.ManagedDOMString; @@ -152,7 +142,6 @@ * UserEditable: (boolean|undefined), * DeviceEditable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedDOMStringList */ chrome.networkingPrivate.ManagedDOMStringList; @@ -167,7 +156,6 @@ * UserEditable: (boolean|undefined), * DeviceEditable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIPConfigType */ chrome.networkingPrivate.ManagedIPConfigType; @@ -182,7 +170,6 @@ * UserEditable: (boolean|undefined), * DeviceEditable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProxySettingsType */ chrome.networkingPrivate.ManagedProxySettingsType; @@ -196,7 +183,6 @@ * Password: (string|undefined), * Username: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-APNProperties */ chrome.networkingPrivate.APNProperties; @@ -210,7 +196,6 @@ * Password: (!chrome.networkingPrivate.ManagedDOMString|undefined), * Username: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedAPNProperties */ chrome.networkingPrivate.ManagedAPNProperties; @@ -225,7 +210,6 @@ * UserEditable: (boolean|undefined), * DeviceEditable: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedAPNList */ chrome.networkingPrivate.ManagedAPNList; @@ -235,7 +219,6 @@ * Code: string, * Country: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularProviderProperties */ chrome.networkingPrivate.CellularProviderProperties; @@ -245,7 +228,6 @@ * currentPin: string, * newPin: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularSimState */ chrome.networkingPrivate.CellularSimState; @@ -256,7 +238,6 @@ * Organization: (string|undefined), * OrganizationalUnit: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-IssuerSubjectPattern */ chrome.networkingPrivate.IssuerSubjectPattern; @@ -267,7 +248,6 @@ * Organization: (!chrome.networkingPrivate.ManagedDOMString|undefined), * OrganizationalUnit: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIssuerSubjectPattern */ chrome.networkingPrivate.ManagedIssuerSubjectPattern; @@ -278,7 +258,6 @@ * IssuerCARef: (!Array<string>|undefined), * Subject: (!chrome.networkingPrivate.IssuerSubjectPattern|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-CertificatePattern */ chrome.networkingPrivate.CertificatePattern; @@ -289,7 +268,6 @@ * IssuerCARef: (!chrome.networkingPrivate.ManagedDOMStringList|undefined), * Subject: (!chrome.networkingPrivate.ManagedIssuerSubjectPattern|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedCertificatePattern */ chrome.networkingPrivate.ManagedCertificatePattern; @@ -312,7 +290,6 @@ * UseProactiveKeyCaching: (boolean|undefined), * UseSystemCAs: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-EAPProperties */ chrome.networkingPrivate.EAPProperties; @@ -335,7 +312,6 @@ * UseProactiveKeyCaching: (!chrome.networkingPrivate.ManagedBoolean|undefined), * UseSystemCAs: (!chrome.networkingPrivate.ManagedBoolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedEAPProperties */ chrome.networkingPrivate.ManagedEAPProperties; @@ -347,7 +323,6 @@ * ShortName: (string|undefined), * LongName: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-FoundNetworkProperties */ chrome.networkingPrivate.FoundNetworkProperties; @@ -360,7 +335,6 @@ * Type: (string|undefined), * WebProxyAutoDiscoveryUrl: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-IPConfigProperties */ chrome.networkingPrivate.IPConfigProperties; @@ -373,7 +347,6 @@ * Type: (!chrome.networkingPrivate.ManagedDOMString|undefined), * WebProxyAutoDiscoveryUrl: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIPConfigProperties */ chrome.networkingPrivate.ManagedIPConfigProperties; @@ -383,7 +356,6 @@ * SaveCredentials: (boolean|undefined), * Username: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-XAUTHProperties */ chrome.networkingPrivate.XAUTHProperties; @@ -393,7 +365,6 @@ * SaveCredentials: (!chrome.networkingPrivate.ManagedBoolean|undefined), * Username: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedXAUTHProperties */ chrome.networkingPrivate.ManagedXAUTHProperties; @@ -413,7 +384,6 @@ * ServerCARefs: (!Array<string>|undefined), * XAUTH: (!chrome.networkingPrivate.XAUTHProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-IPSecProperties */ chrome.networkingPrivate.IPSecProperties; @@ -433,7 +403,6 @@ * ServerCARefs: (!chrome.networkingPrivate.ManagedDOMStringList|undefined), * XAUTH: (!chrome.networkingPrivate.ManagedXAUTHProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedIPSecProperties */ chrome.networkingPrivate.ManagedIPSecProperties; @@ -444,7 +413,6 @@ * SaveCredentials: (boolean|undefined), * Username: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-L2TPProperties */ chrome.networkingPrivate.L2TPProperties; @@ -455,7 +423,6 @@ * SaveCredentials: (!chrome.networkingPrivate.ManagedBoolean|undefined), * Username: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedL2TPProperties */ chrome.networkingPrivate.ManagedL2TPProperties; @@ -465,7 +432,6 @@ * PostData: (string|undefined), * Url: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-PaymentPortal */ chrome.networkingPrivate.PaymentPortal; @@ -474,7 +440,6 @@ * Host: string, * Port: number * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ProxyLocation */ chrome.networkingPrivate.ProxyLocation; @@ -483,7 +448,6 @@ * Host: !chrome.networkingPrivate.ManagedDOMString, * Port: !chrome.networkingPrivate.ManagedLong * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProxyLocation */ chrome.networkingPrivate.ManagedProxyLocation; @@ -494,7 +458,6 @@ * FTPProxy: (!chrome.networkingPrivate.ProxyLocation|undefined), * SOCKS: (!chrome.networkingPrivate.ProxyLocation|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManualProxySettings */ chrome.networkingPrivate.ManualProxySettings; @@ -505,7 +468,6 @@ * FTPProxy: (!chrome.networkingPrivate.ManagedProxyLocation|undefined), * SOCKS: (!chrome.networkingPrivate.ManagedProxyLocation|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedManualProxySettings */ chrome.networkingPrivate.ManagedManualProxySettings; @@ -516,7 +478,6 @@ * ExcludeDomains: (!Array<string>|undefined), * PAC: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ProxySettings */ chrome.networkingPrivate.ProxySettings; @@ -527,7 +488,6 @@ * ExcludeDomains: (!chrome.networkingPrivate.ManagedDOMStringList|undefined), * PAC: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProxySettings */ chrome.networkingPrivate.ManagedProxySettings; @@ -536,7 +496,6 @@ * Name: (string|undefined), * Type: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-VerifyX509 */ chrome.networkingPrivate.VerifyX509; @@ -545,7 +504,6 @@ * Name: (!chrome.networkingPrivate.ManagedDOMString|undefined), * Type: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedVerifyX509 */ chrome.networkingPrivate.ManagedVerifyX509; @@ -590,7 +548,6 @@ * VerifyHash: (string|undefined), * VerifyX509: (!chrome.networkingPrivate.VerifyX509|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-OpenVPNProperties */ chrome.networkingPrivate.OpenVPNProperties; @@ -635,7 +592,6 @@ * VerifyHash: (!chrome.networkingPrivate.ManagedDOMString|undefined), * VerifyX509: (!chrome.networkingPrivate.ManagedVerifyX509|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedOpenVPNProperties */ chrome.networkingPrivate.ManagedOpenVPNProperties; @@ -645,7 +601,6 @@ * LockEnabled: boolean, * RetriesLeft: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-SIMLockStatus */ chrome.networkingPrivate.SIMLockStatus; @@ -654,7 +609,6 @@ * ExtensionID: string, * ProviderName: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ThirdPartyVPNProperties */ chrome.networkingPrivate.ThirdPartyVPNProperties; @@ -663,7 +617,6 @@ * ExtensionID: !chrome.networkingPrivate.ManagedDOMString, * ProviderName: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedThirdPartyVPNProperties */ chrome.networkingPrivate.ManagedThirdPartyVPNProperties; @@ -702,7 +655,6 @@ * SupportNetworkScan: (boolean|undefined), * SupportedCarriers: (!Array<string>|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularProperties */ chrome.networkingPrivate.CellularProperties; @@ -741,7 +693,6 @@ * SupportNetworkScan: (boolean|undefined), * SupportedCarriers: (!Array<string>|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedCellularProperties */ chrome.networkingPrivate.ManagedCellularProperties; @@ -754,7 +705,6 @@ * SIMPresent: (boolean|undefined), * SignalStrength: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-CellularStateProperties */ chrome.networkingPrivate.CellularStateProperties; @@ -764,7 +714,6 @@ * Authentication: (string|undefined), * EAP: (!chrome.networkingPrivate.EAPProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-EthernetProperties */ chrome.networkingPrivate.EthernetProperties; @@ -774,7 +723,6 @@ * Authentication: (!chrome.networkingPrivate.ManagedDOMString|undefined), * EAP: (!chrome.networkingPrivate.ManagedEAPProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedEthernetProperties */ chrome.networkingPrivate.ManagedEthernetProperties; @@ -782,7 +730,6 @@ * @typedef {{ * Authentication: string * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-EthernetStateProperties */ chrome.networkingPrivate.EthernetStateProperties; @@ -793,7 +740,6 @@ * HasConnectedToHost: boolean, * SignalStrength: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-TetherProperties */ chrome.networkingPrivate.TetherProperties; @@ -807,7 +753,6 @@ * ThirdPartyVPN: (!chrome.networkingPrivate.ThirdPartyVPNProperties|undefined), * Type: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-VPNProperties */ chrome.networkingPrivate.VPNProperties; @@ -821,7 +766,6 @@ * ThirdPartyVPN: (!chrome.networkingPrivate.ManagedThirdPartyVPNProperties|undefined), * Type: (!chrome.networkingPrivate.ManagedDOMString|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedVPNProperties */ chrome.networkingPrivate.ManagedVPNProperties; @@ -831,7 +775,6 @@ * IPsec: (!chrome.networkingPrivate.IPSecProperties|undefined), * ThirdPartyVPN: (!chrome.networkingPrivate.ThirdPartyVPNProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-VPNStateProperties */ chrome.networkingPrivate.VPNStateProperties; @@ -852,7 +795,6 @@ * Security: (string|undefined), * SignalStrength: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-WiFiProperties */ chrome.networkingPrivate.WiFiProperties; @@ -873,7 +815,6 @@ * Security: !chrome.networkingPrivate.ManagedDOMString, * SignalStrength: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedWiFiProperties */ chrome.networkingPrivate.ManagedWiFiProperties; @@ -886,7 +827,6 @@ * SignalStrength: (number|undefined), * SSID: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-WiFiStateProperties */ chrome.networkingPrivate.WiFiStateProperties; @@ -896,7 +836,6 @@ * EAP: (!chrome.networkingPrivate.EAPProperties|undefined), * SignalStrength: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-WiMAXProperties */ chrome.networkingPrivate.WiMAXProperties; @@ -906,7 +845,6 @@ * EAP: (!chrome.networkingPrivate.ManagedEAPProperties|undefined), * SignalStrength: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedWiMAXProperties */ chrome.networkingPrivate.ManagedWiMAXProperties; @@ -914,7 +852,6 @@ * @typedef {{ * SignalStrength: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-WiMAXStateProperties */ chrome.networkingPrivate.WiMAXStateProperties; @@ -934,7 +871,6 @@ * WiFi: (!chrome.networkingPrivate.WiFiProperties|undefined), * WiMAX: (!chrome.networkingPrivate.WiMAXProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkConfigProperties */ chrome.networkingPrivate.NetworkConfigProperties; @@ -963,7 +899,6 @@ * WiFi: (!chrome.networkingPrivate.WiFiProperties|undefined), * WiMAX: (!chrome.networkingPrivate.WiMAXProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkProperties */ chrome.networkingPrivate.NetworkProperties; @@ -992,7 +927,6 @@ * WiFi: (!chrome.networkingPrivate.ManagedWiFiProperties|undefined), * WiMAX: (!chrome.networkingPrivate.ManagedWiMAXProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-ManagedProperties */ chrome.networkingPrivate.ManagedProperties; @@ -1013,7 +947,6 @@ * WiFi: (!chrome.networkingPrivate.WiFiStateProperties|undefined), * WiMAX: (!chrome.networkingPrivate.WiMAXStateProperties|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkStateProperties */ chrome.networkingPrivate.NetworkStateProperties; @@ -1025,7 +958,6 @@ * State: !chrome.networkingPrivate.DeviceStateType, * Type: !chrome.networkingPrivate.NetworkType * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-DeviceStateProperties */ chrome.networkingPrivate.DeviceStateProperties; @@ -1040,7 +972,6 @@ * deviceSsid: string, * deviceBssid: string * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-VerificationProperties */ chrome.networkingPrivate.VerificationProperties; @@ -1051,7 +982,6 @@ * configured: (boolean|undefined), * limit: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-NetworkFilter */ chrome.networkingPrivate.NetworkFilter; @@ -1060,7 +990,6 @@ * AllowOnlyPolicyNetworksToAutoconnect: (boolean|undefined), * AllowOnlyPolicyNetworksToConnect: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-GlobalPolicy */ chrome.networkingPrivate.GlobalPolicy; @@ -1073,7 +1002,6 @@ * PKCS11Id: (string|undefined), * hardwareBacked: boolean * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-Certificate */ chrome.networkingPrivate.Certificate; @@ -1082,7 +1010,6 @@ * serverCaCertificates: !Array<!chrome.networkingPrivate.Certificate>, * userCertificates: !Array<!chrome.networkingPrivate.Certificate> * }} - * @see https://developer.chrome.com/extensions/networkingPrivate#type-CertificateLists */ chrome.networkingPrivate.CertificateLists; @@ -1092,7 +1019,6 @@ * @param {string} networkGuid The GUID of the network to get properties for. * @param {function(!chrome.networkingPrivate.NetworkProperties):void} callback * Called with the network properties when received. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getProperties */ chrome.networkingPrivate.getProperties = function(networkGuid, callback) {}; @@ -1103,7 +1029,6 @@ * @param {string} networkGuid The GUID of the network to get properties for. * @param {function(!chrome.networkingPrivate.ManagedProperties):void} callback * Called with the managed network properties when received. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getManagedProperties */ chrome.networkingPrivate.getManagedProperties = function(networkGuid, callback) {}; @@ -1118,7 +1043,6 @@ * @param {string} networkGuid The GUID of the network to get properties for. * @param {function(!chrome.networkingPrivate.NetworkStateProperties):void} * callback Called immediately with the network state properties. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getState */ chrome.networkingPrivate.getState = function(networkGuid, callback) {}; @@ -1130,7 +1054,6 @@ * @param {!chrome.networkingPrivate.NetworkConfigProperties} properties The * properties to set. * @param {function():void=} callback Called when the operation has completed. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-setProperties */ chrome.networkingPrivate.setProperties = function(networkGuid, properties, callback) {}; @@ -1144,7 +1067,6 @@ * properties to configure the new network with. * @param {function(string):void=} callback Called with the GUID for the new * network configuration once the network has been created. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-createNetwork */ chrome.networkingPrivate.createNetwork = function(shared, properties, callback) {}; @@ -1155,7 +1077,6 @@ * configuration exists, an error will be set and the operation will fail. * @param {string} networkGuid The GUID of the network to forget. * @param {function():void=} callback Called when the operation has completed. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-forgetNetwork */ chrome.networkingPrivate.forgetNetwork = function(networkGuid, callback) {}; @@ -1170,7 +1091,6 @@ * @param {function(!Array<!chrome.networkingPrivate.NetworkStateProperties>):void} * callback Called with a dictionary of networks and their state * properties when received. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getNetworks */ chrome.networkingPrivate.getNetworks = function(filter, callback) {}; @@ -1181,7 +1101,6 @@ * @param {function(!Array<!chrome.networkingPrivate.NetworkStateProperties>):void} * callback * @deprecated Use getNetworks. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getVisibleNetworks */ chrome.networkingPrivate.getVisibleNetworks = function(networkType, callback) {}; @@ -1190,7 +1109,6 @@ * @param {function(!Array<!chrome.networkingPrivate.NetworkType>):void} * callback * @deprecated Use getDeviceStates. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getEnabledNetworkTypes */ chrome.networkingPrivate.getEnabledNetworkTypes = function(callback) {}; @@ -1198,7 +1116,6 @@ * Returns a list of $(ref:networkingPrivate.DeviceStateProperties) objects. * @param {function(!Array<!chrome.networkingPrivate.DeviceStateProperties>):void} * callback Called with a list of devices and their state. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getDeviceStates */ chrome.networkingPrivate.getDeviceStates = function(callback) {}; @@ -1207,7 +1124,6 @@ * represent multiple network types (e.g. 'Wireless'). * @param {!chrome.networkingPrivate.NetworkType} networkType The type of * network to enable. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-enableNetworkType */ chrome.networkingPrivate.enableNetworkType = function(networkType) {}; @@ -1216,7 +1132,6 @@ * $(ref:networkingPrivate.enableNetworkType). * @param {!chrome.networkingPrivate.NetworkType} networkType The type of * network to disable. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-disableNetworkType */ chrome.networkingPrivate.disableNetworkType = function(networkType) {}; @@ -1228,7 +1143,6 @@ * @param {!chrome.networkingPrivate.NetworkType=} networkType If provided, * requests a scan specific to the type. For Cellular a mobile network * scan will be requested if supported. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-requestNetworkScan */ chrome.networkingPrivate.requestNetworkScan = function(networkType) {}; @@ -1241,7 +1155,6 @@ * If the connect request immediately failed (e.g. the network is * unconfigured), $(ref:runtime.lastError) will be set with a failure * reason. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-startConnect */ chrome.networkingPrivate.startConnect = function(networkGuid, callback) {}; @@ -1250,7 +1163,6 @@ * @param {string} networkGuid The GUID of the network to disconnect from. * @param {function():void=} callback Called when the disconnect request has * been sent. See note for $(ref:startConnect). - * @see https://developer.chrome.com/extensions/networkingPrivate#method-startDisconnect */ chrome.networkingPrivate.startDisconnect = function(networkGuid, callback) {}; @@ -1263,7 +1175,6 @@ * @param {string=} carrier Optional name of carrier to activate. * @param {function():void=} callback Called when the activation request has * been sent. See note for $(ref:startConnect). - * @see https://developer.chrome.com/extensions/networkingPrivate#method-startActivate */ chrome.networkingPrivate.startActivate = function(networkGuid, carrier, callback) {}; @@ -1275,7 +1186,6 @@ * @param {function(boolean):void} callback A callback function that indicates * whether or not the device is a trusted device. * @deprecated Use networking.castPrivate API. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-verifyDestination */ chrome.networkingPrivate.verifyDestination = function(properties, callback) {}; @@ -1289,7 +1199,6 @@ * @param {function(string):void} callback A callback function that receives * base64-encoded encrypted credential data to send to a trusted device. * @deprecated Use networking.castPrivate API. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-verifyAndEncryptCredentials */ chrome.networkingPrivate.verifyAndEncryptCredentials = function(properties, networkGuid, callback) {}; @@ -1303,7 +1212,6 @@ * @param {function(string):void} callback A callback function that receives * base64-encoded encrypted data to send to a trusted device. * @deprecated Use networking.castPrivate API. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-verifyAndEncryptData */ chrome.networkingPrivate.verifyAndEncryptData = function(properties, data, callback) {}; @@ -1319,7 +1227,6 @@ * indicates that the lookup timed out. Otherwise a valid status is * returned (see $(ref:getWifiTDLSStatus)). * @deprecated Use networking.castPrivate API. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-setWifiTDLSEnabledState */ chrome.networkingPrivate.setWifiTDLSEnabledState = function(ip_or_mac_address, enabled, callback) {}; @@ -1330,7 +1237,6 @@ * string with the current TDLS status which can be 'Connected', * 'Disabled', 'Disconnected', 'Nonexistent', or 'Unknown'. * @deprecated Use networking.castPrivate API. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getWifiTDLSStatus */ chrome.networkingPrivate.getWifiTDLSStatus = function(ip_or_mac_address, callback) {}; @@ -1341,7 +1247,6 @@ * @param {function(!chrome.networkingPrivate.CaptivePortalStatus):void} * callback A callback function that returns the results of the query for * network captive portal status. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getCaptivePortalStatus */ chrome.networkingPrivate.getCaptivePortalStatus = function(networkGuid, callback) {}; @@ -1356,7 +1261,6 @@ * @param {string} pin The current SIM PIN, or the new PIN if PUK is provided. * @param {string=} puk The operator provided PUK for unblocking a blocked SIM. * @param {function():void=} callback Called when the operation has completed. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-unlockCellularSim */ chrome.networkingPrivate.unlockCellularSim = function(networkGuid, pin, puk, callback) {}; @@ -1373,7 +1277,6 @@ * @param {!chrome.networkingPrivate.CellularSimState} simState The SIM state to * set. * @param {function():void=} callback Called when the operation has completed. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-setCellularSimState */ chrome.networkingPrivate.setCellularSimState = function(networkGuid, simState, callback) {}; @@ -1385,7 +1288,6 @@ * network for. If empty, the default cellular device will be used. * @param {string} networkId The networkId to select. * @param {function():void=} callback Called when the operation has completed. - * @see https://developer.chrome.com/extensions/networkingPrivate#method-selectCellularMobileNetwork */ chrome.networkingPrivate.selectCellularMobileNetwork = function(networkGuid, networkId, callback) {}; @@ -1393,14 +1295,12 @@ * Gets the global policy properties. These properties are not expected to * change during a session. * @param {function(!chrome.networkingPrivate.GlobalPolicy):void} callback - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getGlobalPolicy */ chrome.networkingPrivate.getGlobalPolicy = function(callback) {}; /** * Gets the lists of certificates available for network configuration. * @param {function(!chrome.networkingPrivate.CertificateLists):void} callback - * @see https://developer.chrome.com/extensions/networkingPrivate#method-getCertificateLists */ chrome.networkingPrivate.getCertificateLists = function(callback) {}; @@ -1408,7 +1308,6 @@ * Fired when the properties change on any of the networks. Sends a list of * GUIDs for networks whose properties have changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/networkingPrivate#event-onNetworksChanged */ chrome.networkingPrivate.onNetworksChanged; @@ -1416,7 +1315,6 @@ * Fired when the list of networks has changed. Sends a complete list of GUIDs * for all the current networks. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/networkingPrivate#event-onNetworkListChanged */ chrome.networkingPrivate.onNetworkListChanged; @@ -1424,7 +1322,6 @@ * Fired when the list of devices has changed or any device state properties * have changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/networkingPrivate#event-onDeviceStateListChanged */ chrome.networkingPrivate.onDeviceStateListChanged; @@ -1432,13 +1329,11 @@ * Fired when a portal detection for a network completes. Sends the guid of the * network and the corresponding captive portal status. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/networkingPrivate#event-onPortalDetectionCompleted */ chrome.networkingPrivate.onPortalDetectionCompleted; /** * Fired when any certificate list has changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/networkingPrivate#event-onCertificateListsChanged */ chrome.networkingPrivate.onCertificateListsChanged;
diff --git a/third_party/closure_compiler/externs/passwords_private.js b/third_party/closure_compiler/externs/passwords_private.js index ce982ad..af5735bd 100644 --- a/third_party/closure_compiler/externs/passwords_private.js +++ b/third_party/closure_compiler/externs/passwords_private.js
@@ -18,7 +18,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/passwordsPrivate#type-ExportProgressStatus */ chrome.passwordsPrivate.ExportProgressStatus = { NOT_STARTED: 'NOT_STARTED', @@ -34,7 +33,6 @@ * shown: string, * link: string * }} - * @see https://developer.chrome.com/extensions/passwordsPrivate#type-UrlCollection */ chrome.passwordsPrivate.UrlCollection; @@ -43,7 +41,6 @@ * urls: !chrome.passwordsPrivate.UrlCollection, * username: string * }} - * @see https://developer.chrome.com/extensions/passwordsPrivate#type-LoginPair */ chrome.passwordsPrivate.LoginPair; @@ -54,7 +51,6 @@ * federationText: (string|undefined), * index: number * }} - * @see https://developer.chrome.com/extensions/passwordsPrivate#type-PasswordUiEntry */ chrome.passwordsPrivate.PasswordUiEntry; @@ -63,7 +59,6 @@ * index: number, * plaintextPassword: string * }} - * @see https://developer.chrome.com/extensions/passwordsPrivate#type-PlaintextPasswordEventParameters */ chrome.passwordsPrivate.PlaintextPasswordEventParameters; @@ -72,7 +67,6 @@ * urls: !chrome.passwordsPrivate.UrlCollection, * index: number * }} - * @see https://developer.chrome.com/extensions/passwordsPrivate#type-ExceptionEntry */ chrome.passwordsPrivate.ExceptionEntry; @@ -81,7 +75,6 @@ * status: !chrome.passwordsPrivate.ExportProgressStatus, * message: (string|undefined), * }} - * @see https://developer.chrome.com/extensions/passwordsPrivate#type-PasswordExportProgress */ chrome.passwordsPrivate.PasswordExportProgress; @@ -89,7 +82,6 @@ * Removes the saved password corresponding to |loginPair|. If no saved password * for this pair exists, this function is a no-op. * @param {number} index The index for the password entry being removed. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-removeSavedPassword */ chrome.passwordsPrivate.removeSavedPassword = function(index) {}; @@ -97,13 +89,11 @@ * Removes the saved password exception corresponding to |exceptionUrl|. If no * exception with this URL exists, this function is a no-op. * @param {number} index The index for the exception url entry being removed. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-removePasswordException */ chrome.passwordsPrivate.removePasswordException = function(index) {}; /** * Undoes the last removal of a saved password or exception. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-undoRemoveSavedPasswordOrException */ chrome.passwordsPrivate.undoRemoveSavedPasswordOrException = function() {}; @@ -114,7 +104,6 @@ * onPlaintextPasswordRetrieved event. TODO(hcarmona): Investigate using a * callback for consistency. * @param {number} index The index for the password entry being being retrieved. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-requestPlaintextPassword */ chrome.passwordsPrivate.requestPlaintextPassword = function(index) {}; @@ -122,7 +111,6 @@ * Returns the list of saved passwords. * @param {function(!Array<!chrome.passwordsPrivate.PasswordUiEntry>):void} * callback Called with the list of saved passwords. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-getSavedPasswordList */ chrome.passwordsPrivate.getSavedPasswordList = function(callback) {}; @@ -130,13 +118,11 @@ * Returns the list of password exceptions. * @param {function(!Array<!chrome.passwordsPrivate.ExceptionEntry>):void} * callback Called with the list of password exceptions. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-getPasswordExceptionList */ chrome.passwordsPrivate.getPasswordExceptionList = function(callback) {}; /** * Triggers the Password Manager password import functionality. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-importPasswords */ chrome.passwordsPrivate.importPasswords = function() {}; @@ -146,13 +132,11 @@ * callback Called with no error, if the new export request was accepted and * started. If rejected, <code>chrome.runtime.lastError</code> will be * set to 'in-progress'. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-exportPasswords */ chrome.passwordsPrivate.exportPasswords = function(callback) {}; /** * Triggers the cancelling of a password export flow. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-cancelExportPasswords */ chrome.passwordsPrivate.cancelExportPasswords = function() {}; @@ -160,7 +144,6 @@ * Triggers the Password Manager password export status query functionality. * @param {function(!chrome.passwordsPrivate.ExportProgressStatus):void} * callback Called with the status of the current export. - * @see https://developer.chrome.com/extensions/passwordsPrivate#method-requestExportProgressStatus */ chrome.passwordsPrivate.requestExportProgressStatus = function(callback) {}; @@ -168,7 +151,6 @@ * Fired when the saved passwords list has changed, meaning that an entry has * been added or removed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/passwordsPrivate#event-onSavedPasswordsListChanged */ chrome.passwordsPrivate.onSavedPasswordsListChanged; @@ -176,7 +158,6 @@ * Fired when the password exceptions list has changed, meaning that an entry * has been added or removed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/passwordsPrivate#event-onPasswordExceptionsListChanged */ chrome.passwordsPrivate.onPasswordExceptionsListChanged; @@ -184,7 +165,6 @@ * Fired when a plaintext password has been fetched in response to a call to * chrome.passwordsPrivate.requestPlaintextPassword(). * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/passwordsPrivate#event-onPlaintextPasswordRetrieved */ chrome.passwordsPrivate.onPlaintextPasswordRetrieved; @@ -192,6 +172,5 @@ /** * Fired when status of the export has progressed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/passwordsPrivate#event-onPasswordsExportCompleted */ chrome.passwordsPrivate.onPasswordsFileExportProgress;
diff --git a/third_party/closure_compiler/externs/quick_unlock_private.js b/third_party/closure_compiler/externs/quick_unlock_private.js index 4229b89e..38d1786 100644 --- a/third_party/closure_compiler/externs/quick_unlock_private.js +++ b/third_party/closure_compiler/externs/quick_unlock_private.js
@@ -21,13 +21,11 @@ * token: string, * lifetimeSeconds: number * }} - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-TokenInfo */ chrome.quickUnlockPrivate.TokenInfo; /** * @enum {string} - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-QuickUnlockMode */ chrome.quickUnlockPrivate.QuickUnlockMode = { PIN: 'PIN', @@ -35,7 +33,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-CredentialProblem */ chrome.quickUnlockPrivate.CredentialProblem = { TOO_SHORT: 'TOO_SHORT', @@ -49,7 +46,6 @@ * errors: !Array<!chrome.quickUnlockPrivate.CredentialProblem>, * warnings: !Array<!chrome.quickUnlockPrivate.CredentialProblem> * }} - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-CredentialCheck */ chrome.quickUnlockPrivate.CredentialCheck; @@ -58,7 +54,6 @@ * minLength: number, * maxLength: number * }} - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#type-CredentialRequirements */ chrome.quickUnlockPrivate.CredentialRequirements; @@ -67,7 +62,6 @@ * seconds until the token expires. * @param {string} accountPassword The account password for the logged in user. * @param {function(!chrome.quickUnlockPrivate.TokenInfo):void} onComplete - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getAuthToken */ chrome.quickUnlockPrivate.getAuthToken = function(accountPassword, onComplete) {}; @@ -79,7 +73,6 @@ * @param {string} token The token returned by $(ref:getAuthToken). * @param {boolean} enabled * @param {function():void=} onComplete - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-setLockScreenEnabled */ chrome.quickUnlockPrivate.setLockScreenEnabled = function(token, enabled, onComplete) {}; @@ -88,7 +81,6 @@ * Some quick unlock modes may be disabled by policy. * @param {function(!Array<!chrome.quickUnlockPrivate.QuickUnlockMode>):void} * onComplete - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getAvailableModes */ chrome.quickUnlockPrivate.getAvailableModes = function(onComplete) {}; @@ -97,7 +89,6 @@ * lock screen. * @param {function(!Array<!chrome.quickUnlockPrivate.QuickUnlockMode>):void} * onComplete - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getActiveModes */ chrome.quickUnlockPrivate.getActiveModes = function(onComplete) {}; @@ -110,7 +101,6 @@ * @param {function(!chrome.quickUnlockPrivate.CredentialCheck):void} onComplete * Called with a list of warnings and errors the given |credential| has * (or an empty list if there are none). - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-checkCredential */ chrome.quickUnlockPrivate.checkCredential = function(mode, credential, onComplete) {}; @@ -121,7 +111,6 @@ * @param {function(!chrome.quickUnlockPrivate.CredentialRequirements):void} * onComplete Called with the credential requirements of the given * |mode|. - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-getCredentialRequirements */ chrome.quickUnlockPrivate.getCredentialRequirements = function(mode, onComplete) {}; @@ -136,13 +125,11 @@ * @param {function():void} onComplete Called with true if the quick unlock * state was updated, false otherwise. The update is treated as a single * atomic operation. - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#method-setModes */ chrome.quickUnlockPrivate.setModes = function(token, modes, credentials, onComplete) {}; /** * Called after the active set of quick unlock modes has changed. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/quickUnlockPrivate#event-onActiveModesChanged */ chrome.quickUnlockPrivate.onActiveModesChanged;
diff --git a/third_party/closure_compiler/externs/safe_browsing_private.js b/third_party/closure_compiler/externs/safe_browsing_private.js index 48e7ef89..d11808b9 100644 --- a/third_party/closure_compiler/externs/safe_browsing_private.js +++ b/third_party/closure_compiler/externs/safe_browsing_private.js
@@ -22,7 +22,6 @@ * userName: string, * isPhishing: boolean * }} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#type-PolicySpecifiedPasswordReuse */ chrome.safeBrowsingPrivate.PolicySpecifiedPasswordReuse; @@ -33,7 +32,6 @@ * sha256: string, * userName: (string|undefined) * }} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#type-DangerousDownloadInfo */ chrome.safeBrowsingPrivate.DangerousDownloadInfo; @@ -43,41 +41,35 @@ * reason: string, * netErrorCode: (number|undefined) * }} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#type-InterstitialInfo */ chrome.safeBrowsingPrivate.InterstitialInfo; /** * Fired when Chrome detects a reuse of a policy specified password. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onPolicySpecifiedPasswordReuseDetected */ chrome.safeBrowsingPrivate.onPolicySpecifiedPasswordReuseDetected; /** * Fired when the user changed their policy specified password. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onPolicySpecifiedPasswordChanged */ chrome.safeBrowsingPrivate.onPolicySpecifiedPasswordChanged; /** * Fired when the user opened a dangerous download. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onDangerousDownloadOpened */ chrome.safeBrowsingPrivate.onDangerousDownloadOpened; /** * Fired when a security interstitial is shown to the user. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onInterstitialShown */ chrome.safeBrowsingPrivate.onInterstitialShown; /** * Fired when the user clicked-through a security interstitial. * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/safeBrowsingPrivate#event-onInterstitialProceeded */ chrome.safeBrowsingPrivate.onInterstitialProceeded;
diff --git a/third_party/closure_compiler/externs/settings_private.js b/third_party/closure_compiler/externs/settings_private.js index f62dd3f..a95a2ff 100644 --- a/third_party/closure_compiler/externs/settings_private.js +++ b/third_party/closure_compiler/externs/settings_private.js
@@ -18,7 +18,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/settingsPrivate#type-PrefType */ chrome.settingsPrivate.PrefType = { BOOLEAN: 'BOOLEAN', @@ -31,7 +30,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/settingsPrivate#type-ControlledBy */ chrome.settingsPrivate.ControlledBy = { DEVICE_POLICY: 'DEVICE_POLICY', @@ -43,7 +41,6 @@ /** * @enum {string} - * @see https://developer.chrome.com/extensions/settingsPrivate#type-Enforcement */ chrome.settingsPrivate.Enforcement = { ENFORCED: 'ENFORCED', @@ -62,7 +59,6 @@ * extensionId: (string|undefined), * extensionCanBeDisabled: (boolean|undefined) * }} - * @see https://developer.chrome.com/extensions/settingsPrivate#type-PrefObject */ chrome.settingsPrivate.PrefObject; @@ -73,14 +69,12 @@ * @param {string} pageId The user metrics identifier or null. * @param {function(boolean):void} callback The callback for whether the pref * was set or not. - * @see https://developer.chrome.com/extensions/settingsPrivate#method-setPref */ chrome.settingsPrivate.setPref = function(name, value, pageId, callback) {}; /** * Gets an array of all the prefs. * @param {function(!Array<!chrome.settingsPrivate.PrefObject>):void} callback - * @see https://developer.chrome.com/extensions/settingsPrivate#method-getAllPrefs */ chrome.settingsPrivate.getAllPrefs = function(callback) {}; @@ -88,7 +82,6 @@ * Gets the value of a specific pref. * @param {string} name * @param {function(!chrome.settingsPrivate.PrefObject):void} callback - * @see https://developer.chrome.com/extensions/settingsPrivate#method-getPref */ chrome.settingsPrivate.getPref = function(name, callback) {}; @@ -96,7 +89,6 @@ * Gets the default page zoom factor. Possible values are currently between 0.25 * and 5. For a full list, see zoom::kPresetZoomFactors. * @param {function(number):void} callback - * @see https://developer.chrome.com/extensions/settingsPrivate#method-getDefaultZoom */ chrome.settingsPrivate.getDefaultZoom = function(callback) {}; @@ -105,7 +97,6 @@ * zoom::kPresetZoomFactors. * @param {number} zoom * @param {function(boolean):void=} callback - * @see https://developer.chrome.com/extensions/settingsPrivate#method-setDefaultZoom */ chrome.settingsPrivate.setDefaultZoom = function(zoom, callback) {}; @@ -113,6 +104,5 @@ * <p>Fired when a set of prefs has changed.</p><p>|prefs| The prefs that * changed.</p> * @type {!ChromeEvent} - * @see https://developer.chrome.com/extensions/settingsPrivate#event-onPrefsChanged */ chrome.settingsPrivate.onPrefsChanged;
diff --git a/third_party/closure_compiler/externs/users_private.js b/third_party/closure_compiler/externs/users_private.js index c7338c5..57bb0c0 100644 --- a/third_party/closure_compiler/externs/users_private.js +++ b/third_party/closure_compiler/externs/users_private.js
@@ -25,14 +25,12 @@ * isSupervised: boolean, * isChild: boolean * }} - * @see https://developer.chrome.com/extensions/usersPrivate#type-User */ chrome.usersPrivate.User; /** * Gets a list of the currently whitelisted users. * @param {function(!Array<!chrome.usersPrivate.User>):void} callback - * @see https://developer.chrome.com/extensions/usersPrivate#method-getWhitelistedUsers */ chrome.usersPrivate.getWhitelistedUsers = function(callback) {}; @@ -42,7 +40,6 @@ * because the user was already present, or the current user isn't the owner). * @param {string} email * @param {function(boolean):void} callback - * @see https://developer.chrome.com/extensions/usersPrivate#method-addWhitelistedUser */ chrome.usersPrivate.addWhitelistedUser = function(email, callback) {}; @@ -53,20 +50,17 @@ * owner). * @param {string} email * @param {function(boolean):void} callback - * @see https://developer.chrome.com/extensions/usersPrivate#method-removeWhitelistedUser */ chrome.usersPrivate.removeWhitelistedUser = function(email, callback) {}; /** * Whether the whitelist is managed by enterprise. * @param {function(boolean):void} callback - * @see https://developer.chrome.com/extensions/usersPrivate#method-isWhitelistManaged */ chrome.usersPrivate.isWhitelistManaged = function(callback) {}; /** * Returns the current user. * @param {function(!chrome.usersPrivate.User):void} callback - * @see https://developer.chrome.com/extensions/usersPrivate#method-getCurrentUser */ chrome.usersPrivate.getCurrentUser = function(callback) {};
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index 4dba16b..62abc55 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Short Name: crashpad URL: https://crashpad.chromium.org/ Version: unknown -Revision: 7c6d2334a93ce5ae9d376db9f8f577a51682338f +Revision: c0a0d70a2b7a5d973828e6079386cb2a852e5b1c License: Apache 2.0 License File: crashpad/LICENSE Security Critical: yes
diff --git a/third_party/crashpad/crashpad/BUILD.gn b/third_party/crashpad/crashpad/BUILD.gn index e09f72dd..065a5e1 100644 --- a/third_party/crashpad/crashpad/BUILD.gn +++ b/third_party/crashpad/crashpad/BUILD.gn
@@ -45,6 +45,7 @@ "snapshot:crashpad_snapshot_test_module_large", "snapshot:crashpad_snapshot_test_module_small", "test:crashpad_test_test_multiprocess_exec_test_child", + "util:generate_test_server_key", "util:http_transport_test_server", ] @@ -60,6 +61,17 @@ name = "http_transport_test_server" dest = "crashpad_test_data/http_transport_test_server" }, + + # These aren't actually tests, but that seems to be the only way to + # convince package() to get them from the output directory. + { + name = "crashpad_util_test_cert.pem" + dest = "crashpad_test_data/crashpad_util_test_cert.pem" + }, + { + name = "crashpad_util_test_key.pem" + dest = "crashpad_test_data/crashpad_util_test_key.pem" + }, ] loadable_modules = [
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS index d9231e1..fbbd899 100644 --- a/third_party/crashpad/crashpad/DEPS +++ b/third_party/crashpad/crashpad/DEPS
@@ -29,7 +29,7 @@ '5e2b3ddde7cda5eb6bc09a5546a76b00e49d888f', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - 'd5a36d3c51a7a270afc2c888baaaec2a6e496219', + 'd5523a7033c013dd2ae73fa29428f7b70dc0b3a0', 'crashpad/third_party/libfuzzer/src': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' + 'fda403cf93ecb8792cb1d061564d89a6553ca020',
diff --git a/third_party/crashpad/crashpad/client/annotation.h b/third_party/crashpad/crashpad/client/annotation.h index c7d92d80..46cde62 100644 --- a/third_party/crashpad/crashpad/client/annotation.h +++ b/third_party/crashpad/crashpad/client/annotation.h
@@ -72,7 +72,7 @@ static constexpr size_t kNameMaxLength = 64; //! \brief The maximum size of an annotation’s value, in bytes. - static constexpr size_t kValueMaxSize = 2048; + static constexpr size_t kValueMaxSize = 5 * 4096; //! \brief The type used for \a SetSize(). using ValueSizeType = uint32_t;
diff --git a/third_party/crashpad/crashpad/doc/developing.md b/third_party/crashpad/crashpad/doc/developing.md index c8bb430..84d1cf7 100644 --- a/third_party/crashpad/crashpad/doc/developing.md +++ b/third_party/crashpad/crashpad/doc/developing.md
@@ -86,28 +86,25 @@ ## Building -Crashpad uses [GYP](https://gyp.gsrc.io/) to generate -[Ninja](https://ninja-build.org/) build files. The build is described by `.gyp` -files throughout the Crashpad source code tree. The -[`build/gyp_crashpad.py`](https://chromium.googlesource.com/crashpad/crashpad/+/master/build/gyp_crashpad.py) -script runs GYP properly for Crashpad, and is also called when you run `fetch -crashpad`, `gclient sync`, or `gclient runhooks`. +### Windows, Mac, Linux, Fuchsia -The Ninja build files and build output are in the `out` directory. Both debug- -and release-mode configurations are available. The examples below show the debug -configuration. To build and test the release configuration, substitute `Release` -for `Debug`. On Windows, four configurations are available: `Debug` and -`Release` produce 32-bit x86 executables, and `Debug_x64` and `Release_x64` -produce x86_64 executables. +On Windows, Mac, Linux, and Fuchsia Crashpad uses +[GN](https://gn.googlesource.com/gn) to generate +[Ninja](https://ninja-build.org/) build files. For example, ``` $ cd ~/crashpad/crashpad -$ ninja -C out/Debug +$ gn gen out/Default +$ ninja -C out/Default ``` -Ninja is part of the +You can then use `gn args out/Default` or edit `out/Default/args.gn` to +configure the build, for example things like `is_debug=true` or +`target_cpu="x86"`. + +GN and Ninja are part of the [depot_tools](https://www.chromium.org/developers/how-tos/depottools). There’s -no need to install it separately. +no need to install them separately. ### Android
diff --git a/third_party/crashpad/crashpad/test/test_paths.cc b/third_party/crashpad/crashpad/test/test_paths.cc index 7bfc5de0..50165e4 100644 --- a/third_party/crashpad/crashpad/test/test_paths.cc +++ b/third_party/crashpad/crashpad/test/test_paths.cc
@@ -232,6 +232,14 @@ break; case FileType::kCertificate: +#if defined(CRASHPAD_IS_IN_FUCHSIA) + // When running in the Fuchsia tree, the .pem files are packaged as assets + // into the test data folder. This will need to be rationalized when + // things are actually run from a package. + // https://crashpad.chromium.org/bug/196. + directory = + base::FilePath(FILE_PATH_LITERAL("/system/test/crashpad_test_data")); +#endif extension = FILE_PATH_LITERAL(".pem"); break; }
diff --git a/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc b/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc index c587196..ca0fd56 100644 --- a/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc +++ b/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc
@@ -40,80 +40,42 @@ return basic.type; } -enum class SuspensionResult { - FailedSuspendCall, - FailedToSuspendInTimelyFashion, - Succeeded, -}; - -SuspensionResult SuspendThread(zx_handle_t thread) { - zx_status_t status = zx_task_suspend(thread); - ZX_LOG_IF(ERROR, status != ZX_OK, status) << "zx_task_suspend"; - if (status != ZX_OK) - return SuspensionResult::FailedSuspendCall; - // zx_task_suspend() suspends the thread "sometime soon", but it's hard to - // use when it's not guaranteed to be suspended after return. Try reading the - // thread state until the registers are retrievable, which means that the - // thread is actually suspended. Don't wait forever in case the suspend - // failed for whatever reason, but try a few times. - for (int i = 0; i < 5; ++i) { - zx_thread_state_general_regs_t regs; - status = zx_thread_read_state( - thread, ZX_THREAD_STATE_GENERAL_REGS, ®s, sizeof(regs)); - if (status == ZX_OK) { - return SuspensionResult::Succeeded; - } - zx_nanosleep(zx_deadline_after(ZX_MSEC(10))); +// Returns the suspend token of the suspended thread. This function attempts +// to wait a short time for the thread to actually suspend before returning +// but this is not guaranteed. +base::ScopedZxHandle SuspendThread(zx_handle_t thread) { + zx_handle_t token = ZX_HANDLE_INVALID; + zx_status_t status = zx_task_suspend_token(thread, &token); + if (status != ZX_OK) { + ZX_LOG(ERROR, status) << "zx_task_suspend"; + base::ScopedZxHandle(); } - LOG(ERROR) << "thread failed to suspend"; - return SuspensionResult::FailedToSuspendInTimelyFashion; -} -bool ResumeThread(zx_handle_t thread) { - zx_status_t status = zx_task_resume(thread, 0); - ZX_LOG_IF(ERROR, status != ZX_OK, status) << "zx_task_resume"; - return status == ZX_OK; + zx_signals_t observed = 0u; + if (zx_object_wait_one(thread, ZX_THREAD_SUSPENDED, + zx_deadline_after(ZX_MSEC(50)), &observed) != ZX_OK) { + LOG(ERROR) << "thread failed to suspend"; + } + return base::ScopedZxHandle(token); } } // namespace -ScopedTaskSuspend::ScopedTaskSuspend(zx_handle_t task) : task_(task) { - DCHECK_NE(task_, zx_process_self()); - DCHECK_NE(task_, zx_thread_self()); +ScopedTaskSuspend::ScopedTaskSuspend(zx_handle_t task) { + DCHECK_NE(task, zx_process_self()); + DCHECK_NE(task, zx_thread_self()); - zx_obj_type_t type = GetHandleType(task_); + zx_obj_type_t type = GetHandleType(task); if (type == ZX_OBJ_TYPE_THREAD) { - // Note that task_ is only marked invalid if the zx_task_suspend() call - // completely fails, otherwise the suspension might just not have taken - // effect yet, so avoid leaving it suspended forever by still resuming on - // destruction. - if (SuspendThread(task_) == SuspensionResult::FailedSuspendCall) { - task_ = ZX_HANDLE_INVALID; - } + suspend_tokens_.push_back(SuspendThread(task)); } else if (type == ZX_OBJ_TYPE_PROCESS) { - for (const auto& thread : GetChildHandles(task_, ZX_INFO_PROCESS_THREADS)) { - SuspendThread(thread.get()); - } + for (const auto& thread : GetChildHandles(task, ZX_INFO_PROCESS_THREADS)) + suspend_tokens_.push_back(SuspendThread(thread.get())); } else { LOG(ERROR) << "unexpected handle type"; - task_ = ZX_HANDLE_INVALID; } } -ScopedTaskSuspend::~ScopedTaskSuspend() { - if (task_ != ZX_HANDLE_INVALID) { - zx_obj_type_t type = GetHandleType(task_); - if (type == ZX_OBJ_TYPE_THREAD) { - ResumeThread(task_); - } else if (type == ZX_OBJ_TYPE_PROCESS) { - for (const auto& thread : - GetChildHandles(task_, ZX_INFO_PROCESS_THREADS)) { - ResumeThread(thread.get()); - } - } else { - LOG(ERROR) << "unexpected handle type"; - } - } -} +ScopedTaskSuspend::~ScopedTaskSuspend() = default; } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.h b/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.h index d3790c8..f817364d 100644 --- a/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.h +++ b/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.h
@@ -17,20 +17,21 @@ #include <zircon/types.h> +#include <vector> + +#include "base/fuchsia/scoped_zx_handle.h" #include "base/macros.h" namespace crashpad { //! \brief Manages the suspension of another task. //! -//! Currently, suspends and resumes are not counted on Fuchsia, so while this -//! class attempts to manage suspension of a task, if another caller or process -//! is simultaneously suspending or resuming this task, the results may not be -//! as expected. +//! The underlying API only supports suspending threads (despite its name) not +//! entire tasks. As a result, it's possible some threads may not be correctly +//! suspended/resumed as their creation might race enumeration. //! -//! Additionally, the underlying API only supports suspending threads (despite -//! its name) not entire tasks. As a result, it's possible some threads may not -//! be correctly suspended/resumed as their creation might race enumeration. +//! Additionally, suspending a thread is asynchronous and may take an +//! arbitrary amount of time. //! //! Because of these limitations, this class is limited to being a best-effort, //! and correct suspension/resumption cannot be relied upon. @@ -43,7 +44,8 @@ ~ScopedTaskSuspend(); private: - zx_handle_t task_; // weak + // Could be one (for a thread) or many (for every process in a thread). + std::vector<base::ScopedZxHandle> suspend_tokens_; DISALLOW_COPY_AND_ASSIGN(ScopedTaskSuspend); };
diff --git a/third_party/crashpad/crashpad/util/net/generate_test_server_key.py b/third_party/crashpad/crashpad/util/net/generate_test_server_key.py index 5f67bb87..6e6340e 100755 --- a/third_party/crashpad/crashpad/util/net/generate_test_server_key.py +++ b/third_party/crashpad/crashpad/util/net/generate_test_server_key.py
@@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import subprocess # GN requires a Python script for actions, so this just wraps the openssl @@ -23,4 +24,5 @@ cert = 'crashpad_util_test_cert.pem' subprocess.check_call( ['openssl', 'req', '-x509', '-nodes', '-subj', '/CN=localhost', - '-days', '365', '-newkey', 'rsa:2048', '-keyout', key, '-out', cert]) + '-days', '365', '-newkey', 'rsa:2048', '-keyout', key, '-out', cert], + stderr=open(os.devnull, 'w'))
diff --git a/tools/cfi/blacklist.txt b/tools/cfi/blacklist.txt index 2301ebdb..41e5b4d 100644 --- a/tools/cfi/blacklist.txt +++ b/tools/cfi/blacklist.txt
@@ -151,7 +151,6 @@ src:*chrome/browser/speech/tts_linux.cc src:*device/udev_linux/udev0_loader.cc src:*device/udev_linux/udev1_loader.cc -src:*net/proxy_resolution/proxy_config_service_linux.cc # Calls to auto-generated stubs by ui/gl/generate_bindings.py src:*ui/gl/gl_bindings_autogen_*
diff --git a/tools/grit/grit/tool/xmb.py b/tools/grit/grit/tool/xmb.py index c25dbf1..eb10e71 100755 --- a/tools/grit/grit/tool/xmb.py +++ b/tools/grit/grit/tool/xmb.py
@@ -165,6 +165,8 @@ return 'Exports all translateable messages into an XMB file.' def Run(self, opts, args): + os.environ['cwd'] = os.getcwd() + self.SetOptions(opts) limit_file = None
diff --git a/tools/grit/grit_info.py b/tools/grit/grit_info.py index a7f9601..3b85dab 100755 --- a/tools/grit/grit_info.py +++ b/tools/grit/grit_info.py
@@ -110,6 +110,8 @@ def DoMain(argv): + os.environ['cwd'] = os.getcwd() + parser = optparse.OptionParser() parser.add_option("--inputs", action="store_true", dest="inputs") parser.add_option("--outputs", action="store_true", dest="outputs")
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index c7ffbdc..5ecd026 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -12988,6 +12988,7 @@ </action> <action name="Net.URLRequest_StartJob_InvalidReferrer"> + <obsolete>Deprecated 6/2018.</obsolete> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> </action>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index b77f53fd..f5512e6 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -19957,6 +19957,7 @@ <int value="2" label="Chrome App"/> <int value="3" label="Drive App"/> <int value="4" label="ARC App"/> + <int value="5" label="Crostini App"/> </enum> <enum name="FileManagerVolumeType"> @@ -26266,6 +26267,12 @@ <int value="6" label="= 100%"/> </enum> +<enum name="LazyLoad.FrameInitialDeferralAction"> + <int value="0" label="Deferred"/> + <int value="1" label="Loaded because near or in viewport"/> + <int value="2" label="Loaded because hidden"/> +</enum> + <enum name="LevelDBCorruptionRestoreValue"> <int value="0" label="Database Delete Success"/> <int value="1" label="Database Delete Failure"/> @@ -27376,6 +27383,7 @@ <int value="-1052415111" label="malware-interstitial-v2"/> <int value="-1052219252" label="disable-captive-portal-bypass-proxy"/> <int value="-1048901516" label="ChromeMemex:enabled"/> + <int value="-1046641729" label="TranslateUI:enabled"/> <int value="-1046627610" label="password-import:enabled"/> <int value="-1045900007" label="NoCreditCardAbort:disabled"/> <int value="-1045882995" label="UseNewDoodleApi:enabled"/> @@ -27506,6 +27514,7 @@ <int value="-763759697" label="enable-audio-support-for-desktop-share"/> <int value="-762687134" label="ExperimentalCrostiniUI:enabled"/> <int value="-759830869" label="enable-tab-discarding"/> + <int value="-758048639" label="InfiniteSessionRestore:enabled"/> <int value="-757946835" label="OmniboxUIExperimentShowSuggestionFavicons:enabled"/> <int value="-751273871" label="AutofillCreditCardBankNameDisplay:enabled"/> @@ -27520,6 +27529,7 @@ <int value="-726892130" label="AndroidMessagesIntegration:disabled"/> <int value="-723224470" label="enable-password-force-saving:enabled"/> <int value="-722474177" label="browser-side-navigation:disabled"/> + <int value="-719819631" label="TranslateUI:disabled"/> <int value="-719147284" label="ExperimentalProductivityFeatures:disabled"/> <int value="-718884399" label="NewTabPageUIMd:enabled"/> <int value="-718626298" label="SysInternals:enabled"/> @@ -28129,6 +28139,7 @@ <int value="651844675" label="EasyUnlockPromotions:enabled"/> <int value="652561231" label="CustomContextMenu:enabled"/> <int value="659086147" label="OverlayScrollbarFlashWhenMouseEnter:enabled"/> + <int value="664363259" label="SiteCharacteristicsDatabase:enabled"/> <int value="665409384" label="AutofillToolkitViewsCreditCardDialogsMac:enabled"/> <int value="679931272" label="DcheckIsFatal:enabled"/> @@ -28241,6 +28252,7 @@ label="OmniboxUIExperimentElideSuggestionUrlAfterHost:enabled"/> <int value="908523940" label="PassiveEventListenersDueToFling:disabled"/> <int value="909439558" label="disable-device-discovery"/> + <int value="912119426" label="InfiniteSessionRestore:disabled"/> <int value="913138924" label="RecurrentInterstitialFeature:disabled"/> <int value="916316159" label="disable-new-app-list-mixer"/> <int value="918046854" label="NtlmV2Enabled:disabled"/> @@ -28256,6 +28268,7 @@ <int value="939554480" label="enable-credit-card-scan"/> <int value="939603162" label="BackgroundLoadingForDownloads:disabled"/> <int value="941036016" label="ContentSuggestionsSettings:disabled"/> + <int value="941883332" label="ProactiveTabFreezeAndDiscard:disabled"/> <int value="943319566" label="enable-intent-picker"/> <int value="946688335" label="OmniboxSpareRenderer:disabled"/> <int value="952558794" label="enable-remote-assistance"/> @@ -28394,6 +28407,7 @@ <int value="1221559505" label="enable-spelling-feedback-field-trial"/> <int value="1222017136" label="WebRtcUseEchoCanceller3:disabled"/> <int value="1226624874" label="Mus:disabled"/> + <int value="1228115769" label="SiteCharacteristicsDatabase:disabled"/> <int value="1235800887" label="V8Ignition:enabled"/> <int value="1235940786" label="ChromeHomePersistentIph:enabled"/> <int value="1237297772" label="no-pings"/> @@ -28403,6 +28417,7 @@ <int value="1247293682" label="topchrome-md"/> <int value="1250071868" label="disable-timezone-tracking-option"/> <int value="1253698118" label="ash-disable-stable-overview-order"/> + <int value="1257482622" label="PageAlmostIdle:enabled"/> <int value="1257980502" label="disable-accelerated-video-decode"/> <int value="1260186484" label="spurious-power-button-screen-accel"/> <int value="1261713150" label="ChromeHomeOptOutSnackbar:disabled"/> @@ -28712,6 +28727,7 @@ <int value="1913298816" label="OverlayScrollbar:enabled"/> <int value="1913926782" label="ChromeModernAlternateCardLayout:disabled"/> <int value="1915178511" label="disable-blink-features"/> + <int value="1924192543" label="ProactiveTabFreezeAndDiscard:enabled"/> <int value="1925627218" label="FullscreenToolbarReveal:disabled"/> <int value="1927259098" label="TranslateLanguageByULP:enabled"/> <int value="1928407249" label="NewPhotoPicker:enabled"/> @@ -28730,6 +28746,7 @@ <int value="1951466218" label="enable-data-reduction-proxy-lite-page"/> <int value="1951645673" label="PasswordsKeyboardAccessory:disabled"/> <int value="1955677113" label="trace-export-events-to-etw"/> + <int value="1957273171" label="PageAlmostIdle:disabled"/> <int value="1957358530" label="ContextualSearchSecondTap:enabled"/> <int value="1958387645" label="ScanCardsInWebPayments:enabled"/> <int value="1959148757" label="OffMainThreadFetch:enabled"/> @@ -29025,6 +29042,14 @@ <int value="2" label="Failed to store DM Token to the device"/> </enum> +<enum name="MachineLevelUserCloudPolicyEnrollmentStartupDialog"> + <int value="0" label="Shown"/> + <int value="1" label="ClosedSuccess"/> + <int value="2" label="ClosedRelaunch"/> + <int value="3" label="ClosedFail"/> + <int value="4" label="ClosedAbort"/> +</enum> + <enum name="MacOSBluetoothOperationsResult"> <int value="-2" label="Unknown error domain"/> <int value="-1" label="No error"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index da00e84..ed5f9d9 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3190,6 +3190,13 @@ <summary>Cumulative count of low memory kills in one user session.</summary> </histogram> +<histogram name="Arc.LowMemoryKiller.FirstKillLatency"> + <owner>cywang@google.com</owner> + <owner>elijahtaylor@google.com</owner> + <owner>shihuis@google.com</owner> + <summary>Elapsed time for TabManager to find a victim to kill .</summary> +</histogram> + <histogram name="Arc.LowMemoryKiller.FreedSize" units="KB"> <owner>elijahtaylor@google.com</owner> <owner>shihuis@google.com</owner> @@ -8176,6 +8183,42 @@ </summary> </histogram> +<histogram name="Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction" + enum="LazyLoad.FrameInitialDeferralAction"> + <owner>sclittle@chromium.org</owner> + <summary> + Records the initial lazy loading action taken for a cross-origin iframe. + </summary> +</histogram> + +<histogram + name="Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred" + enum="NQEEffectiveConnectionType"> + <owner>sclittle@chromium.org</owner> + <summary> + Records the effective connection type whenever a lazily-loaded iframe that + wasn't initially hidden or near the viewport starts loading. The count for + an effective connection type in this histogram can be subtracted from the + 'Deferred' bucket from the + Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction.* histogram for the + corresponding effective connection type to determine the number of iframes + that LazyLoad is avoiding to load altogether. + </summary> +</histogram> + +<histogram name="Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred" + enum="NQEEffectiveConnectionType"> + <owner>sclittle@chromium.org</owner> + <summary> + Records the effective connection type whenever a lazily-loaded iframe that + wasn't initially hidden or near the viewport becomes visible. The count for + an effective connection type in this histogram can be subtracted from the + corresponding count in + Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred to determine + how many iframes were loaded unnecessarily by LazyLoad. + </summary> +</histogram> + <histogram name="Blink.MediaDocument.DownloadButton" enum="MediaDocumentDownloadButtonType"> <obsolete> @@ -22137,12 +22180,52 @@ </summary> </histogram> +<histogram + name="Enterprise.MachineLevelUserCloudPolicyEnrollment.RequestFailureTime" + units="ms"> + <owner>rogerta@chromium.org</owner> + <summary> + Time since the enrollment request was made until an error is returned from + the server. + </summary> +</histogram> + +<histogram + name="Enterprise.MachineLevelUserCloudPolicyEnrollment.RequestSuccessTime" + units="ms"> + <owner>rogerta@chromium.org</owner> + <summary> + Time since the enrollment request was made until a successful enrollment + response is returned from the server. + </summary> +</histogram> + <histogram name="Enterprise.MachineLevelUserCloudPolicyEnrollment.Result" enum="MachineLevelUserCloudPolicyEnrollmentResult"> <owner>zmin@chromium.org</owner> <summary>The result of machine level user cloud policy enrollment.</summary> </histogram> +<histogram + name="Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialog" + enum="MachineLevelUserCloudPolicyEnrollmentStartupDialog"> + <owner>rogerta@chromium.org</owner> + <summary> + Records whether the machine level user cloud policy enrollment dialog is + shown to the user and the action they took. + </summary> +</histogram> + +<histogram + name="Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialogTime" + units="ms"> + <owner>rogerta@chromium.org</owner> + <summary> + The length of time the machine level user cloud policy enrollment dialog was + visible to the user. + </summary> +</histogram> + <histogram name="Enterprise.ONC.PolicyValidation" enum="BooleanSuccess"> <owner>mnissler@chromium.org</owner> <summary>Result of the OpenNetworkConfiguration policy validation.</summary> @@ -61702,6 +61785,30 @@ </summary> </histogram> +<histogram name="OfflinePages.Background.ResourceCompletion.Css" + enum="BooleanEnabled"> + <owner>petewil@chromium.org</owner> + <summary> + True if all requested CSS was loaded when a background page loaded. + </summary> +</histogram> + +<histogram name="OfflinePages.Background.ResourceCompletion.Image" + enum="BooleanEnabled"> + <owner>petewil@chromium.org</owner> + <summary> + True if all requested images were loaded when a background page loaded. + </summary> +</histogram> + +<histogram name="OfflinePages.Background.ResourceCompletion.Xhr" + enum="BooleanEnabled"> + <owner>petewil@chromium.org</owner> + <summary> + True if all requested XHRs were completed when a background page loaded. + </summary> +</histogram> + <histogram name="OfflinePages.Background.SavePageFromCCT"> <owner>chili@chromium.org</owner> <summary>Whether the save page result came from chrome custom tabs.</summary> @@ -79668,6 +79775,20 @@ </summary> </histogram> +<histogram name="RenderFrameHostImpl.ReceivedPostMessageFromNonDescendant" + enum="BooleanReceived" expires_after="2018-10-30"> + <owner>alexmos@chromium.org</owner> + <owner>boliu@chromium.org</owner> + <summary> + Record whether a local root frame ever received post messages from another + cross origin frame that's not a descendent. This is useful to evaluate if a + frame is safe to be reloaded automatically. Recorded when a frame crashed + while invisible, and then becomes visible to the user; this is the point a + crashed frame would be reloaded. Note this is not logged for the main frame, + which only has descendant frames. + </summary> +</histogram> + <histogram name="RenderFrameObservers.DidChangeScrollOffset" units="ms"> <obsolete> Deprecated 2/2018 @@ -83579,6 +83700,16 @@ </summary> </histogram> +<histogram name="SBClientDownload.DownloadFileHasDetachedSignatures" + enum="Boolean"> + <owner>jialiul@chromium.org</owner> + <summary> + A Mac-only metric that records whether a given download contains a detached + code signature file. This metric is logged before Chrome sends SafeBrowsing + download pings. + </summary> +</histogram> + <histogram name="SBClientDownload.DownloadFileHasDmgSignature" enum="Boolean"> <owner>jialiul@chromium.org</owner> <summary> @@ -87636,6 +87767,8 @@ DevTools was attached during startup. This is intended to avoid including the time for debugging. 3) The request is for New Tab Page. This is because it tends to dominate the stats and makes the results largely skewed. + + This isn't recorded when NetS13nSW(https://crbug.com/715640) is disabled. </summary> </histogram> @@ -87647,6 +87780,9 @@ active worker to dispatch a FetchEvent for a main frame resource request. See details at ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time. The suffixed histograms for .Time record the time required for each type. + + This is recorded regardless of whether NetS13nSW(https://crbug.com/715640) + is enabled or disabled. </summary> </histogram> @@ -87847,9 +87983,16 @@ <histogram name="ServiceWorker.DiskCache.WriteResponseResult" enum="ServiceWorkerWriteResponseResult"> + <owner>bashi@chromium.org</owner> <owner>nhiroki@chromium.org</owner> <summary> - Records result of writing response into ServiceWorkerDiskCache. + Records result of writing response into ServiceWorkerDiskCache. This is not + recorded when response has no body. Note that this is recorded on every + write operation, and can there can be multiple write operations for the same + response if it is large enough. + + This is recorded regardless of whether NetS13nSW (https://crbug.com/715640) + is enabled or disabled. </summary> </histogram> @@ -99551,6 +99694,15 @@ </summary> </histogram> +<histogram name="TabManager.Discarding.LogMemoryTime" units="ms"> + <owner>cywang@chromium.org</owner> + <owner>georgesak@chromium.org</owner> + <summary> + Elapsed time to collect memory usage of each tab triggered by a LogMemory() + call(). + </summary> +</histogram> + <histogram name="TabManager.Discarding.ReloadCount" units="Reloads"> <owner>georgesak@chromium.org</owner> <summary> @@ -113338,6 +113490,18 @@ <affected-histogram name="BlinkGC.TimeForTotalCollectGarbage"/> </histogram_suffixes> +<histogram_suffixes name="BlinkLazyLoadEffectiveConnectionTypeSuffixes" + separator="."> + <suffix name="2G" label="2G effective connection type"/> + <suffix name="3G" label="3G effective connection type"/> + <suffix name="4G" label="4G effective connection type"/> + <suffix name="Offline" label="Offline effective connection type"/> + <suffix name="Slow2G" label="Slow-2G effective connection type"/> + <suffix name="Unknown" label="Unknown effective connection type"/> + <affected-histogram + name="Blink.LazyLoad.CrossOriginFrames.InitialDeferralAction"/> +</histogram_suffixes> + <histogram_suffixes name="BlinkVisibleLoadTimeSuffixes" separator="."> <suffix name="2G" label="2G effective connection type"/> <suffix name="3G" label="3G effective connection type"/> @@ -120307,6 +120471,7 @@ name="PageLoad.Experimental.PaintTiming.ParseStartToFirstMeaningfulPaint"/> <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstContentfulPaint"/> + <affected-histogram name="PageLoad.PaintTiming.NavigationToFirstPaint"/> <affected-histogram name="PageLoad.PaintTiming.ParseStartToFirstContentfulPaint"/> <affected-histogram name="PageLoad.ParseTiming.NavigationToParseStart"/> @@ -120725,6 +120890,17 @@ matches either/both the sync password or a saved password This is a superset (and should be equal to or larger than) SyncPasswordEntry and ProtectedPasswordEntry"/> + <suffix name="GSuiteSyncPasswordEntry" + label="Password protection triggered by entering the sync password that + is associated with a GSuite account. This is a subset of + SyncPasswordEntry. Note that GSuite sync password reuse + detection is only triggered if configured appropriate enterprise + policy."/> + <suffix name="NonGaiaEnterprisePasswordEntry" + label="Password protection triggered by entering a password that + matches a non-Gaia enterprise password. Note that non-Gaia + enterprise password reuse detection is only triggered if + configured appropriate enterprise policy."/> <suffix name="PasswordFieldOnFocus" label="Password protection triggered by password field on focus event."/> <suffix name="ProtectedPasswordEntry" @@ -121373,7 +121549,7 @@ <histogram_suffixes name="Previews.Types" separator="."> <suffix name="AMPRedirection" label="AMP Redirection previews"/> <suffix name="LitePage" label="Lite page previews"/> - <suffix name="LoFi" label="Server LoFi previews"/> + <suffix name="LoFi" label="LoFi previews"/> <suffix name="NoScript" label="NoScript previews"/> <suffix name="Offline" label="Offline previews"/> <affected-histogram name="Previews.EligibilityReason"/> @@ -122044,11 +122220,8 @@ separator="."> <suffix name="Background"/> <suffix name="Foreground"/> - <affected-histogram name="RendererScheduler.TaskCPUDurationPerThreadType"/> <affected-histogram name="RendererScheduler.TaskCPUDurationPerThreadType2"/> - <affected-histogram name="RendererScheduler.TaskDurationPerTaskType"/> <affected-histogram name="RendererScheduler.TaskDurationPerTaskType2"/> - <affected-histogram name="RendererScheduler.TaskDurationPerThreadType"/> <affected-histogram name="RendererScheduler.TaskDurationPerThreadType2"/> </histogram_suffixes> @@ -122124,7 +122297,6 @@ <suffix name="Visible" label="Time spent in tasks of a particular type when the renderer is visible."/> - <affected-histogram name="RendererScheduler.TaskDurationPerQueueType2"/> <affected-histogram name="RendererScheduler.TaskDurationPerQueueType3"/> </histogram_suffixes> @@ -122133,7 +122305,7 @@ <suffix name="UseCaseInputHandling"/> <suffix name="UseCaseLoading"/> <suffix name="UseCaseNone"/> - <affected-histogram name="RendererScheduler.TaskDurationPerTaskType"/> + <affected-histogram name="RendererScheduler.TaskDurationPerTaskType2"/> </histogram_suffixes> <histogram_suffixes name="RendererThreadType" separator=".">
diff --git a/tools/perf/core/shard_maps/linux_perf_shard_map.json b/tools/perf/core/shard_maps/linux_perf_shard_map.json index bd35a9f..7a3d869 100644 --- a/tools/perf/core/shard_maps/linux_perf_shard_map.json +++ b/tools/perf/core/shard_maps/linux_perf_shard_map.json
@@ -295,5 +295,12 @@ "wasm": {}, "webrtc": {} } + }, + "extra_infos": { + "num_stories": 2401, + "predicted_min_shard_time": 2442.7268490479796, + "predicted_min_shard_index": 18, + "predicted_max_shard_time": 3869.938049616162, + "predicted_max_shard_index": 17 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/mac_1012_low_end_26_shard_map.json b/tools/perf/core/shard_maps/mac_1012_low_end_26_shard_map.json index 60e1db8..bd13f98 100644 --- a/tools/perf/core/shard_maps/mac_1012_low_end_26_shard_map.json +++ b/tools/perf/core/shard_maps/mac_1012_low_end_26_shard_map.json
@@ -303,5 +303,12 @@ "wasm": {}, "webrtc": {} } + }, + "extra_infos": { + "num_stories": 2401, + "predicted_min_shard_time": 2686.0698310505054, + "predicted_min_shard_index": 19, + "predicted_max_shard_time": 3190.7565990909093, + "predicted_max_shard_index": 18 } -} +} \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/mac_1013_high_end_26_shard_map.json b/tools/perf/core/shard_maps/mac_1013_high_end_26_shard_map.json index ed301cb0..e2195dd8c 100644 --- a/tools/perf/core/shard_maps/mac_1013_high_end_26_shard_map.json +++ b/tools/perf/core/shard_maps/mac_1013_high_end_26_shard_map.json
@@ -308,5 +308,12 @@ "wasm": {}, "webrtc": {} } + }, + "extra_infos": { + "num_stories": 2401, + "predicted_min_shard_time": 1956.2044916944444, + "predicted_min_shard_index": 18, + "predicted_max_shard_time": 3590.0444336944443, + "predicted_max_shard_index": 17 } } \ No newline at end of file
diff --git a/tools/perf/core/sharding_map_generator.py b/tools/perf/core/sharding_map_generator.py index 26571163..3b5816f 100644 --- a/tools/perf/core/sharding_map_generator.py +++ b/tools/perf/core/sharding_map_generator.py
@@ -122,6 +122,11 @@ total_time = 0 sharding_map = OrderedDict() debug_map = OrderedDict() + min_shard_time = float('inf') + min_shard_index = None + max_shard_time = 0 + max_shard_index = None + num_stories = len(story_timing_dict) for i in range(num_shards): sharding_map[str(i)] = {'benchmarks': OrderedDict()} debug_map[str(i)] = OrderedDict() @@ -136,9 +141,25 @@ debug_map[str(i)][story] = time _add_benchmarks_to_shard(sharding_map, i, stories_in_shard, all_stories) debug_map[str(i)]['full_time'] = time_per_shard + if time_per_shard > max_shard_time: + max_shard_time = time_per_shard + max_shard_index = i + if time_per_shard < min_shard_time: + min_shard_time = time_per_shard + min_shard_index = i if debug: with open(debug, 'w') as output_file: json.dump(debug_map, output_file, indent = 4, separators=(',', ': ')) + + + sharding_map['extra_infos'] = OrderedDict([ + ('num_stories', num_stories), + # Double all the time stats by 2 to account for reference build. + ('predicted_min_shard_time', min_shard_time * 2), + ('predicted_min_shard_index', min_shard_index), + ('predicted_max_shard_time', max_shard_time * 2), + ('predicted_max_shard_index', max_shard_index), + ]) return sharding_map @@ -222,6 +243,7 @@ with open(sharding_map_file) as f: sharding_map = json.load(f, object_pairs_hook=OrderedDict) + sharding_map.pop('extra_infos', None) for shard in sharding_map: results[shard] = OrderedDict() shard_total_time = 0
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index beda627..2437aad 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -339,6 +339,7 @@ crbug.com/803461 [ Nexus_5 ] system_health.common_mobile/browse:chrome:newtab [ Skip ] crbug.com/842163 [ Android_One ] system_health.common_mobile/browse:social:facebook_infinite_scroll [ Skip ] crbug.com/842163 [ Android_One ] system_health.common_mobile/browse:social:pinterest_infinite_scroll [ Skip ] +crbug.com/854683 [ Android_Webview ] system_health.common_mobile/browse:news:cnn [ Skip ] crbug.com/852840 [ Android_Webview ] system_health.common_mobile/browse:media:youtube [ Skip ] # Benchmark: system_health.memory_desktop
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index dc18810..8947dab 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -91,7 +91,7 @@ <item id="download_web_contents_frame" hash_code="56351037" type="0" content_hash_code="3657889" os_list="linux,windows" file_path="content/browser/web_contents/web_contents_impl.cc"/> <item id="downloads_api_run_async" hash_code="121068967" type="0" content_hash_code="87443585" os_list="linux,windows" file_path="chrome/browser/extensions/api/downloads/downloads_api.cc"/> <item id="drag_download_file" hash_code="95910019" type="0" content_hash_code="126492858" os_list="linux,windows" file_path="content/browser/download/drag_download_file.cc"/> - <item id="expect_ct_reporter" hash_code="57276415" type="0" content_hash_code="130492494" os_list="windows" file_path="services/network/expect_ct_reporter.cc"/> + <item id="expect_ct_reporter" hash_code="57276415" type="0" deprecated="2018-06-20" content_hash_code="130492494" file_path=""/> <item id="extension_blacklist" hash_code="59592717" type="0" content_hash_code="116742516" os_list="linux,windows" file_path="chrome/browser/extensions/blacklist_state_fetcher.cc"/> <item id="extension_crx_fetcher" hash_code="21145003" type="0" content_hash_code="79150319" os_list="linux,windows" file_path="extensions/browser/updater/extension_downloader.cc"/> <item id="extension_install_signer" hash_code="50464499" type="0" content_hash_code="88088656" os_list="linux,windows" file_path="chrome/browser/extensions/install_signer.cc"/>
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 72694e3..eaca778f 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -394,6 +394,25 @@ } } +SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayForRelation( + const ax::mojom::IntListAttribute& attribute) { + std::vector<int32_t> id_list = GetIntListAttribute(attribute); + SAFEARRAY* propertyvalue = + SafeArrayCreateVector(VT_UNKNOWN, 0, id_list.size()); + + LONG i = 0; + for (int32_t node_id : id_list) { + AXPlatformNodeWin* node = + static_cast<AXPlatformNodeWin*>(delegate_->GetFromNodeID(node_id)); + DCHECK(node); + node->AddRef(); + SafeArrayPutElement(propertyvalue, &i, node); + ++i; + } + + return propertyvalue; +} + // // AXPlatformNodeBase implementation. // @@ -2603,6 +2622,7 @@ const AXNodeData& data = GetData(); int int_attribute; + ax::mojom::IntListAttribute relation_attribute; result->vt = VT_EMPTY; switch (property_id) { @@ -2631,9 +2651,13 @@ break; case UIA_ClickablePointPropertyId: - case UIA_ControllerForPropertyId: // TODO(suproteem) break; + case UIA_ControllerForPropertyId: + result->vt = VT_ARRAY; + relation_attribute = ax::mojom::IntListAttribute::kControlsIds; + result->parray = CreateUIAElementsArrayForRelation(relation_attribute); + break; case UIA_CulturePropertyId: result->vt = VT_BSTR; @@ -2642,7 +2666,17 @@ break; case UIA_DescribedByPropertyId: + result->vt = VT_ARRAY; + relation_attribute = ax::mojom::IntListAttribute::kDescribedbyIds; + result->parray = CreateUIAElementsArrayForRelation(relation_attribute); + break; + case UIA_FlowsToPropertyId: + result->vt = VT_ARRAY; + relation_attribute = ax::mojom::IntListAttribute::kFlowtoIds; + result->parray = CreateUIAElementsArrayForRelation(relation_attribute); + break; + case UIA_FrameworkIdPropertyId: case UIA_IsContentElementPropertyId: case UIA_IsControlElementPropertyId: @@ -2669,10 +2703,12 @@ case UIA_ItemStatusPropertyId: case UIA_ItemTypePropertyId: - case UIA_LabeledByPropertyId: // TODO(suproteem) break; + case UIA_LabeledByPropertyId: + break; + case UIA_LocalizedControlTypePropertyId: break;
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h index e16a88c..f1304b7f 100644 --- a/ui/accessibility/platform/ax_platform_node_win.h +++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -9,6 +9,7 @@ #include <atlcom.h> #include <objbase.h> #include <oleacc.h> +#include <oleauto.h> #include <uiautomation.h> #include <wrl/client.h> @@ -839,6 +840,12 @@ const char* html_attribute_name, const char* uia_aria_property); + // If the IntList attribute |attribute| is present, return an array + // of automation elements referenced by the ids in the + // IntList attribute. Otherwise return an empty array. + SAFEARRAY* CreateUIAElementsArrayForRelation( + const ax::mojom::IntListAttribute& attribute); + void AddAlertTarget(); void RemoveAlertTarget();
diff --git a/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java b/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java index 949d804..048805eb 100644 --- a/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java +++ b/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java
@@ -33,6 +33,7 @@ @Override public void setImageDrawable(@Nullable Drawable drawable) { + if (drawable == getDrawable()) return; super.setImageDrawable(drawable); refreshDrawableState(); }
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index d0660a6..9d09a03 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -313,6 +313,7 @@ "//ui/events:test_support", "//ui/gfx", "//ui/gfx/geometry", + "//ui/platform_window", "//ui/wm", ] @@ -416,6 +417,7 @@ "//ui/gfx", "//ui/gfx/geometry", "//ui/gl:test_support", + "//ui/platform_window", "//ui/platform_window/stub", "//ui/wm", ]
diff --git a/ui/aura/test/test_screen.cc b/ui/aura/test/test_screen.cc index e33e4e7..c5c294b 100644 --- a/ui/aura/test/test_screen.cc +++ b/ui/aura/test/test_screen.cc
@@ -18,6 +18,7 @@ #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/native_widget_types.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace aura { @@ -51,8 +52,9 @@ host_ = WindowTreeClientPrivate(window_tree_client_) .CallWmNewDisplayAdded(GetPrimaryDisplay()); } else { - host_ = - WindowTreeHost::Create(gfx::Rect(GetPrimaryDisplay().GetSizeInPixel())); + host_ = WindowTreeHost::Create(ui::PlatformWindowInitProperties{gfx::Rect( + GetPrimaryDisplay().GetSizeInPixel())}) + .release(); } // Some tests don't correctly manage window focus/activation states. // Makes sure InputMethod is default focused so that IME basics can work. @@ -153,7 +155,7 @@ void TestScreen::OnWindowDestroying(Window* window) { if (host_->window() == window) { host_->window()->RemoveObserver(this); - host_ = NULL; + host_ = nullptr; } }
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc index 6cb3c598..e3b90c76 100644 --- a/ui/aura/window_event_dispatcher_unittest.cc +++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -47,6 +47,7 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/transform.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace aura { namespace { @@ -174,8 +175,8 @@ // Check that we correctly track whether any touch devices are down in response // to touch press and release events with two WindowTreeHost. TEST_P(WindowEventDispatcherTest, TouchDownState) { - std::unique_ptr<WindowTreeHost> second_host( - WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50))); + std::unique_ptr<WindowTreeHost> second_host = WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(20, 30, 100, 50)}); second_host->InitHost(); second_host->window()->Show(); @@ -1705,7 +1706,10 @@ TEST_P(WindowEventDispatcherTest, DeleteDispatcherDuringPreDispatch) { // Create a host for the window hierarchy. This host will be destroyed later // on. - WindowTreeHost* host = WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100)); + WindowTreeHost* host = + WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(0, 0, 100, 100)}) + .release(); host->InitHost(); host->window()->Show(); @@ -1782,8 +1786,8 @@ ValidRootDuringDestructionWindowObserver observer(&got_destroying, &has_valid_root); { - std::unique_ptr<WindowTreeHost> host( - WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100))); + std::unique_ptr<WindowTreeHost> host = WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(0, 0, 100, 100)}); host->InitHost(); host->window()->Show(); // Owned by WindowEventDispatcher. @@ -1890,7 +1894,9 @@ // we don't crash. TEST_P(WindowEventDispatcherTest, DeleteHostFromHeldMouseEvent) { // Should be deleted by |delegate|. - WindowTreeHost* h2 = WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100)); + WindowTreeHost* h2 = WindowTreeHost::Create(ui::PlatformWindowInitProperties{ + gfx::Rect(0, 0, 100, 100)}) + .release(); h2->InitHost(); h2->window()->Show(); DeleteHostFromHeldMouseEventDelegate delegate(h2); @@ -2528,8 +2534,8 @@ // event being dispatched is moved to a different dispatcher in response to an // event in the inner loop. TEST_P(WindowEventDispatcherTest, NestedEventDispatchTargetMoved) { - std::unique_ptr<WindowTreeHost> second_host( - WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50))); + std::unique_ptr<WindowTreeHost> second_host = WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(20, 30, 100, 50)}); second_host->InitHost(); second_host->window()->Show(); Window* second_root = second_host->window(); @@ -2591,8 +2597,8 @@ &delegate, 123, gfx::Rect(20, 10, 10, 20), root_window())); window->Show(); - std::unique_ptr<WindowTreeHost> second_host( - WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50))); + std::unique_ptr<WindowTreeHost> second_host = WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(20, 30, 100, 50)}); second_host->InitHost(); second_host->window()->Show(); WindowEventDispatcher* second_dispatcher = second_host->dispatcher(); @@ -2632,8 +2638,8 @@ TEST_P(WindowEventDispatcherTest, RedirectedEventToDifferentDispatcherLocation) { - std::unique_ptr<WindowTreeHost> second_host( - WindowTreeHost::Create(gfx::Rect(20, 30, 100, 50))); + std::unique_ptr<WindowTreeHost> second_host = WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(20, 30, 100, 50)}); second_host->InitHost(); second_host->window()->Show(); client::SetCaptureClient(second_host->window(),
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc index a4658e0..eb60ca9 100644 --- a/ui/aura/window_tree_host.cc +++ b/ui/aura/window_tree_host.cc
@@ -38,6 +38,7 @@ #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/icc_profile.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace aura {
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h index 052d9dd..c92d59a 100644 --- a/ui/aura/window_tree_host.h +++ b/ui/aura/window_tree_host.h
@@ -40,6 +40,7 @@ class EventSink; class InputMethod; class ViewProp; +struct PlatformWindowInitProperties; } namespace aura { @@ -63,8 +64,9 @@ public: ~WindowTreeHost() override; - // Creates a new WindowTreeHost. The caller owns the returned value. - static WindowTreeHost* Create(const gfx::Rect& bounds_in_pixels); + // Creates a new WindowTreeHost with the specified |properties|. + static std::unique_ptr<WindowTreeHost> Create( + ui::PlatformWindowInitProperties properties); // Returns the WindowTreeHost for the specified accelerated widget, or NULL // if there is none associated.
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc index f47c7d2b..ae7a71a 100644 --- a/ui/aura/window_tree_host_platform.cc +++ b/ui/aura/window_tree_host_platform.cc
@@ -40,17 +40,15 @@ namespace aura { // static -WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) { - return new WindowTreeHostPlatform(bounds); +std::unique_ptr<WindowTreeHost> WindowTreeHost::Create( + ui::PlatformWindowInitProperties properties) { + return std::make_unique<WindowTreeHostPlatform>(std::move(properties)); } -WindowTreeHostPlatform::WindowTreeHostPlatform(const gfx::Rect& bounds) - : WindowTreeHostPlatform() { - bounds_ = bounds; +WindowTreeHostPlatform::WindowTreeHostPlatform( + ui::PlatformWindowInitProperties properties) { + bounds_ = properties.bounds; CreateCompositor(); - - ui::PlatformWindowInitProperties properties; - properties.bounds = bounds_; CreateAndSetPlatformWindow(std::move(properties)); }
diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h index ca55a0e..c420f20 100644 --- a/ui/aura/window_tree_host_platform.h +++ b/ui/aura/window_tree_host_platform.h
@@ -31,7 +31,7 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost, public ui::PlatformWindowDelegate { public: - explicit WindowTreeHostPlatform(const gfx::Rect& bounds); + explicit WindowTreeHostPlatform(ui::PlatformWindowInitProperties properties); ~WindowTreeHostPlatform() override; // WindowTreeHost:
diff --git a/ui/aura_extra/DEPS b/ui/aura_extra/DEPS index 1e35c16d7a..28d322e 100644 --- a/ui/aura_extra/DEPS +++ b/ui/aura_extra/DEPS
@@ -5,4 +5,5 @@ "+ui/compositor", "+ui/events", "+ui/gfx", + "+ui/platform_window", ]
diff --git a/ui/aura_extra/window_occlusion_impl_unittest_win.cc b/ui/aura_extra/window_occlusion_impl_unittest_win.cc index 44e8efeb..c492eed 100644 --- a/ui/aura_extra/window_occlusion_impl_unittest_win.cc +++ b/ui/aura_extra/window_occlusion_impl_unittest_win.cc
@@ -9,6 +9,7 @@ #include "ui/aura/test/aura_test_base.h" #include "ui/aura/window_tree_host_platform.h" #include "ui/gfx/geometry/rect.h" +#include "ui/platform_window/platform_window_init_properties.h" namespace aura_extra { @@ -79,8 +80,8 @@ } aura::WindowTreeHost* AddRootAuraWindowWithBounds(const gfx::Rect& bounds) { - std::unique_ptr<aura::WindowTreeHost> window_tree_host( - aura::WindowTreeHost::Create(bounds)); + std::unique_ptr<aura::WindowTreeHost> window_tree_host = + aura::WindowTreeHost::Create(ui::PlatformWindowInitProperties{bounds}); window_tree_host->window()->Show(); EvaluatorArgs args{true, bounds, window_tree_host->GetAcceleratedWidget()}; @@ -422,8 +423,8 @@ } void CreateAuraWindowWithBounds(const gfx::Rect& bounds) { - std::unique_ptr<aura::WindowTreeHost> host( - aura::WindowTreeHost::Create(bounds)); + std::unique_ptr<aura::WindowTreeHost> host = + aura::WindowTreeHost::Create(ui::PlatformWindowInitProperties{bounds}); host->window()->Show(); evaluator_.AddToStack(host->window()); window_tree_hosts_.push_back(std::move(host));
diff --git a/ui/base/clipboard/clipboard_mac_unittest.mm b/ui/base/clipboard/clipboard_mac_unittest.mm index b196332a..fdd0bde 100644 --- a/ui/base/clipboard/clipboard_mac_unittest.mm +++ b/ui/base/clipboard/clipboard_mac_unittest.mm
@@ -27,6 +27,16 @@ namespace ui { +namespace { + +// CGDataProviderReleaseDataCallback that releases the CreateImage buffer. +void CreateImageBufferReleaser(void* info, const void* data, size_t size) { + DCHECK_EQ(info, data); + free(info); +} + +} // namespace + class ClipboardMacTest : public PlatformTest { public: ClipboardMacTest() { } @@ -41,11 +51,12 @@ // representation for an NSImage. This doesn't work, because when the // result is written, and then read from an NSPasteboard, the new NSImage // loses its "retina-ness". - std::unique_ptr<uint8_t, base::FreeDeleter> buffer( - static_cast<uint8_t*>(calloc(pixel_width * pixel_height, 4))); + uint8_t* buffer = + static_cast<uint8_t*>(calloc(pixel_width * pixel_height, 4)); base::ScopedCFTypeRef<CGDataProviderRef> provider( - CGDataProviderCreateWithData( - nullptr, buffer.get(), (pixel_width * pixel_height * 4), nullptr)); + CGDataProviderCreateWithData(buffer, buffer, + (pixel_width * pixel_height * 4), + &CreateImageBufferReleaser)); base::ScopedCFTypeRef<CGColorSpaceRef> color_space( CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); base::ScopedCFTypeRef<CGImageRef> image_ref( @@ -58,12 +69,7 @@ } }; -#if defined(MEMORY_SANITIZER) || defined(ADDRESS_SANITIZER) -#define MAYBE_ReadImageRetina DISABLED_ReadImageRetina -#else -#define MAYBE_ReadImageRetina ReadImageRetina -#endif -TEST_F(ClipboardMacTest, MAYBE_ReadImageRetina) { +TEST_F(ClipboardMacTest, ReadImageRetina) { int32_t width = 99; int32_t height = 101; scoped_refptr<ui::UniquePasteboard> pasteboard = new ui::UniquePasteboard; @@ -79,12 +85,7 @@ EXPECT_EQ(2 * height, bitmap.height()); } -#if defined(MEMORY_SANITIZER) || defined(ADDRESS_SANITIZER) -#define MAYBE_ReadImageNonRetina DISABLED_ReadImageNonRetina -#else -#define MAYBE_ReadImageNonRetina ReadImageNonRetina -#endif -TEST_F(ClipboardMacTest, MAYBE_ReadImageNonRetina) { +TEST_F(ClipboardMacTest, ReadImageNonRetina) { int32_t width = 99; int32_t height = 101; scoped_refptr<ui::UniquePasteboard> pasteboard = new ui::UniquePasteboard;
diff --git a/ui/base/cocoa/command_dispatcher.h b/ui/base/cocoa/command_dispatcher.h index 556dd02..0fca888 100644 --- a/ui/base/cocoa/command_dispatcher.h +++ b/ui/base/cocoa/command_dispatcher.h
@@ -73,6 +73,23 @@ @end +namespace ui { + +enum class PerformKeyEquivalentResult { + // The CommandDispatcherDelegate did not handle the key equivalent. + kUnhandled, + + // The CommandDispatcherDelegate handled the key equivalent. + kHandled, + + // The CommandDispatcherDelegate did not handle the key equivalent, but wants + // the event to be passed to the MainMenu, which will handle the key + // equivalent. + kPassToMainMenu, +}; + +} // namespace ui + // Provides CommandDispatcher with the means to redirect key equivalents at // different stages of event handling. @protocol CommandDispatcherDelegate @@ -81,16 +98,17 @@ // responder. See https://crbug.com/846893#c5 for more details on // keyEquivalent consumer ordering. |window| is the CommandDispatchingWindow // that owns CommandDispatcher, not the window of the event. -- (BOOL)prePerformKeyEquivalent:(NSEvent*)event window:(NSWindow*)window; +- (ui::PerformKeyEquivalentResult)prePerformKeyEquivalent:(NSEvent*)event + window:(NSWindow*)window; // Gives the delegate a chance to process the keyEquivalent after the first // responder has declined to process the event. See https://crbug.com/846893#c5 // for more details on keyEquivalent consumer ordering. // |window| is the CommandDispatchingWindow that owns CommandDispatcher, not the // window of the event. -- (BOOL)postPerformKeyEquivalent:(NSEvent*)event - window:(NSWindow*)window - isRedispatch:(BOOL)isRedispatch; +- (ui::PerformKeyEquivalentResult)postPerformKeyEquivalent:(NSEvent*)event + window:(NSWindow*)window + isRedispatch:(BOOL)isRedispatch; @end
diff --git a/ui/base/cocoa/command_dispatcher.mm b/ui/base/cocoa/command_dispatcher.mm index 0c99e2e..45a34b6 100644 --- a/ui/base/cocoa/command_dispatcher.mm +++ b/ui/base/cocoa/command_dispatcher.mm
@@ -94,6 +94,9 @@ return NO; } +// |delegate_| may be nil in this method. Rather than adding nil checks to every +// call, we rely on the fact that method calls to nil return nil, and that nil +// == ui::PerformKeyEquivalentResult::kUnhandled; - (BOOL)doPerformKeyEquivalent:(NSEvent*)event { // If the event is being redispatched, then this is the second time // performKeyEquivalent: is being called on the event. The first time, a @@ -106,17 +109,24 @@ // We skip all steps before postPerformKeyEquivalent, since those were already // triggered on the first pass of the event. if ([self isEventBeingRedispatched:event]) { - if ([delegate_ postPerformKeyEquivalent:event + ui::PerformKeyEquivalentResult result = + [delegate_ postPerformKeyEquivalent:event window:owner_ - isRedispatch:YES]) { + isRedispatch:YES]; + if (result == ui::PerformKeyEquivalentResult::kHandled) return YES; - } + if (result == ui::PerformKeyEquivalentResult::kPassToMainMenu) + return NO; return [[self bubbleParent] performKeyEquivalent:event]; } // First, give the delegate an opportunity to consume this event. - if ([delegate_ prePerformKeyEquivalent:event window:owner_]) + ui::PerformKeyEquivalentResult result = + [delegate_ prePerformKeyEquivalent:event window:owner_]; + if (result == ui::PerformKeyEquivalentResult::kHandled) return YES; + if (result == ui::PerformKeyEquivalentResult::kPassToMainMenu) + return NO; // Next, pass the event down the NSView hierarchy. Surprisingly, this doesn't // use the responder chain. See implementation of -[NSWindow @@ -129,8 +139,12 @@ // If the firstResponder [e.g. omnibox] chose not to handle the keyEquivalent, // then give the delegate another chance to consume it. - if ([delegate_ postPerformKeyEquivalent:event window:owner_ isRedispatch:NO]) + result = + [delegate_ postPerformKeyEquivalent:event window:owner_ isRedispatch:NO]; + if (result == ui::PerformKeyEquivalentResult::kHandled) return YES; + if (result == ui::PerformKeyEquivalentResult::kPassToMainMenu) + return NO; // Allow commands to "bubble up" to CommandDispatchers in parent windows, if // they were not handled here.
diff --git a/ui/base/l10n/l10n_util.cc b/ui/base/l10n/l10n_util.cc index 35b202f..265c80ed 100644 --- a/ui/base/l10n/l10n_util.cc +++ b/ui/base/l10n/l10n_util.cc
@@ -62,6 +62,7 @@ "br", // Breton "bs", // Bosnian "ca", // Catalan + "ceb", // Cebuano "ckb", // Kurdish (Arabci), Sorani "co", // Corsican "cs", // Czech @@ -119,10 +120,12 @@ "hi", // Hindi "hmn", // Hmong "hr", // Croatian + "ht", // Haitian Creole "hu", // Hungarian "hy", // Armenian "ia", // Interlingua "id", // Indonesian + "ig", // Igbo "is", // Icelandic "it", // Italian "it-CH", // Italian (Switzerland) @@ -142,6 +145,8 @@ "lo", // Laothian "lt", // Lithuanian "lv", // Latvian + "mg", // Malagasy + "mi", // Maori "mk", // Macedonian "ml", // Malayalam "mn", // Mongolian @@ -149,11 +154,13 @@ "mr", // Marathi "ms", // Malay "mt", // Maltese + "my", // Burmese "nb", // Norwegian (Bokmal) "ne", // Nepali "nl", // Dutch "nn", // Norwegian (Nynorsk) "no", // Norwegian + "ny", // Nyanja "oc", // Occitan "om", // Oromo "or", // Oriya
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index 7efccc2..b898799 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -100,6 +100,8 @@ // This is privileged interface to the compositor. It is a global object. class COMPOSITOR_EXPORT ContextFactoryPrivate { public: + virtual ~ContextFactoryPrivate() {} + // Creates a reflector that copies the content of the |mirrored_compositor| // onto |mirroring_layer|. virtual std::unique_ptr<Reflector> CreateReflector(
diff --git a/ui/compositor/host/BUILD.gn b/ui/compositor/host/BUILD.gn new file mode 100644 index 0000000..e84b2c4 --- /dev/null +++ b/ui/compositor/host/BUILD.gn
@@ -0,0 +1,38 @@ +# 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. + +import("//build/config/ui.gni") + +source_set("host") { + public = [ + "external_begin_frame_controller_client_impl.h", + ] + sources = [ + "external_begin_frame_controller_client_impl.cc", + ] + + deps = [ + "//mojo/public/cpp/bindings", + "//ui/compositor", + ] + + public_deps = [ + "//services/viz/privileged/interfaces/compositing", + ] + + if (use_aura || is_mac) { + public += [ "host_context_factory_private.h" ] + sources += [ "host_context_factory_private.cc" ] + + deps += [ + "//cc/mojo_embedder", + "//components/viz/client", + "//components/viz/common", + "//components/viz/host", + "//ui/gfx", + ] + + public_deps += [ "//services/viz/public/interfaces" ] + } +}
diff --git a/ui/compositor/host/DEPS b/ui/compositor/host/DEPS new file mode 100644 index 0000000..d34c1d89 --- /dev/null +++ b/ui/compositor/host/DEPS
@@ -0,0 +1,6 @@ +include_rules = [ + "+components/viz/client", + "+mojo/public/cpp/bindings", + "+services/viz/public/interfaces", + "+services/viz/privileged/interfaces/compositing", +]
diff --git a/content/browser/compositor/external_begin_frame_controller_client_impl.cc b/ui/compositor/host/external_begin_frame_controller_client_impl.cc similarity index 90% rename from content/browser/compositor/external_begin_frame_controller_client_impl.cc rename to ui/compositor/host/external_begin_frame_controller_client_impl.cc index 6137b75..964ca2f 100644 --- a/content/browser/compositor/external_begin_frame_controller_client_impl.cc +++ b/ui/compositor/host/external_begin_frame_controller_client_impl.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/compositor/external_begin_frame_controller_client_impl.h" +#include "ui/compositor/host/external_begin_frame_controller_client_impl.h" #include "ui/compositor/compositor.h" -namespace content { +namespace ui { ExternalBeginFrameControllerClientImpl::ExternalBeginFrameControllerClientImpl( ui::ExternalBeginFrameClient* client) @@ -42,4 +42,4 @@ client_->OnDisplayDidFinishFrame(ack); } -} // namespace content +} // namespace ui
diff --git a/content/browser/compositor/external_begin_frame_controller_client_impl.h b/ui/compositor/host/external_begin_frame_controller_client_impl.h similarity index 82% rename from content/browser/compositor/external_begin_frame_controller_client_impl.h rename to ui/compositor/host/external_begin_frame_controller_client_impl.h index 548471e..2313e53 100644 --- a/content/browser/compositor/external_begin_frame_controller_client_impl.h +++ b/ui/compositor/host/external_begin_frame_controller_client_impl.h
@@ -2,17 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CONTROLLER_CLIENT_IMPL_H_ -#define CONTENT_BROWSER_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CONTROLLER_CLIENT_IMPL_H_ +#ifndef UI_COMPOSITOR_HOST_EXTERNAL_BEGIN_FRAME_CONTROLLER_CLIENT_IMPL_H_ +#define UI_COMPOSITOR_HOST_EXTERNAL_BEGIN_FRAME_CONTROLLER_CLIENT_IMPL_H_ #include "mojo/public/cpp/bindings/binding.h" #include "services/viz/privileged/interfaces/compositing/external_begin_frame_controller.mojom.h" namespace ui { -class ExternalBeginFrameClient; -} // namespace ui -namespace content { +class ExternalBeginFrameClient; // ExternalBeginFrameControllerClient implementation that notifies an // ExternalBeginFrameClient about BeginFrame events. @@ -41,6 +39,6 @@ viz::mojom::ExternalBeginFrameControllerAssociatedPtr controller_; }; -} // namespace content +} // namespace ui -#endif // CONTENT_BROWSER_COMPOSITOR_GPU_PROCESS_TRANSPORT_FACTORY_H_ +#endif // UI_COMPOSITOR_HOST_EXTERNAL_BEGIN_FRAME_CONTROLLER_CLIENT_IMPL_H_
diff --git a/ui/compositor/host/host_context_factory_private.cc b/ui/compositor/host/host_context_factory_private.cc new file mode 100644 index 0000000..2242da97 --- /dev/null +++ b/ui/compositor/host/host_context_factory_private.cc
@@ -0,0 +1,278 @@ +// 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 "ui/compositor/host/host_context_factory_private.h" + +#include "build/build_config.h" +#include "cc/mojo_embedder/async_layer_tree_frame_sink.h" +#include "components/viz/client/hit_test_data_provider_draw_quad.h" +#include "components/viz/client/local_surface_id_provider.h" +#include "components/viz/host/host_display_client.h" +#include "components/viz/host/host_frame_sink_manager.h" +#include "components/viz/host/renderer_settings_creation.h" +#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h" +#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h" +#include "ui/compositor/host/external_begin_frame_controller_client_impl.h" +#include "ui/compositor/reflector.h" + +#if defined(OS_WIN) +#include "ui/gfx/win/rendering_window_manager.h" +#endif + +namespace ui { + +HostContextFactoryPrivate::HostContextFactoryPrivate( + uint32_t client_id, + viz::HostFrameSinkManager* host_frame_sink_manager, + scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner) + : frame_sink_id_allocator_(client_id), + host_frame_sink_manager_(host_frame_sink_manager), + renderer_settings_(viz::CreateRendererSettings()), + resize_task_runner_(std::move(resize_task_runner)) { + DCHECK(host_frame_sink_manager_); +} + +HostContextFactoryPrivate::~HostContextFactoryPrivate() = default; + +void HostContextFactoryPrivate::ConfigureCompositor( + base::WeakPtr<Compositor> compositor_weak_ptr, + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::RasterContextProvider> worker_context_provider) { + Compositor* compositor = compositor_weak_ptr.get(); + if (!compositor) + return; + + bool gpu_compositing = + !is_gpu_compositing_disabled_ && !compositor->force_software_compositor(); + +// TODO(sky): need to add reconnection logic here. See +// VizProcessTransportFactory. +#if defined(OS_WIN) + gfx::RenderingWindowManager::GetInstance()->RegisterParent( + compositor->widget()); +#endif + + auto& compositor_data = compositor_data_map_[compositor]; + + auto root_params = viz::mojom::RootCompositorFrameSinkParams::New(); + + // Create interfaces for a root CompositorFrameSink. + viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info; + root_params->compositor_frame_sink = mojo::MakeRequest(&sink_info); + viz::mojom::CompositorFrameSinkClientRequest client_request = + mojo::MakeRequest(&root_params->compositor_frame_sink_client); + root_params->display_private = + mojo::MakeRequest(&compositor_data.display_private); + compositor_data.display_client = + std::make_unique<viz::HostDisplayClient>(compositor->widget()); + root_params->display_client = + compositor_data.display_client->GetBoundPtr(resize_task_runner_) + .PassInterface(); + +#if defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW) + gpu::SurfaceHandle surface_handle = compositor->widget(); +#else + // TODO(kylechar): Fix this when we support macOS. + gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle; +#endif + + // Initialize ExternalBeginFrameController client if enabled. + compositor_data.external_begin_frame_controller_client.reset(); + if (compositor->external_begin_frames_enabled()) { + compositor_data.external_begin_frame_controller_client = + std::make_unique<ExternalBeginFrameControllerClientImpl>(compositor); + root_params->external_begin_frame_controller = + compositor_data.external_begin_frame_controller_client + ->GetControllerRequest(); + root_params->external_begin_frame_controller_client = + compositor_data.external_begin_frame_controller_client->GetBoundPtr() + .PassInterface(); + } + + root_params->frame_sink_id = compositor->frame_sink_id(); + root_params->widget = surface_handle; + root_params->gpu_compositing = gpu_compositing; + root_params->renderer_settings = renderer_settings_; + + // Connects the viz process end of CompositorFrameSink message pipes. The + // browser compositor may request a new CompositorFrameSink on context loss, + // which will destroy the existing CompositorFrameSink. + GetHostFrameSinkManager()->CreateRootCompositorFrameSink( + std::move(root_params)); + compositor_data.display_private->Resize(compositor->size()); + + // Create LayerTreeFrameSink with the browser end of CompositorFrameSink. + cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params; + params.compositor_task_runner = compositor->task_runner(); + params.gpu_memory_buffer_manager = + compositor->context_factory()->GetGpuMemoryBufferManager(); + params.pipes.compositor_frame_sink_associated_info = std::move(sink_info); + params.pipes.client_request = std::move(client_request); + params.local_surface_id_provider = + std::make_unique<viz::DefaultLocalSurfaceIdProvider>(); + params.enable_surface_synchronization = true; + params.hit_test_data_provider = + std::make_unique<viz::HitTestDataProviderDrawQuad>( + /*should_ask_for_child_region=*/false); + compositor->SetLayerTreeFrameSink( + std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>( + std::move(context_provider), std::move(worker_context_provider), + ¶ms)); +#if defined(OS_WIN) + gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild( + compositor->widget()); +#endif +} + +void HostContextFactoryPrivate::UnconfigureCompositor(Compositor* compositor) { +#if defined(OS_WIN) + // TODO(crbug.com/791660): Make sure that GpuProcessHost::SetChildSurface() + // doesn't crash the GPU process after parent is unregistered. + gfx::RenderingWindowManager::GetInstance()->UnregisterParent( + compositor->widget()); +#endif + + compositor_data_map_.erase(compositor); +} + +std::unique_ptr<Reflector> HostContextFactoryPrivate::CreateReflector( + Compositor* source, + Layer* target) { + // TODO(crbug.com/601869): Reflector needs to be rewritten for viz. + NOTIMPLEMENTED(); + return nullptr; +} + +void HostContextFactoryPrivate::RemoveReflector(Reflector* reflector) { + // TODO(crbug.com/601869): Reflector needs to be rewritten for viz. + NOTIMPLEMENTED(); +} + +viz::FrameSinkId HostContextFactoryPrivate::AllocateFrameSinkId() { + return frame_sink_id_allocator_.NextFrameSinkId(); +} + +viz::HostFrameSinkManager* +HostContextFactoryPrivate::GetHostFrameSinkManager() { + return host_frame_sink_manager_; +} + +void HostContextFactoryPrivate::SetDisplayVisible(Compositor* compositor, + bool visible) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->SetDisplayVisible(visible); +} + +void HostContextFactoryPrivate::ResizeDisplay(Compositor* compositor, + const gfx::Size& size) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->Resize(size); +} + +void HostContextFactoryPrivate::DisableSwapUntilResize(Compositor* compositor) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + { + // Browser needs to block for Viz to receive and process this message. + // Otherwise when we return from WM_WINDOWPOSCHANGING message handler and + // receive a WM_WINDOWPOSCHANGED the resize is finalized and any swaps of + // wrong size by Viz can cause the swapped content to get scaled. + // TODO(samans): Investigate nonblocking ways for solving + // https://crbug.com/811945. + mojo::SyncCallRestrictions::ScopedAllowSyncCall scoped_allow_sync_call; + iter->second.display_private->DisableSwapUntilResize(); + } +} + +void HostContextFactoryPrivate::SetDisplayColorMatrix( + Compositor* compositor, + const SkMatrix44& matrix) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->SetDisplayColorMatrix(gfx::Transform(matrix)); +} + +void HostContextFactoryPrivate::SetDisplayColorSpace( + Compositor* compositor, + const gfx::ColorSpace& blending_color_space, + const gfx::ColorSpace& output_color_space) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->SetDisplayColorSpace(blending_color_space, + output_color_space); +} + +void HostContextFactoryPrivate::SetAuthoritativeVSyncInterval( + Compositor* compositor, + base::TimeDelta interval) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->SetAuthoritativeVSyncInterval(interval); +} + +void HostContextFactoryPrivate::SetDisplayVSyncParameters( + Compositor* compositor, + base::TimeTicks timebase, + base::TimeDelta interval) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->SetDisplayVSyncParameters(timebase, interval); +} + +void HostContextFactoryPrivate::IssueExternalBeginFrame( + Compositor* compositor, + const viz::BeginFrameArgs& args) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + + DCHECK(iter->second.external_begin_frame_controller_client); + iter->second.external_begin_frame_controller_client->GetController() + ->IssueExternalBeginFrame(args); +} + +void HostContextFactoryPrivate::SetOutputIsSecure(Compositor* compositor, + bool secure) { + auto iter = compositor_data_map_.find(compositor); + if (iter == compositor_data_map_.end() || !iter->second.display_private) + return; + iter->second.display_private->SetOutputIsSecure(secure); +} + +viz::FrameSinkManagerImpl* HostContextFactoryPrivate::GetFrameSinkManager() { + // When running with viz there is no FrameSinkManagerImpl in the browser + // process. FrameSinkManagerImpl runs in the GPU process instead. Anything in + // the browser process that relies FrameSinkManagerImpl or SurfaceManager + // internal state needs to change. See https://crbug.com/787097 and + // https://crbug.com/760181 for more context. + NOTREACHED(); + return nullptr; +} + +base::flat_set<Compositor*> HostContextFactoryPrivate::GetAllCompositors() { + base::flat_set<Compositor*> all_compositors; + all_compositors.reserve(compositor_data_map_.size()); + for (auto& pair : compositor_data_map_) + all_compositors.insert(pair.first); + return all_compositors; +} + +HostContextFactoryPrivate::CompositorData::CompositorData() = default; +HostContextFactoryPrivate::CompositorData::CompositorData( + CompositorData&& other) = default; +HostContextFactoryPrivate::CompositorData::~CompositorData() = default; +HostContextFactoryPrivate::CompositorData& +HostContextFactoryPrivate::CompositorData::operator=(CompositorData&& other) = + default; + +} // namespace ui
diff --git a/ui/compositor/host/host_context_factory_private.h b/ui/compositor/host/host_context_factory_private.h new file mode 100644 index 0000000..76319de --- /dev/null +++ b/ui/compositor/host/host_context_factory_private.h
@@ -0,0 +1,122 @@ +// 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 UI_COMPOSITOR_HOST_HOST_CONTEXT_FACTORY_PRIVATE_H_ +#define UI_COMPOSITOR_HOST_HOST_CONTEXT_FACTORY_PRIVATE_H_ + +#include <stdint.h> + +#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "components/viz/common/display/renderer_settings.h" +#include "components/viz/common/surfaces/frame_sink_id_allocator.h" +#include "services/viz/privileged/interfaces/compositing/display_private.mojom.h" +#include "ui/compositor/compositor.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace viz { +class ContextProvider; +class HostDisplayClient; +class RasterContextProvider; +} // namespace viz + +namespace ui { + +class ExternalBeginFrameControllerClientImpl; + +class HostContextFactoryPrivate : public ContextFactoryPrivate { + public: + HostContextFactoryPrivate( + uint32_t client_id, + viz::HostFrameSinkManager* host_frame_sink_manager, + scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner); + ~HostContextFactoryPrivate() override; + + void ConfigureCompositor( + base::WeakPtr<Compositor> compositor_weak_ptr, + scoped_refptr<viz::ContextProvider> context_provider, + scoped_refptr<viz::RasterContextProvider> worker_context_provider); + + void UnconfigureCompositor(Compositor* compositor); + + // ContextFactoryPrivate implementation. + std::unique_ptr<Reflector> CreateReflector(Compositor* source, + Layer* target) override; + void RemoveReflector(Reflector* reflector) override; + viz::FrameSinkId AllocateFrameSinkId() override; + viz::HostFrameSinkManager* GetHostFrameSinkManager() override; + void SetDisplayVisible(Compositor* compositor, bool visible) override; + void ResizeDisplay(Compositor* compositor, const gfx::Size& size) override; + void DisableSwapUntilResize(Compositor* compositor) override; + void SetDisplayColorMatrix(Compositor* compositor, + const SkMatrix44& matrix) override; + void SetDisplayColorSpace(Compositor* compositor, + const gfx::ColorSpace& blending_color_space, + const gfx::ColorSpace& output_color_space) override; + void SetAuthoritativeVSyncInterval(Compositor* compositor, + base::TimeDelta interval) override; + void SetDisplayVSyncParameters(Compositor* compositor, + base::TimeTicks timebase, + base::TimeDelta interval) override; + void IssueExternalBeginFrame(Compositor* compositor, + const viz::BeginFrameArgs& args) override; + void SetOutputIsSecure(Compositor* compositor, bool secure) override; + viz::FrameSinkManagerImpl* GetFrameSinkManager() override; + + protected: + void set_is_gpu_compositing_disabled(bool value) { + is_gpu_compositing_disabled_ = value; + } + bool is_gpu_compositing_disabled() const { + return is_gpu_compositing_disabled_; + } + + scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner() { + return resize_task_runner_; + } + + base::flat_set<Compositor*> GetAllCompositors(); + + private: + struct CompositorData { + CompositorData(); + CompositorData(CompositorData&& other); + ~CompositorData(); + CompositorData& operator=(CompositorData&& other); + + // Privileged interface that controls the display for a root + // CompositorFrameSink. + viz::mojom::DisplayPrivateAssociatedPtr display_private; + std::unique_ptr<viz::HostDisplayClient> display_client; + + // Controls external BeginFrames for the display. Only set if external + // BeginFrames are enabled for the compositor. + std::unique_ptr<ExternalBeginFrameControllerClientImpl> + external_begin_frame_controller_client; + + private: + DISALLOW_COPY_AND_ASSIGN(CompositorData); + }; + + base::flat_map<Compositor*, CompositorData> compositor_data_map_; + + viz::FrameSinkIdAllocator frame_sink_id_allocator_; + viz::HostFrameSinkManager* host_frame_sink_manager_; + const viz::RendererSettings renderer_settings_; + + bool is_gpu_compositing_disabled_ = false; + + scoped_refptr<base::SingleThreadTaskRunner> const resize_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(HostContextFactoryPrivate); +}; + +} // namespace ui + +#endif // UI_COMPOSITOR_HOST_HOST_CONTEXT_FACTORY_PRIVATE_H_
diff --git a/ui/display/types/gamma_ramp_rgb_entry.h b/ui/display/types/gamma_ramp_rgb_entry.h index 39654b1..9bdafee 100644 --- a/ui/display/types/gamma_ramp_rgb_entry.h +++ b/ui/display/types/gamma_ramp_rgb_entry.h
@@ -12,6 +12,9 @@ namespace display { // Provides a single entry for a gamma correction table in a GPU. +// Each color component is UNORM16 fixed point format. This means each component +// must be in the range [0, 2^16) and 0xffff represents the maximum value for +// the color component. struct DISPLAY_TYPES_EXPORT GammaRampRGBEntry { uint16_t r; uint16_t g;
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index a644c64..095f69df 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -119,11 +119,11 @@ defines = [ "EVENTS_BASE_IMPLEMENTATION" ] deps = [ + ":dom_keycode_converter", "//base/third_party/dynamic_annotations", ] public_deps = [ - ":dom_keycode_converter", ":event_constants", ":platform_event", "//base", @@ -393,6 +393,7 @@ ] public_deps = [ + ":dom_keycode_converter", ":events", ":events_base", ":gesture_detection",
diff --git a/ui/file_manager/file_manager/background/js/test_util_base.js b/ui/file_manager/file_manager/background/js/test_util_base.js index c96d21f..e2240c21 100644 --- a/ui/file_manager/file_manager/background/js/test_util_base.js +++ b/ui/file_manager/file_manager/background/js/test_util_base.js
@@ -124,48 +124,6 @@ }; /** - * Gets a document in the Files app's window, including iframes. - * - * @param {Window} contentWindow Window to be used. - * @param {string=} opt_iframeQuery Query for the iframe. - * @return {Document} Returns the found document or null if not found. - * @private - */ -test.util.sync.getDocument_ = function(contentWindow, opt_iframeQuery) { - if (opt_iframeQuery) { - var iframe = contentWindow.document.querySelector(opt_iframeQuery); - var doc = iframe && iframe.contentWindow && iframe.contentWindow.document; - return doc ? doc : null; - } - - return contentWindow.document ? contentWindow.document : null; -}; - -/** - * Gets the element specified by |targetQuery|. - * - * @param {Window} contentWindow Window to be used. - * @param {string} targetQuery Query to specify the element. - * @param {string=} opt_iframeQuery Query for the iframe. - * @return {Element} If the specified element is not found, null is returned. - * @private - */ -test.util.sync.getElement_ = function( - contentWindow, targetQuery, opt_iframeQuery) { - var doc = test.util.sync.getDocument_(contentWindow, opt_iframeQuery); - if (!doc) - return null; - - var target = doc.querySelector(targetQuery); - if (!target) { - console.error('Target element for ' + targetQuery + ' not found.'); - return null; - } - - return target; -}; - -/** * Gets total Javascript error count from background page and each app window. * @return {number} Error count. */ @@ -226,7 +184,6 @@ * * @param {!Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element. - * @param {?string} iframeQuery Iframe selector or null if no iframe. * @param {Array<string>=} opt_styleNames List of CSS property name to be * obtained. * @return {!Array<{attributes:Object<string>, text:string, @@ -235,9 +192,9 @@ * values, hidden attribute, and style names and values. */ test.util.sync.queryAllElements = function( - contentWindow, targetQuery, iframeQuery, opt_styleNames) { + contentWindow, targetQuery, opt_styleNames) { return test.util.sync.deepQueryAllElements( - contentWindow, [targetQuery], iframeQuery, opt_styleNames); + contentWindow, [targetQuery], opt_styleNames); }; /** @@ -247,7 +204,6 @@ * @param {!Array<string>} targetQuery Query to specify the element. * |targetQuery[0]| specifies the first element(s). |targetQuery[1]| specifies * elements inside the shadow DOM of the first element, and so on. - * @param {?string} iframeQuery Iframe selector or null if no iframe. * @param {Array<string>=} opt_styleNames List of CSS property name to be * obtained. * @return {!Array<{attributes:Object<string>, text:string, @@ -256,13 +212,12 @@ * values, hidden attribute, and style names and values. */ test.util.sync.deepQueryAllElements = function( - contentWindow, targetQuery, iframeQuery, opt_styleNames) { - var doc = test.util.sync.getDocument_( - contentWindow, iframeQuery || undefined); - if (!doc) + contentWindow, targetQuery, opt_styleNames) { + if (!contentWindow.document) return []; - var elems = test.util.sync.deepQuerySelectorAll_(doc, targetQuery); + var elems = + test.util.sync.deepQuerySelectorAll_(contentWindow.document, targetQuery); return elems.map(function(element) { return extractElementInfo(element, contentWindow, opt_styleNames); }); @@ -299,8 +254,6 @@ * Gets the information of the active element. * * @param {Window} contentWindow Window to be tested. - * @param {string} targetQuery Query to specify the element. - * @param {?string} iframeQuery Iframe selector or null if no iframe. * @param {Array<string>=} opt_styleNames List of CSS property name to be * obtained. * @return {?{attributes:Object<string>, text:string, @@ -309,14 +262,12 @@ * values, hidden attribute, and style names and values. If there is no * active element, returns null. */ -test.util.sync.getActiveElement = function( - contentWindow, targetQuery, iframeQuery, opt_styleNames) { - var doc = test.util.sync.getDocument_( - contentWindow, iframeQuery || undefined); - if (!doc || !doc.activeElement) +test.util.sync.getActiveElement = function(contentWindow, opt_styleNames) { + if (!contentWindow.document || !contentWindow.document.activeElement) return null; - return extractElementInfo(doc.activeElement, contentWindow, opt_styleNames); + return extractElementInfo( + contentWindow.document.activeElement, contentWindow, opt_styleNames); }; /** @@ -341,25 +292,22 @@ * element(s), |targetQuery[1]| specifies elements inside the shadow DOM of * the first element, and so on. * @param {!Event} event Event to be sent. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if the event is sent to the target, false otherwise. */ -test.util.sync.sendEvent = function( - contentWindow, targetQuery, event, opt_iframeQuery) { - var target; +test.util.sync.sendEvent = function(contentWindow, targetQuery, event) { + if (!contentWindow.document) + return false; + + let target; if (targetQuery === null) { target = contentWindow.document.activeElement; } else if (typeof targetQuery === 'string') { - target = - test.util.sync.getElement_(contentWindow, targetQuery, opt_iframeQuery); + target = contentWindow.document.querySelector(targetQuery); } else if (Array.isArray(targetQuery)) { - var doc = test.util.sync.getDocument_( - contentWindow, opt_iframeQuery || undefined); - if (doc) { - var elems = test.util.sync.deepQuerySelectorAll_(doc, targetQuery); - if (elems.length > 0) - target = elems[0]; - } + let elems = test.util.sync.deepQuerySelectorAll_( + contentWindow.document, targetQuery); + if (elems.length > 0) + target = elems[0]; } if (!target) @@ -405,12 +353,10 @@ * @param {boolean} ctrl Whether CTRL should be pressed, or not. * @param {boolean} shift whether SHIFT should be pressed, or not. * @param {boolean} alt whether ALT should be pressed, or not. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if the event is sent to the target, false otherwise. */ test.util.sync.fakeKeyDown = function( - contentWindow, targetQuery, key, keyIdentifier, ctrl, shift, alt, - opt_iframeQuery) { + contentWindow, targetQuery, key, keyIdentifier, ctrl, shift, alt) { var event = new KeyboardEvent('keydown', { bubbles: true, @@ -420,8 +366,7 @@ shiftKey: shift, altKey: alt }); - return test.util.sync.sendEvent( - contentWindow, targetQuery, event, opt_iframeQuery); + return test.util.sync.sendEvent(contentWindow, targetQuery, event); }; /** @@ -435,24 +380,22 @@ * If targetQuery is an array, |targetQuery[0]| specifies the first * element(s), |targetQuery[1]| specifies elements inside the shadow DOM of * the first element, and so on. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if the all events are sent to the target, false * otherwise. */ -test.util.sync.fakeMouseClick = function( - contentWindow, targetQuery, opt_iframeQuery) { +test.util.sync.fakeMouseClick = function(contentWindow, targetQuery) { var mouseOverEvent = new MouseEvent('mouseover', {bubbles: true, detail: 1}); - var resultMouseOver = test.util.sync.sendEvent( - contentWindow, targetQuery, mouseOverEvent, opt_iframeQuery); + var resultMouseOver = + test.util.sync.sendEvent(contentWindow, targetQuery, mouseOverEvent); var mouseDownEvent = new MouseEvent('mousedown', {bubbles: true, detail: 1}); - var resultMouseDown = test.util.sync.sendEvent( - contentWindow, targetQuery, mouseDownEvent, opt_iframeQuery); + var resultMouseDown = + test.util.sync.sendEvent(contentWindow, targetQuery, mouseDownEvent); var mouseUpEvent = new MouseEvent('mouseup', {bubbles: true, detail: 1}); - var resultMouseUp = test.util.sync.sendEvent( - contentWindow, targetQuery, mouseUpEvent, opt_iframeQuery); + var resultMouseUp = + test.util.sync.sendEvent(contentWindow, targetQuery, mouseUpEvent); var clickEvent = new MouseEvent('click', {bubbles: true, detail: 1}); - var resultClick = test.util.sync.sendEvent( - contentWindow, targetQuery, clickEvent, opt_iframeQuery); + var resultClick = + test.util.sync.sendEvent(contentWindow, targetQuery, clickEvent); return resultMouseOver && resultMouseDown && resultMouseUp && resultClick; }; @@ -462,21 +405,17 @@ * * @param {Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if the event is sent to the target, false * otherwise. */ -test.util.sync.fakeMouseRightClick = function( - contentWindow, targetQuery, opt_iframeQuery) { +test.util.sync.fakeMouseRightClick = function(contentWindow, targetQuery) { var mouseDownEvent = new MouseEvent('mousedown', {bubbles: true, button: 2}); - if (!test.util.sync.sendEvent(contentWindow, targetQuery, mouseDownEvent, - opt_iframeQuery)) { + if (!test.util.sync.sendEvent(contentWindow, targetQuery, mouseDownEvent)) { return false; } var contextMenuEvent = new MouseEvent('contextmenu', {bubbles: true}); - return test.util.sync.sendEvent(contentWindow, targetQuery, contextMenuEvent, - opt_iframeQuery); + return test.util.sync.sendEvent(contentWindow, targetQuery, contextMenuEvent); }; /** @@ -485,29 +424,24 @@ * * @param {Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if the event is sent to the target, false otherwise. */ -test.util.sync.fakeMouseDoubleClick = function( - contentWindow, targetQuery, opt_iframeQuery) { +test.util.sync.fakeMouseDoubleClick = function(contentWindow, targetQuery) { // Double click is always preceded with a single click. - if (!test.util.sync.fakeMouseClick( - contentWindow, targetQuery, opt_iframeQuery)) { + if (!test.util.sync.fakeMouseClick(contentWindow, targetQuery)) { return false; } // Send the second click event, but with detail equal to 2 (number of clicks) // in a row. var event = new MouseEvent('click', { bubbles: true, detail: 2 }); - if (!test.util.sync.sendEvent( - contentWindow, targetQuery, event, opt_iframeQuery)) { + if (!test.util.sync.sendEvent(contentWindow, targetQuery, event)) { return false; } // Send the double click event. var event = new MouseEvent('dblclick', { bubbles: true }); - if (!test.util.sync.sendEvent( - contentWindow, targetQuery, event, opt_iframeQuery)) { + if (!test.util.sync.sendEvent(contentWindow, targetQuery, event)) { return false; } @@ -519,14 +453,11 @@ * * @param {Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if the event is sent to the target, false otherwise. */ -test.util.sync.fakeMouseDown = function( - contentWindow, targetQuery, opt_iframeQuery) { +test.util.sync.fakeMouseDown = function(contentWindow, targetQuery) { var event = new MouseEvent('mousedown', { bubbles: true }); - return test.util.sync.sendEvent( - contentWindow, targetQuery, event, opt_iframeQuery); + return test.util.sync.sendEvent(contentWindow, targetQuery, event); }; /** @@ -534,14 +465,11 @@ * * @param {Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if the event is sent to the target, false otherwise. */ -test.util.sync.fakeMouseUp = function( - contentWindow, targetQuery, opt_iframeQuery) { +test.util.sync.fakeMouseUp = function(contentWindow, targetQuery) { var event = new MouseEvent('mouseup', { bubbles: true }); - return test.util.sync.sendEvent( - contentWindow, targetQuery, event, opt_iframeQuery); + return test.util.sync.sendEvent(contentWindow, targetQuery, event); }; /** @@ -550,13 +478,13 @@ * * @param {Window} contentWindow Window to be tested. * @param {string} targetQuery Query to specify the element. - * @param {string=} opt_iframeQuery Optional iframe selector. * @return {boolean} True if focus method of the element has been called, false * otherwise. */ -test.util.sync.focus = function(contentWindow, targetQuery, opt_iframeQuery) { - var target = test.util.sync.getElement_( - contentWindow, targetQuery, opt_iframeQuery); +test.util.sync.focus = function(contentWindow, targetQuery) { + var target = contentWindow.document && + contentWindow.document.querySelector(targetQuery); + if (!target) return false;
diff --git a/ui/file_manager/file_manager/test/js/test_util.js b/ui/file_manager/file_manager/test/js/test_util.js index 1532894..730588e 100644 --- a/ui/file_manager/file_manager/test/js/test_util.js +++ b/ui/file_manager/file_manager/test/js/test_util.js
@@ -366,23 +366,14 @@ /** * Waits for the specified element appearing in the DOM. - * @param {string|!Array<string>} query Query string for the element. - * |query[0]| specifies the first element(s). |query[1]| specifies - * elements inside the shadow DOM of the first element, and so on. + * @param {string} query Query string for the element. * @return {Promise} Promise to be fulfilled when the element appears. */ test.waitForElement = function(query) { return test.repeatUntil(() => { - if (typeof query == 'string') - query = [query]; - let result = document.querySelector(query[0]); - for (let i = 1; i < query.length && result; i++) { - result = result.shadowRoot; - if (result) - result = result.querySelector(query[i]); - } - if (result) - return result; + let element = document.querySelector(query); + if (element) + return element; return test.pending('Element %s is not found.', query); }); };
diff --git a/ui/file_manager/file_manager/test/quick_view.js b/ui/file_manager/file_manager/test/quick_view.js index 3af472c..bd45cc8 100644 --- a/ui/file_manager/file_manager/test/quick_view.js +++ b/ui/file_manager/file_manager/test/quick_view.js
@@ -14,15 +14,17 @@ assertTrue(test.selectFile('My Desktop Background.png')); // Press Space key. assertTrue(test.fakeKeyDown('#file-list', ' ', ' ', false, false, false)); - return test.waitForElement(['#quick-view', '#dialog']) - .then((result) => { - // Wait until Quick View is displayed and files-safe-media.src is set. - return test.repeatUntil(() => { - if (getComputedStyle(result).display === 'block' && - result.querySelector('files-safe-media').src) - return result; - return test.pending('Quick View is not opened yet.'); - }); + // Wait until Quick View is displayed and files-safe-media.src is set. + return test + .repeatUntil(() => { + let element = document.querySelector('#quick-view'); + if (element && element.shadowRoot) { + element = element.shadowRoot.querySelector('#dialog'); + if (getComputedStyle(element).display === 'block' && + element.querySelector('files-safe-media').src) + return element; + } + return test.pending('Quick View is not opened yet.'); }) .then((result) => { // Click panel and wait for close.
diff --git a/ui/file_manager/integration_tests/file_manager/open_image_files.js b/ui/file_manager/integration_tests/file_manager/open_image_files.js index 345eb52..d94faff9 100644 --- a/ui/file_manager/integration_tests/file_manager/open_image_files.js +++ b/ui/file_manager/integration_tests/file_manager/open_image_files.js
@@ -7,72 +7,47 @@ (function() { /** - * Tests if the gallery shows up for the selected image and is loaded - * successfully. + * Tests opening (then closing) the image Gallery from Files app. * - * @param {string} path Directory path to be tested. + * @param {string} path Directory path (Downloads or Drive). */ function imageOpen(path) { - var appId; - var galleryAppId; - - var expectedFilesBefore = - TestEntryInfo.getExpectedRows(path == RootPath.DRIVE ? - BASIC_DRIVE_ENTRY_SET : BASIC_LOCAL_ENTRY_SET).sort(); - var expectedFilesAfter = - expectedFilesBefore.concat([ENTRIES.image3.getExpectedRow()]).sort(); + let appId; + let galleryAppId; StepsRunner.run([ + // Open Files.App on |path|, add image3 to Downloads and Drive. function() { - setupAndWaitUntilReady(null, path, this.next); + setupAndWaitUntilReady( + null, path, this.next, [ENTRIES.image3], [ENTRIES.image3]); }, - // Select the song. + // Open the image file in Files app. function(results) { appId = results.windowId; - - // Add an additional image file. - addEntries(['local', 'drive'], [ENTRIES.image3], this.next); - }, - function(result) { - chrome.test.assertTrue(result); - remoteCall.waitForFileListChange(appId, expectedFilesBefore.length). - then(this.next); - }, - function(actualFilesAfter) { - chrome.test.assertEq(expectedFilesAfter, actualFilesAfter); - // Open a file in the Files app. remoteCall.callRemoteTestUtil( - 'openFile', appId, ['My Desktop Background.png'], this.next); + 'openFile', appId, [ENTRIES.image3.targetPath], this.next); }, + // Check: the Gallery window should open. function(result) { chrome.test.assertTrue(result); - // Wait for the window. galleryApp.waitForWindow('gallery.html').then(this.next); }, - function(inAppId) { - galleryAppId = inAppId; - // Wait for the file opened. - galleryApp.waitForSlideImage( - galleryAppId, 800, 600, 'My Desktop Background').then(this.next); - }, - function() { - // Open another file in the Files app. - remoteCall.callRemoteTestUtil( - 'openFile', appId, ['image3.jpg'], this.next); - }, - function(result) { - chrome.test.assertTrue(result); - // Wait for the file opened. + // Check: the image should appear in the Gallery window. + function(windowId) { + galleryAppId = windowId; galleryApp.waitForSlideImage( galleryAppId, 640, 480, 'image3').then(this.next); }, + // Close the Gallery window. function() { - // Close window galleryApp.closeWindowAndWait(galleryAppId).then(this.next); }, - // Wait for closing. + // Check: the Gallery window should close. function(result) { - chrome.test.assertTrue(result, 'Fail to close the window'); + chrome.test.assertTrue(result, 'Failed to close Gallery window'); + this.next(); + }, + function() { checkIfNoErrorsOccured(this.next); } ]);
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js index 7d7c79c..1c931d21 100644 --- a/ui/file_manager/integration_tests/file_manager/quick_view.js +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -40,7 +40,7 @@ const elements = ['#quick-view', '#dialog']; return remoteCall .callRemoteTestUtil( - 'deepQueryAllElements', appId, [elements, null, ['display']]) + 'deepQueryAllElements', appId, [elements, ['display']]) .then(checkQuickViewElementsDisplayBlock); }).then(this.next); }, @@ -78,7 +78,7 @@ const elements = ['#quick-view', '#dialog']; return remoteCall .callRemoteTestUtil( - 'deepQueryAllElements', appId, [elements, null, ['display']]) + 'deepQueryAllElements', appId, [elements, ['display']]) .then(checkQuickViewElementsDisplayNone); }).then(this.next); },
diff --git a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js index 3b8cfda..6657ab6 100644 --- a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js +++ b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
@@ -60,10 +60,7 @@ return remoteCall .callRemoteTestUtil( 'queryAllElements', appId, - [ - '.share-dialog-webview-wrapper.loaded', null /* iframe */, - ['width', 'height'] - ]) + ['.share-dialog-webview-wrapper.loaded', ['width', 'height']]) .then(function(elements) { // TODO(mtomasz): Fix the wrong geometry of the share dialog. // return elements[0] &&
diff --git a/ui/file_manager/integration_tests/remote_call.js b/ui/file_manager/integration_tests/remote_call.js index 164b81c..051c7e89 100644 --- a/ui/file_manager/integration_tests/remote_call.js +++ b/ui/file_manager/integration_tests/remote_call.js
@@ -158,26 +158,17 @@ * Waits for the specified element appearing in the DOM. * @param {string} windowId Target window ID. * @param {string} query Query string for the element. - * @param {string=} opt_iframeQuery Query string for the iframe containing the - * element. * @return {Promise} Promise to be fulfilled when the element appears. */ -RemoteCall.prototype.waitForElement = function( - windowId, query, opt_iframeQuery) { +RemoteCall.prototype.waitForElement = function(windowId, query) { var caller = getCaller(); return repeatUntil(function() { - return this.callRemoteTestUtil( - 'queryAllElements', - windowId, - [query, opt_iframeQuery] - ).then(function(elements) { - if (elements.length > 0) - return elements[0]; - else - return pending( - caller, 'Element %s (maybe in iframe %s) is not found.', query, - opt_iframeQuery); - }); + return this.callRemoteTestUtil('queryAllElements', windowId, [query]) + .then(function(elements) { + if (elements.length > 0) + return elements[0]; + return pending(caller, 'Element %s is not found.', query); + }); }.bind(this)); }; @@ -185,23 +176,17 @@ * Waits for the specified element leaving from the DOM. * @param {string} windowId Target window ID. * @param {string} query Query string for the element. - * @param {string=} opt_iframeQuery Query string for the iframe containing the - * element. * @return {Promise} Promise to be fulfilled when the element is lost. */ -RemoteCall.prototype.waitForElementLost = function( - windowId, query, opt_iframeQuery) { +RemoteCall.prototype.waitForElementLost = function(windowId, query) { var caller = getCaller(); return repeatUntil(function() { - return this.callRemoteTestUtil( - 'queryAllElements', - windowId, - [query, opt_iframeQuery] - ).then(function(elements) { - if (elements.length > 0) - return pending(caller, 'Elements %j is still exists.', elements); - return true; - }); + return this.callRemoteTestUtil('queryAllElements', windowId, [query]) + .then(function(elements) { + if (elements.length > 0) + return pending(caller, 'Elements %j is still exists.', elements); + return true; + }); }.bind(this)); };
diff --git a/ui/gfx/font_list.cc b/ui/gfx/font_list.cc index 69220c8..5cb2b22 100644 --- a/ui/gfx/font_list.cc +++ b/ui/gfx/font_list.cc
@@ -8,8 +8,8 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkTypeface.h" -#include "third_party/skia/include/ports/SkFontMgr.h" #include "ui/gfx/font_list_impl.h" namespace {
diff --git a/ui/gfx/win/direct_write.cc b/ui/gfx/win/direct_write.cc index 3a4ed2e..56d0d3c 100644 --- a/ui/gfx/win/direct_write.cc +++ b/ui/gfx/win/direct_write.cc
@@ -12,7 +12,7 @@ #include "base/win/registry.h" #include "base/win/windows_version.h" #include "skia/ext/fontmgr_default_win.h" -#include "third_party/skia/include/ports/SkFontMgr.h" +#include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkTypeface_win.h" #include "ui/gfx/platform_font_win.h" #include "ui/gfx/switches.h"
diff --git a/ui/gl/gl_implementation.cc b/ui/gl/gl_implementation.cc index d682388..58e7ad29 100644 --- a/ui/gl/gl_implementation.cc +++ b/ui/gl/gl_implementation.cc
@@ -54,22 +54,20 @@ if (g_libraries) { // We do not call base::UnloadNativeLibrary() for these libraries as // unloading libGL without closing X display is not allowed. See - // crbug.com/250813 for details. - bool unload_libraries = false; -#if defined(OS_WIN) - // However during fallback from ANGLE to SwiftShader ANGLE library needs to + // https://crbug.com/250813 for details. + // However, if we fallback to a software renderer (e.g., SwiftShader), + // then the above concern becomes irrelevant. + // During fallback from ANGLE to SwiftShader ANGLE library needs to // be unloaded, otherwise software SwiftShader loading will fail. See - // crbug.com/760063 for details. - unload_libraries = due_to_fallback && - *static_cast<bool*>(due_to_fallback) && - GetGLImplementation() == kGLImplementationEGLGLES2; -#endif - if (unload_libraries) { + // https://crbug.com/760063 for details. + // During fallback from VMware mesa to SwiftShader mesa libraries need + // to be unloaded. See https://crbug.com/852537 for details. + if (due_to_fallback && *static_cast<bool*>(due_to_fallback)) { for (auto* library : *g_libraries) base::UnloadNativeLibrary(library); } delete g_libraries; - g_libraries = NULL; + g_libraries = nullptr; } }
diff --git a/ui/keyboard/container_floating_behavior.cc b/ui/keyboard/container_floating_behavior.cc index 005bfc8..3743c05 100644 --- a/ui/keyboard/container_floating_behavior.cc +++ b/ui/keyboard/container_floating_behavior.cc
@@ -190,9 +190,9 @@ DCHECK(controller_); auto kb_offset = gfx::Vector2d(event.x(), event.y()); - aura::Window* container = controller_->GetContainerWindow(); + aura::Window* contents = controller_->GetContentsWindow(); - const gfx::Rect& keyboard_bounds_in_screen = container->GetBoundsInScreen(); + const gfx::Rect& keyboard_bounds_in_screen = contents->GetBoundsInScreen(); // Don't handle events if this runs in a partially initialized state. if (keyboard_bounds_in_screen.height() <= 0) @@ -277,7 +277,7 @@ controller_->MoveToDisplayWithTransition(new_display, new_bounds_in_local); } - SavePosition(container->GetBoundsInScreen(), new_display.size()); + SavePosition(contents->GetBoundsInScreen(), new_display.size()); return true; } break;
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc index 3d816af..94d2bcf 100644 --- a/ui/keyboard/keyboard_controller.cc +++ b/ui/keyboard/keyboard_controller.cc
@@ -99,46 +99,6 @@ return kAllowedStateTransition.count(std::make_pair(from, to)) == 1; }; -// The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. -// This is necessary to make sure that the synthetic key-events reach the target -// window. -// The delegate deletes itself when the window is destroyed. -class KeyboardWindowDelegate : public aura::WindowDelegate { - public: - KeyboardWindowDelegate() {} - ~KeyboardWindowDelegate() override {} - - private: - // Overridden from aura::WindowDelegate: - gfx::Size GetMinimumSize() const override { return gfx::Size(); } - gfx::Size GetMaximumSize() const override { return gfx::Size(); } - void OnBoundsChanged(const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) override {} - gfx::NativeCursor GetCursor(const gfx::Point& point) override { - return gfx::kNullCursor; - } - int GetNonClientComponent(const gfx::Point& point) const override { - return HTNOWHERE; - } - bool ShouldDescendIntoChildForEventHandling( - aura::Window* child, - const gfx::Point& location) override { - return true; - } - bool CanFocus() override { return false; } - void OnCaptureLost() override {} - void OnPaint(const ui::PaintContext& context) override {} - void OnDeviceScaleFactorChanged(float old_device_scale_factor, - float new_device_scale_factor) override {} - void OnWindowDestroying(aura::Window* window) override {} - void OnWindowDestroyed(aura::Window* window) override { delete this; } - void OnWindowTargetVisibilityChanged(bool visible) override {} - bool HasHitTestMask() const override { return false; } - void GetHitTestMask(gfx::Path* mask) const override {} - - DISALLOW_COPY_AND_ASSIGN(KeyboardWindowDelegate); -}; - void SetTouchEventLogging(bool enable) { // TODO(moshayedi): crbug.com/642863. Revisit when we have mojo interface for // InputController for processes that aren't mus-ws. @@ -223,16 +183,6 @@ ui_ = std::move(ui); - // TODO(https://crbug.com/845780): Move |container_| and friends to a separate - // class that manages the container window. - container_ = std::make_unique<aura::Window>(new KeyboardWindowDelegate()); - container_->SetName("KeyboardContainer"); - container_->set_owned_by_parent(false); - container_->Init(ui::LAYER_NOT_DRAWN); - container_->AddObserver(this); - container_->SetLayoutManager(new KeyboardLayoutManager(this)); - container_->AddPreTargetHandler(&event_filter_); - layout_delegate_ = delegate; show_on_content_update_ = false; keyboard_locked_ = false; @@ -249,6 +199,9 @@ if (!enabled()) return; + if (parent_container_) + DeactivateKeyboard(); + // TODO(https://crbug.com/731537): Move KeyboardController members into a // subobject so we can just put this code into the subobject destructor. queued_display_change_.reset(); @@ -256,12 +209,6 @@ container_behavior_.reset(); animation_observer_.reset(); - if (container_->GetRootWindow()) - container_->GetRootWindow()->RemoveObserver(this); - container_->RemoveObserver(this); - container_->RemovePreTargetHandler(&event_filter_); - container_.reset(); - ui_->GetInputMethod()->RemoveObserver(this); for (KeyboardControllerObserver& observer : observer_list_) observer.OnKeyboardClosed(); @@ -269,6 +216,33 @@ ui_.reset(); } +void KeyboardController::ActivateKeyboardInContainer(aura::Window* parent) { + DCHECK(parent); + DCHECK(!parent_container_); + parent_container_ = parent; + // Observe changes to root window bounds. + parent_container_->GetRootWindow()->AddObserver(this); + + if (GetContentsWindow()) { + DCHECK(!GetContentsWindow()->parent()); + parent_container_->AddChild(GetContentsWindow()); + } +} + +void KeyboardController::DeactivateKeyboard() { + DCHECK(parent_container_); + + // Ensure the keyboard is not visible before deactivating it. + HideKeyboardExplicitlyBySystem(); + + if (GetContentsWindow() && GetContentsWindow()->parent()) { + DCHECK_EQ(parent_container_, GetContentsWindow()->parent()); + parent_container_->RemoveChild(GetContentsWindow()); + } + parent_container_->GetRootWindow()->RemoveObserver(this); + parent_container_ = nullptr; +} + // static KeyboardController* KeyboardController::Get() { DCHECK(g_keyboard_controller); @@ -284,12 +258,12 @@ return state_ == KeyboardControllerState::SHOWN; } -aura::Window* KeyboardController::GetContainerWindow() { - return container_.get(); +aura::Window* KeyboardController::GetContentsWindow() { + return ui_ && ui_->HasContentsWindow() ? ui_->GetContentsWindow() : nullptr; } aura::Window* KeyboardController::GetRootWindow() { - return container_->GetRootWindow(); + return parent_container_ ? parent_container_->GetRootWindow() : nullptr; } void KeyboardController::NotifyContentsBoundsChanging( @@ -317,12 +291,12 @@ } void KeyboardController::SetContainerBounds(const gfx::Rect& new_bounds) { - ui::LayerAnimator* animator = container_->layer()->GetAnimator(); + ui::LayerAnimator* animator = GetContentsWindow()->layer()->GetAnimator(); // Stops previous animation if a window resize is requested during animation. if (animator->is_animating()) animator->StopAnimating(); - container_->SetBounds(new_bounds); + GetContentsWindow()->SetBounds(new_bounds); // We need to send out this notification only if keyboard is visible since // the contents window is resized even if keyboard is hidden. @@ -342,7 +316,7 @@ // Do not move the keyboard to another display after switch to an IME in // a different extension. ShowKeyboardInDisplay( - display_util_.GetNearestDisplayToWindow(GetContainerWindow())); + display_util_.GetNearestDisplayToWindow(GetContentsWindow())); } else { ShowKeyboard(false /* lock */); } @@ -417,15 +391,16 @@ set_keyboard_locked(false); + aura::Window* window = GetContentsWindow(); + DCHECK(window); + animation_observer_ = std::make_unique<CallbackAnimationObserver>( base::BindOnce(&KeyboardController::HideAnimationFinished, base::Unretained(this))); ui::ScopedLayerAnimationSettings layer_animation_settings( - container_->layer()->GetAnimator()); + window->layer()->GetAnimator()); layer_animation_settings.AddObserver(animation_observer_.get()); - aura::Window* window = container_.get(); - { // Scoped settings go into effect when scope ends. ::wm::ScopedHidingAnimationSettings hiding_settings(window); @@ -490,7 +465,7 @@ if (queued_display_change_) { ShowKeyboardInDisplay(queued_display_change_->new_display()); - container_->SetBounds(queued_display_change_->new_bounds_in_local()); + SetContainerBounds(queued_display_change_->new_bounds_in_local()); queued_display_change_ = nullptr; } } @@ -535,7 +510,7 @@ void KeyboardController::OnWindowHierarchyChanged( const HierarchyChangeParams& params) { - if (params.new_parent && params.target == container_.get()) + if (params.new_parent && params.target == GetContentsWindow()) OnTextInputStateChanged(ui_->GetInputMethod()->GetTextInputClient()); } @@ -563,7 +538,7 @@ if (!ui_->HasContentsWindow()) return; - container_behavior_->SetCanonicalBounds(GetContainerWindow(), new_bounds); + container_behavior_->SetCanonicalBounds(GetContentsWindow(), new_bounds); } void KeyboardController::Reload() { @@ -656,6 +631,13 @@ TRACE_EVENT0("vk", "PopulateKeyboardContent"); + if (parent_container_->children().empty()) { + DCHECK_EQ(state_, KeyboardControllerState::INITIAL); + aura::Window* contents = ui_->GetContentsWindow(); + parent_container_->AddChild(contents); + } + + DCHECK(ui_->HasContentsWindow()); if (layout_delegate_ != nullptr) { if (display.is_valid()) layout_delegate_->MoveKeyboardToDisplay(display); @@ -663,13 +645,8 @@ layout_delegate_->MoveKeyboardToTouchableDisplay(); } - if (container_->children().empty()) { - DCHECK_EQ(state_, KeyboardControllerState::INITIAL); - aura::Window* contents = ui_->GetContentsWindow(); - contents->Show(); - container_->AddChild(contents); - contents->set_owned_by_parent(false); - } + aura::Window* contents = ui_->GetContentsWindow(); + DCHECK_EQ(parent_container_, contents->parent()); switch (state_) { case KeyboardControllerState::SHOWN: @@ -683,11 +660,6 @@ ui_->ReloadKeyboardIfNeeded(); - ui::LayerAnimator* container_animator = container_->layer()->GetAnimator(); - - // Ensure that the keyboard is either hidden or is in the process of hiding. - DCHECK(!container_->IsVisible() || container_animator->is_animating()); - SetTouchEventLogging(!show_keyboard /* enable */); switch (state_) { @@ -702,8 +674,7 @@ case KeyboardControllerState::HIDDEN: { // If the container is not animating, makes sure the position and opacity // are at begin states for animation. - container_behavior_->InitializeShowAnimationStartingState( - container_.get()); + container_behavior_->InitializeShowAnimationStartingState(contents); break; } default: @@ -714,10 +685,11 @@ keyboard::LogKeyboardControlEvent(keyboard::KEYBOARD_CONTROL_SHOW); + ui::LayerAnimator* container_animator = contents->layer()->GetAnimator(); container_animator->set_preemption_strategy( ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); - ui_->ShowKeyboardContainer(container_.get()); + ui_->ShowKeyboardContainer(contents); animation_observer_ = std::make_unique<CallbackAnimationObserver>(base::BindOnce( @@ -725,7 +697,7 @@ ui::ScopedLayerAnimationSettings settings(container_animator); settings.AddObserver(animation_observer_.get()); - container_behavior_->DoShowingAnimation(container_.get(), &settings); + container_behavior_->DoShowingAnimation(contents, &settings); // the queued container behavior will notify JS to change layout when it // gets destroyed. @@ -744,9 +716,9 @@ NotifyKeyboardBoundsChangingAndEnsureCaretInWorkArea() { // Notify observers after animation finished to prevent reveal desktop // background during animation. - NotifyContentsBoundsChanging(container_->bounds()); + NotifyContentsBoundsChanging(GetContentsWindow()->bounds()); ui_->EnsureCaretInWorkArea( - container_behavior_->GetOccludedBounds(container_->bounds())); + container_behavior_->GetOccludedBounds(GetContentsWindow()->bounds())); } void KeyboardController::NotifyKeyboardConfigChanged() { @@ -755,8 +727,8 @@ } void KeyboardController::AdjustKeyboardBounds() { - container_behavior_->SetCanonicalBounds( - GetContainerWindow(), container_->GetRootWindow()->bounds()); + container_behavior_->SetCanonicalBounds(GetContentsWindow(), + GetRootWindow()->bounds()); } void KeyboardController::CheckStateTransition(KeyboardControllerState prev, @@ -856,7 +828,7 @@ bool KeyboardController::HandlePointerEvent(const ui::LocatedEvent& event) { const display::Display& current_display = - display_util_.GetNearestDisplayToWindow(container_->GetRootWindow()); + display_util_.GetNearestDisplayToWindow(GetRootWindow()); return container_behavior_->HandlePointerEvent(event, current_display); }
diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h index 8ff121b..ecde9ea0 100644 --- a/ui/keyboard/keyboard_controller.h +++ b/ui/keyboard/keyboard_controller.h
@@ -84,9 +84,19 @@ // Does nothing if the keyboard is already disabled. void DisableKeyboard(); - // Returns the container for the keyboard, which is owned by - // KeyboardController. - aura::Window* GetContainerWindow(); + // Attach the KeyboardUI contents window as a child of the given window. + // Can only be called when the keyboard is not activated. |parent| must not + // have any children. + void ActivateKeyboardInContainer(aura::Window* parent); + + // Detach the KeyboardUI contents window from its parent container window. + // Can only be called when the keyboard is activated. Explicitly hides the + // keyboard if it is currently visible. + void DeactivateKeyboard(); + + // Returns the KeyboardUI contents window, or null if the keyboard contents + // window has not been created yet. + aura::Window* GetContentsWindow(); // Returns the root window that this keyboard controller is attached to, or // null if the keyboard has not been attached to any root window. @@ -325,7 +335,10 @@ std::unique_ptr<KeyboardUI> ui_; KeyboardLayoutDelegate* layout_delegate_; - std::unique_ptr<aura::Window> container_; + + // Container window that the keyboard UI contents window is a child of. + aura::Window* parent_container_ = nullptr; + // CallbackAnimationObserver should destructed before container_ because it // uses container_'s animator. std::unique_ptr<CallbackAnimationObserver> animation_observer_;
diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc index bcc6624..52cd0f9b 100644 --- a/ui/keyboard/keyboard_controller_unittest.cc +++ b/ui/keyboard/keyboard_controller_unittest.cc
@@ -31,6 +31,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/keyboard/container_full_width_behavior.h" #include "ui/keyboard/keyboard_controller_observer.h" +#include "ui/keyboard/keyboard_layout_manager.h" #include "ui/keyboard/keyboard_test_util.h" #include "ui/keyboard/keyboard_ui.h" #include "ui/keyboard/keyboard_util.h" @@ -45,13 +46,6 @@ const int kDefaultVirtualKeyboardHeight = 100; -// Verify if the |keyboard| window covers the |container| window completely. -void VerifyKeyboardWindowSize(aura::Window* container, aura::Window* keyboard) { - ASSERT_EQ(gfx::Rect(0, 0, container->bounds().width(), - container->bounds().height()), - keyboard->bounds()); -} - // Steps a layer animation until it is completed. Animations must be enabled. void RunAnimationForLayer(ui::Layer* layer) { // Animations must be enabled for stepping to work. @@ -94,27 +88,6 @@ DISALLOW_COPY_AND_ASSIGN(TestFocusController); }; -// Keeps a count of all the events a window receives. -class EventObserver : public ui::EventHandler { - public: - EventObserver() {} - ~EventObserver() override {} - - int GetEventCount(ui::EventType type) { - return event_counts_[type]; - } - - private: - // Overridden from ui::EventHandler: - void OnEvent(ui::Event* event) override { - ui::EventHandler::OnEvent(event); - event_counts_[event->type()]++; - } - - std::map<ui::EventType, int> event_counts_; - DISALLOW_COPY_AND_ASSIGN(EventObserver); -}; - class KeyboardContainerObserver : public aura::WindowObserver { public: explicit KeyboardContainerObserver(aura::Window* window, @@ -200,7 +173,7 @@ controller_.EnableKeyboard( std::make_unique<TestKeyboardUI>(host()->GetInputMethod()), layout_delegate_.get()); - root_window()->AddChild(controller().GetContainerWindow()); + controller_.ActivateKeyboardInContainer(root_window()); controller_.AddObserver(this); } @@ -324,21 +297,21 @@ DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); }; -// TODO(https://crbug.com/849995): This is testing KeyboardLayoutManager. Put -// this test there. +// TODO(https://crbug.com/849995): This is testing KeyboardLayoutManager / +// ContainerFullWidthBehavior. Put this test there. TEST_F(KeyboardControllerTest, KeyboardSize) { + root_window()->SetLayoutManager(new KeyboardLayoutManager(&controller())); + controller().LoadKeyboardUiInBackground(); - aura::Window* keyboard_window = ui()->GetContentsWindow(); - aura::Window* container = controller().GetContainerWindow(); + aura::Window* keyboard_window = controller().GetContentsWindow(); // The container should be positioned at the bottom of screen and has 0 // height. const gfx::Rect screen_bounds = root_window()->bounds(); - const gfx::Rect initial_keyboard_bounds = container->bounds(); + const gfx::Rect initial_keyboard_bounds = keyboard_window->bounds(); EXPECT_EQ(0, initial_keyboard_bounds.height()); EXPECT_EQ(screen_bounds.height(), initial_keyboard_bounds.y()); - VerifyKeyboardWindowSize(container, keyboard_window); // Attempt to change window width or move window up from the bottom are // ignored. Changing window height is supported. @@ -350,59 +323,14 @@ // screen. See http://crbug.com/510595. gfx::Rect new_bounds(10, 0, 50, 50); keyboard_window->SetBounds(new_bounds); - EXPECT_EQ(expected_keyboard_bounds, container->bounds()); - VerifyKeyboardWindowSize(container, keyboard_window); + EXPECT_EQ(expected_keyboard_bounds, keyboard_window->bounds()); MockRotateScreen(); // The above call should resize keyboard to new width while keeping the old // height. EXPECT_EQ( gfx::Rect(0, screen_bounds.width() - 50, screen_bounds.height(), 50), - container->bounds()); - VerifyKeyboardWindowSize(container, keyboard_window); -} - -// Tests that tapping/clicking inside the keyboard does not give it focus. -// TODO(https://crbug.com/849995): This is testing KeyboardWindowDelegate. Move -// KeyboardWindowDelegate to its own file and test it there. -TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) { - aura::Window* keyboard_container = controller().GetContainerWindow(); - ShowKeyboard(); - - // Create a window behind the keyboard with the same size as the screen. - aura::test::EventCountDelegate delegate; - auto background_window = std::make_unique<aura::Window>(&delegate); - background_window->Init(ui::LAYER_NOT_DRAWN); - background_window->SetBounds(root_window()->bounds()); - root_window()->AddChild(background_window.get()); - root_window()->StackChildBelow(background_window.get(), keyboard_container); - background_window->Show(); - background_window->Focus(); - - EXPECT_TRUE(background_window->IsVisible()); - EXPECT_TRUE(keyboard_container->IsVisible()); - EXPECT_TRUE(background_window->HasFocus()); - EXPECT_FALSE(keyboard_container->HasFocus()); - - // Click on the keyboard. Make sure the keyboard receives the event, but does - // not get focus. - EventObserver observer; - keyboard_container->AddPreTargetHandler(&observer); - - ui::test::EventGenerator generator(root_window()); - generator.MoveMouseTo(keyboard_container->bounds().CenterPoint()); - generator.ClickLeftButton(); - EXPECT_TRUE(background_window->HasFocus()); - EXPECT_FALSE(keyboard_container->HasFocus()); - EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset()); - EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_PRESSED)); - EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_RELEASED)); - - // Click outside of the keyboard. It should reach the window behind. - generator.MoveMouseTo(gfx::Point()); - generator.ClickLeftButton(); - EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset()); - keyboard_container->RemovePreTargetHandler(&observer); + keyboard_window->bounds()); } // Tests that blur-then-focus that occur in less than the transient threshold @@ -412,21 +340,21 @@ ui::DummyTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE); base::RunLoop run_loop; - aura::Window* keyboard_container = controller().GetContainerWindow(); + controller().LoadKeyboardUiInBackground(); + aura::Window* keyboard_window = controller().GetContentsWindow(); auto keyboard_container_observer = - std::make_unique<KeyboardContainerObserver>(keyboard_container, - &run_loop); + std::make_unique<KeyboardContainerObserver>(keyboard_window, &run_loop); // Keyboard is hidden - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); // Set programmatic focus to the text field. Nothing happens SetProgrammaticFocus(&input_client); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); // Click it for real. Keyboard starts to appear. SetFocus(&input_client); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); // Focus a non text field SetFocus(&no_input_client); @@ -434,7 +362,7 @@ // It waits 100 ms and then hides. Wait for this routine to finish. EXPECT_TRUE(WillHideKeyboard()); RunLoop(&run_loop); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); // Virtually wait half a second AddTimeToTransientBlurCounter(0.5); @@ -444,7 +372,7 @@ // TODO(blakeo): this is not technically wrong, but the DummyTextInputClient // should allow for overriding the text input flags, to simulate testing // a web-based text field. - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); EXPECT_FALSE(WillHideKeyboard()); } @@ -455,21 +383,21 @@ ui::DummyTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE); base::RunLoop run_loop; - aura::Window* keyboard_container(controller().GetContainerWindow()); + controller().LoadKeyboardUiInBackground(); + aura::Window* keyboard_window = controller().GetContentsWindow(); auto keyboard_container_observer = - std::make_unique<KeyboardContainerObserver>(keyboard_container, - &run_loop); + std::make_unique<KeyboardContainerObserver>(keyboard_window, &run_loop); // Keyboard is hidden - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); // Set programmatic focus to the text field. Nothing happens SetProgrammaticFocus(&input_client); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); // Click it for real. Keyboard starts to appear. SetFocus(&input_client); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); // Focus a non text field SetFocus(&no_input_client); @@ -477,12 +405,12 @@ // It waits 100 ms and then hides. Wait for this routine to finish. EXPECT_TRUE(WillHideKeyboard()); RunLoop(&run_loop); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); // Wait 5 seconds and then set programmatic focus to a text field AddTimeToTransientBlurCounter(5.0); SetProgrammaticFocus(&input_client); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); } TEST_F(KeyboardControllerTest, VisibilityChangeWithTextInputTypeChange) { @@ -493,27 +421,27 @@ ui::DummyTextInputClient no_input_client_1(ui::TEXT_INPUT_TYPE_NONE); base::RunLoop run_loop; - aura::Window* keyboard_container(controller().GetContainerWindow()); + controller().LoadKeyboardUiInBackground(); + aura::Window* keyboard_window = controller().GetContentsWindow(); auto keyboard_container_observer = - std::make_unique<KeyboardContainerObserver>(keyboard_container, - &run_loop); + std::make_unique<KeyboardContainerObserver>(keyboard_window, &run_loop); SetFocus(&input_client_0); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); SetFocus(&no_input_client_0); // Keyboard should not immediately hide itself. It is delayed to avoid layout // flicker when the focus of input field quickly change. - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); EXPECT_TRUE(WillHideKeyboard()); // Wait for hide keyboard to finish. RunLoop(&run_loop); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); SetFocus(&input_client_1); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); // Schedule to hide keyboard. SetFocus(&no_input_client_1); @@ -522,7 +450,7 @@ SetFocus(&input_client_2); EXPECT_FALSE(WillHideKeyboard()); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); } // Test to prevent spurious overscroll boxes when changing tabs during keyboard @@ -552,30 +480,30 @@ ui::DummyTextInputClient no_input_client_1(ui::TEXT_INPUT_TYPE_NONE); base::RunLoop run_loop; - aura::Window* keyboard_container = controller().GetContainerWindow(); + controller().LoadKeyboardUiInBackground(); + aura::Window* keyboard_window = controller().GetContentsWindow(); auto keyboard_container_observer = - std::make_unique<KeyboardContainerObserver>(keyboard_container, - &run_loop); + std::make_unique<KeyboardContainerObserver>(keyboard_window, &run_loop); SetFocus(&input_client_0); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); // Lock keyboard. controller().set_keyboard_locked(true); SetFocus(&no_input_client_0); // Keyboard should not try to hide itself as it is locked. - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); EXPECT_FALSE(WillHideKeyboard()); // Implicit hiding will not do anything when the keyboard is locked. controller().HideKeyboardImplicitlyBySystem(); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); EXPECT_FALSE(WillHideKeyboard()); SetFocus(&input_client_1); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); // Unlock keyboard. controller().set_keyboard_locked(false); @@ -586,15 +514,16 @@ // Wait for hide keyboard to finish. RunLoop(&run_loop); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); } // Tests that deactivates keyboard will get closed event. TEST_F(KeyboardControllerTest, CloseKeyboard) { - aura::Window* keyboard_container = controller().GetContainerWindow(); + controller().LoadKeyboardUiInBackground(); + aura::Window* keyboard_window = controller().GetContentsWindow(); ShowKeyboard(); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); EXPECT_FALSE(IsKeyboardClosed()); controller().DisableKeyboard(); @@ -641,8 +570,10 @@ KeyboardControllerTest::SetUp(); - const gfx::Rect& root_bounds = root_window()->bounds(); - keyboard_container()->SetBounds(root_bounds); + // Preload the keyboard contents so that we can set its bounds. + controller().LoadKeyboardUiInBackground(); + controller().NotifyContentsLoaded(); + keyboard_window()->SetBounds(root_window()->bounds()); } void TearDown() override { @@ -650,24 +581,19 @@ } protected: - aura::Window* keyboard_container() { - return controller().GetContainerWindow(); - } - - aura::Window* contents_window() { return ui()->GetContentsWindow(); } + aura::Window* keyboard_window() { return ui()->GetContentsWindow(); } private: DISALLOW_COPY_AND_ASSIGN(KeyboardControllerAnimationTest); }; TEST_F(KeyboardControllerAnimationTest, ContainerAnimation) { - ui::Layer* layer = keyboard_container()->layer(); + ui::Layer* layer = keyboard_window()->layer(); ShowKeyboard(); // Keyboard container and window should immediately become visible before // animation starts. - EXPECT_TRUE(keyboard_container()->IsVisible()); - EXPECT_TRUE(contents_window()->IsVisible()); + EXPECT_TRUE(keyboard_window()->IsVisible()); float show_start_opacity = layer->opacity(); gfx::Transform transform; transform.Translate(0, keyboard::kFullWidthKeyboardAnimationDistance); @@ -679,24 +605,22 @@ EXPECT_FALSE(notified_is_available()); RunAnimationForLayer(layer); - EXPECT_TRUE(keyboard_container()->IsVisible()); - EXPECT_TRUE(contents_window()->IsVisible()); + EXPECT_TRUE(keyboard_window()->IsVisible()); float show_end_opacity = layer->opacity(); EXPECT_LT(show_start_opacity, show_end_opacity); EXPECT_EQ(gfx::Transform(), layer->transform()); // KeyboardController should notify the bounds of container window to its // observers after show animation finished. - EXPECT_EQ(keyboard_container()->bounds(), notified_visible_bounds()); - EXPECT_EQ(keyboard_container()->bounds(), notified_occluding_bounds()); + EXPECT_EQ(keyboard_window()->bounds(), notified_visible_bounds()); + EXPECT_EQ(keyboard_window()->bounds(), notified_occluding_bounds()); EXPECT_TRUE(notified_is_available()); // Directly hide keyboard without delay. float hide_start_opacity = layer->opacity(); controller().HideKeyboardExplicitlyBySystem(); - EXPECT_FALSE(keyboard_container()->IsVisible()); - EXPECT_FALSE(keyboard_container()->layer()->visible()); - EXPECT_FALSE(contents_window()->IsVisible()); - layer = keyboard_container()->layer(); + EXPECT_FALSE(keyboard_window()->IsVisible()); + EXPECT_FALSE(keyboard_window()->layer()->visible()); + layer = keyboard_window()->layer(); // KeyboardController should notify the bounds of keyboard window to its // observers before hide animation starts. EXPECT_EQ(gfx::Rect(), notified_visible_bounds()); @@ -704,9 +628,8 @@ EXPECT_FALSE(notified_is_available()); RunAnimationForLayer(layer); - EXPECT_FALSE(keyboard_container()->IsVisible()); - EXPECT_FALSE(keyboard_container()->layer()->visible()); - EXPECT_FALSE(contents_window()->IsVisible()); + EXPECT_FALSE(keyboard_window()->IsVisible()); + EXPECT_FALSE(keyboard_window()->layer()->visible()); float hide_end_opacity = layer->opacity(); EXPECT_GT(hide_start_opacity, hide_end_opacity); EXPECT_EQ(gfx::Rect(), notified_visible_bounds()); @@ -723,7 +646,7 @@ EXPECT_EQ(1, invocation_counter.invocation_count_for_status(true)); EXPECT_EQ(0, invocation_counter.invocation_count_for_status(false)); // Visible bounds and occluding bounds are now different. - EXPECT_EQ(keyboard_container()->bounds(), notified_visible_bounds()); + EXPECT_EQ(keyboard_window()->bounds(), notified_visible_bounds()); EXPECT_EQ(gfx::Rect(), notified_occluding_bounds()); EXPECT_TRUE(notified_is_available()); @@ -739,12 +662,11 @@ TEST_F(KeyboardControllerAnimationTest, ChangeContainerModeWithBounds) { SetModeCallbackInvocationCounter invocation_counter; - ui::Layer* layer = keyboard_container()->layer(); + ui::Layer* layer = keyboard_window()->layer(); ShowKeyboard(); RunAnimationForLayer(layer); EXPECT_EQ(ContainerType::FULL_WIDTH, controller().GetActiveContainerType()); - EXPECT_TRUE(keyboard_container()->IsVisible()); - EXPECT_TRUE(contents_window()->IsVisible()); + EXPECT_TRUE(keyboard_window()->IsVisible()); // Changing the mode to another mode invokes hiding + showing. const gfx::Rect target_bounds(0, 0, 1200, 600); @@ -759,9 +681,9 @@ RunAnimationForLayer(layer); // Hiding animation finished. The container window should be resized to the // target bounds. - EXPECT_EQ(keyboard_container()->bounds().size(), target_bounds.size()); + EXPECT_EQ(keyboard_window()->bounds().size(), target_bounds.size()); // Then showing animation automatically start. - layer = keyboard_container()->layer(); + layer = keyboard_window()->layer(); RunAnimationForLayer(layer); EXPECT_EQ(1, invocation_counter.invocation_count_for_status(true)); EXPECT_EQ(0, invocation_counter.invocation_count_for_status(false)); @@ -771,41 +693,40 @@ // and the keyboard should animate in. // Test for crbug.com/333284. TEST_F(KeyboardControllerAnimationTest, ContainerShowWhileHide) { - ui::Layer* layer = keyboard_container()->layer(); + ui::Layer* layer = keyboard_window()->layer(); ShowKeyboard(); RunAnimationForLayer(layer); controller().HideKeyboardExplicitlyBySystem(); // Before hide animation finishes, show keyboard again. ShowKeyboard(); - layer = keyboard_container()->layer(); + layer = keyboard_window()->layer(); RunAnimationForLayer(layer); - EXPECT_TRUE(keyboard_container()->IsVisible()); - EXPECT_TRUE(contents_window()->IsVisible()); + EXPECT_TRUE(keyboard_window()->IsVisible()); EXPECT_EQ(1.0, layer->opacity()); } -TEST_F(KeyboardControllerAnimationTest, SetBoundsOnOldKeyboardUiReference) { - +TEST_F(KeyboardControllerAnimationTest, + SetKeyboardWindowBoundsOnDeactivatedKeyboard) { // Ensure keyboard ui is populated - ui::Layer* layer = keyboard_container()->layer(); + ui::Layer* layer = keyboard_window()->layer(); ShowKeyboard(); RunAnimationForLayer(layer); ASSERT_TRUE(controller().ui()); - aura::Window* container_window = controller().GetContainerWindow(); - - // Simulate removal of keyboard controller from root window as done by - // RootWindowController::DeactivateKeyboard() - container_window->parent()->RemoveChild(container_window); + controller().DeactivateKeyboard(); // lingering handle to the contents window is adjusted. // container_window's LayoutManager should abort silently and not crash. - controller().ui()->GetContentsWindow()->SetBounds(gfx::Rect()); + keyboard_window()->SetBounds(gfx::Rect()); } +// TODO(https://crbug.com/849995): This is testing KeyboardLayoutManager / +// ContainerFullWidthBehavior. Put this test there. TEST_F(KeyboardControllerTest, DisplayChangeShouldNotifyBoundsChange) { + root_window()->SetLayoutManager(new KeyboardLayoutManager(&controller())); + ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT); SetFocus(&input_client); @@ -831,27 +752,27 @@ ui::TEXT_INPUT_MODE_NONE); base::RunLoop run_loop; - aura::Window* keyboard_container(controller().GetContainerWindow()); + controller().LoadKeyboardUiInBackground(); + aura::Window* keyboard_window = controller().GetContentsWindow(); auto keyboard_container_observer = - std::make_unique<KeyboardContainerObserver>(keyboard_container, - &run_loop); + std::make_unique<KeyboardContainerObserver>(keyboard_window, &run_loop); SetFocus(&input_client); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); SetFocus(&no_input_client); // Keyboard should not immediately hide itself. It is delayed to avoid layout // flicker when the focus of input field quickly change. - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); EXPECT_TRUE(WillHideKeyboard()); // Wait for hide keyboard to finish. RunLoop(&run_loop); - EXPECT_FALSE(keyboard_container->IsVisible()); + EXPECT_FALSE(keyboard_window->IsVisible()); SetFocus(&input_client); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); } // Checks that floating keyboard does not cause focused window to move upwards. @@ -873,19 +794,23 @@ controller().GetActiveContainerType()); // Ensure keyboard ui is populated - ui::Layer* layer = keyboard_container()->layer(); + ui::Layer* layer = keyboard_window()->layer(); SetFocus(&mock_input_client); RunAnimationForLayer(layer); - EXPECT_TRUE(keyboard_container()->IsVisible()); + EXPECT_TRUE(keyboard_window()->IsVisible()); + + // Unfocus from the MockTextInputClient before destroying it. + ui()->GetInputMethod()->DetachTextInputClient(&mock_input_client); } // Checks DisableKeyboard() doesn't clear the observer list. TEST_F(KeyboardControllerTest, DontClearObserverList) { - aura::Window* keyboard_container = controller().GetContainerWindow(); + ShowKeyboard(); + aura::Window* keyboard_window = controller().GetContentsWindow(); ShowKeyboard(); - EXPECT_TRUE(keyboard_container->IsVisible()); + EXPECT_TRUE(keyboard_window->IsVisible()); EXPECT_FALSE(IsKeyboardClosed()); controller().DisableKeyboard();
diff --git a/ui/keyboard/keyboard_layout_manager.cc b/ui/keyboard/keyboard_layout_manager.cc index 08e4801..7326f0f 100644 --- a/ui/keyboard/keyboard_layout_manager.cc +++ b/ui/keyboard/keyboard_layout_manager.cc
@@ -12,31 +12,28 @@ namespace keyboard { +KeyboardLayoutManager::KeyboardLayoutManager(KeyboardController* controller) + : controller_(controller) {} + +KeyboardLayoutManager::~KeyboardLayoutManager() = default; + // Overridden from aura::LayoutManager -void KeyboardLayoutManager::OnWindowResized() { - if (contents_window_) { - gfx::Rect container_bounds = controller_->GetContainerWindow()->bounds(); - // Always align container window and keyboard window. - SetChildBounds(contents_window_, container_bounds); - } -} void KeyboardLayoutManager::OnWindowAddedToLayout(aura::Window* child) { - DCHECK(!contents_window_); - contents_window_ = child; - controller_->GetContainerWindow()->SetBounds(gfx::Rect()); + // Reset the keyboard window bounds when it gets added to the keyboard + // container to ensure that its bounds are valid. + SetChildBounds(child, gfx::Rect()); } void KeyboardLayoutManager::SetChildBounds(aura::Window* child, const gfx::Rect& requested_bounds) { - DCHECK(child == contents_window_); + aura::Window* contents_window = controller_->GetContentsWindow(); + if (contents_window != child) + return; + TRACE_EVENT0("vk", "KeyboardLayoutSetChildBounds"); - // Request to change the bounds of the contents window - // should change the container window first. Then the contents window is - // resized and covers the container window. Note the contents' bound is only - // set in OnWindowResized. - + // The requested bounds must be adjusted. aura::Window* root_window = controller_->GetRootWindow(); // If the keyboard has been deactivated, this reference will be null. @@ -54,16 +51,15 @@ requested_bounds + display_offset) - display_offset; - // Containar bounds should only be reset when the contents window bounds + // Keyboard bounds should only be reset when the contents window bounds // actually change. Otherwise it interrupts the initial animation of showing // the keyboard. Described in crbug.com/356753. - gfx::Rect old_bounds = contents_window_->GetTargetBounds(); + gfx::Rect old_bounds = contents_window->GetTargetBounds(); - aura::Window::ConvertRectToTarget(contents_window_, root_window, &old_bounds); if (new_bounds == old_bounds) return; - SetChildBoundsDirect(contents_window_, gfx::Rect(new_bounds.size())); + SetChildBoundsDirect(contents_window, new_bounds); controller_->SetContainerBounds(new_bounds); }
diff --git a/ui/keyboard/keyboard_layout_manager.h b/ui/keyboard/keyboard_layout_manager.h index 8c76e25..17a0b6b 100644 --- a/ui/keyboard/keyboard_layout_manager.h +++ b/ui/keyboard/keyboard_layout_manager.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "ui/aura/layout_manager.h" #include "ui/aura/window.h" +#include "ui/keyboard/keyboard_export.h" namespace keyboard { @@ -16,13 +17,13 @@ // LayoutManager for the virtual keyboard container. Manages a single window // (the virtual keyboard) and keeps it positioned at the bottom of the // owner window. -class KeyboardLayoutManager : public aura::LayoutManager { +class KEYBOARD_EXPORT KeyboardLayoutManager : public aura::LayoutManager { public: - explicit KeyboardLayoutManager(KeyboardController* controller) - : controller_(controller), contents_window_(nullptr) {} + explicit KeyboardLayoutManager(KeyboardController* controller); + ~KeyboardLayoutManager() override; // Overridden from aura::LayoutManager - void OnWindowResized() override; + void OnWindowResized() override {} void OnWindowAddedToLayout(aura::Window* child) override; void OnWillRemoveWindowFromLayout(aura::Window* child) override {} void OnWindowRemovedFromLayout(aura::Window* child) override {} @@ -33,7 +34,6 @@ private: KeyboardController* controller_; - aura::Window* contents_window_; DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); };
diff --git a/ui/keyboard/keyboard_test_util.cc b/ui/keyboard/keyboard_test_util.cc index 4184424..0db6c0e 100644 --- a/ui/keyboard/keyboard_test_util.cc +++ b/ui/keyboard/keyboard_test_util.cc
@@ -63,7 +63,7 @@ bool WaitVisibilityChangesTo(bool visibility) { aura::Window* keyboard_window = - keyboard::KeyboardController::Get()->GetContainerWindow(); + keyboard::KeyboardController::Get()->GetContentsWindow(); WindowVisibilityChangeWaiter waiter(keyboard_window, visibility); waiter.Wait(); return true;
diff --git a/ui/login/bubble.js b/ui/login/bubble.js index 13bebb7..60ef133 100644 --- a/ui/login/bubble.js +++ b/ui/login/bubble.js
@@ -213,7 +213,7 @@ */ showForElement: function(el, attachment, opt_offset, opt_padding) { /* showForElement() is used only to display Accessibility popup in - * oobe_screen_network*. It requires old-style bubble, so it is safe + * oobe_screen_welcome*. It requires old-style bubble, so it is safe * to always set this flag here. */ this.showContentForElement(
diff --git a/ui/login/display_manager.js b/ui/login/display_manager.js index 74e2c6e..714e8bb 100644 --- a/ui/login/display_manager.js +++ b/ui/login/display_manager.js
@@ -7,7 +7,7 @@ */ // TODO(xiyuan): Find a better to share those constants. -/** @const */ var SCREEN_OOBE_NETWORK = 'connect'; +/** @const */ var SCREEN_OOBE_WELCOME = 'connect'; /** @const */ var SCREEN_OOBE_HID_DETECTION = 'hid-detection'; /** @const */ var SCREEN_OOBE_EULA = 'eula'; /** @const */ var SCREEN_OOBE_ENABLE_DEBUGGING = 'debugging'; @@ -133,7 +133,7 @@ * @type Array<Array<string>> * @const */ - var SCREEN_GROUPS = [[SCREEN_OOBE_NETWORK, + var SCREEN_GROUPS = [[SCREEN_OOBE_WELCOME, SCREEN_OOBE_EULA, SCREEN_OOBE_UPDATE, SCREEN_OOBE_AUTO_ENROLLMENT_CHECK] @@ -145,7 +145,7 @@ * @const */ var RESET_AVAILABLE_SCREEN_GROUP = [ - SCREEN_OOBE_NETWORK, + SCREEN_OOBE_WELCOME, SCREEN_OOBE_EULA, SCREEN_OOBE_UPDATE, SCREEN_OOBE_ENROLLMENT, @@ -175,7 +175,7 @@ */ var ENABLE_DEBUGGING_AVAILABLE_SCREEN_GROUP = [ SCREEN_OOBE_HID_DETECTION, - SCREEN_OOBE_NETWORK, + SCREEN_OOBE_WELCOME, SCREEN_OOBE_EULA, SCREEN_OOBE_UPDATE, SCREEN_TERMS_OF_SERVICE @@ -199,7 +199,7 @@ * @const */ var DEMO_MODE_SETUP_AVAILABLE_SCREEN_GROUP = [ - SCREEN_OOBE_NETWORK, + SCREEN_OOBE_WELCOME, ]; /** @@ -430,7 +430,7 @@ if (currentStepId == SCREEN_GAIA_SIGNIN || currentStepId == SCREEN_ACCOUNT_PICKER) { chrome.send('toggleEnrollmentScreen'); - } else if (currentStepId == SCREEN_OOBE_NETWORK || + } else if (currentStepId == SCREEN_OOBE_WELCOME || currentStepId == SCREEN_OOBE_EULA) { // In this case update check will be skipped and OOBE will // proceed straight to enrollment screen when EULA is accepted. @@ -593,7 +593,7 @@ if (newStep.onAfterShow) newStep.onAfterShow(screenData); - // Workaround for gaia and network screens. + // Workaround for gaia and welcome screens. // Due to other origin iframe and long ChromeVox focusing correspondingly // passive aria-label title is not pronounced. // Gaia hack can be removed on fixed crbug.com/316726.
diff --git a/ui/native_theme/common_theme.cc b/ui/native_theme/common_theme.cc index b3e32c6..f40cbe53 100644 --- a/ui/native_theme/common_theme.cc +++ b/ui/native_theme/common_theme.cc
@@ -105,7 +105,7 @@ // Separator: static const SkColor kSeparatorColor = SkColorSetRGB(0xE9, 0xE9, 0xE9); // Link: - static const SkColor kLinkEnabledColor = gfx::kGoogleBlue600; + static const SkColor kLinkEnabledColor = gfx::kGoogleBlue700; // Text selection colors: static const SkColor kTextSelectionBackgroundFocused = SkColorSetARGB(0x54, 0x60, 0xA8, 0xEB);
diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc index bc3b231..42587de 100644 --- a/ui/ozone/platform/wayland/wayland_window.cc +++ b/ui/ozone/platform/wayland/wayland_window.cc
@@ -236,6 +236,13 @@ // if xdg_surface_set_fullscreen() is not provided with wl_output, it's up to // the compositor to choose which display will be used to map this surface. if (!IsFullscreen()) { + // Fullscreen state changes have to be handled manually and then checked + // against configuration events, which come from a compositor. The reason + // of manually changing the |state_| is that the compositor answers about + // state changes asynchronously, which leads to a wrong return value in + // DesktopWindowTreeHostPlatform::IsFullscreen, for example, and media + // files can never be set to fullscreen. + state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN; // Client might have requested a fullscreen state while the window was in // a maximized state. Thus, |restored_bounds_| can contain the bounds of a // "normal" state before the window was maximized. We don't override them @@ -245,6 +252,9 @@ restored_bounds_ = bounds_; xdg_surface_->SetFullscreen(); } else { + // Check the comment above. If it's not handled synchronously, media files + // may not leave the fullscreen mode. + state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN; xdg_surface_->UnSetFullscreen(); } @@ -382,6 +392,11 @@ bool is_activated) { // Propagate the window state information to the client. PlatformWindowState old_state = state_; + + // Ensure that manually handled state changes to fullscreen correspond to the + // configuration events from a compositor. + DCHECK(is_fullscreen == IsFullscreen()); + // There are two cases, which must be handled for the minimized state. // The first one is the case, when the surface goes into the minimized state // (check comment in WaylandWindow::Minimize), and the second case is when the @@ -392,7 +407,10 @@ is_minimizing_ = false; state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED; } else if (is_fullscreen) { - state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN; + // To ensure the |delegate_| is notified about state changes to fullscreen, + // assume the old_state is UNKNOWN (check comment in ToggleFullscreen). + old_state = PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN; + DCHECK(state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN); } else if (is_maximized) { state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED; } else {
diff --git a/ui/ozone/platform/wayland/wayland_window_unittest.cc b/ui/ozone/platform/wayland/wayland_window_unittest.cc index 87b2a1b..5522fa3 100644 --- a/ui/ozone/platform/wayland/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -173,6 +173,9 @@ } TEST_P(WaylandWindowTest, SetFullscreenAndRestore) { + // Ensure the initial state is unknown. + EXPECT_EQ(window_->GetPlatformWindowState(), PLATFORM_WINDOW_STATE_UNKNOWN); + wl_array states; InitializeWlArrayWithActivatedState(&states); @@ -182,6 +185,10 @@ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_FULLSCREEN))); window_->ToggleFullscreen(); + // Make sure than WaylandWindow manually handles fullscreen states. Check the + // comment in the WaylandWindow::ToggleFullscreen. + EXPECT_EQ(window_->GetPlatformWindowState(), + PLATFORM_WINDOW_STATE_FULLSCREEN); SendConfigureEvent(0, 0, 1, &states); Sync(); @@ -189,6 +196,7 @@ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_NORMAL))); window_->Restore(); + EXPECT_EQ(window_->GetPlatformWindowState(), PLATFORM_WINDOW_STATE_UNKNOWN); // Reinitialize wl_array, which removes previous old states. InitializeWlArrayWithActivatedState(&states); SendConfigureEvent(0, 0, 2, &states);
diff --git a/ui/platform_window/platform_window_init_properties.cc b/ui/platform_window/platform_window_init_properties.cc index 7bb846a27..b8590ed 100644 --- a/ui/platform_window/platform_window_init_properties.cc +++ b/ui/platform_window/platform_window_init_properties.cc
@@ -7,6 +7,11 @@ namespace ui { PlatformWindowInitProperties::PlatformWindowInitProperties() = default; + +PlatformWindowInitProperties::PlatformWindowInitProperties( + const gfx::Rect& bounds) + : bounds(bounds) {} + PlatformWindowInitProperties::PlatformWindowInitProperties( PlatformWindowInitProperties&& props) = default;
diff --git a/ui/platform_window/platform_window_init_properties.h b/ui/platform_window/platform_window_init_properties.h index 40c5fed..222f4f4 100644 --- a/ui/platform_window/platform_window_init_properties.h +++ b/ui/platform_window/platform_window_init_properties.h
@@ -27,6 +27,10 @@ // with a desired set of properties. struct PlatformWindowInitProperties { PlatformWindowInitProperties(); + + // Initializes properties with the specified |bounds|. + explicit PlatformWindowInitProperties(const gfx::Rect& bounds); + PlatformWindowInitProperties(PlatformWindowInitProperties&& props); ~PlatformWindowInitProperties();
diff --git a/ui/strings/translations/ui_strings_am.xtb b/ui/strings/translations/ui_strings_am.xtb index 4b98465..c770ce09 100644 --- a/ui/strings/translations/ui_strings_am.xtb +++ b/ui/strings/translations/ui_strings_am.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">የዳሰሳ ጥናት</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> ቴባ/ሰ</translation> <translation id="24452542372838207">ማሳወቂያን ዘርጋ</translation> +<translation id="2482878487686419369">ማስታወቂያዎች</translation> <translation id="2497284189126895209">ሁሉም ፋይሎች</translation> <translation id="2522350507219695259">ልኬት ማስተካከል ተጠናቅቋል</translation> <translation id="252373100621549798">ያልታወቀ ማሳያ</translation>
diff --git a/ui/strings/translations/ui_strings_ar.xtb b/ui/strings/translations/ui_strings_ar.xtb index 97b8224..95bf887 100644 --- a/ui/strings/translations/ui_strings_ar.xtb +++ b/ui/strings/translations/ui_strings_ar.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">الاستطلاع</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> تيرابايت/ثانية</translation> <translation id="24452542372838207">توسيع الإشعار</translation> +<translation id="2482878487686419369">الاشعارات</translation> <translation id="2497284189126895209">الملفّات كلّها</translation> <translation id="2522350507219695259">اكتملت المعايرة</translation> <translation id="252373100621549798">شاشة عرض غير معروفة</translation>
diff --git a/ui/strings/translations/ui_strings_bg.xtb b/ui/strings/translations/ui_strings_bg.xtb index 1a6de69d..5855166 100644 --- a/ui/strings/translations/ui_strings_bg.xtb +++ b/ui/strings/translations/ui_strings_bg.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Анкета</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> ТБ/сек</translation> <translation id="24452542372838207">Разгъване на известието</translation> +<translation id="2482878487686419369">Известия</translation> <translation id="2497284189126895209">Всички файлове</translation> <translation id="2522350507219695259">Калибрирането завърши</translation> <translation id="252373100621549798">Неизвестен дисплей</translation>
diff --git a/ui/strings/translations/ui_strings_bn.xtb b/ui/strings/translations/ui_strings_bn.xtb index 3911a912..e6fd7eda 100644 --- a/ui/strings/translations/ui_strings_bn.xtb +++ b/ui/strings/translations/ui_strings_bn.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">সমীক্ষা</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">বিজ্ঞপ্তি প্রসারিত করুন</translation> +<translation id="2482878487686419369">বিজ্ঞপ্তিগুলি</translation> <translation id="2497284189126895209">সকল ফাইল</translation> <translation id="2522350507219695259">ক্রমাঙ্কন সম্পূর্ণ হয়েছে</translation> <translation id="252373100621549798">অজানা প্রদর্শন</translation>
diff --git a/ui/strings/translations/ui_strings_ca.xtb b/ui/strings/translations/ui_strings_ca.xtb index 91f1c8af..0b69e534 100644 --- a/ui/strings/translations/ui_strings_ca.xtb +++ b/ui/strings/translations/ui_strings_ca.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Enquesta</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Desplega la notificació</translation> +<translation id="2482878487686419369">Notificacions</translation> <translation id="2497284189126895209">Tots els fitxers</translation> <translation id="2522350507219695259">S'ha acabat de calibrar</translation> <translation id="252373100621549798">Pantalla desconeguda</translation>
diff --git a/ui/strings/translations/ui_strings_cs.xtb b/ui/strings/translations/ui_strings_cs.xtb index 60bd079..690e8b5d 100644 --- a/ui/strings/translations/ui_strings_cs.xtb +++ b/ui/strings/translations/ui_strings_cs.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Průzkum</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Rozbalit oznámení</translation> +<translation id="2482878487686419369">Oznámení</translation> <translation id="2497284189126895209">Všechny soubory</translation> <translation id="2522350507219695259">Kalibrace je dokončena</translation> <translation id="252373100621549798">Neznámý displej</translation>
diff --git a/ui/strings/translations/ui_strings_da.xtb b/ui/strings/translations/ui_strings_da.xtb index a1edd0b..505135b 100644 --- a/ui/strings/translations/ui_strings_da.xtb +++ b/ui/strings/translations/ui_strings_da.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Undersøgelse</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/sek.</translation> <translation id="24452542372838207">Udvid underretning</translation> +<translation id="2482878487686419369">Underretninger</translation> <translation id="2497284189126895209">Alle filer</translation> <translation id="2522350507219695259">Kalibreringen er fuldført</translation> <translation id="252373100621549798">Ukendt skærm</translation>
diff --git a/ui/strings/translations/ui_strings_de.xtb b/ui/strings/translations/ui_strings_de.xtb index 65f3bac..cfc6891c5 100644 --- a/ui/strings/translations/ui_strings_de.xtb +++ b/ui/strings/translations/ui_strings_de.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Umfrage</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Benachrichtigung erweitern</translation> +<translation id="2482878487686419369">Benachrichtigungen</translation> <translation id="2497284189126895209">Alle Dateien</translation> <translation id="2522350507219695259">Die Kalibrierung ist abgeschlossen</translation> <translation id="252373100621549798">Display unbekannt</translation>
diff --git a/ui/strings/translations/ui_strings_el.xtb b/ui/strings/translations/ui_strings_el.xtb index 6db75430..ec2bdc0 100644 --- a/ui/strings/translations/ui_strings_el.xtb +++ b/ui/strings/translations/ui_strings_el.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Έρευνα</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Ανάπτυξη ειδοποίησης</translation> +<translation id="2482878487686419369">Ειδοποιήσεις</translation> <translation id="2497284189126895209">Όλα τα αρχεία</translation> <translation id="2522350507219695259">Η βαθμονόμηση ολοκληρώθηκε</translation> <translation id="252373100621549798">Άγνωστη οθόνη</translation>
diff --git a/ui/strings/translations/ui_strings_en-GB.xtb b/ui/strings/translations/ui_strings_en-GB.xtb index 697f07f6..6a545b6 100644 --- a/ui/strings/translations/ui_strings_en-GB.xtb +++ b/ui/strings/translations/ui_strings_en-GB.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Survey</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Expand notification</translation> +<translation id="2482878487686419369">Notifications</translation> <translation id="2497284189126895209">All Files</translation> <translation id="2522350507219695259">Calibration is completed</translation> <translation id="252373100621549798">Unknown Display</translation>
diff --git a/ui/strings/translations/ui_strings_es-419.xtb b/ui/strings/translations/ui_strings_es-419.xtb index c6e97e7..75c61d4 100644 --- a/ui/strings/translations/ui_strings_es-419.xtb +++ b/ui/strings/translations/ui_strings_es-419.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Encuesta</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Expandir notificación</translation> +<translation id="2482878487686419369">Notificaciones</translation> <translation id="2497284189126895209">Todos los archivos</translation> <translation id="2522350507219695259">Se completó la calibración</translation> <translation id="252373100621549798">Pantalla desconocida</translation>
diff --git a/ui/strings/translations/ui_strings_es.xtb b/ui/strings/translations/ui_strings_es.xtb index fb451e0..183c4a1d 100644 --- a/ui/strings/translations/ui_strings_es.xtb +++ b/ui/strings/translations/ui_strings_es.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Encuesta</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Mostrar notificación</translation> +<translation id="2482878487686419369">Notificaciones</translation> <translation id="2497284189126895209">Todos los archivos</translation> <translation id="2522350507219695259">Se ha completado la calibración</translation> <translation id="252373100621549798">Pantalla desconocida</translation>
diff --git a/ui/strings/translations/ui_strings_et.xtb b/ui/strings/translations/ui_strings_et.xtb index 7940a6d..9b573a3 100644 --- a/ui/strings/translations/ui_strings_et.xtb +++ b/ui/strings/translations/ui_strings_et.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Küsitlus</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Laienda märguannet</translation> +<translation id="2482878487686419369">Märguanded</translation> <translation id="2497284189126895209">Kõik failid</translation> <translation id="2522350507219695259">Kalibreerimine on lõpetatud</translation> <translation id="252373100621549798">Tundmatu ekraan</translation>
diff --git a/ui/strings/translations/ui_strings_fa.xtb b/ui/strings/translations/ui_strings_fa.xtb index dbd35ed..a34e732 100644 --- a/ui/strings/translations/ui_strings_fa.xtb +++ b/ui/strings/translations/ui_strings_fa.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">نظرسنجی</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> ترابایت/ثانیه</translation> <translation id="24452542372838207">بزرگ کردن اعلان</translation> +<translation id="2482878487686419369">اعلانها</translation> <translation id="2497284189126895209">همه فایلها</translation> <translation id="2522350507219695259">کالیبراسیون تمام شد</translation> <translation id="252373100621549798">نمایش ناشناس</translation>
diff --git a/ui/strings/translations/ui_strings_fi.xtb b/ui/strings/translations/ui_strings_fi.xtb index 0ea68c5..d5583cd 100644 --- a/ui/strings/translations/ui_strings_fi.xtb +++ b/ui/strings/translations/ui_strings_fi.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Kysely</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> Tt/s</translation> <translation id="24452542372838207">Laajenna ilmoitus</translation> +<translation id="2482878487686419369">Ilmoitukset</translation> <translation id="2497284189126895209">Kaikki tiedostot</translation> <translation id="2522350507219695259">Kalibrointi on valmis.</translation> <translation id="252373100621549798">Tuntematon näyttö</translation>
diff --git a/ui/strings/translations/ui_strings_fil.xtb b/ui/strings/translations/ui_strings_fil.xtb index 5b5b1d92..269c1f0 100644 --- a/ui/strings/translations/ui_strings_fil.xtb +++ b/ui/strings/translations/ui_strings_fil.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Survey</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> (na) TB/s</translation> <translation id="24452542372838207">Palawakin ang notification</translation> +<translation id="2482878487686419369">Mga Abiso</translation> <translation id="2497284189126895209">Lahat ng Mga File</translation> <translation id="2522350507219695259">Nakumpleto na ang pag-calibrate</translation> <translation id="252373100621549798">Hindi Kilalang Display</translation>
diff --git a/ui/strings/translations/ui_strings_fr.xtb b/ui/strings/translations/ui_strings_fr.xtb index fcdde334..fcf08132 100644 --- a/ui/strings/translations/ui_strings_fr.xtb +++ b/ui/strings/translations/ui_strings_fr.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Enquête</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> To/s</translation> <translation id="24452542372838207">Développer la notification</translation> +<translation id="2482878487686419369">Notifications</translation> <translation id="2497284189126895209">Tous les fichiers</translation> <translation id="2522350507219695259">Calibrage terminé</translation> <translation id="252373100621549798">Écran inconnu</translation>
diff --git a/ui/strings/translations/ui_strings_gu.xtb b/ui/strings/translations/ui_strings_gu.xtb index e5aab73..d284d19 100644 --- a/ui/strings/translations/ui_strings_gu.xtb +++ b/ui/strings/translations/ui_strings_gu.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">સર્વેક્ષણ</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">નોટિફિકેશન વિસ્તૃત કરો</translation> +<translation id="2482878487686419369">સૂચનાઓ</translation> <translation id="2497284189126895209">બધી ફાઇલો</translation> <translation id="2522350507219695259">કૅલિબ્રેશન પૂર્ણ થયું</translation> <translation id="252373100621549798">અજ્ઞાત પ્રદર્શન</translation>
diff --git a/ui/strings/translations/ui_strings_hi.xtb b/ui/strings/translations/ui_strings_hi.xtb index 559458d..ed909cf 100644 --- a/ui/strings/translations/ui_strings_hi.xtb +++ b/ui/strings/translations/ui_strings_hi.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">सर्वे</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">सूचना को विस्तृत करें</translation> +<translation id="2482878487686419369">अधिसूचनाएं</translation> <translation id="2497284189126895209">सभी फ़ाइलें</translation> <translation id="2522350507219695259">कैलिब्रेशन पूरा हो गया</translation> <translation id="252373100621549798">अज्ञात डिस्प्ले</translation>
diff --git a/ui/strings/translations/ui_strings_hr.xtb b/ui/strings/translations/ui_strings_hr.xtb index f2d4b8b..50081ffc 100644 --- a/ui/strings/translations/ui_strings_hr.xtb +++ b/ui/strings/translations/ui_strings_hr.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Anketa</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Proširi obavijest</translation> +<translation id="2482878487686419369">Obavijesti</translation> <translation id="2497284189126895209">Sve datoteke</translation> <translation id="2522350507219695259">Kalibracija je gotova</translation> <translation id="252373100621549798">Nepoznati zaslon</translation>
diff --git a/ui/strings/translations/ui_strings_hu.xtb b/ui/strings/translations/ui_strings_hu.xtb index 4151697..d21afea 100644 --- a/ui/strings/translations/ui_strings_hu.xtb +++ b/ui/strings/translations/ui_strings_hu.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Felmérés</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Értesítés kibontása</translation> +<translation id="2482878487686419369">Értesítések</translation> <translation id="2497284189126895209">Minden fájl</translation> <translation id="2522350507219695259">A kalibrálás befejeződött</translation> <translation id="252373100621549798">Ismeretlen kijelző</translation>
diff --git a/ui/strings/translations/ui_strings_id.xtb b/ui/strings/translations/ui_strings_id.xtb index 4de5393..b938f5b 100644 --- a/ui/strings/translations/ui_strings_id.xtb +++ b/ui/strings/translations/ui_strings_id.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Survei</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/dtk</translation> <translation id="24452542372838207">Luaskan notifikasi</translation> +<translation id="2482878487686419369">Notifikasi</translation> <translation id="2497284189126895209">Semua Jenis File</translation> <translation id="2522350507219695259">Kalibrasi selesai</translation> <translation id="252373100621549798">Tampilan yang Tidak Diketahui</translation>
diff --git a/ui/strings/translations/ui_strings_it.xtb b/ui/strings/translations/ui_strings_it.xtb index 890101d..7d6638fe 100644 --- a/ui/strings/translations/ui_strings_it.xtb +++ b/ui/strings/translations/ui_strings_it.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Sondaggio</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Espandi la notifica</translation> +<translation id="2482878487686419369">Notifiche</translation> <translation id="2497284189126895209">Tutti i file</translation> <translation id="2522350507219695259">Calibrazione completata</translation> <translation id="252373100621549798">Display sconosciuto</translation>
diff --git a/ui/strings/translations/ui_strings_iw.xtb b/ui/strings/translations/ui_strings_iw.xtb index 7357f6b..7e5ad780 100644 --- a/ui/strings/translations/ui_strings_iw.xtb +++ b/ui/strings/translations/ui_strings_iw.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">סקר</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">הרחבת ההודעה</translation> +<translation id="2482878487686419369">התראות</translation> <translation id="2497284189126895209">כל הקבצים</translation> <translation id="2522350507219695259">הכיול הושלם</translation> <translation id="252373100621549798">תצוגה לא ידועה</translation>
diff --git a/ui/strings/translations/ui_strings_ja.xtb b/ui/strings/translations/ui_strings_ja.xtb index 6f1c0ebf..7d77585 100644 --- a/ui/strings/translations/ui_strings_ja.xtb +++ b/ui/strings/translations/ui_strings_ja.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">アンケート</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/秒</translation> <translation id="24452542372838207">通知を展開</translation> +<translation id="2482878487686419369">通知</translation> <translation id="2497284189126895209">すべてのファイル</translation> <translation id="2522350507219695259">キャリブレーションが完了しました</translation> <translation id="252373100621549798">不明なディスプレイ</translation>
diff --git a/ui/strings/translations/ui_strings_kn.xtb b/ui/strings/translations/ui_strings_kn.xtb index d19377d9..32da2e9a 100644 --- a/ui/strings/translations/ui_strings_kn.xtb +++ b/ui/strings/translations/ui_strings_kn.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">ಸಮೀಕ್ಷೆ</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">ವಿಸ್ತರಿಸುವ ಅಧಿಸೂಚನೆ</translation> +<translation id="2482878487686419369">ಸೂಚನೆಗಳು</translation> <translation id="2497284189126895209">ಎಲ್ಲ ಫೈಲ್ಗಳು</translation> <translation id="2522350507219695259">ಮಾಪನಾಂಕವು ಪೂರ್ಣಗೊಂಡಿದೆ</translation> <translation id="252373100621549798">ಅಪರಿಚಿತ ಪ್ರದರ್ಶನ</translation> @@ -178,5 +179,5 @@ <translation id="9150735707954472829">ಟ್ಯಾಬ್</translation> <translation id="9161053988251441839">ಸಲಹೆ ಮಾಡಿರುವ ಅಪ್ಲಿಕೇಶನ್ಗಳು</translation> <translation id="9170848237812810038">&ರದ್ದುಮಾಡು</translation> -<translation id="932327136139879170">ಮುಖಪುಟ</translation> +<translation id="932327136139879170">Home</translation> </translationbundle> \ No newline at end of file
diff --git a/ui/strings/translations/ui_strings_ko.xtb b/ui/strings/translations/ui_strings_ko.xtb index d0f27a91..eaad838 100644 --- a/ui/strings/translations/ui_strings_ko.xtb +++ b/ui/strings/translations/ui_strings_ko.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">설문조사</translation> <translation id="2297836609126180313"><ph name="QUANTITY" />TB/s</translation> <translation id="24452542372838207">알림 펼치기</translation> +<translation id="2482878487686419369">알림</translation> <translation id="2497284189126895209">모든 파일</translation> <translation id="2522350507219695259">보정이 완료되었습니다.</translation> <translation id="252373100621549798">알 수 없는 디스플레이</translation>
diff --git a/ui/strings/translations/ui_strings_lt.xtb b/ui/strings/translations/ui_strings_lt.xtb index a6ade229..943170ac6 100644 --- a/ui/strings/translations/ui_strings_lt.xtb +++ b/ui/strings/translations/ui_strings_lt.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Apklausa</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Išskleisti pranešimą</translation> +<translation id="2482878487686419369">Pranešimai</translation> <translation id="2497284189126895209">Visi failai</translation> <translation id="2522350507219695259">Kalibravimas baigtas</translation> <translation id="252373100621549798">Nežinoma pateiktis</translation>
diff --git a/ui/strings/translations/ui_strings_lv.xtb b/ui/strings/translations/ui_strings_lv.xtb index 1bf80a5..6be09015 100644 --- a/ui/strings/translations/ui_strings_lv.xtb +++ b/ui/strings/translations/ui_strings_lv.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Aptauja</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Izvērst paziņojumu</translation> +<translation id="2482878487686419369">Paziņojumi</translation> <translation id="2497284189126895209">Visi faili</translation> <translation id="2522350507219695259">Kalibrēšana ir pabeigta.</translation> <translation id="252373100621549798">Nezināms displejs</translation>
diff --git a/ui/strings/translations/ui_strings_ml.xtb b/ui/strings/translations/ui_strings_ml.xtb index 8a7d37ef..732bea3 100644 --- a/ui/strings/translations/ui_strings_ml.xtb +++ b/ui/strings/translations/ui_strings_ml.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">സർവ്വേ</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">അറിയിപ്പ് വികസിപ്പിക്കുക</translation> +<translation id="2482878487686419369">വിജ്ഞാപനങ്ങള്</translation> <translation id="2497284189126895209">എല്ലാ ഫയലുകളും</translation> <translation id="2522350507219695259">കാലിബറേഷൻ പൂർത്തിയായി</translation> <translation id="252373100621549798">അജ്ഞാത പ്രദർശനം</translation>
diff --git a/ui/strings/translations/ui_strings_mr.xtb b/ui/strings/translations/ui_strings_mr.xtb index c1bc9f3..9306b82 100644 --- a/ui/strings/translations/ui_strings_mr.xtb +++ b/ui/strings/translations/ui_strings_mr.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">सर्वेक्षण</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">सूचना विस्तृत करा</translation> +<translation id="2482878487686419369">सूचना</translation> <translation id="2497284189126895209">सर्व फाइल</translation> <translation id="2522350507219695259">कॅलिब्रेशन पूर्ण झाले</translation> <translation id="252373100621549798">अज्ञात प्रदर्शन</translation>
diff --git a/ui/strings/translations/ui_strings_ms.xtb b/ui/strings/translations/ui_strings_ms.xtb index 764fc2b..2af1c630 100644 --- a/ui/strings/translations/ui_strings_ms.xtb +++ b/ui/strings/translations/ui_strings_ms.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Tinjauan</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Kembangkan pemberitahuan</translation> +<translation id="2482878487686419369">Pemberitahuan</translation> <translation id="2497284189126895209">Semua Fail</translation> <translation id="2522350507219695259">Penentukuran telah selesai</translation> <translation id="252373100621549798">Paparan Tidak Diketahui</translation>
diff --git a/ui/strings/translations/ui_strings_nl.xtb b/ui/strings/translations/ui_strings_nl.xtb index 795d3f0..e1be5e1 100644 --- a/ui/strings/translations/ui_strings_nl.xtb +++ b/ui/strings/translations/ui_strings_nl.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Enquête</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Melding uitvouwen</translation> +<translation id="2482878487686419369">Meldingen</translation> <translation id="2497284189126895209">Alle bestanden</translation> <translation id="2522350507219695259">Kalibratie is voltooid</translation> <translation id="252373100621549798">Onbekend display</translation>
diff --git a/ui/strings/translations/ui_strings_no.xtb b/ui/strings/translations/ui_strings_no.xtb index 574cea6..8e9296e5 100644 --- a/ui/strings/translations/ui_strings_no.xtb +++ b/ui/strings/translations/ui_strings_no.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Undersøkelse</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB per sek</translation> <translation id="24452542372838207">Vis varselet</translation> +<translation id="2482878487686419369">Varsler</translation> <translation id="2497284189126895209">Alle filer</translation> <translation id="2522350507219695259">Kalibreringen er ferdig</translation> <translation id="252373100621549798">Ukjent skjerm</translation>
diff --git a/ui/strings/translations/ui_strings_pl.xtb b/ui/strings/translations/ui_strings_pl.xtb index 9c893492..0b6f20a4 100644 --- a/ui/strings/translations/ui_strings_pl.xtb +++ b/ui/strings/translations/ui_strings_pl.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Ankieta</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Rozwiń powiadomienie</translation> +<translation id="2482878487686419369">Powiadomienia</translation> <translation id="2497284189126895209">Wszystkie pliki</translation> <translation id="2522350507219695259">Kalibracja została ukończona</translation> <translation id="252373100621549798">Nieznany wyświetlacz</translation>
diff --git a/ui/strings/translations/ui_strings_pt-BR.xtb b/ui/strings/translations/ui_strings_pt-BR.xtb index 6cf6a0f7a6..85997f0 100644 --- a/ui/strings/translations/ui_strings_pt-BR.xtb +++ b/ui/strings/translations/ui_strings_pt-BR.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Pesquisa</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Expandir notificação</translation> +<translation id="2482878487686419369">Notificações</translation> <translation id="2497284189126895209">Todos os arquivos</translation> <translation id="2522350507219695259">A calibração está concluída</translation> <translation id="252373100621549798">Exibição desconhecida</translation>
diff --git a/ui/strings/translations/ui_strings_pt-PT.xtb b/ui/strings/translations/ui_strings_pt-PT.xtb index 69d182b6..c3983cb1 100644 --- a/ui/strings/translations/ui_strings_pt-PT.xtb +++ b/ui/strings/translations/ui_strings_pt-PT.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Inquérito</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Expandir notificação</translation> +<translation id="2482878487686419369">Notificações</translation> <translation id="2497284189126895209">Todos os ficheiros</translation> <translation id="2522350507219695259">A calibração foi concluída</translation> <translation id="252373100621549798">Apresentação Desconhecida</translation>
diff --git a/ui/strings/translations/ui_strings_ro.xtb b/ui/strings/translations/ui_strings_ro.xtb index 51bd1985..9ddbb6c 100644 --- a/ui/strings/translations/ui_strings_ro.xtb +++ b/ui/strings/translations/ui_strings_ro.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Sondaj</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Extinde notificarea</translation> +<translation id="2482878487686419369">Notificări</translation> <translation id="2497284189126895209">Toate fișierele</translation> <translation id="2522350507219695259">Calibrarea este finalizată</translation> <translation id="252373100621549798">Afișaj necunoscut</translation>
diff --git a/ui/strings/translations/ui_strings_ru.xtb b/ui/strings/translations/ui_strings_ru.xtb index d833bca2..af18a80 100644 --- a/ui/strings/translations/ui_strings_ru.xtb +++ b/ui/strings/translations/ui_strings_ru.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Опрос</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> ТБ/с</translation> <translation id="24452542372838207">Развернуть уведомление</translation> +<translation id="2482878487686419369">Уведомления</translation> <translation id="2497284189126895209">Все файлы</translation> <translation id="2522350507219695259">Калибровка завершена</translation> <translation id="252373100621549798">Неизвестный дисплей</translation>
diff --git a/ui/strings/translations/ui_strings_sk.xtb b/ui/strings/translations/ui_strings_sk.xtb index a5eef61..e30c16f 100644 --- a/ui/strings/translations/ui_strings_sk.xtb +++ b/ui/strings/translations/ui_strings_sk.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Prieskum</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Rozbaliť upozornenie</translation> +<translation id="2482878487686419369">Upozornenia</translation> <translation id="2497284189126895209">Všetky súbory</translation> <translation id="2522350507219695259">Kalibrácia je dokončená</translation> <translation id="252373100621549798">Neznáma obrazovka</translation>
diff --git a/ui/strings/translations/ui_strings_sl.xtb b/ui/strings/translations/ui_strings_sl.xtb index 27d905f..144cb76 100644 --- a/ui/strings/translations/ui_strings_sl.xtb +++ b/ui/strings/translations/ui_strings_sl.xtb
@@ -34,6 +34,7 @@ <translation id="2295140143284145483">Anketa</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Razširi obvestilo</translation> +<translation id="2482878487686419369">Obvestila</translation> <translation id="2497284189126895209">Vse datoteke</translation> <translation id="2522350507219695259">Umerjanje je končano</translation> <translation id="252373100621549798">Neznan prikaz</translation>
diff --git a/ui/strings/translations/ui_strings_sr.xtb b/ui/strings/translations/ui_strings_sr.xtb index d357b3d..1bc70a36 100644 --- a/ui/strings/translations/ui_strings_sr.xtb +++ b/ui/strings/translations/ui_strings_sr.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Анкета</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Прошири обавештење</translation> +<translation id="2482878487686419369">Обавештења</translation> <translation id="2497284189126895209">Све датотеке</translation> <translation id="2522350507219695259">Калибрација је довршена</translation> <translation id="252373100621549798">Непознати приказ</translation>
diff --git a/ui/strings/translations/ui_strings_sv.xtb b/ui/strings/translations/ui_strings_sv.xtb index f881cc8..8abc2e0e 100644 --- a/ui/strings/translations/ui_strings_sv.xtb +++ b/ui/strings/translations/ui_strings_sv.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Enkät</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/sek</translation> <translation id="24452542372838207">Utöka avisering</translation> +<translation id="2482878487686419369">Aviseringar</translation> <translation id="2497284189126895209">Alla filer</translation> <translation id="2522350507219695259">Kalibreringen är slutförd</translation> <translation id="252373100621549798">Okänd visning</translation>
diff --git a/ui/strings/translations/ui_strings_sw.xtb b/ui/strings/translations/ui_strings_sw.xtb index 091e86c..5d178f84 100644 --- a/ui/strings/translations/ui_strings_sw.xtb +++ b/ui/strings/translations/ui_strings_sw.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Utafiti</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">Panua arifa</translation> +<translation id="2482878487686419369">Arifa</translation> <translation id="2497284189126895209">Faili zote</translation> <translation id="2522350507219695259">Imemaliza kurekebisha usahihi</translation> <translation id="252373100621549798">Onyesho Lisilojulikana</translation>
diff --git a/ui/strings/translations/ui_strings_ta.xtb b/ui/strings/translations/ui_strings_ta.xtb index 1399c8d..6122fb8 100644 --- a/ui/strings/translations/ui_strings_ta.xtb +++ b/ui/strings/translations/ui_strings_ta.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">கருத்துக்கணிப்பு</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> டெ.பை/வி</translation> <translation id="24452542372838207">அறிவிப்பை விரிவாக்கு</translation> +<translation id="2482878487686419369">அறிவிப்புகள்</translation> <translation id="2497284189126895209">அனைத்து கோப்புகளும்</translation> <translation id="2522350507219695259">அளவுத்திருத்தம் முடிந்தது</translation> <translation id="252373100621549798">அறியாதது</translation>
diff --git a/ui/strings/translations/ui_strings_te.xtb b/ui/strings/translations/ui_strings_te.xtb index ebc1256..3abbbf884 100644 --- a/ui/strings/translations/ui_strings_te.xtb +++ b/ui/strings/translations/ui_strings_te.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">సర్వే</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">నోటిఫికేషన్ని విస్తరించు</translation> +<translation id="2482878487686419369">ప్రకటనలు</translation> <translation id="2497284189126895209">మొత్తం ఫైళ్లు</translation> <translation id="2522350507219695259">క్రమాంకనం పూర్తయింది</translation> <translation id="252373100621549798">తెలియని ప్రదర్శన</translation>
diff --git a/ui/strings/translations/ui_strings_th.xtb b/ui/strings/translations/ui_strings_th.xtb index 9ed39a23..399f78ce 100644 --- a/ui/strings/translations/ui_strings_th.xtb +++ b/ui/strings/translations/ui_strings_th.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">แบบสำรวจ</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/วินาที</translation> <translation id="24452542372838207">ขยายการแจ้งเตือน</translation> +<translation id="2482878487686419369">การแจ้งเตือน</translation> <translation id="2497284189126895209">ไฟล์ทั้งหมด</translation> <translation id="2522350507219695259">การปรับเทียบเสร็จสมบูรณ์</translation> <translation id="252373100621549798">หน้าจอที่ไม่รู้จัก</translation>
diff --git a/ui/strings/translations/ui_strings_tr.xtb b/ui/strings/translations/ui_strings_tr.xtb index 22d1f91..be6135c76 100644 --- a/ui/strings/translations/ui_strings_tr.xtb +++ b/ui/strings/translations/ui_strings_tr.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Anket</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/sn</translation> <translation id="24452542372838207">Bildirimi genişlet</translation> +<translation id="2482878487686419369">Bildirimler</translation> <translation id="2497284189126895209">Tüm Dosyalar</translation> <translation id="2522350507219695259">Kalibrasyon tamamlandı</translation> <translation id="252373100621549798">Bilinmeyen Görünüm</translation>
diff --git a/ui/strings/translations/ui_strings_uk.xtb b/ui/strings/translations/ui_strings_uk.xtb index 0c858611..5321f0c 100644 --- a/ui/strings/translations/ui_strings_uk.xtb +++ b/ui/strings/translations/ui_strings_uk.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Опитування</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> ТБ/сек.</translation> <translation id="24452542372838207">Розгорнути сповіщення</translation> +<translation id="2482878487686419369">Сповіщення</translation> <translation id="2497284189126895209">Усі файли</translation> <translation id="2522350507219695259">Калібрування завершено</translation> <translation id="252373100621549798">Невідомий дисплей</translation>
diff --git a/ui/strings/translations/ui_strings_vi.xtb b/ui/strings/translations/ui_strings_vi.xtb index 665f18da..cd9d43e4 100644 --- a/ui/strings/translations/ui_strings_vi.xtb +++ b/ui/strings/translations/ui_strings_vi.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">Khảo sát</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/giây</translation> <translation id="24452542372838207">Mở rộng thông báo</translation> +<translation id="2482878487686419369">Thông báo</translation> <translation id="2497284189126895209">Tất cả Tệp tin</translation> <translation id="2522350507219695259">Hiệu chỉnh xong</translation> <translation id="252373100621549798">Màn hình không xác định</translation>
diff --git a/ui/strings/translations/ui_strings_zh-CN.xtb b/ui/strings/translations/ui_strings_zh-CN.xtb index 910ef9e1..43ef294 100644 --- a/ui/strings/translations/ui_strings_zh-CN.xtb +++ b/ui/strings/translations/ui_strings_zh-CN.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">调查问卷</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> <translation id="24452542372838207">展开通知</translation> +<translation id="2482878487686419369">通知</translation> <translation id="2497284189126895209">所有文件</translation> <translation id="2522350507219695259">已完成校准</translation> <translation id="252373100621549798">未知展示广告</translation>
diff --git a/ui/strings/translations/ui_strings_zh-TW.xtb b/ui/strings/translations/ui_strings_zh-TW.xtb index 3ef1e6b..c3059573 100644 --- a/ui/strings/translations/ui_strings_zh-TW.xtb +++ b/ui/strings/translations/ui_strings_zh-TW.xtb
@@ -38,6 +38,7 @@ <translation id="2295140143284145483">問卷調查</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/秒</translation> <translation id="24452542372838207">展開通知</translation> +<translation id="2482878487686419369">通知</translation> <translation id="2497284189126895209">所有檔案</translation> <translation id="2522350507219695259">校正完成</translation> <translation id="252373100621549798">顯示器不明</translation>
diff --git a/ui/views/controls/menu/menu_config.cc b/ui/views/controls/menu/menu_config.cc index c54d0076..f8a17b2 100644 --- a/ui/views/controls/menu/menu_config.cc +++ b/ui/views/controls/menu/menu_config.cc
@@ -8,7 +8,6 @@ #include "ui/views/controls/menu/menu_controller.h" #include "ui/views/controls/menu/menu_image_util.h" #include "ui/views/controls/menu/menu_item_view.h" -#include "ui/views/layout/layout_provider.h" #include "ui/views/round_rect_painter.h" namespace views { @@ -25,11 +24,10 @@ minimum_text_item_height(0), minimum_container_item_height(0), minimum_menu_width(0), - item_horizontal_padding(LayoutProvider::Get()->GetDistanceMetric( - DistanceMetric::DISTANCE_RELATED_CONTROL_HORIZONTAL)), - touchable_item_horizontal_padding( - LayoutProvider::Get()->GetDistanceMetric( - DistanceMetric::DISTANCE_TOUCHABLE_RELATED_CONTROL_HORIZONTAL)), + // TODO(ftirelo): Paddings should come from the layout provider, once + // Harmony is the default behavior. + item_horizontal_padding(8), + touchable_item_horizontal_padding(16), label_to_arrow_padding(8), arrow_to_edge_padding(5), touchable_icon_size(20),
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index f058ad6..c31d283f 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -1107,18 +1107,25 @@ gfx::Size child_size = GetChildPreferredSize(); MenuItemDimensions dimensions; - // Get the container height. dimensions.children_width = child_size.width(); const MenuConfig& menu_config = MenuConfig::instance(); if (GetMenuController() && GetMenuController()->use_touchable_layout()) { - // Touchable layout uses a fixed size, but adjusts the height for icons. dimensions.height = menu_config.touchable_menu_height; + + // For container MenuItemViews, the width components should only include the + // |children_width|. Setting a |standard_width| would result in additional + // width being added to the container because the total width used in layout + // is |children_width| + |standard_width|. + if (IsContainer()) + return dimensions; + + dimensions.standard_width = menu_config.touchable_menu_width; + if (icon_view_) { dimensions.height = icon_view_->height() + 2 * menu_config.vertical_touchable_menu_item_padding; } - dimensions.standard_width = menu_config.touchable_menu_width; return dimensions; }
diff --git a/ui/views/controls/menu/menu_item_view_unittest.cc b/ui/views/controls/menu/menu_item_view_unittest.cc index dc4eac69..07273f5d 100644 --- a/ui/views/controls/menu/menu_item_view_unittest.cc +++ b/ui/views/controls/menu/menu_item_view_unittest.cc
@@ -11,7 +11,6 @@ #include "ui/compositor/canvas_painter.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/controls/menu/submenu_view.h" -#include "ui/views/layout/layout_provider.h" #include "ui/views/test/menu_test_utils.h" #include "ui/views/test/views_test_base.h" #include "ui/views/vector_icons.h" @@ -48,21 +47,7 @@ DISALLOW_COPY_AND_ASSIGN(TestMenuItemView); }; -class MenuItemViewUnitTest : public ::testing::Test { - public: - MenuItemViewUnitTest() = default; - ~MenuItemViewUnitTest() override = default; - - private: - // The layout provider is meant to be a singleton, but it is not initialized - // for unit tests. Constructing one here makes it globally available, which - // is later used by the menu item during initialization. - LayoutProvider layout_provider_; - - DISALLOW_COPY_AND_ASSIGN(MenuItemViewUnitTest); -}; - -TEST_F(MenuItemViewUnitTest, TestMenuItemViewWithFlexibleWidthChild) { +TEST(MenuItemViewUnitTest, TestMenuItemViewWithFlexibleWidthChild) { TestMenuItemView root_menu; root_menu.set_owned_by_client(); @@ -101,7 +86,7 @@ // Tests that the top-level menu item with hidden children should contain the // "(empty)" menu item to display. -TEST_F(MenuItemViewUnitTest, TestEmptyTopLevelWhenAllItemsAreHidden) { +TEST(MenuItemViewUnitTest, TestEmptyTopLevelWhenAllItemsAreHidden) { TestMenuItemView root_menu; views::MenuItemView* item1 = root_menu.AppendMenuItemWithLabel(1, base::ASCIIToUTF16("item 1")); @@ -132,7 +117,7 @@ // Tests that submenu with hidden children should contain the "(empty)" menu // item to display. -TEST_F(MenuItemViewUnitTest, TestEmptySubmenuWhenAllChildItemsAreHidden) { +TEST(MenuItemViewUnitTest, TestEmptySubmenuWhenAllChildItemsAreHidden) { TestMenuItemView root_menu; MenuItemView* submenu_item = root_menu.AppendSubMenu(1, base::ASCIIToUTF16("My Submenu")); @@ -163,7 +148,7 @@ empty_item->title()); } -TEST_F(MenuItemViewUnitTest, UseMnemonicOnPlatform) { +TEST(MenuItemViewUnitTest, UseMnemonicOnPlatform) { TestMenuItemView root_menu; views::MenuItemView* item1 = root_menu.AppendMenuItemWithLabel(1, base::ASCIIToUTF16("&Item 1"));
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index e957c3a..1d22a51 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -2161,13 +2161,23 @@ } if (drop_cursor_visible_ && !IsDropCursorForInsertion()) { - // Mark the entire text that will be replaced by the drop. - canvas->FillRect(ToEnclosedRect(render_text->GetStringRect()), - GetSelectionBackgroundColor()); + // Draw as selected to mark the entire text that will be replaced by drop. + // TODO(http://crbug.com/853678): Replace this state push/pop with a clean + // call to a finer grained rendering API when one becomes available. These + // changes are only applied because RenderText is so stateful and subtle + // (e.g. focus is required for the selection to be rendered as selected). + const gfx::SelectionModel sm = render_text->selection_model(); + const bool focused = render_text->focused(); + render_text->SelectAll(true); + render_text->set_focused(true); + render_text->Draw(canvas); + render_text->set_focused(focused); + render_text->SetSelection(sm); + } else { + // Draw text as normal + render_text->Draw(canvas); } - render_text->Draw(canvas); - if (drop_cursor_visible_ && IsDropCursorForInsertion()) { // Draw a drop cursor that marks where the text will be dropped/inserted. canvas->FillRect(render_text->GetCursorBounds(drop_cursor_position_, true),
diff --git a/ui/views/layout/layout_provider.cc b/ui/views/layout/layout_provider.cc index 3bc135a..caba8a52 100644 --- a/ui/views/layout/layout_provider.cc +++ b/ui/views/layout/layout_provider.cc
@@ -94,8 +94,6 @@ return 6; case DistanceMetric::DISTANCE_RELATED_CONTROL_HORIZONTAL: return 8; - case DistanceMetric::DISTANCE_TOUCHABLE_RELATED_CONTROL_HORIZONTAL: - return 16; case DistanceMetric::DISTANCE_RELATED_CONTROL_VERTICAL: return 8; case DistanceMetric::DISTANCE_RELATED_LABEL_HORIZONTAL:
diff --git a/ui/views/layout/layout_provider.h b/ui/views/layout/layout_provider.h index 7206914..cf92ab71 100644 --- a/ui/views/layout/layout_provider.h +++ b/ui/views/layout/layout_provider.h
@@ -85,9 +85,6 @@ DISTANCE_RELATED_BUTTON_HORIZONTAL, // Horizontal spacing between controls that are logically related. DISTANCE_RELATED_CONTROL_HORIZONTAL, - // Horizontal spacing between controls in a touchable context that are - // logically related. - DISTANCE_TOUCHABLE_RELATED_CONTROL_HORIZONTAL, // The spacing between a pair of related vertical controls, used for // dialog layout. DISTANCE_RELATED_CONTROL_VERTICAL,
diff --git a/ui/views/mus/aura_init.cc b/ui/views/mus/aura_init.cc index 16609fc1..0a3c977 100644 --- a/ui/views/mus/aura_init.cc +++ b/ui/views/mus/aura_init.cc
@@ -46,6 +46,10 @@ } // namespace +AuraInit::InitParams::InitParams() : resource_file("views_mus_resources.pak") {} + +AuraInit::InitParams::~InitParams() = default; + AuraInit::AuraInit() { if (!ViewsDelegate::GetInstance()) views_delegate_ = std::make_unique<MusViewsDelegate>(); @@ -53,71 +57,53 @@ AuraInit::~AuraInit() = default; -std::unique_ptr<AuraInit> AuraInit::Create( - service_manager::Connector* connector, - const service_manager::Identity& identity, - const std::string& resource_file, - const std::string& resource_file_200, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - Mode mode, - bool register_path_provider) { +// static +std::unique_ptr<AuraInit> AuraInit::Create(const InitParams& params) { + // Using 'new' to access a non-public constructor. go/totw/134 std::unique_ptr<AuraInit> aura_init = base::WrapUnique(new AuraInit()); - if (!aura_init->Init(connector, identity, resource_file, resource_file_200, - io_task_runner, mode, register_path_provider)) { + if (!aura_init->Init(params)) aura_init.reset(); - } return aura_init; } -bool AuraInit::Init(service_manager::Connector* connector, - const service_manager::Identity& identity, - const std::string& resource_file, - const std::string& resource_file_200, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - Mode mode, - bool register_path_provider) { +bool AuraInit::Init(const InitParams& params) { env_ = aura::Env::CreateInstance(aura::Env::Mode::MUS); - if (mode == Mode::AURA_MUS || mode == Mode::AURA_MUS2) { - MusClient::InitParams params; - params.connector = connector; - params.identity = identity; - params.io_task_runner = io_task_runner; - params.wtc_config = mode == Mode::AURA_MUS2 - ? aura::WindowTreeClient::Config::kMus2 - : aura::WindowTreeClient::Config::kMash; - params.create_wm_state = true; - mus_client_ = std::make_unique<MusClient>(params); + if (params.mode == Mode::AURA_MUS || params.mode == Mode::AURA_MUS2) { + MusClient::InitParams mus_params; + mus_params.connector = params.connector; + mus_params.identity = params.identity; + mus_params.io_task_runner = params.io_task_runner; + mus_params.wtc_config = params.mode == Mode::AURA_MUS2 + ? aura::WindowTreeClient::Config::kMus2 + : aura::WindowTreeClient::Config::kMash; + mus_params.create_wm_state = true; + mus_client_ = std::make_unique<MusClient>(mus_params); } // MaterialDesignController may have initialized already (such as happens // in the utility process). if (!ui::MaterialDesignController::is_mode_initialized()) ui::MaterialDesignController::Initialize(); - if (!InitializeResources(connector, resource_file, resource_file_200, - register_path_provider)) { + if (!InitializeResources(params)) return false; - } ui::InitializeInputMethodForTesting(); return true; } -bool AuraInit::InitializeResources(service_manager::Connector* connector, - const std::string& resource_file, - const std::string& resource_file_200, - bool register_path_provider) { +bool AuraInit::InitializeResources(const InitParams& params) { // Resources may have already been initialized (e.g. when chrome with mash is // used to launch the current app). if (ui::ResourceBundle::HasSharedInstance()) return true; - std::set<std::string> resource_paths({resource_file}); - if (!resource_file_200.empty()) - resource_paths.insert(resource_file_200); + std::set<std::string> resource_paths({params.resource_file}); + if (!params.resource_file_200.empty()) + resource_paths.insert(params.resource_file_200); catalog::ResourceLoader loader; filesystem::mojom::DirectoryPtr directory; - connector->BindInterface(catalog::mojom::kServiceName, &directory); + params.connector->BindInterface(catalog::mojom::kServiceName, &directory); // TODO(jonross): if this proves useful in resolving the crash of // mash_unittests then switch AuraInit to have an Init method, returning a // bool for success. Then update all callsites to use this to determine the @@ -127,17 +113,17 @@ // Calling services will shutdown ServiceContext as appropriate. if (!loader.OpenFiles(std::move(directory), resource_paths)) return false; - if (register_path_provider) + if (params.register_path_provider) ui::RegisterPathProvider(); - base::File pak_file = loader.TakeFile(resource_file); + base::File pak_file = loader.TakeFile(params.resource_file); base::File pak_file_2 = pak_file.Duplicate(); ui::ResourceBundle::InitSharedInstanceWithPakFileRegion( std::move(pak_file), base::MemoryMappedFile::Region::kWholeFile); ui::ResourceBundle::GetSharedInstance().AddDataPackFromFile( std::move(pak_file_2), ui::SCALE_FACTOR_100P); - if (!resource_file_200.empty()) + if (!params.resource_file_200.empty()) ui::ResourceBundle::GetSharedInstance().AddDataPackFromFile( - loader.TakeFile(resource_file_200), ui::SCALE_FACTOR_200P); + loader.TakeFile(params.resource_file_200), ui::SCALE_FACTOR_200P); return true; }
diff --git a/ui/views/mus/aura_init.h b/ui/views/mus/aura_init.h index 1840adb..026af03 100644 --- a/ui/views/mus/aura_init.h +++ b/ui/views/mus/aura_init.h
@@ -9,6 +9,7 @@ #include <string> #include "base/macros.h" +#include "services/service_manager/public/cpp/identity.h" #include "ui/aura/env.h" #include "ui/views/mus/mus_export.h" @@ -22,7 +23,6 @@ namespace service_manager { class Connector; -class Identity; } namespace views { @@ -49,20 +49,24 @@ ~AuraInit(); + struct VIEWS_MUS_EXPORT InitParams { + InitParams(); + ~InitParams(); + service_manager::Connector* connector = nullptr; + service_manager::Identity identity; + // File for strings and 1x icons. Defaults to views_mus_resources.pak. + std::string resource_file; + // File for 2x icons. Can be empty. + std::string resource_file_200; + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr; + Mode mode = Mode::AURA_MUS; + bool register_path_provider = true; + }; + // Returns an AuraInit if initialization can be completed successfully, // otherwise a nullptr is returned. If initialization fails then Aura is in an // unusable state, and calling services should shutdown. - // |resource_file| is the file to load strings and 1x icons from. - // |resource_file_200| can be an empty string, otherwise it is the file to - // load 2x icons from. - static std::unique_ptr<AuraInit> Create( - service_manager::Connector* connector, - const service_manager::Identity& identity, - const std::string& resource_file, - const std::string& resource_file_200 = std::string(), - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr, - Mode mode = Mode::AURA_MUS, - bool register_path_provider = true); + static std::unique_ptr<AuraInit> Create(const InitParams& params); // Only valid if Mode::AURA_MUS was passed to constructor. MusClient* mus_client() { return mus_client_.get(); } @@ -73,18 +77,10 @@ // Returns true if AuraInit was able to successfully complete initialization. // If this returns false, then Aura is in an unusable state, and calling // services should shutdown. - bool Init(service_manager::Connector* connector, - const service_manager::Identity& identity, - const std::string& resource_file, - const std::string& resource_file_200, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - Mode mode, - bool register_path_provider); + bool Init(const InitParams& params); - bool InitializeResources(service_manager::Connector* connector, - const std::string& resource_file, - const std::string& resource_file_200, - bool register_path_provider); + // Returns true on success. + bool InitializeResources(const InitParams& params); std::unique_ptr<aura::Env> env_; std::unique_ptr<MusClient> mus_client_;
diff --git a/ui/views/style/platform_style.cc b/ui/views/style/platform_style.cc index ef68fb5..2ee8334 100644 --- a/ui/views/style/platform_style.cc +++ b/ui/views/style/platform_style.cc
@@ -40,6 +40,11 @@ const bool PlatformStyle::kIsOkButtonLeading = false; #endif +// Set kFocusHaloInset to negative half of kFocusHaloThickness to draw half of +// the focus ring inside and half outside the parent elmeent +const float PlatformStyle::kFocusHaloThickness = 4.f; +const float PlatformStyle::kFocusHaloInset = -2.f; + #if !defined(OS_MACOSX) const int PlatformStyle::kMinLabelButtonWidth = 70; @@ -57,9 +62,6 @@ const bool PlatformStyle::kTextfieldScrollsToStartOnFocusChange = false; const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = true; const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = false; -const float PlatformStyle::kFocusHaloThickness = 2.f; -const float PlatformStyle::kFocusHaloInset = - -PlatformStyle::kFocusHaloThickness; const bool PlatformStyle::kPreferFocusRings = false; // static
diff --git a/ui/views/style/platform_style_mac.mm b/ui/views/style/platform_style_mac.mm index 2106dcce..945f4b2e 100644 --- a/ui/views/style/platform_style_mac.mm +++ b/ui/views/style/platform_style_mac.mm
@@ -42,8 +42,6 @@ const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true; const bool PlatformStyle::kShouldElideBookmarksInBookmarksBar = true; const bool PlatformStyle::kUseRipples = false; -const float PlatformStyle::kFocusHaloThickness = 4.f; -const float PlatformStyle::kFocusHaloInset = -2.f; const bool PlatformStyle::kPreferFocusRings = true; const Button::NotifyAction PlatformStyle::kMenuNotifyActivationAction =
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html index da685bf..7c20b90 100644 --- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html +++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -2,6 +2,7 @@ <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/default-theme.html"> @@ -60,6 +61,7 @@ :host ::slotted([slot=body]) { -webkit-padding-end: 20px; -webkit-padding-start: 20px; + color: var(--secondary-text-color); padding-bottom: 0; padding-top: 0; @apply --cr-dialog-body; @@ -76,6 +78,7 @@ :host ::slotted([slot=title]) { -webkit-padding-end: 20px; -webkit-padding-start: 20px; + color: var(--primary-text-color); flex: 1; font-size: calc(15 / 13 * 100%); line-height: 1;
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.js b/ui/webui/resources/cr_elements/cr_input/cr_input.js index 6ad8bde..5fe6d52 100644 --- a/ui/webui/resources/cr_elements/cr_input/cr_input.js +++ b/ui/webui/resources/cr_elements/cr_input/cr_input.js
@@ -119,7 +119,6 @@ hostAttributes: { 'aria-disabled': 'false', - role: 'textbox', }, listeners: {
diff --git a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html index f1beac3..12dc331 100644 --- a/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html +++ b/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html
@@ -70,9 +70,7 @@ } #subLabel { - /* TODO(dschuyler): replace with: @apply --cr-secondary-text; */ - color: var(--paper-grey-600); - font-weight: 400; + @apply --cr-secondary-text; } </style> <button disabled="[[disabled]]">
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html index 8f1807c..679e3a8 100644 --- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html +++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html
@@ -25,6 +25,7 @@ flex: 1; font-size: 123%; font-weight: 400; + letter-spacing: .25px; line-height: normal; }
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index 1b8e37594..a934ba9a 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -6,6 +6,9 @@ <custom-style> <style is="custom-style"> html { + --primary-text-color: var(--google-grey-900); + --secondary-text-color: var(--google-grey-700); + --cr-actionable: { cursor: pointer; }; @@ -47,12 +50,12 @@ } --cr-primary-text: { - color: var(--paper-grey-900); + color: var(--primary-text-color); line-height: 154%; /* 20px. */ } --cr-secondary-text: { - color: var(--paper-grey-600); + color: var(--secondary-text-color); font-weight: 400; } @@ -89,7 +92,7 @@ }; --cr-section-text: { - color: var(--paper-grey-700); + color: var(--google-grey-700); font-size: 100%; /* Likely to be 13px. */ font-weight: 500; }; @@ -153,6 +156,7 @@ --google-grey-refresh-100: #F1F3F4; --google-grey-200: #E8EAED; --google-grey-400: #BDC1C6; + --google-grey-600: #80868B; --google-grey-900: #202124; --google-red-600: #D93025; }
diff --git a/ui/wm/BUILD.gn b/ui/wm/BUILD.gn index 4309bae..f833d4c 100644 --- a/ui/wm/BUILD.gn +++ b/ui/wm/BUILD.gn
@@ -119,6 +119,7 @@ "//ui/base/ime", "//ui/events", "//ui/events:events_base", + "//ui/platform_window", ] } @@ -158,6 +159,7 @@ "//ui/gfx/animation", "//ui/gfx/geometry", "//ui/gl:test_support", + "//ui/platform_window", "//ui/resources", "//ui/wm/public", ]
diff --git a/ui/wm/core/DEPS b/ui/wm/core/DEPS index 3d4d8af..255fd3b 100644 --- a/ui/wm/core/DEPS +++ b/ui/wm/core/DEPS
@@ -14,6 +14,7 @@ "+ui/compositor_extra", "+ui/events", "+ui/gfx", + "+ui/platform_window", "+ui/resources/grit/ui_resources.h", "+ui/views/views_export.h", ]
diff --git a/ui/wm/core/capture_controller_unittest.cc b/ui/wm/core/capture_controller_unittest.cc index ecbe720..26a1f6e6 100644 --- a/ui/wm/core/capture_controller_unittest.cc +++ b/ui/wm/core/capture_controller_unittest.cc
@@ -18,6 +18,7 @@ #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/events/test/event_generator.h" +#include "ui/platform_window/platform_window_init_properties.h" #include "ui/wm/core/capture_controller.h" namespace wm { @@ -58,7 +59,8 @@ AuraTestBase::SetUp(); capture_controller_.reset(new ScopedCaptureClient(root_window())); - second_host_.reset(aura::WindowTreeHost::Create(gfx::Rect(0, 0, 800, 600))); + second_host_ = aura::WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(0, 0, 800, 600)}); second_host_->InitHost(); second_host_->window()->Show(); second_host_->SetBoundsInPixels(gfx::Rect(800, 600));
diff --git a/ui/wm/test/DEPS b/ui/wm/test/DEPS index 657fde12..e6b51d4 100644 --- a/ui/wm/test/DEPS +++ b/ui/wm/test/DEPS
@@ -5,6 +5,7 @@ "+ui/base/resource/resource_bundle.h", "+ui/base/ui_base_paths.h", "+ui/gl", + "+ui/platform_window", "+ui/views", ]
diff --git a/ui/wm/test/wm_test_helper.cc b/ui/wm/test/wm_test_helper.cc index 045d3f8..05b0718 100644 --- a/ui/wm/test/wm_test_helper.cc +++ b/ui/wm/test/wm_test_helper.cc
@@ -18,6 +18,7 @@ #include "ui/aura/test/mus/window_tree_client_private.h" #include "ui/aura/test/test_focus_client.h" #include "ui/aura/window.h" +#include "ui/platform_window/platform_window_init_properties.h" #include "ui/wm/core/compound_event_filter.h" #include "ui/wm/core/default_activation_client.h" #include "ui/wm/core/wm_state.h" @@ -48,8 +49,7 @@ new aura::client::DefaultCaptureClient(host_->window())); } -WMTestHelper::~WMTestHelper() { -} +WMTestHelper::~WMTestHelper() = default; aura::Window* WMTestHelper::GetDefaultParent(aura::Window* window, const gfx::Rect& bounds) { @@ -57,7 +57,8 @@ } void WMTestHelper::InitLocalHost(const gfx::Size& default_window_size) { - host_.reset(aura::WindowTreeHost::Create(gfx::Rect(default_window_size))); + host_ = aura::WindowTreeHost::Create( + ui::PlatformWindowInitProperties{gfx::Rect(default_window_size)}); host_->InitHost(); }